diff --git a/C3d/Include/action.h b/C3d/Include/action.h new file mode 100644 index 0000000..670ccf1 --- /dev/null +++ b/C3d/Include/action.h @@ -0,0 +1,1276 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции работы с кривыми, поверхностями, оболочками, телами. + \en Functions for operating with curves, surfaces, shells and solids. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_H +#define __ACTION_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbPlanarGrid; +class MATH_CLASS MbGrid; +class MATH_CLASS MbSNameMaker; +class IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить оболочку на предмет разделения на отдельные части. + \en Check if the shell can be subdivided into separate parts. \~ + \details \ru Проверить замкнутую оболочку на предмет разделения на отдельные части с анализом вложенности. \n + \en Check if the closed shell can be subdivided into separate parts with inclusion analysis. \n \~ + \param[in] shell - \ru Исходная оболочка. + \en The initial shell. \~ + \result \ru Возвращает true, если оболочка состоит из нескольких частей. + \en Returns 'true' if the shell consists of several parts. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsMultiShell( const MbFaceShell * shell, bool checkNesting = true ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отделить части оболочки. + \en Separate parts from a shell. \~ + \details \ru Отделить части оболочки без анализа вложенности. + Если sort == true, то наибольшая часть оболочки останется в исходной оболочке, + а отделившиеся от неё части будут сложены в parts с сортировкой по убыванию габарита. \n + \en Separate parts from a shell without inclusion analysis. + If 'sort' == 'true', the greatest part of the shell will remain in the initial shell, + separated parts will be collected in array 'parts' sorted by bounding box size in descending order. \n \~ + \param[in] shell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[out] parts - \ru Оболочки, полученные из shell. + \en The shells separated from 'shell'. \~ + \param[in] sort - \ru Выполнять ли сортировку частей оболочки по убыванию габарита? + \en If 'sort' == true, the parts separated from the initial shell will be sorted by bounding box size in descending order. \~ + \result \ru Возвращает количество оболочек в parts. + \en Returns number of shells in 'parts'. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (size_t) DetachShells( MbFaceShell & shell, RPArray & parts, bool sort ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отделить части оболочки. + \en Separate parts from a shell. \~ + \details \ru Отделить части оболочки без анализа вложенности. + Исходная оболочка всегда остаётся неизменённой. + Если исходная оболочка распадается на части, то все части складываются в parts. \n + \en Separate parts from a shell without inclusion analysis. + The initial shell always remains unchangeable. + If the initial shell is decomposed, all the parts are put into array 'parts'. \n \~ + \param[in] shell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[out] parts - \ru Оболочки, полученные из shell. + \en The shells separated from 'shell'. \~ + \result \ru Возвращает количество оболочек в parts. + \en Returns number of shells in 'parts'. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (size_t) CreateShells( MbFaceShell & shell, RPArray & parts ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку выдавливанием плоских контуров. + \en Create a shell by extrusion of planar contours. \~ + \details \ru Построить оболочку выдавливанием плоских контуров. \n + \en Create a shell by extrusion of planar contours. \n \~ + \param[in] surface - \ru Поверхность контуров. + \en A surface that contains the contours. \~ + \param[in] contours - \ru Набор двумерных контуров. + \en A set of planar contours. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] params - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] cNames - \ru Набор именователей контуров. + \en A set of objects defining names of the contours. \~ + \param[out] result - \ru Результат операции - оболочка. + \en Result of the operation - a shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtrusionShell( const MbSurface & surface, + RPArray & contours, + const MbVector3D & direction, + const ExtrusionValues & params, + const MbSNameMaker & operNames, + RPArray & cNames, + MbFaceShell *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку вращением плоских контуров. + \en Create a shell by revolution of planar contours. \~ + \details \ru Построить оболочку вращением плоских контуров. \n + \en Create a shell by revolution of planar contours. \n \~ + \param[in] surface - \ru Поверхность контуров. + \en A surface that contains the contours. \~ + \param[in] contours - \ru Набор двумерных контуров. + \en A set of planar contours. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] params - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] cNames - \ru Набор именователей контуров. + \en A set of objects defining names of the contours. \~ + \param[out] result - \ru Результат операции - оболочка. + \en Result of the operation - a shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RevolutionShell( const MbSurface & surface, + RPArray & contours, + const MbAxis3D & axis, + const RevolutionValues & params, + const MbSNameMaker & operNames, + RPArray & cNames, + MbFaceShell *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Объединить компланарные грани. + \en Unite complanar faces. \~ + \details \ru Объединить компланарные грани оболочки и проверить оболочку. \n + \en Unite complanar faces of a shell and validate the shell. \n \~ + \param[in] shell - \ru Модифицируемая оболочка. + \en A shell to be modified. \~ + \param[in] nameMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] checkBaseSurfaces - \ru Найти и устранить общие поверхности-подложки в гранях. + \en Find and eliminate common underlying surfaces of faces \~ + \return \ru Возвращает true, если оболочка была успешно изменена. + \en Returns 'true' if the shell has been successfully modified. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) UnifyOwnComplanarFaces( MbFaceShell & shell, + const MbSNameMaker & nameMaker, + bool checkBaseSurfaces ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти и устранить общие поверхности-подложки в гранях. + \en Find and eliminate common underlying surfaces of faces \~ + \details \ru Найти и устранить общие поверхности-подложки в гранях оболочки. \n + \en Find and eliminate common underlying surfaces of a shell faces. \n \~ + \param[in] shell - \ru Модифицируемая оболочка. + \en A shell to be modified. \~ + \return \ru Возвращает true, если оболочка была изменена. + \en Returns 'true' if the shell has been modified. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) CheckIdenticalBaseSufaces( MbFaceShell & shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Захватить грани одним из способов. + \en Capture the faces in one of proposed methods. \~ + \details \ru Захватить грани одним из способов распространения по связной оболочке. \n + \en Capture the faces in one of methods of propagation in connected shell. \n \~ + \param[in] fp - \ru Cпособ захвата граней. + \en A method of capturing the faces. \~ + \param[in,out] face_set - \ru Набор граней. + \en A set of faces. \~ + \param[in] dir - \ru Направление уклона. + \en A direction of inclination. \~ + \warning \ru Вспомогательная функция операции DraftSolid. + \en An auxillary function of operation DraftSolid. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) FacePropagate( const MbeFacePropagation fp, + RPArray & face_set, + const MbVector3D & dir ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Масштабировать каверны литейной формы. + \en Scale cavities of a mold. \~ + \details \ru Масштабировать каверны литейной формы относительно неподвижной точки. \n + \en Scale cavities of a mold relative to a fixed point. \n \~ + \param[in,out] solids - \ru Модифицируемые тела. + \en The solids to be modified. \~ + \param[in] fixedPoint - \ru Неподвижная точка масштабирования. + \en The fixed point of scaling. \~ + \param[in] deltaX - \ru Относительное приращение размера по направлению X. + \en Relative increment of size in X-direction. \~ + \param[in] deltaY - \ru Относительное приращение размера по направлению Y. + \en Relative increment of size in Y-direction. \~ + \param[in] deltaZ - \ru Относительное приращение размера по направлению Z. + \en Relative increment of size in Z-direction. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) MouldCavitySolids( RPArray & solids, + MbCartPoint3D * fixedPoint, + double deltaX, + double deltaY, + double deltaZ ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить тела на пересечение. + \en Check intersection of solids. \~ + \details \ru Проверить тела на пересечение без уточнения характера пересечения \n + (проверяем до первого пересечения граней). \n + \en Check if solids intersect each other without definition of intersection type \n + (check until the first intersection is detected). \n \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \return \ru Возвращает true, если найдено хотя бы одно пересечение. + \en Returns 'true' if at least one intersection is detected. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsSolidsIntersection( const MbSolid & solid1, const MbSolid & solid2, const MbSNameMaker & snMaker ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить пересечение тел в сборке. + \en Check intersection of solids in an assembly. \~ + \details \ru Определить пересечение тел в сборке. \n + \en Check intersection of solids in an assembly. \n \~ + \param[in] solid1 - \ru Первое тело в локальной системе координат (ЛСК). + \en The first solid in local coordinate system (LCS). \~ + \param[in] matr1 - \ru Матрица преобразования в глобальную СК (ГСК). + \en Matrix of transformation to the global coordinate system (GCS). \~ + \param[in] solid2 - \ru Второе тело в ЛСК. + \en The second solid in LCS. \~ + \param[in] matr2 - \ru Матрица преобразования в ГСК. + \en Matrix of transformation to GCS. \~ + \param[in] checkTangent - \ru Считать касания пересечениями. + \en Consider tangencies as intersections. \~ + \param[in] getIntersectionSolids - \ru Получить не касательные пересечения в виде тел. + \en Get non-tangent intersections in the form of bodies. \~ + \param[in] checkTouchPoints - \ru Искать точки касания. + \en Find touch points. \~ + \param[out] intData - \ru Информация о пересечении двух тел. + \en Information about two solids intersection. \~ + \return \ru Возвращает true, если найдено хотя бы одно пересечение. + \en Returns 'true' if at least one intersection is detected. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsSolidsIntersection( const MbSolid & solid1, const MbMatrix3D & matr1, + const MbSolid & solid2, const MbMatrix3D & matr2, + bool checkTangent, // \ru Считать касания пересечениями \en Consider tangencies as intersections + bool getIntersectionSolids, // \ru Получить не касательные пересечения в виде тел \en Get non-tangency intersection as solids + bool checkTouchPoints, // \ru Искать точки касания \en Find touch points + RPArray & intData ); + +//------------------------------------------------------------------------------ +/** \brief \ru Определить минимальное расстояние между телами в сборке. + \en Determine the minimum distance between solids in an assembly. \~ + \details \ru Определить минимальное расстояние между телами в сборке. В случае пересечения или касания тел возвращается нулевая дистанция.\n + При многократном использовании первого тела следует установить isMultipleUseSolid1 = true, иначе false. Аналогично для второго тела.\n + \en Determine the minimum distance between solids in an assembly. In case of intersection or tangent of the shells returns to zero distance.\n + With multiple use of the first body should be set isMultipleUseSolid1 = true, else false. Similarly for the second body.\n \~ + \param[in] solid1 - \ru Первое тело в локальной системе координат (ЛСК). + \en The first solid in local coordinate system (LCS). \~ + \param[in] matr1 - \ru Матрица преобразования в глобальную СК (ГСК). + \en Matrix of transformation to the global coordinate system (GCS). \~ + \param[in] isMultipleUseSolid1 - \ru Множественное использование первого тела. + \en Multiple use of the first body. \~ + \param[in] solid2 - \ru Второе тело в ЛСК. + \en The second solid in LCS. \~ + \param[in] matr2 - \ru Матрица преобразования в ГСК. + \en Matrix of transformation to GCS. \~ + \param[in] isMultipleUseSolid2 - \ru Множественное использование второго тела. + \en Multiple use of the second body. \~ + \param[in] lowerLimitDistance - \ru Минимальное допустимое расстояние. + \en Minimum allowed distance. \~ + \param[in] tillFirstLowerLimit - \ru Искать до первого найденного удовлетворяющего минимально допустимому расстоянию. + \en Search until the first found that satisfies the minimum acceptable distance. \~ + \param[out] shellsDistanceData - \ru Информация о расстоянии между телами. + \en Information about the distance between solids. \~ + \return \ru Возвращает true, если определено хотя бы одно расстояние. + \en Returns 'true' if at least one distance is obtained. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MinimumSolidsDistance( const MbSolid & solid1, const MbMatrix3D & matr1, bool isMultipleUseSolid1, + const MbSolid & solid2, const MbMatrix3D & matr2, bool isMultipleUseSolid2, + double lowerLimitDistance, bool tillFirstLowerLimit, + std::vector & shellsDistanceData ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния от контура на плоскости до поверхности. + \en Find the distances from a contour on a plane to a surface. \~ + \details \ru Найти расстояния от контура на плоскости до поверхности. \n + Прямое направление - это направление оси Z системы координат двумерной кривой. \n + Расстояние в прямом направлении найдено, если значение не отрицательное. \n + Расстояние в обратном направлении найдено, если значение не положительное. \n + \en Find the distances from a contour on a plane to a surface. \n + A forward direction is a direction of Z-axis of two-dimensional curve coordinate system. \n + The distance in a forward direction is found if the value is non-negative. \n + The distance in a backward direction is found if the value is non-positive. \n \~ + \param[in] pl - \ru Система координат двумерной кривой. + \en A coordinate system of two-dimensional curve. \~ + \param[in] curve - \ru Двумерная кривая. + \en A two-dimensional curve. \~ + \param[in] surf - \ru Поверхность, до которой проводится поиск расстояний. + \en A surface to measure the distances up to. \~ + \param[out] lPlus - \ru Расстояние в прямом направлении. + \en The distance in a forward direction. \~ + \param[out] lMinus - \ru Расстояние в обратном направлении. + \en The distance in a backward direction. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) GetDistanceToSurface( const MbPlacement3D & pl, + const MbCurve * curve, + const MbSurface * surf, + double & lPlus, + double & lMinus ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание поверхностей сечения выдавливания плоского контура. + \en Create cutter surfaces for extrusion of planar contours. \~ + \details \ru Создание поверхностей сечения выдавливания плоского контура и определение направлений выдавливаний. \n + \en Create cutter surfaces for extrusion of planar contours and define directions of extrusions. \n \~ + \param[in] surface - \ru Поверхность контуров. + \en A surface that contains the contours. \~ + \param[in] contours - \ru Набор двумерных контуров. + \en A set of planar contours. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] params - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] version - \ru Версия построения. + \en The version of construction. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \param[out] surfAndDir- \ru Результат операции - поверхности и направление относительно direction. + \en Result of the operation - surfaces and directions relative to parameter direction. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (void) CreateExtrusionCutSurfaces( const MbSurface & surface, + const c3d::PlaneContoursSPtrVector & contours, + const MbVector3D & direction, + ExtrusionValues & params, + VERSION version, + MbResultType & resType, + std::vector< std::pair> & surfAndDir ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния от контура на поверхности до габаритного куба оболочки. + \en Find the distances from a contour on a surface to the bounding box of a shell. \~ + \details \ru Найти расстояния от контура на поверхности до габаритного куба оболочки. \n + Расстояние в прямом направлении найдено, если значение не отрицательное. \n + Расстояние в обратном направлении найдено, если значение не положительное. \n + \en Find the distances from a contour on a surface to the bounding box of a shell. \n + The distance in a forward direction is found if the value is nonnegative. \n + The distance in a backward direction is found if the value is non-positive. \n \~ + \param[in] surface - \ru Поверхность, на которой лежит двумерная кривая. + \en A surface that contains the two-dimensional curve. \~ + \param[in] direction - \ru Направление поиска (выдавливания) + \en A direction of the distance calculation (an extrusion direction). \~ + \param[in] curve - \ru Двумерная кривая, лежащая на поверхности surface. + \en A two-dimensional curve on surface 'surface'. \~ + \param[in] cube - \ru Габаритный куб оболочки. + \en The bounding box of the shell. \~ + \param[out] lPlus - \ru Расстояние в прямом направлении. + \en The distance in a forward direction. \~ + \param[out] lMinus - \ru Расстояние в обратном направлении. + \en The distance in a backward direction. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) GetDistanceToCube( const MbSurface & surface, + const MbVector3D & direction, + const MbCurve & curve, + const MbCube & cube, + double & lPlus, + double & lMinus, + MbResultType & resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния от набора кривых на поверхности до габаритного куба оболочки. + \en Find the distances from curves on a surface to the bounding box of a shell. \~ + \details \ru Найти расстояния от набора кривых на поверхности до габаритного куба оболочки. \n + Расстояние в прямом направлении найдено, если значение не отрицательное. \n + Расстояние в обратном направлении найдено, если значение не положительное. \n + \en Find the distances from curves on a surface to the bounding box of a shell. \n + The distance in a forward direction is found if the value is nonnegative. \n + The distance in a backward direction is found if the value is nonpositive. \n \~ + \param[in] surface - \ru Поверхность, на которой лежат двумерные кривые. + \en A surface that contains two-dimensional curves. \~ + \param[in] direction - \ru Направление поиска (выдавливания) + \en A direction of the distance calculation (an extrusion direction). \~ + \param[in] curves - \ru Набор двумерных кривых на поверхности surface. + \en A set of two-dimensional curves on the surface 'surface'. \~ + \param[in] cube - \ru Габаритный куб оболочки. + \en The bounding box of the shell. \~ + \param[out] lPlus - \ru Расстояние в прямом направлении. + \en The distance in a forward direction. \~ + \param[out] lMinus - \ru Расстояние в обратном направлении. + \en The distance in a backward direction. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) GetDistanceToCube( const MbSurface & surface, + const MbVector3D & direction, + const RPArray & curves, + const MbCube & cube, + double & lPlus, + double & lMinus, + MbResultType & resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния от плоскости до габаритного куба оболочки. + \en Find the distances from a plane to the bounding box of a shell. \~ + \details \ru Найти расстояния от плоскости до габаритного куба оболочки. \n + Расстояние в прямом направлении найдено, если значение не отрицательное. \n + Расстояние в обратном направлении найдено, если значение не положительное. \n + Использует расчет габарита относительно локальной системы координат. \n + Если система координат плоскости лежит вне габаритного куба, \n + то при взведенном флаге findMax ищется максимальное расстояние до куба. \n + \en Find the distances from a plane to the bounding box of a shell. \n + The distance in a forward direction is found if the value is non-negative. \n + The distance in a backward direction is found if the value is non-positive. \n + Calculation of the distance relative to the local coordinate system is used. \n + If a plane coordinate system is out of the bounding box, \n + then if the flag 'findMax' is set to 'true', the maximal distance to bounding box is calculated. \n \~ + \param[in] pl - \ru Система координат плоскости. + \en The plane coordinate system. \~ + \param[in] shell - \ru Целевая оболочка. + \en A target shell. \~ + \param[out] dPlus - \ru Расстояние в прямом направлении. + \en The distance in a forward direction. \~ + \param[out] dMinus - \ru Расстояние в обратном направлении. + \en The distance in a backward direction. \~ + \param[in] findMax - \ru Искать максимальное расстояние до габаритного куба. + \en The maximal distance to bounding box is to be calculated. \~ + \return \ru Возвращает true, если найдено хотя бы одно из расстояний. + \en Returns 'true' if at least one of the distances has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) GetDistanceToCube( const MbPlacement3D & pl, + const MbFaceShell * shell, + double & dPlus, + double & dMinus, + bool findMax = true ); // \ru Искать максимальное \en Find the maximal distance + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния/углы от контура до куба или до поверхности. + \en Find the distances/angles from a contour to a bounding box or to a surface. \~ + \details \ru Найти расстояния/углы от контура до куба или до поверхности. \n + Нужно учесть уклон в двух направлениях. \n + \en Find the distances/angles from a contour to a bounding box or to a surface. \n + The inclination in two directions is to be considered. \n \~ + \param[in] curve - \ru Кривая. + \en A curve. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] rotation - \ru Вращение (true) или выдавливание (false) + \en Rotation (true) or extrusion (false) \~ + \param[in] operationDirection - \ru Вперед (true) или назад (false) + \en Forward (true) or backward (false) \~ + \param[in] toCube - \ru До куба, если указатель ненулевой + \en Up to a cube if the pointer is not null. \~ + \param[in] toSurface - \ru До поверхности, если указатель ненулевой. + \en Up to a surface if the pointer is not null. \~ + \param[in,out] params: +\ru Должны быть заданы параметры: \n + params.side1.rake - Уклон в направлении direction (для плоской образующей). \n + params.side2.rake - Уклон в направлении direction, обратном direction (для плоской образующей). \n + params.thikness1 - Толщина стенки в прямом направлении + (в положительном направлении нормали объекта (грани, поверхности, плоскости кривой)). \n + params.thikness2 - Толщина стенки в обратном направлении. \n + Заполняются параметры: \n + params.side1.scalarValue - Расстояние выдавливания в направлении direction (если operationDirection == true), + иначе обратном. \n + params.side2.scalarValue - Расстояние выдавливания в направлении, обратном direction (если operationDirection == true), + иначе в прямом. \n +\en The following parameters should be defined: \n + params.side1.rake - The inclination in direction 'direction' (for a planar generatrix). \n + params.side2.rake - The inclination in direction opposite to 'direction' (for a planar generatrix). \n + params.thikness1 - Wall thickness in forward direction. + (in the positive direction of the normal of an object (a face, a surface, the plane of a curve)). \n + params.thikness2 - The wall thickness in the backward direction. \n + The output parameters: \n + params.side1.scalarValue - The extrusion distance in the direction 'direction' (if 'operationDirection' == true), + else in the opposite direction. \n + params.side2.scalarValue - The extrusion distance in the direction opposite to 'direction' (if 'operationDirection' == true), + else in the forward direction. \n \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) GetRangeToCubeOrSurface( const MbCurve3D & curve, + const MbVector3D & direction, + const MbAxis3D & axis, + const bool rotation, + bool operationDirection, + const MbCube * toCube, + const MbSurface * toSurface, + SweptValuesAndSides & params, + MbResultType & resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти ближайшие тела при выдавливании с опцией "до ближайшего объекта". + \en Find the nearest solids while extruding with option 'up to the nearest object'. \~ + \details \ru Найти ближайшие тела при выдавливании с опцией "до ближайшего объекта". \n + Возвращает номерa (nPlus и nMinus) ближайших тел с положительной и отрицательной стороны эскиза. + \en Find the nearest solids while extruding with option 'up to the nearest object'. \n + Returns the numbers (nPlus and nMinus) of nearest solids on the positive and the negative sides of the sketch. \~ + \param[in] pl - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] c - \ru Множество двумерных контуров. + \en An array of two-dimensional contours. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] solids - \ru Целевой набор тел. + \en A target set of solids. \~ + \param[out] nPlus - \ru Номер ближайшего тела в положительном направлении. + \en The number of the nearest solid in the positive direction. \~ + \param[out] nMinus - \ru Номер ближайшего тела в отрицательном направлении. + \en The number of the nearest solid in the negative direction. \~ + \return \ru Возвращает true, если найдено тело хотя бы в одном из направлений. + \en Returns 'true' if a solid is found in at least one of directions. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) GetNearestSolid( const MbPlacement3D & pl, + RPArray & c, + MbSweptLayout::Direction direction, + RPArray & solids, + size_t & nPlus, + size_t & nMinus ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти ближайшие тела при выдавливании с опцией "до ближайшего объекта". + \en Find the nearest solids while extruding with option 'up to the nearest object'. \~ + \details \ru Найти ближайшие тела при выдавливании с опцией "до ближайшего объекта". \n + возвращает номерa (nPlus и nMinus) ближайших тел ближайших тел в прямом и обратном направлении. + \en Find the nearest solids while extruding with option 'up to the nearest object'. \n + returns numbers (nPlus and nMinus) of the nearest solids in the forward and the backward direction. \~ + \param[in] curves - \ru Набор кривых. + \en A set of curves. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] operationDirection - \ru Параметры выдавливания "до ближайшего объекта". + \en Parameters of extrusion 'up to the nearest object'. \~ + \param[in] solids - \ru Целевой набор тел. + \en A target set of solids. \~ + \param[out] nPlus - \ru Номер ближайшего тела в положительном направлении. + \en The number of the nearest solid in the positive direction. \~ + \param[out] nMinus - \ru Номер ближайшего тела в отрицательном направлении. + \en The number of the nearest solid in the negative direction. \~ + \return \ru Возвращает true, если найдено тело хотя бы в одном из направлений. + \en Returns 'true' if a solid is found in at least one of directions. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) GetNearestSolid( RPArray & curves, + const MbVector3D & direction, + MbSweptLayout::Direction operationDirection, + RPArray & solids, + size_t & nPlus, + size_t & nMinus ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить оболочку или тело, состоящее из NURBS поверхностей. + \en Check a shell or a solid that consists of NURBS surfaces. \~ + \details \ru Проверить корректность оболочки или тела, состоящего из NURBS поверхностей. \n + \en Check the correctness of a shell or a solid that consists of NURBS surfaces. \n \~ + \param[in] params - \ru Исходные параметры операции. + \en Initial parameters of the operation. \~ + \param[in] nsSolid - \ru Тело - результат операции. + \en A solid - the result of the operation. \~ + \param[in] progBar - \ru Индикатор прогресса выполнения операции. + \en A progress indicator of the operation. \~ + \return \ru Возвращает rt_Success, если тело успешно прошло проверку. + \en Returns rt_Success if the solid has successfully passed the validation. \~ + \warning \ru Проверочная функция операции NurbsSurfacesShell. + \en A checking function of the operation NurbsSurfacesShell. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) CheckNurbsShell( const NurbsSurfaceValues & params, + const MbSolid & nsSolid, + IProgressIndicator * progBar ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Положить эскиз в массив усекающих объектов. + \en Add a sketch to the array of truncating objects. \~ + \details \ru Положить эскиз в массив усекающих объектов путем создания пространственных кривых. \n + \en Add a sketch to the array of truncating objects by creation of spatial curves. \n \~ + \param[in] sketchPlace - \ru Локальная система координат двумерного эскиза. + \en A local coordinate system of two-dimensional sketch. \~ + \param[in] sketchCurves - \ru Двумерные кривые эскиза. + \en Two-dimensional curves of the sketch. \~ + \param[out] items - \ru Выходной массив пространственных объектов. + \en The output array of spatial objects. \~ + \return \ru - Возвращает true в случае добавления элементов в выходной массив. + \en - Returns 'true' if elements are added into output array. \~ + \warning \ru Вспомогательная функция операции TruncateShell. + \en Auxiliary function of the operation TruncateShell. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) AddTruncatingSketch( const MbPlacement3D & sketchPlace, + RPArray & sketchCurves, + RPArray & items ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Положить кривую в массив усекающих объектов. + \en Add a curve to the array of truncating objects. \~ + \details \ru Положить кривую в массив усекающих объектов + (с разбором кривой на составляющие, в случае необходимости). \n + \en Add a curve to the array of truncating objects + (with decomposition of the curve if necessary). \n \~ + \param[in] curve - \ru Пространственная кривая. + \en A space curve. \~ + \param[out] items - \ru Выходной массив пространственных объектов. + \en The output array of spatial objects. \~ + \warning \ru Вспомогательная функция операции TruncateShell. + \en Auxillary function of the operation TruncateShell. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) AddTruncatingCurve( const MbCurve3D & curve, + RPArray & items ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить корректность вскрываемых граней для создания тонкостенного тела. + \en Check the correctness of shelling faces for creation of a thin-walled solid. \~ + \details \ru Проверить корректность набора вскрываемых граней для создания тонкостенного тела. \n + Удаляет из массива не подходящие для операции грани (гладко сопряженные с невыбранными гранями). \n + \en Check the correctness of shelling faces set for creation of a thin-walled solid. \n + Removes unsuitable for the operation faces from the array (Delete faces smoothly connected to unselected faces). \n \~ + \param[in] params - \ru Параметры тонкой стенки. + \en Parameters of a thin wall. \~ + \param[in,out] faces - \ru Множество вскрываемых граней тела. + \en An array of shelling faces of the solid. \~ + \warning \ru Вспомогательная функция операции построения тонкостенного тела. + \en An auxiliary function of thin-walled solid construction operation. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) CheckShellingFaces( const SweptValues & params, RPArray & faces ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить компоненты проекции вектора, заданного в точке на поверхности. + \en Calculate the components of projection of a vector defined at a point on the surface. \~ + \details \ru Вычислить компоненты x и y проекции пространственного вектора, заданного в точке на поверхности. \n + \en Calculate x and y components of projection of a space vector defined at a point on a surface. \n \~ + \param[in] v3d - \ru Пространственный вектор. + \en A space vector. \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] p2d - \ru Параметрическая точка на поверхности. + \en A parametric point on the surface. \~ + \param[out] v2d - \ru Проекция пространственного вектора на поверхность. + \en The projection of the space vector on the surface. \~ + \return \ru - Возвращает true в случае успешного вычисления проекции вектора. + \en - Returns 'true' if the vector projection has been successfully calculated. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) ProjectVectorOn( const MbVector3D & v3d, const MbSurface & surface, const MbCartPoint & p2d, + MbVector & v2d ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширить поверхность для резки тела. + \en Extend a surface for cutting a solid. \~ + \details \ru Расширить поверхность до заданного габарита для резки тела. \n + \en Extend a surface to a given bounding box for cutting a solid. \n \~ + \param[in,out] gabarit - \ru Желаемый габарит расширения. + \en A desirable bounding box of the extended surface. \~ + \param[in] surf - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] prolongState - \ru Состояние типа продления секущих поверхностей. + \en State of prolongation types of cutter surfaces. \~ + \param[in] version - \ru Версия построения. + \en The version of construction. \~ + \return \ru - Возвращает расширенную поверхность, если получилось ее создать. + \en - Returns the extended surface if it has been successfully created. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbSurface *) GetExtendedSurfaceCopy( MbCube & gabarit, + const MbSurface & surf, + const MbShellCuttingParams::ProlongState & prolongState, + VERSION version ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить набор граней с топологией призмы. + \en Create a set of faces with topology of a prism. \~ + \details \ru Построить набор граней с топологией призмы. \n + \en Create a set of faces with topology of a prism. \n \~ + \param[in] place - \ru Локальная система координат (ЛСК). + \en A local coordinate system (LCS). \~ + \param[in] contour - \ru Двумерный контур в ЛСК. + \en A two-dimensional curve in LCS. \~ + \param[in] der - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] sense - \ru Ориентация выходного массива граней как замкнутой оболочки. + \en An orientation of the output array of faces as a closed shell. \~ + \param[in] n - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in,out] initFaces - \ru Множество созданных граней. + \en The array of created faces. \~ + \param[in] useAddCount - \ru Использовать количество граней initFaces на входе для именования новых граней. + \en The number of input faces initFaces is to be used for naming the new faces. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) CreateFaces( const MbPlacement3D & place, const MbContour & contour, + const MbVector3D & der, bool sense, const MbSNameMaker & n, + RPArray & initFaces, bool useAddCount = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Оценить параметры выдавливания для ребра жёсткости. + \en Estimate parameters of extrusion for a rib. \~ + \details \ru Оценить параметры выдавливания для построения ребра жёсткости. \n + \en Estimate parameters of extrusion for creating a rib. \n \~ + \param[in] shell - \ru Целевая оболочка. + \en A target shell. \~ + \param[in] place - \ru Локальная система координат контура. + \en A local coordinate system of the contour. \~ + \param[in] contour - \ru Двумерный контур. + \en A two-dimensional contour. \~ + \param[in] index - \ru Номер сегмента контура. + \en A number of the contour segment. \~ + \param[out] side - \ru Сторона заполнения пространства телом ребра. + \en The side to place the rib on. \~ + \param[out] origin - \ru Точка. + \en A point. \~ + \param[out] dir3D - \ru Вектор. + \en A vector. \~ + \warning \ru Вспомогательная функция операции RibSolid. + \en An auxillary function of the operation RibSolid. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) GetAutoReference( MbFaceShell & shell, + const MbPlacement3D & place, + const MbContour & contour, + ptrdiff_t index, + RibValues::ExtrudeSide & side, + MbCartPoint3D & origin, + MbVector3D & dir3D ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую в параметрах поверхности. + \en Create a curve in the parameter space of a surface. \~ + \details \ru Создать кривую в параметрах поверхности, если нужно - проекционную. \n + Если проекционную кривую создавать не нужно, возвращает дубль двумерной кривой в параметрах поверхности. \n + После использования кривую нужно удалить. \n + \en Create a curve in the parameter space of a surface. The projection curve can be created if necessary. \n + If it is not required to create the projection curve, returns a copy of two-dimensional curve in the parameter space of the surface. \n + The curve is to be deleted after use. \n \~ + \param[in] intersectCurve - \ru Кривая пересечения. + \en The intersection curve \~ + \param[in] first - \ru true - Первая поверхность, false - вторая поверхность. + \en True - The first surface, false - the second surface. \~ + \return \ru Возвращает кривую, если ее получилось построить. + \en Returns the curve if it has been successfully created. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbCurve *) GetProjCurveOnSurface( const MbSurfaceIntersectionCurve & intersectCurve, bool first ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить неизменность вектора кинематической направляющий в разных версиях. + \en Check the invariance of the vector of spine direction in different versions. \~ + \details \ru Проверить, можно ли сохранить кинематическую направляющую из одной версии в другую без изменения формы. \n + \en Check if the spine direction can be preserved between versions without any change of the shape. \n \~ + \param[in] curve - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] srcVersion - \ru Рабочая версия. + \en The current version. \~ + \param[in] dstVersion - \ru Целевая версия. + \en The target version. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsSameSpineDirection( const MbCurve3D & curve, VERSION srcVersion, VERSION dstVersion ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Классифицировать положения второго контура относительно первого. + \en Classify the position of the second contour relative to the first one. \~ + \details \ru Классифицировать положения второго контура относительно первого: \n + iloc_OutOfItem - снаружи, \n + iloc_OnItem - пересекается, \n + iloc_InItem - внутри. \n + \en Classify the position of the second contour relative to the first one: \n + iloc_OutOfItem - outside, \n + iloc_OnItem - intersects, \n + iloc_InItem - inside. \n \~ + \param[in] contour1 - \ru Первый контур. + \en The first contour. \~ + \param[in] contour2 - \ru Второй контур. + \en The second contour. \~ + \param[in] xEpsilon - \ru Погрешность по x. + \en Tolerance in x direction. \~ + \param[in] yEpsilon - \ru Погрешность по y. + \en Tolerance in y direction. \~ + \return \ru Возвращает результат классификации положения. + \en Returns the result of classification of the relative position. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeItemLocation) SecondContourLocation( const MbContour & contour1, const MbContour & contour2, + double xEpsilon, double yEpsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить, близка ли первая кривая ко второй кривой. + \en Determine whether the first curve is close to the second curve. \~ + \details \ru Определить, близка ли кривая curve1 к кривой curve2 с заданной точностью. \n + Близость определяется близостью точек первой кривой, полученных шаганием \n + по кривой с заданным угловым отклонением, ко второй кривой. \n + \en Determine whether curve 'curve1' is close to curve 'curve2' within the given precision. \n + The proximity is defined by the closeness of points of the first curve obtained by sampling \n + with the given turning angle to the second curve. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] xEpsilon - \ru Близость по x. + \en Proximity tolerance in x direction. \~ + \param[in] yEpsilon - \ru Близость по y. + \en Proximity tolerance in y direction. \~ + \param[in] devSag - \ru Максимальное угловое отклонение при шагании по кривой. + \en The maximal turning angle for sampling the curve. \~ + \return \ru Возвращает true, если кривые близки. + \en Returns 'true' if the curves are close. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) IsSpaceNear( const MbCurve & curve1, const MbCurve & curve2, double xEpsilon, double yEpsilon, + double devSag = 5.0 * Math::deviateSag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить, близка ли кривая к поверхности. + \en Determine whether a curve is close to a surface. \~ + \details \ru Определить, близка ли кривая к поверхности с заданной точностью. \n + Выполняется проверка по пробным точкам кривой, полученных шаганием по угловому отклонению. \n + \en Determine whether a curve is close to a surface within the given tolerance. \n + The check uses sample points of curves obtained by sampling with maximal turning angle. \n \~ + \param[in] curv - \ru Кривая. + \en A curve. \~ + \param[in] surf - \ru Поверхность. + \en A surface. \~ + \param[in] surfExt - \ru Проверять на расширенной поверхности. + \en Perform the check for the extended surface. \~ + \param[in] mEps - \ru Метрическая близость. + \en The metric proximity tolerance. \~ + \param[in] devSag - \ru Максимальное угловое отклонение при шагании по кривой. + \en The maximal turning angle for sampling the curve. \~ + \return \ru Возвращает true, если кривая близка к поверхности. + \en Returns 'true' if the curve is close to the surface. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsSpaceNear( const MbCurve3D & curv, const MbSurface & surf, bool surfExt, + double mEps, double devSag = 5.0 * Math::deviateSag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать грань по произвольной поверхности. + \en Create the face on the base of arbitrary surface. \~ + \details \ru Создать грань по произвольной поверхности без самопересечений. \n + \en Create the face on the base of arbitrary surface without selfintersections. \n \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[out] face - \ru Грань. + \en The face. \~ + \return \ru Возвращает true, если грань создана. + \en Returns 'true' if the face was created. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) SurfaceFace( const MbSurface & surface, SPtr & face ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание трёхмерной сетки по двумерной сетке. + \en Creating a three-dimensional grid on a two-dimensional grid. \~ + \details \ru Создание трёхмерной сетки по двумерной сетке. \n + \en Creating a three-dimensional grid on a two-dimensional grid. \n \~ + \param[in] place - \ru Локальная система координат в трёхмерном пространстве. + \en Local coordinate system in three dimensional space. \~ + \param[out] planarGrid - \ru Триангуляция двумерной области. + \en Triangulation of a two-dimensional region. \~ + \return \ru Возвращает true, если грань создана. + \en Returns 'true' if the face was created. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbGrid *) SpaceGrid( const MbPlacement3D & place, const MbPlanarGrid & planarGrid, bool exact = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Заменить элемент на вставку, если расстояние от начала координат до центра + его габарита, превышает размер габаритного куба в заданное число раз \~ + \en Replace an item by an instance if the length from it's bounding box to the + world origin is greater than it's diagonal by specified factor. + \details \ru Объект или его копия смещается на вектор из начала координат до центра габаритного куба объекта + и размещается во вставке, обеспечивающей смещение на вектор противоположного направления. \~ + Обрабатываются только объекты, не являющиеся вставками. \~ + Нулевое или отрицательное значение параметра ratioThreashhold запрещает преобразование. \~ + \en The item or it's replica is moved bey the vector from the origin of the world to the center of the + item's bounding box, then put in the instance, providing the displacement by the reversed vector. \~ + Function processes objects of all types except for instances. \~ + Null or negative value of the ratioThreashhold parameter blocks the transformation. \~ + \param[out] item - \ru Обрабатываемый объект. \~ + \en Processable item. \~ + \param[in] ratioThreashhold - \ru Пороговое значение отношения расстояния до центра габаритного куба и его диагонали, + при превышении которого происходит замена. \~ + \en The replacement threshold value of the ratio of the bounding box's center to the + origin of the world to it's diagonal length. \~ + \param[in] makeCopy - \ru Производить ли трансформацию на копии объекта. \~ + \en Is the copy of the object must be transformed. \~ + \return \ru Возвращает вставку объекта. + \en Returns instance of object. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbItem *) ReplaceByInstance( MbItem * item, double ratioThreashhold = -1.0, bool makeCopy = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построениe «залитого» объема, расположенного между внутренней поверхностью сосуда и ограничивающей поверхностью или телом. \~ + \en The construction of a "flood fill" volume located between the inner surface of the vessel and the bounding surface or body. \~ + \details \ru На вход подаётся тело, дополнительная поверхность или дополнительное тело и координаты источника. + На выходе получаем объём, построенный от источника и ограниченный со всех сторон оболочкой тела и дополнительными объектами. \~ + \en The body, an additional surface or an additional body and the coordinates of the source are fed to the input. + On the output we get the volume, constructed from the source and bounded from all sides by the shell of the body and by additional objects. \~ + \param[in] vessel - \ru Тело сосуда. \~ + \en The vessel. \~ + \param[in] sameShell - \ru Режим копирования тела сосуда. + \en Whether to copy the vessel. \~ + \param[in] bungData - \ru Поверхность уровня или тело пробки. \~ + \en The surface of the level or body of the bung. \~ + \param[in] origin - \ru Точка внутри сосуда. \~ + \en The point inside the vessel. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) FloodFillResult( MbSolid & vessel, + MbeCopyMode sameShell, + const MbSweptData & bungData, + const MbCartPoint3D & origin, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать крепеж по трехмерной точке. НЕ ИСПОЛЬЗОВАТЬ ВНЕ ТЕСТОВОГО ПРИЛОЖЕНИЯ!!! ФУНКЦИЯ НАХОДИТСЯ В РАЗРАБОТКЕ!!! + \en Create fastener using 3D point. \~ + \details \ru Создать крепеж по трехмерной точке. \n + \en Create fastener using 3D point. \n \~ + \param[in] solids - \ru Множество тел для скрепления. + \en An array of bodies to fasten. + \param[in] sameShell - \ru Режим копирования тел. + \en Whether to copy the solids. \~ + \param[in] point - \ru Трехмерная точка, на основе проецирования которой определяется положение крепежа. + \en 3d point. \~ + \param[in] params - \ru Параметры крепежа ( его тип, размеры и т.д. ). + \en Fastener parameters ( type, diameter, etc. ). \~ + \param[in] names - \ru Именователь новых граней. + \en An object defining the name of a new faces. \~ + \param[out] results - \ru Множество тел для скрепления с набором отверстий и набор тел крепежа в отверстиях. + \en Array of bodies with a holes and fastener body. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateFastener ( const RPArray & solids, + MbeCopyMode sameShell, + const MbCartPoint3D & point, + const FastenersValues & params, + const MbSNameMaker & names, + RPArray & results ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздать набор крепежных элементов по трехмерной кривой. НЕ ИСПОЛЬЗОВАТЬ ВНЕ ТЕСТОВОГО ПРИЛОЖЕНИЯ!!! ФУНКЦИЯ НАХОДИТСЯ В РАЗРАБОТКЕ!!! + \en Create an array of fastener elements using 3d curve. \~ + \details \ru Cоздать набор крепежных элементов по трехмерной кривой. + \en Create an array of fastener elements using 3d curve. \~ + \param[in] solids - \ru Множество тел для скрепления. + \en Array of bodies with a hole and fastener body. \~ + \param[in] sameShell - \ru Режим копирования тел. + \en Whether to copy the solids. \~ + \param[in] curve - \ru Трехмерная кривая, на основе проецирования точек которой определяются положения крепежных элементов. + \en 3D curve. \~ + \param[in] number - \ru Количество точек на кривой. Точки расположены равномерно по длине кривой. + \en Number of points on the curve. Points are uniformly located along the length of the curve. \~ + \param[in] params - \ru Параметры крепежа ( его тип, размеры и т.д. ). + \en Fastener parameters ( type, diameter, etc. ). \~ + \param[in] names - \ru Именователь новых граней. + \en An object defining the name of a new faces. \~ + \param[out] results - \ru Множество тел для скрепления с набором отверстий и набор тел крепежа в отверстиях. + \en Array of bodies with a holes and fastener bodies. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateFasteners( const RPArray & solids, + MbeCopyMode sameShell, + const MbCurve3D & curve, + size_t number, + const FastenersValues & params, + const MbSNameMaker & names, + RPArray & results ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Слить несколько граней тела в одну грань. + \en Create a solid with one face instead selected faces. \~ + \details \ru Заменить указанные гладко стыкующиеся грани тела одной геометрически совпадающей гранью. \n + \en To replace these smooth abutting faces to form a single geometrically matching face. \n + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en Whether to copy the source solid. \~ + \param[in] faces - \ru Объединяемые грани тела. + \en The faces of solid to be merged. \~ + \param[in] uParam - \ru Параметры u направления объединяющей поверхности. + \en The operation parameters for common surface in u direction. \~ + \param[in] vParam - \ru Параметры v направления объединяющей поверхности. + \en The operation parameters for common surface in v direction. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] prolong - \ru Параметр добавления гладко стыкующихся граней с faces (prolong>0). + \en The parameter of adding prolong faces (prolong>0). \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateMerging( MbSolid & solid, + MbeCopyMode sameShell, + c3d::FacesVector & faces, + const MbNurbsParameters & uParam, + const MbNurbsParameters & vParam, + const MbSNameMaker & names, + bool prolong, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти грани тел, имеющие контактные площадки. \~ + \en To find contacted faces of bodies. \~ + \details \ru Найти номера контактирующих граней тел, имеющих противоположно направленные нормали, у которых есть общие участки с конечной площадью перекрытия. \~ + \en To find contacted faces of bodies with oppositely directed normals which have a finite overlap area. \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] precision - \ru Точность операции. + \en The precision of operation. \~ + \param[out] facesNumbers - \ru Пары номеров касающихся граней с противоположно направленными нормалями. + \en The couples of number of contacted faces with oppositely directed normals. \~ + \return \ru Возвращает true, если грани контакта найдены. + \en Returns true, if contacted faces were found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) FindTouchedFaces( const MbSolid & solid1, + const MbSolid & solid2, + double precision, + c3d::IndicesPairsVector & facesNumbers ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разбить контактирующие грани тел. \~ + \en To find contacted faces of bodies. \~ + \details \ru Разбить контактирующие грани тел, выделив общие области с конечной площадью перекрытия в отдельные грани. \~ + \en To find contacted faces of bodies and build a finite overlap contacted area as faces. \~ + \param[in/out] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in/out] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] precision - \ru Точность операции. + \en The precision of operation. \~ + \param[in] facesNumbers - \ru Множество пар номеров соприкасающихся граней, у которых требуется построить общие пятна контакта (может быть пустым). + \en The container with pairs of contact face numbers that need to have common contact spots (it can be empty). \~ + \return \ru Возвращает true, если грани контакта найдены. + \en Returns true, if contacted faces were found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) SplitTouchedFaces( MbSolid & solid1, + MbSolid & solid2, + double precision, + c3d::IndicesPairsVector & facesNumbers ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Объединить тела, имеющие контактирующие грани. \~ + \en The function performs unite the bodies with contacted faces. \~ + \details \ru Объединить тела, удалив контактирующие грани. \~ + \en The function performs unite the bodies and removing the contacting faces. \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] sameShell1 - \ru Способ копирования граней первого тела. + \en Method of copying the faces of the first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] sameShell2 - \ru Способ копирования граней второго тела. + \en Method of copying the faces of the second solid. \~ + \param[in] precision - \ru Точность операции. + \en The precision of operation. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) TouchedSolidsMerging( MbSolid & solid1, + MbeCopyMode sameShell1, + MbSolid & solid2, + MbeCopyMode sameShell2, + const MbSNameMaker & names, + double precision, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить трансформированную копию тела. \~ + \en Get transformed copy of a solid. \~ + \details \ru Получить трансформированную копию тела, если матрица трансформации не единичная или оригинал, если единичная. \~ + \en Get transformed copy of a solid if a matrix is not identity matrix or original of the solid if the matrix is identity matrix. \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in,out] copyMode - \ru Исходный режим копирования тела. + \en An initial copy mode. \~ + \param[in] matr - \ru Матрица преобразования. + \en Transformation matrix. \~ + \param[in] transformedMainName - \ru Главное имя для операции трансформации. + \en Main name of transformation operation. \~ + \return \ru Возвращает копию или оригинал тела. + \en Returns copy or original of the solid. \~ + \ingroup Algorithms_3D +*/ +// --- +inline +c3d::SolidSPtr GetTransformedSolid( c3d::SolidSPtr & solid, MbeCopyMode & copyMode, const MbMatrix3D & matr, SimpleName transformedMainName = ct_TransformedSolid ) +{ + c3d::SolidSPtr resSolid( solid ); + + if ( (resSolid != NULL) && !matr.IsSingle() ) { + MbSNameMaker n( transformedMainName, MbSNameMaker::i_SideNone, 0 ); + + MbSolid * resSolidPtr = NULL; + TransformValues tv( matr ); + ::TransformedSolid( *solid, cm_Copy, tv, n, resSolidPtr ); + if ( resSolidPtr != NULL ) { + resSolid = resSolidPtr; + copyMode = cm_Same; + } + } + return resSolid; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Получить трансформированную копию объекта. \~ + \en Get transformed copy of object. \~ + \details \ru Получить трансформированную копию объекта, если матрица трансформации не единичная или оригинал, если единичная. \~ + \en Get transformed copy of an object if a matrix is not identity matrix or original of the solid if the matrix is identity matrix. \~ + \param[in] item - \ru Объект. + \en An object. \~ + \param[in] matr - \ru Матрица преобразования. + \en Transformation matrix. \~ + \return \ru Возвращает копию или оригинал объекта. + \en Returns copy or original of the object. \~ + \ingroup Algorithms_3D +*/ +// --- +template +SPtr GetTransformedItem( SPtr & item, const MbMatrix3D & matr, MbRegDuplicate * iDupReg = NULL, MbRegTransform * iTransReg = NULL ) +{ + SPtr resItem( item ); + if ( (resItem != NULL) && !matr.IsSingle() ) { + resItem = static_cast( &item->Duplicate( iDupReg ) ); + resItem->Transform( matr, iTransReg ); + } + return resItem; +} + + +#endif // __ACTION_H diff --git a/C3d/Include/action_analysis.h b/C3d/Include/action_analysis.h new file mode 100644 index 0000000..f84c5a9 --- /dev/null +++ b/C3d/Include/action_analysis.h @@ -0,0 +1,334 @@ +//////////////////////////////////////////////////////////////////////////////// +/** +\file +\brief \ru Функции для анализа кривизны поверхности. +\en Functions for surface curvature analysis. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_CURVATURE_ANALYSIS_H +#define __ACTION_CURVATURE_ANALYSIS_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Алгоритмы поиска экстремумов на поверхности. + \en Algorithms for finding extremes on the surface. \~ + \details \ru Константы, задающие вызываемый алгоритм поиска экстремальных значений функции на поверхности. + \en Constants defining the called algorithm for searching for extreme values of a function on a surface. \~ + \ingroup Algorithms_3D +*/ +enum MbeExtremsSearchingMethod +{ + esm_GradientDescent = 1, ///< \ru Mетод градиентного спуска. \en Gradient Descent Method. + esm_LineSegregation = 2 ///< \ru Mетод выделения линий смены убывания / возрастания функции по u и по v. \en The method of segregation of lines of change of decrease / increase of the function in u and v directions. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция, заданная на поверхности. + \en The function define on the surface. \~ + \details \ru Рассчитывает значение самой функции и ее градиент. + \en Calculates the value of the function itself and its gradient. \~ + \ingroup Algorithms_3D +*/ +typedef void( *SurfaceFunction )( const MbSurface & surf, // Поверхность, + const MbCartPoint & pnt, // точка на поверхности + double & func, // рассчитываемое значение функции, + MbVector * der );// рассчитываемое значение вектора градиента (если указатель не нулевой). + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности минимальную нормальную кривизну, а также ее градиент. + \en Calculate at the point of the surface the minimum normal curvature, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) MinSurfaceCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности максимальну нормальную кривизну, а также ее градиент. + \en Calculate at the point of the surface the maximum normal curvature, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) MaxSurfaceCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности гауссову кривизну, а также ее градиент. + \en Calculate at a surface point the Gaussian curvature, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) GaussCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности среднюю кривизну, а также ее градиент. + \en Calculate at the point of the surface the mean curvature, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) MeanCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности нормальную кривизна в направлении u , а также ее градиент. + \en Calculate at the surface point the normal curvature in the direction of u, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) UNormalCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить в точке поверхности нормальную кривизна в направлении v, а также ее градиент. + \en Calculate at the surface point the normal curvature in the direction of v, as well as its gradient. \~ + \details \ru Вычисляется значение кривизны и опционально значение ее градиента в точке (если передается ненулевой указатель). + \en The curvature value is calculated and, optionally, its gradient value at a point (if a non-zero pointer is passed). \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] func - \ru Рассчитываемое значение кривизны. + \en Calculated curvature value. \~ + \param[out] der - \ru Рассчитываемое значение градиента кривизны. + \en The calculated value of the curvature gradient. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) VNormalCurvature( const MbSurface & surf, const MbCartPoint & pnt, double & func, MbVector * der = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки поверхности, в которых выбранная кривизна принимает наибольшие по модулю значения. + \en Find the points of the surface at which the selected curvature takes the largest in modulus values. \~ + \details \ru Ищутся точки, в которых выбранная кривизна принимает на поверхности наибольшее положительное и наименьшее отрицательное значение. + \en Looks for points at which the selected curvature takes on the surface the greatest positive and least negative value. \~ + \param[in] surf - \ru Исследуемая поверхность. + \en Test surface. \~ + \param[in] func - \ru Функция расчета кривизны в точке. + \en The function of calculating the curvature at a point. \~ + \param[out] maxNegCurv - \ru Наибольшее по модулю отрицательное значение кривизны (0, если нет такого). + \en The largest in modulus value negative curvature (0, if there is no such). \~ + \param[out] maxNegLoc - \ru Точка, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The point at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxPosCurv - \ru Наибольшее положительное значение кривизны (0, если нет такого). + \en The greatest positive value of curvature (0, if there is no such). \~ + \param[out] maxPosLoc - \ru Точка, в которой кривизна принимает наибольшее положительное значение. + \en The point at which the curvature takes the most positive value. \~ + \param[in] method - \ru Алгоритм поиска экстремумов. + \en Extremum search algorithm. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) SurfaceMinMaxCurvature(const MbSurface & surface, SurfaceFunction func, double & maxNegCurv, MbCartPoint & maxNegLoc, + double & maxPosCurv, MbCartPoint & maxPosLoc, MbeExtremsSearchingMethod method = esm_LineSegregation ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки оболочки, в которых выбранная кривизна принимает наибольшие по модулю значения. + \en Find the points of the shell at which the selected curvature takes the most modulo values. \~ + \details \ru Ищутся точки на оболочке, в которых выбранная кривизна принимают наибольшее положительное и наименьшее отрицательное значение. + \en Finds points on the shell at which the selected curvature takes the largest positive and lowest negative values. \~ + \param[in] faces - \ru Грани оболочки. + \en Faces of the shell. \~ + \param[in] func - \ru Функция расчета кривизны в точке. + \en The function of calculating the curvature at a point. \~ + \param[out] maxNegCurv - \ru Наибольшее по модулю отрицательное значение кривизны (0, если нет такого). + \en The largest in modulus value negative curvature (0, if there is no such). \~ + \param[out] maxNegFace - \ru Грань, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The face at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxNegLoc - \ru Точка, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The point at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxPosCurv - \ru Наибольшее положительное значение кривизны (0, если нет такого). + \en The greatest positive value of curvature (0, if there is no such). \~ + \param[out] maxPosFace - \ru Грань, в которой кривизна принимает наибольшее положительное значение. + \en The face at which the curvature takes the most positive value. \~ + \param[out] maxPosLoc - \ru Точка, в которой кривизна принимает наибольшее положительное значение. + \en The point at which the curvature takes the most positive value. \~ + \param[in] borderControl - \ru Учитывать границы граней при поиске экстремумов. + \en Take into account the boundaries of the faces when searching for extrema. \~ + \param[in] method - \ru Алгоритм поиска экстремумов. + \en Extremum search algorithm. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) FacesMinMaxCurvature( const RPArray & faces, SurfaceFunction func, double & maxNegCurv, MbFace *& maxNegFace, MbCartPoint & maxNegLoc, + double & maxPosCurv, MbFace *& maxPosFace, MbCartPoint & maxPosLoc, bool borderControl = false, + MbeExtremsSearchingMethod method = esm_LineSegregation ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки на поверхности, в которых главные нормальные кривизны принимают наибольшие по модулю значения. + \en Find the points on the surface at which the major normal curvatures take the largest values in the module. \~ + \details \ru Ищутся точки на поверхности, в которых главные нормальные кривизны принимают наибольшее положительное и наименьшее отрицательное значение. + \en Looks for points on the surface at which the major normal curvatures take the largest positive and smallest negative values. \~ + \param[in] surf - \ru Исследуемая поверхность. + \en Test surface. \~ + \param[out] maxNegCurv - \ru Наибольшее по модулю отрицательное значение кривизны (0, если нет такого). + \en The largest in modulus value negative curvature (0, if there is no such). \~ + \param[out] maxNegLoc - \ru Точка, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The point at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxPosCurv - \ru Наибольшее положительное значение кривизны (0, если нет такого). + \en The greatest positive value of curvature (0, if there is no such). \~ + \param[out] maxPosLoc - \ru Точка, в которой кривизна принимает наибольшее положительное значение. + \en The point at which the curvature takes the most positive value. \~ + \param[in] method - \ru Алгоритм поиска экстремумов. + \en Extremum search algorithm. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) SurfaceMinMaxCurvature(const MbSurface & surface, double & maxNegCurv, MbCartPoint & maxNegLoc, + double & maxPosCurv, MbCartPoint & maxPosLoc, MbeExtremsSearchingMethod method = esm_LineSegregation ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки на оболочке, в которых главные нормальные кривизны принимают наибольшие по модулю значения. + \en Find the points on the shell at which the major normal curvatures take the largest values in the module. \~ + \details \ru Ищутся точки на оболочке, в которых главные нормальные кривизны принимают наибольшее положительное и наименьшее отрицательное значение. + \en Looks for points on the shell at which the major normal curvatures take the largest positive and smallest negative values. \~ + \param[in] faces - \ru Грани оболочки. + \en Faces of the shell. \~ + \param[out] maxNegCurv - \ru Наибольшее по модулю отрицательное значение кривизны (0, если нет такого). + \en The largest in modulus value negative curvature (0, if there is no such). \~ + \param[out] maxNegFace - \ru Грань, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The face at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxNegLoc - \ru Точка, в которой кривизна принимает наибольшее по модулю отрицательное значение. + \en The point at which the curvature takes the largest in modulus negative value. \~ + \param[out] maxPosCurv - \ru Наибольшее положительное значение кривизны (0, если нет такого). + \en The greatest positive value of curvature (0, if there is no such). \~ + \param[out] maxPosFace - \ru Грань, в которой кривизна принимает наибольшее положительное значение. + \en The face at which the curvature takes the most positive value. \~ + \param[out] maxPosLoc - \ru Точка, в которой кривизна принимает наибольшее положительное значение. + \en The point at which the curvature takes the most positive value. \~ + \param[in] borderControl - \ru Учитывать границы граней при поиске экстремумов. + \en Take into account the boundaries of the faces when searching for extrema. \~ + \param[in] method - \ru Алгоритм поиска экстремумов. + \en Extremum search algorithm. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) FacesMinMaxCurvature( const RPArray & faces, double & maxNegCurv, MbFace *& maxNegFace, MbCartPoint & maxNegLoc, + double & maxPosCurv, MbFace *& maxPosFace, MbCartPoint & maxPosLoc, bool borderControl = false, + MbeExtremsSearchingMethod method = esm_LineSegregation ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Ориентированная кривизна для плоской кривой. + \en Oriented curvature for a plane curve. \~ + \details \ru Для плоской кривой функция возвращает кривизну в точке, ориентированную относительно нормали плоскости, + в которой она лежит. Для неплоской кривой функция просто возвращает кривизну в точке. + \en For a flat curve, the function returns the curvature at a point oriented relative to the normal to the plane, + in which she lies. For a non-flat curve, the function simply returns the curvature at the point. \~ + \param[in] curve - \ru Исследуемая кривая. + \en Test curve. \~ + \param[in] param - \ru Параметр на кривой. + \en Parameter on the curve. \~ + \param[in] planeNorm - \ru Нормаль плоскости, в которой лежит кривая. Если нормаль не передается в функцию, алгоритм самостоятельно + выполняет проверку, лежит ли кривая в плоскости, и вычисляет нормаль, если проверка выполняется. + \en The normal of the plane in which the curve lies. If the normal is not passed to the function, the algorithm itself + checks if the curve is in the plane and calculates normal if the test is being performed. \~ + \return \ru Возвращается значение ориентированной кривизны в точке. + \en The value of the oriented curvature at the point is returned. \~ + + \ingroup Algorithms_3D +*/ +MATH_FUNC( double ) CurveOrientedCurvature(const MbCurve3D & curve, double & param, const MbVector3D * planeNorm = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки на кривой, в которых кривизна принимает наибольшее и наименьшее значения. + \en Find the points on the curve at which the curvature takes the largest and smallest values. \~ + \details \ru Для плоской кривой наибольшее и наименьшее значение может уходить в отрицательную область. + Для неплоской кривой наибольшее и наименьшее значение всегда неотрицательны. + \en For a flat curve, the largest and smallest value may go into the negative region. + For a non-planar curve, the largest and smallest values are always non-negative. \~ + \param[in] curve - \ru Исследуемая кривая. + \en Test curve. \~ + \param[out] maxCurv - \ru Наибольшее значение кривизны. + \en The greatest value of curvature. \~ + \param[out] maxParam - \ru Точка, в которой кривизна принимает наибольшее значение. + \en The point at which the curvature takes the largest value. \~ + \param[out] minCurv - \ru Наименьшее значение кривизны. + \en The smallest value of curvature. \~ + \param[out] minParam - \ru Точка, в которой кривизна принимает наибольшее значение. + \en The point at which the curvature takes the smallest value. \~ + \param[out] bendPoints - \ru Mассив параметров точек перегиба. + \en Array of parameters of bend points. \~ + \param[out] maxPoints - \ru Mассив параметров, в которых достигается локальный максимум кривизны по модулю. + \en An array of parameters in which the local maximum curvature modulo is reached. \~ + \param[out] minPoints - \ru Mассив параметров, в которых достигается локальный минимум кривизны по модулю. + \en An array of parameters in which the local minimum curvature modulo is reached. \~ + \param[out] rapPoints - \ru Mассив параметров, в которых кривизна терпит разрыв. + Для каждого разрыва вставляются две точки, до и после. + \en Array of parameters in which curvature breaks. + For each break two points are inserted, before and after. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) CurveMinMaxCurvature( const MbCurve3D & curve, double & maxCurv, double & maxParam, double & minCurv, double & minParam, + std::vector * bendPoints = NULL, std::vector * maxPoints = NULL, + std::vector * minPoints = NULL, std::vector * rapPoints = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Направление максимальной нормальной кривизны поверхности. + \en The direction of the maximum normal surface curvature. \~ + \details \ru Вычисляется направление на поверхности, в котором нормальная кривизна поверхности принимает максимальное значение. + \en The direction on the surface is calculated in which the normal curvature of the surface takes a maximum value. \~ + \param[in] surf - \ru Поверхность. + \en Surface. \~ + \param[in] pnt - \ru Точка расчета. + \en Point of calculation. \~ + \param[out] dir - \ru Рассчитываемое направление. + \en The calculated direction. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC( void ) SurfaceMaxCurvatureDirection( const MbSurface & surf, const MbCartPoint & pnt, MbVector & dir ); + +#endif // __ACTION_CURVATURE_ANALYSIS_H diff --git a/C3d/Include/action_b_shaper.h b/C3d/Include/action_b_shaper.h new file mode 100644 index 0000000..208f375 --- /dev/null +++ b/C3d/Include/action_b_shaper.h @@ -0,0 +1,396 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \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 +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbMesh; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbFace; +class MATH_CLASS MbCollection; + + +//------------------------------------------------------------------------------ +/** \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 Параметры построения оболочки тела по полигональной сетке. + \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 Tolerance. \~ + \details \ru Точность работы метода: допустимое отклонение граней тела от вершин сетки. + \en Tolerance: maximum distance from BRep faces to mesh vertices. \~ + */ + double tolerance; + + /** \brief \ru Режим распознавания поверхностей. + \en Surface reconstruction mode. \~ + */ + MbeSurfReconstructMode surfReconstructMode; + + /// \ru Конструктор по умолчанию. \en Default constructor. + explicit MbMeshProcessorValues( bool useRelTol = true, double tol = 0.01, MbeSurfReconstructMode mode = srm_Default ) + : useRelativeTolerance( useRelTol ) + , tolerance ( tol ) + , surfReconstructMode ( mode ) + {} +}; + + +//------------------------------------------------------------------------------ +/** \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 Установить флаг сглаживания входной сетки. + \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 & 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 paramters). \n \~ + \param[out] pShell - \ru Указатель на созданную оболочку. + \en The pointer to created shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects + */ + virtual MbResultType CreateBRepShell( MbFaceShell *& pShell ) = 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 Возвращает указатель на поверхность для сегмента, если поверхность определена, иначе - NULL. + \en Returns pointer to segment surface if it exists, else - NULL. \~ + \ingroup Polygonal_Objects + */ + virtual const MbSurface * GetSegmentSurface( size_t idxSegment ) const = 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 & 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> & 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() ); + +#endif // __ACTION_B_SHAPER_H diff --git a/C3d/Include/action_curve.h b/C3d/Include/action_curve.h new file mode 100644 index 0000000..8d4af22 --- /dev/null +++ b/C3d/Include/action_curve.h @@ -0,0 +1,757 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения двумерных кривых. + \en Functions for two-dimensional curves construction. \~ + \details \ru Двумерные кривые могут быть построены с помощью аналитических функций, + по набору точек, на базе других двумерных кривых. + \en Two-dimensional curves can be constructed using analytical functions, + for a point set or on the basis of other two-dimensional curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_CURVE_H +#define __ACTION_CURVE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurve; +class MATH_CLASS MbContour; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbFace; + + +//------------------------------------------------------------------------------ +/** \brief \ru Перечисление способов создания эллипса (окружности) или их дуг в двумерном пространстве. + \en Enumeration of ways to create an ellipse (circle) or their arcs in two-dimensional space. \~ +\ingroup Curve_Modeling +*/ +// --- +enum MbeArcCreateWay +{ + /** + \ru Окружность по центру и радиусу, задается 'center' и радиус в 'c'. + \en Circle by center and radius, set the 'center' and radius in 'c'. + */ + acw_CircleByCenterAndRadius, + + /** + \ru Дуга окружности по центру и двум точкам. + Задается: 'center', две точки в 'points', направление в 'option' (true - по часовой стрелке). + Возвращается: начальный угол дуги в 'а', конечный угол в 'b', радиус в 'c'. + \en Circular arc by center and two points. + Set: 'center', two points in 'points', direction in 'option' (true - clockwise direction). + Return: start angle in 'a', end in 'b', radius in 'c'. + */ + acw_ArcByCenterAnd2Points, + + /** + \ru Дуга окружности по центру и двум углам. + Задается: 'center', начальный угол в 'a', конечный в 'b', радиус в 'c', + направление в 'option' (true - по часовой стрелке). Углы задаются в радианах. + \en Circular arc by center and two angles, + Set: 'center', start angle in 'a', end in 'b', radius in 'c', + direction in 'option' (true - clockwise direction). The angles are given in radians. + */ + acw_ArcByCenterAnd2Angles, + /** + \ru Дуга окружности по трем точкам, заданным в 'points', точки points[0] и points[2] конечные. + Возвращается: начальный угол дуги в 'а', конечный угол в 'b', радиус в 'c'. + \en Circular arc by three points specified in 'points', points[0] and points[2] are the end point. + Return: start angle in 'a', end in 'b', radius in 'c'. + */ + acw_ArcBy3Points, + + /** + \ru Эллипс с заданными полуосями и углом наклона. + Задается 'center', X полуось в 'a', Y полуось в 'b', угол наклона в 'с'. Угол задается в радианах. + \en Ellipse by semiaxes and angle. + Set : 'center', X semiaxis in 'a', Y semiaxis in 'b', angle in 'c'. The angle are given in radians. + */ + acw_EllipseByCenterAndSemiaxis, + + /** + \ru Эллипс по центру и трем точкам на нем. + Задается 'center' и 3 точки в 'points'. + Возвращаются: X полуось в 'a', Y полуось в 'b', угол наклона в 'с'. Угол задается в радианах. + \en Ellipse by centre and three points on ellipse. + Set: 'center', 3 points in 'points'. + Return: X semiaxis in 'a', Y semiaxis in 'b', angle in 'c'. The angle are given in radians. + */ + acw_EllipseByCenterAnd3Points, + + /** + \ru Дуга эллипса, обрезанная двумя лучами из центра к заданным точкам. + Задается 'center' и 2 точки в 'points', X полуось в 'a', Y полуось в 'b', угол наклона в 'с', + направление в 'option' (true - по часовой стрелке). Угол задается в радианах. + \en Elliptical arc is trimmed by two rays, starting from the center and passing through points. + Set: 'center', 2 points in 'points', X semiaxis in 'a', Y semiaxis in 'b', angle in 'c', + direction in 'option' (true - clockwise direction). The angle are given in radians. + */ + acw_EArcByCenterAnd2Points +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Создать прямую. + \en Create a line. \~ + \details \ru Создать прямую по двум точкам. \n + \en Create a line given two points. \n \~ + \param[in] point1 - \ru Первая точка. + \en The first point. \~ + \param[in] point2 - \ru Вторая точка. + \en The second point. \~ + \param[out] result - \ru Прямая. + \en The line. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbResultType) Line( const MbCartPoint & point1, + const MbCartPoint & point2, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать отрезок прямой. + \en Create a line segment. \~ + \details \ru Создать отрезок прямой по двум точкам. \n + \en Create a line segment given two points. \n \~ + \param[in] point1 - \ru Первая точка. + \en The first point. \~ + \param[in] point2 - \ru Вторая точка. + \en The second point. \~ + \param[out] result - \ru Отрезок. + \en The segment. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbResultType) Segment( const MbCartPoint & point1, + const MbCartPoint & point2, + MbCurve *& result ); + + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эллипс (окружность) или его дугу указанным способом. + \en Create an ellipse (circle) or an elliptical (circular) arc in the specified way. \~ +\details \ru Создать эллипс (окружность) или его дугу указанным способом.\n Входные параметры интерпретируются в соответствии с выбранным путем создания. + \en Create an ellipse (circle) or an elliptical (circular) arc in the specified way. \n The input parameters are interpreted according to the selected create way. +\param[in] createWay - \ru Способ создания. Определяет как интерпретировать входные параметры. + \en Create way. Defines how to interpret the input parameters.\~ +\param[in] center - \ru Центр + \en Сenter. \~ +\param[in] points - \ru Конечные точки или точки через которые проходит кривая. + \en Endpoints or points through which the curve passes. \~ +\param[in,out] a - \ru Интерпретация параметра зависит от способа создания дуги, см. enum #ArcCreateWay + \en Interpretation of parameter depends on a way of creation of an arc, see enum #ArcCreateWay. \~ +\param[in,out] b - \ru Интерпретация параметра зависит от способа создания дуги, см. enum #ArcCreateWay + \en Interpretation of parameter depends on a way of creation of an arc, see enum #ArcCreateWay. \~ +\param[in,out] с - \ru Интерпретация параметра зависит от способа создания дуги, см. enum #ArcCreateWay + \en Interpretation of parameter depends on a way of creation of an arc, see enum #ArcCreateWay. \~ +\param[in] option - \ru Интерпретация параметра зависит от способа создания дуги, см. enum #ArcCreateWay + \en Interpretation of parameter depends on a way of creation of an arc, see enum #ArcCreateWay. \~ +\param[out] result - \ru Эллипс (окружность) или его дуга. + \en The ellipse (circle) or the elliptical (circular) arc. \~ +\return \ru Возвращает код результата операции. + \en Returns operation result code. \~ +\ingroup Curve_Modeling +*/ +//--- + +MATH_FUNC( MbResultType ) Arc( MbeArcCreateWay createWay, + const MbCartPoint & center, + const std::vector & points, + double & a, double & b, double & c, + bool option, + MbCurve *& result ); + +//------------------------------------------------------------------------------ +/**\attention \ru Функция устарела. Вместо неё применять #Arc. + \en The function is deprecated. Use #Arc instead. \~ +\ingroup Curve_Modeling +*/ +// 2018 +//--- +MATH_FUNC( MbResultType ) Arc( const MbCartPoint & centre, + const SArray & points, + bool curveClosed, double angle, + double & a, double & b, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую, проходящую по набору точек. + \en Create a curve passing through a set of points. \~ + \details \ru Создать кривую, проходящую по набору точек, следующего типа: \n + - curveType == pt_LineSegment - отрезок, \n + - curveType == pt_Arc - окружность или дуга, \n + - curveType == pt_Polyline - ломаная, \n + - curveType == pt_Bezier - кривая Безье, \n + - curveType == pt_CubicSpline - кубический сплайн, \n + - curveType == pt_Hermit - составной кубический сплайн Эрмита, \n + - curveType == pt_Nurbs - неоднородный рациональный B-сплайн четвертого порядка (кубический). \n + \en Create a curve passing through a set of points that has the following type: \n + - curveType == pt_LineSegment - a line segment, \n + - curveType == pt_Arc - a circle or an arc, \n + - curveType == pt_Polyline - a polyline, \n + - curveType == pt_Bezier - a Bezier curve, \n + - curveType == pt_CubicSpline - a cubic spline, \n + - curveType == pt_Hermit - a cubic Hermite spline, \n + - curveType == pt_Nurbs - a nonuniform rational B-spline of fourth order (cubic). \n \~ + \param[in] pointList - \ru Набор точек. + \en A point set. \~ + \param[in] curveClosed - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[in] curveType - \ru Тип кривой. + \en A curve type. \~ + \param[out] result - \ru Кривая. + \en The curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplineCurve( const SArray & pointList, + bool curveClosed, MbePlaneType curveType, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать NURBS-кривую. + \en Create a NURBS-curve. \~ + \details \ru Создать NURBS-кривую, построенную по набору контрольных точек. \n + Контейнер weightList может быть пустым. \n + Контейнер knotList может быть пустым. \n + \en Create a NURBS-curve given a sequence of control points. \n + Container 'weightList' can be empty. \n + Container 'knotList' can be empty. \n \~ + \param[in] pointList - \ru Множество точек. + \en An array of points. \~ + \param[in] weightList - \ru Множество весов. + \en An array of weights. \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline degree. \~ + \param[in] knotList - \ru Множество параметрических узлов (Узловой вектор). + \en An array of parametric knots (A knot vector). \~ + \param[in] curveClosed - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) NurbsCurve( const SArray & pointList, + const SArray & weightList, size_t degree, + const SArray & knotList, bool curveClosed, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать копию кривой в виде NURBS. + \en Create a copy of a curve as a NURBS-curve. \~ + \details \ru Создать копию кривой в виде NURBS. \n + \en Create a copy of a curve as a NURBS-curve. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] result - \ru Сплайновая копия кривой. + \en The spline copy of the curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) NurbsCopy( const MbCurve & curve, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать правильный многоугольник, вписанный в окружность или описанный вокруг окружности. + \en Create a regular polygon inscribed in a circle or circumscribed around a circle. \~ + \details \ru Создать правильный многоугольник, вписанный в окружность (describe == false) или + описанный вокруг окружности (describe == true) с центром centre, проходящей через point: \n + - при vertexCount == 0 строится окружность с центром centre, проходящая через point, \n + - при vertexCount == 1 строится отрезок c крайними точками centre и point, \n + - при vertexCount == 2 строится прямоугольник со сторонами, параллельными глобальным осям и противоположными вершинами в centre и point, \n + - при vertexCount >= 3 строится правильный многоугольник с заданным числом сторон, + вписанный в окружность (describe == false) или описанный вокруг окружности (describe == true) с центром centre, проходящей через point: \n + \en Create a regular polygon inscribed in a circle (describe == false) or + circumscribed around a circle (describe == true) with the specified centre and passing through the given point: \n + - if vertexCount == 0, a circle with center 'center' passing through 'point' is created, \n + - if vertexCount == 1, a line segment with end points at 'centre' and 'point' is created, \n + - if vertexCount, == 2 a rectangle aligned with the global axes with the opposite vertices at points 'centre' and 'point' is created, \n + - if vertexCount >= 3, a regular polygon is created with a given number of sides, + inscribed in a circle (describe == false) or circumscribed around a circle (describe == true) with the specified centre and passing through the given point: \n \~ + \param[in] centre - \ru Центр фигуры. + \en A figure centre. \~ + \param[in] point - \ru Точка для построения. + \en A point for the curve construction. \~ + \param[in] vertexCount - \ru Количество вершин правильного многоугольника. + \en The number of vertices of a regular polygon. \~ + \param[in] describe - \ru Флаг построения многоугольника: описать вокруг окружности (true), вписать в окружность (false). + \en A polygon construction flag: circumscribe the polygon around the circle, inscribe the polygon in the circle (false). \~ + \param[out] result - \ru Результат построения. + \en The curve creation result. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) RegularPolygon( const MbCartPoint & centre, + const MbCartPoint & point, + size_t vertexCount, + bool describe, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать косинусоиду. + \en Create a cosine curve. \~ + \details \ru Создать косинусоиду по точкам, фазе и длине волны. \n + \en Create a cosine curve given the points, phase and wave length. \n \~ + \param[in] point0 - \ru Начало локальной системы координат (ЛСК). + \en The origin of local coordinate system (LCS). \~ + \param[in] point1 - \ru Точка на оси X ЛСК. + \en A point on the X-axis of LCS. \~ + \param[in] point2 - \ru Точка на оси Y ЛСК. + \en A point on the Y-axis of LCS. \~ + \param[in] phase - \ru Фаза. + \en The phase. \~ + \param[in] waveLength - \ru Длина Волны. + \en The wave length. \~ + \param[out] result - \ru Косинусоида. + \en The cosine curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) Cosinusoid( const MbCartPoint & point0, + const MbCartPoint & point1, + const MbCartPoint & point2, + double phase, + double waveLength, + MbCurve *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Создать косинусоиду. + \en Create a cosine curve. \~ + \details \ru Создать косинусоиду по точкам, фазе и длине волны. \n + \en Create a cosine curve given the points, phase and wave length. \n \~ + \param[in] origin - \ru Начало локальной системы координат (ЛСК). + \en The origin of local coordinate system (LCS). \~ + \param[in] amplitude - \ru Амплитуда волны. + \en The amplitude of the wave. \~ + \param[in] waveLength - \ru Длина Волны. + \en The wave length. \~ + \param[in] wavesCount - \ru Количество волн. + \en The number of waves. \~ + \param[in] phase - \ru Фаза. + \en The phase. \~ + \param[out] result - \ru Косинусоида. + \en The cosine curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) Cosinusoid( const MbCartPoint & origin, + double amplitude, + double waveLength, + double wavesCount, + double phase, + MbCurve *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать составную кривую (контур). + \en Create a composite curve (contour). \~ + \details \ru Создать составную кривую (контур) на базе исходной кривой. \n + \en Create a composite curve (contour) on the basis of the given curve. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] result - \ru Контур на основе кривой. + \en The contour created on the basis of the curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) CreateContour( MbCurve & curve, + MbContour *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать копию кривой. + \en Create a copy of a curve. \~ + \details \ru Создать копию кривой с заменой некоторых кривых. \n + \en Create a copy of a curve with substitution of some curves. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \return \ru Возвращает модифицированную копию кривой, если получилось ее создать. + \en Returns a modified copy of the curve if it has been successfully created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbCurve *) DuplicateCurve( const MbCurve & curve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать копию контура. + \en Create a copy of a contour. \~ + \details \ru Создать копию контура с заменой некоторых кривых и его модификацией по флагу. + Модификация - слияние подобных кривых и удаление вырожденных. \n + \en Create a copy of a contour with substitution of some curves and its modification according to the flag. + Modification is a merging of similar curves and deleting of degenerate ones. \n \~ + \param[in] cntr - \ru Исходный контур. + \en The initial contour. \~ + \param[in] modifySegments - \ru Флаг разрешения замены и слияния сегментов. + \en The flag determines whether segments can be replaced or merged. \~ + \param[in] names - \ru Именователь, синхронизированный с контуром. + \en An object defining the names synchronized with contour. \~ + \return \ru Возвращает модифицированнную копию контура, если получилось его создать. + \en Returns a modified copy of the contour if it has been successfully created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbContour *) DuplicateContour( const MbContour & cntr, + bool modifySegments, + MbSNameMaker * names = NULL ); + + +//------------------------------------------------------------------------------ +// Создание эквидистантной кривой. +/** \brief \ru Создать эквидистантную кривую. + \en Create an offset curve. \~ + \details \ru Создать эквидистантную кривую по базовой кривой и смещению в крайних точках. \n + \en Create the offset curve for a given curve with offset in the begin and the end points. \n \~ + \param[in] curve - \ru Базовая кривая. + \en Base curve. \~ + \param[in] offset1 - \ru Смещение в точке Tmin базовой кривой. + \en Offset distance on point Tmin of base curve. \~ + \param[in] offset2 - \ru Смещение в точке Tmax базовой кривой. + \en Offset distance on point Tmax of base curve. \~ + \param[in] type - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \return \ru Возвращает эквидистантную кривую. + \en Returns the offset curve. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbCurve *) OffsetCurve( const MbCurve & curve, + double offset1, + double offset2, + MbeOffsetType type ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантный контур. + \en Create an offset contour. \~ + \details \ru Создать эквидистантный контур к исходному контуру. \n + \en Create the offset contour for a given contour. \n \~ + \param[in] cntr - \ru Исходный контур. + \en The initial contour. \~ + \param[in] rad - \ru Величина эквидистантного смещения. + \en The offset value. \~ + \param[in] xEpsilon - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEpsilon - \ru Точность по y. + \en Tolerance in y direction. \~ + \param[in] modifySegments - \ru Флаг разрешения замены и слияния сегментов. + \en The flag determines whether segments can be replaced or merged. \~ + \param[in] version - \ru Версия исполнения. + \en The version. \~ + \return \ru Возвращает эквидистантный контур, если получилось его создать. + \en Returns the offset contour if it has been successfully created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbContour *) OffsetContour( const MbContour & cntr, + double rad, + double xEpsilon, + double yEpsilon, + bool modifySegments, + VERSION version = Math::DefaultMathVersion()/*BUG_61694*/ ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантный контур, начинающийся и оканчивающийся на оси вращения. + \en Create an offset contour with start and end points on the rotation axis. \~ + \details \ru Создать незамкнутый эквидистантный контур, начинающийся и оканчивающийся на оси вращения. \n + Cчитается, что, если контур замкнуть, то он будет ориентирован против движения часовой стрелки. \n + \en Create an open offset contour with start and end points on the rotation axis. \n + It is considered that if one closes the contour, it will be oriented counterclockwise. \n \~ + \param[in] cntr - \ru Исходный контур. + \en The initial contour. \~ + \param[in] q1 - \ru Начальная точка оси вращения. + \en The start point of the rotation axis. \~ + \param[in] q2 - \ru Конечная точка оси вращения. + \en The end point of the rotation axis. \~ + \param[in] rad - \ru Величина эквидистантного смещения. + \en The offset value. \~ + \param[in] xEpsilon - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEpsilon - \ru Точность по y. + \en Tolerance in y direction. \~ + \return \ru Возвращает эквидистантный контур, если получилось его создать. + \en Returns the offset contour if it has been successfully created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbContour *) AxisOffsetOpenContour( const MbContour & cntr, + const MbCartPoint & q1, + const MbCartPoint & q2, + double rad, + double xEpsilon, + double yEpsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Инициализировать кривую по новым параметрам. + \en Initialize a curve with new parameters. \~ + \details \ru Инициализировать кривую по новым параметрам. \n + \en Initialize a curve with new parameters. \n \~ + \param[in,out] curve - \ru Изменяемая кривая. + \en The curve to be modified. \~ + \param[in] t1 - \ru Новый начальный параметр. + \en A new start parameter. \~ + \param[in] t2 - \ru Новый конечный параметр. + \en A new end parameter. \~ + \param[in] eps - \ru Точность. + \en Tolerance. \~ + \return \ru Возвращает true, если получилось модифицировать кривую. + \en Returns 'true' if the curve has been successfully modified. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (bool) CurveTrim( MbCurve & curve, + double t1, + double t2, + double eps = METRIC_PRECISION ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить кривую в составную кривую (контур). + \en Add a curve to a composite curve (a contour). \~ + \details \ru Добавить кривую curve в составную кривую (контур) contour. \n + Если toEnd == true, то добавить в конец. \n + Если toEnd == false, то добавить в начало. \n + \en Add a curve to a composite curve (a contour) 'contour'. \n + If toEnd == true, the curve is to be added to the end. \n + If toEnd == true, the curve is to be added to the beginning. \n \~ + \param[in] curve - \ru Добавляемая кривая + \en A curve to be added. \~ + \param[in,out] contour - \ru Модифицируемый контур. + \en A contour to be modified. \~ + \param[in] toEnd - \ru Флаг места добавления кривой. + \en The flag determines the place of the curve in the contour. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) AddCurveToContour( MbCurve & curve, + MbContour & contour, + bool toEnd ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти пересечения кривой с плоскостью. + \en Calculate the intersections of a curve and a surface. \~ + \details \ru Найти пересечения кривой с плоскостью. \n + Результат - массив точек или массив двумерных кривых на плоскости. + \en Calculate the intersections of a curve and a surface. \n + The result is an array of points or an array of two-dimensional curves on the plane. \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in] place - \ru Система координат плоскости. + \en The plane coordinate system. \~ + \param[out] result - \ru Множество точек на плоскости. + \en The array of points on the plane. \~ + \param[out] resultCurve - \ru Множество кривых на плоскости. + \en The array of curves on the plane. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CurveSection( const MbCurve3D & curve, + const MbPlacement3D & place, + SArray & result, + RPArray & resultCurve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти пересечения поверхности с плоскостью. + \en Calculate the intersections of a surface and a plane. \~ + \details \ru Найти пересечения поверхности с плоскостью. \n + Результат - массив кривых на поверхности и двумерных кривых на плоскости. + \en Calculate the intersections of a surface and a plane. \n + The result is an array of curves on the surface and two-dimensional curves on the plane. \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] place - \ru Система координат плоскости. + \en The plane coordinate system. \~ + \param[out] result - \ru Множество кривых на плоскости. + \en The array of curves on the plane. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) SurfaceSection( const MbSurface & surface, + const MbPlacement3D & place, + RPArray & result, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать двумерный сегмент поверхности проецированием ориентированного ребра. + \en Create a two-dimensional segment on a surface by projection of an oriented edge. \~ + \details \ru Создать двумерный сегмент поверхности проецированием ориентированного ребра. \n + Результатом является двумерная кривая в параметрической области поверхности surface. + \en Create a two-dimensional segment on a surface by projection of an oriented edge. \n + The result is a two-dimensional curve in the parametric domain of the given surface. \~ + \param[in] face - \ru Грань поверхности. + \en A face defined on the surface. \~ + \param[in] loopInd - \ru Номер цикла в грани. + \en The number of a loop in the face. \~ + \param[in] edgeInd - \ru Номер проецируемого ребра в цикле. + \en Index of the edge in the loop to be projected. \~ + \param[in] surface - \ru Поверхность проецирования. + \en A surface to project on. \~ + \param[in] version - \ru Версия изготовления. + \en Version. \~ + \param[out] result - \ru Двумерная кривая. + \en A two-dimensional curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +//--- +MATH_FUNC (MbResultType) FaceBoundSegment( const MbFace & face, + size_t loopInd, + size_t edgeInd, // \ru Проецируемое ребро грани \en The edge of face to be pojected. + const MbSurface & surface, // \ru На поверхность \en On the surface + VERSION version, + MbCurve *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Создать двумерную границу поверхности проецированием пространственной кривой. + \en Create a two-dimension boundary of a surface by projection of a space curve. \~ + \details \ru Создать двумерную границу поверхности проецированием пространственной кривой \n + (предполагается, что пространственные граничные кривые лежат на поверхности). \n + \en Create a two-dimension boundary of a surface by projection of a space curve \n + (the boundary space curves are considered to belong to the surface) \n \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] spaceCurve - \ru Пространственная кривая. + \en A space curve. \~ + \param[in] version - \ru Версия изготовления. + \en Version. \~ + \param[out] result - \ru Двумерный контур на поверхности. + \en The two-dimensional contour on the surface. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SurfaceBoundContour( const MbSurface & surface, + const MbCurve3D & spaceCurve, + VERSION version, + MbContour *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скорректировать начальную точку. + \en Correct the start point. \~ + \details \ru Изменить начальную точку кривой на новую.\n + Меняет начальную точку у кривых типа:\n + pt_Nurbs, pt_Hermit, pt_Polyline, pt_Bezier, + pt_CubicSpline, pt_LineSegment, pt_ReparamCurve,\n + или у контура pt_Contour, если первый его сегмент одного из перечисленных типов. + \en Change the start point of curve with a new one.\n + Changes the start point for curves of types:\n + pt_Nurbs, pt_Hermit, pt_Polyline, pt_Bezier, + pt_CubicSpline, pt_LineSegment, pt_ReparamCurve,\n + or for contour pt_Contour if its first segment is of one of the listed types. \~ + \param[in] segment - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] p1 - \ru Новая начальная точка. + \en A new start point. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) ChangeFirstPoint( MbCurve * segment, const MbCartPoint & p1 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скорректировать конечную точку. + \en Correct the last point. \~ + \details \ru Изменить конечную точку кривой на новую.\n + Меняет начальную точку у кривых типа:\n + pt_Nurbs, pt_Hermit, pt_Polyline, pt_Bezier, + pt_CubicSpline, pt_LineSegment, pt_ReparamCurve,\n + или у контура pt_Contour, если последний его сегмент одного из перечисленных типов. + \en Change the end point of curve with a new one.\n + Changes the end point for curves of types:\n + pt_Nurbs, pt_Hermit, pt_Polyline, pt_Bezier, + pt_CubicSpline, pt_LineSegment, pt_ReparamCurve,\n + or for contour pt_Contour if its last segment is of one of the listed types. \~ + \param[in] segment - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] p1 - \ru Новая начальная точка. + \en A new start point. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) ChangeLastPoint( MbCurve * segment, const MbCartPoint & p2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Является ли кривая прямолинейной независимо от ее параметризации. + \en Whether the curve is like straight-line regardless of its parameterisation. \~ + \details \ru Является ли кривая прямолинейной независимо от ее параметризации.\n + \en Whether the curve is like straight-line regardless of its parameterisation. \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[in] eps - \ru Точность. + \en Accuracy. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (bool) IsLikeStraightLine( const MbCurve & curve, double eps ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить вырожденные сегменты из контура. + \en Delete degenerate segments from contour. \~ + \details \ru Удалить вырожденные сегменты из контура с заменой некоторых кривых и модификацией по флагу. \n + \en Delete degenerate segments from contour with substitution of some curves and its modification according to the flag. \n \~ + \param[in] cntr - \ru Исходный контур. + \en The initial contour. \~ + \param[in] modifySegments - \ru Флаг разрешения замены сегментов. + \en The flag determines whether segments can be replaced. \~ + \param[in] names - \ru Именователь, синхронизированный с контуром. + \en An object defining the names synchronized with contour. \~ + \return \ru Возвращает модифицированнную копию контура, если получилось его создать. + \en Returns a modified copy of the contour if it has been successfully created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC( MbContour * ) DeleteDegenerateSegments( const MbContour & cntr, + bool modifySegments, + MbSNameMaker * names = NULL ); + + +#endif // __ACTION_CURVE_H diff --git a/C3d/Include/action_curve3d.h b/C3d/Include/action_curve3d.h new file mode 100644 index 0000000..e0201a0 --- /dev/null +++ b/C3d/Include/action_curve3d.h @@ -0,0 +1,1226 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения трехмерных кривых. + \en Functions for three-dimensional curves construction. \~ + \details \ru На базе кривых строятся рёбра. Рёбра используются в твёрдотельной и каркасной модели. + Кроме того, кривые используются для построения поверхностей, а также могут служить + вспомогательными элементами модели. + \en Edges are created on the basis of curves. Edges are used in solid and wireframe model. + In addition curves are used for construction of surfaces as well as can be used + as auxiliary elements of a model. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_CURVE3D_H +#define __ACTION_CURVE3D_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbNurbs3D; +class MATH_CLASS MbContour3D; +class MATH_CLASS MbFace; +class MATH_CLASS MbSurface; +class MATH_CLASS MbWireFrame; +class MATH_CLASS MbItem; +class MATH_CLASS MbName; +class MATH_CLASS MbSweptData; +struct MATH_CLASS EvolutionValues; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать прямую. + \en Create a line. \~ + \details \ru Создать прямую по двум точкам. \n + \en Create a line given two points. \n \~ + \param[in] point1 - \ru Первая точка. + \en The first point. \~ + \param[in] point2 - \ru Вторая точка. + \en The second point. \~ + \param[out] result - \ru Прямая. + \en The line. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) Line( const MbCartPoint3D & point1, + const MbCartPoint3D & point2, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать отрезок прямой. + \en Create a line segment. \~ + \details \ru Создать отрезок прямой по двум точкам. \n + \en Create a line segment given two points. \n \~ + \param[in] point1 - \ru Первая точка. + \en The first point. \~ + \param[in] point2 - \ru Вторая точка. + \en The second point. \~ + \param[out] result - \ru Отрезок. + \en The segment. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) Segment( const MbCartPoint3D & point1, + const MbCartPoint3D & point2, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эллипс (окружность) или его дугу. + \en Create an ellipse (circle) or an elliptical (circular) arc. \~ + \details \ru Создать эллипс (окружность) или его дугу. \n + Контейнер points может содержать 0, 2 элементов. \n + \en Create an ellipse (circle) or an elliptical (circular) arc. \n + The container 'points' should contain 0 or 2 elements. \n \~ + \param[in] centre - \ru Центр эллипса (окружности) + \en The center of an ellipse (circle). \~ + \param[in] points - \ru Точки дуги. + \en Points on the arc. \~ + \param[in] curveClosed - \ru Замкнутость дуги. + \en The closedness of the arc. \~ + \param[in] angle - \ru Угол наклона. + \en The inclination angle. \~ + \param[in,out] a - \ru Длина большой полуоси. + \en The major axis length. \~ + \param[in,out] b - \ru Длина малой полуоси. + \en The minor axis length. \~ + \param[out] result - \ru Эллипс (окружность) или его дуга. + \en The ellipse (circle) or the elliptical (circular) arc. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) Arc( const MbCartPoint3D & centre, + const SArray & points, + bool curveClosed, double angle, + double & a, double & b, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую, проходящую по набору точек. + \en Create a curve passing through a set of points. \~ + \details \ru Создать кривую, проходящую по набору точек, следующего типа: \n + curveType == st_LineSegment3D - отрезок, \n + curveType == st_Arc3D - окружность или дуга, \n + curveType == st_Polyline3D - ломаная, \n + curveType == st_Bezier3D - кривая Безье, \n + curveType == st_CubicSpline3D - кубический сплайн, \n + curveType == st_Hermit3D - составной кубический сплайн Эрмита, \n + curveType == st_Nurbs3D - неоднородный рациональный B-сплайн четвертого порядка (кубический). \n + \en Create a curve passing through a set of points that has the following type: \n + curveType == st_LineSegment3D - a line segment, \n + curveType == st_Arc3D - a circle or an arc, \n + curveType == st_Polyline3D - a polyline, \n + curveType == st_Bezier3D - a Bezier curve, \n + curveType == st_CubicSpline3D - a cubic spline, \n + curveType == st_Hermit3D - a cubic Hermite spline, \n + curveType == st_Nurbs3D - a nonuniform rational B-spline of fourth order (cubic). \n \~ + \param[in] pointList - \ru Набор точек. + \en A point set. \~ + \param[in] curveClosed - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[in] curveType - \ru Тип кривой. + \en A curve type. \~ + \param[out] result - \ru Кривая. + \en The curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplineCurve( const SArray & pointList, + bool curveClosed, + MbeSpaceType curveType, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать NURBS-кривую. + \en Create a NURBS-curve. \~ + \details \ru Создать NURBS-кривую, построенную по набору контрольных точек. \n + Контейнер weightList может быть пустым. \n + Контейнер knotList может быть пустым. \n + \en Create a NURBS-curve given a sequence of control points. \n + Container 'weightList' can be empty. \n + Container 'knotList' can be empty. \n \~ + \param[in] pointList - \ru Множество точек. + \en An array of points. \~ + \param[in] weightList - \ru Множество весов. + \en An array of weights. \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline degree. \~ + \param[in] knotList - \ru Множество параметрических узлов (Узловой вектор). + \en An array of parametric knots (A knot vector). \~ + \param[in] curveClosed - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) NurbsCurve( const SArray & pointList, + const SArray & weightList, size_t degree, + const SArray & knotList, bool curveClosed, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать копию кривой в виде NURBS. + \en Create a copy of a curve as a NURBS-curve. \~ + \details \ru Создать копию кривой в виде NURBS. \n + \en Create a copy of a curve as a NURBS-curve. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] result - \ru Сплайновая копия кривой. + \en The spline copy of the curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) NurbsCopy( const MbCurve3D & curve, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать правильный многоугольник, вписанный в окружность. + \en Create a regular polygon inscribed in a circle. \~ + \details \ru Создать правильный многоугольник, вписанный в окружность \n + (при describe == true описанного вокруг окружности) с центром centre и проходящей через point: \n + - при vertexCount <= 1 строится окружность с центром centre и проходящая через point, \n + - при vertexCount == 2 строится прямоугольник со сторонами, параллельными глобальным осям + и противоположными вершинами в centre и point. \n + \en Create a regular polygon inscribed in a circle \n + (if 'describe' == true circumscribed around a circle) with the specified centre and passing through the given point: \n + - if vertexCount <= 1, a circle with center 'center' passing through 'point' is created, \n + - if vertexCount == 2, a rectangle aligned with the global axes + with the opposite vertices at points 'centre' and 'point' is created. \n \~ + \param[in] centre - \ru Центр. + \en The center. \~ + \param[in] point - \ru Точка. + \en A point. \~ + \param[in] axisZ - \ru Ось Z для создания ЛСК кривой. + \en Z-axis for curve LCS creation. \~ + \param[in] vertexCount - \ru Количество вершин. + \en Number of vertices. \~ + \param[in] describe - \ru Описанный вокруг окружности. + \en Circumscribing around the circle. \~ + \param[out] result - \ru Правильный многоугольник. + \en The regular polygon. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) RegularPolygon( const MbCartPoint3D & centre, + const MbCartPoint3D & point, + const MbVector3D & axisZ, + size_t vertexCount, + bool describe, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать спираль. + \en Create a spiral. \~ + \details \ru Создать спираль. \n + Если spiralAxis == true, то lawCurve - определяет плоскую ось спирали. \n + Если spiralAxis == false, то lawCurve - определяет закон изменения радиуса спирали. \n + \en Create a spiral. \n + If 'spiralAxis' == true, 'lawCurve' determines the axis of a spiral. \n + If spiralAxis == false, then 'lawCurve' - determines a radius law. \n \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] radius - \ru Радиус спирали. + \en A spiral radius. \~ + \param[in] step - \ru Шаг спирали. + \en A pitch. \~ + \param[in] lawCurve - \ru Формообразующая кривая. + \en A guide curve. \~ + \param[in] spiralAxis - \ru Выбор режима формообразования + \en A spiral construction mode. \~ + \param[out] result - \ru Спиральная кривая. + \en The spiral curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SpiralCurve( const MbPlacement3D & place, + double radius, + double step, + MbCurve & lawCurve, + bool spiralAxis, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать спираль. + \en Create a spiral. \~ + \details \ru Создать спираль. \n + Если spiralAxis == true, то lawCurve - определяет плоскую ось спирали. \n + Если spiralAxis == false, то lawCurve - определяет закон изменения радиуса спирали. \n + Если lawCurve == NULL, то строится коническая спираль с углом конусности angle. \n + \en Create a spiral. \n + If 'spiralAxis' == true, 'lawCurve' determines the axis of a spiral. \n + If spiralAxis == false, then 'lawCurve' - determines a radius law. \n + If lawCurve == NULL, a conical spiral is created with the specified taper angle. \n \~ + \param[in] point0 - \ru Начало локальной системы координат (ЛСК). + \en The origin of local coordinate system (LCS). \~ + \param[in] point1 - \ru Точка на оси Z ЛСК. + \en A point on Z-axis of LCS. \~ + \param[in] point2 - \ru Точка на оси X ЛСК. + \en A point on the X-axis of LCS. \~ + \param[in] radius - \ru Радиус спирали. + \en A spiral radius. \~ + \param[in] step - \ru Шаг спирали. + \en A pitch. \~ + \param[in] angle - \ru Угол коничности спирали. + \en A taper angle. \~ + \param[in] lawCurve - \ru Формообразующая кривая. + \en A guide curve. \~ + \param[in] spiralAxis - \ru Выбор режима формообразования + \en A spiral construction mode. \~ + \param[out] result - \ru Спиральная кривая. + \en The spiral curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SpiralCurve( const MbCartPoint3D & point0, + const MbCartPoint3D & point1, + const MbCartPoint3D & point2, + double radius, + double step, + double angle, + MbCurve * lawCurve, + bool spiralAxis, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать составную кривую (контур). + \en Create a composite curve (contour). \~ + \details \ru Создать составную кривую (контур) на базе исходной кривой. \n + \en Create a composite curve (contour) on the basis of the given curve. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] result - \ru Контур на основе кривой. + \en The contour created on the basis of the curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) CreateContour( MbCurve3D & curve, + MbContour3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать копию кривой. + \en Create a copy of a curve. \~ + \details \ru Создать копию кривой с разбивкой ломаной линии и заменой некоторых кривых. \n + \en Create a copy of a curve with splitting of a polyline and replacement of some curves. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] version - \ru Версия исполнения. + \en The version. \~ + \return \ru Возвращает модифицированную копию кривой, если получилось ее создать. + \en Returns a modified copy of the curve if it has been successfully created. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCurve3D *) DuplicateCurve( const MbCurve3D & curve, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить кривую в составную кривую (контур). + \en Add a curve to a composite curve (a contour). \~ + \details \ru Добавить кривую curve в составную кривую (контур) contour. \n + Если toEnd == true, то добавить в конец. \n + Если toEnd == false, то добавить в начало. \n + \en Add a curve to a composite curve (a contour) 'contour'. \n + If toEnd == true, the curve is to be added to the end. \n + If toEnd == true, the curve is to be added to the beginning. \n \~ + \param[in] curve - \ru Добавляемая кривая + \en A curve to be added. \~ + \param[in,out] contour - \ru Модифицируемый контур. + \en A contour to be modified. \~ + \param[in] toEnd - \ru Флаг места добавления кривой. + \en The flag determines the place of the curve in the contour. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) AddCurveToContour( MbCurve3D & curve, + MbCurve3D & contour, + bool toEnd ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить кривую в пространстве по двумерной кривой. + \en Create a space curve from a two-dimensional curve. \~ + \details \ru Построить кривую в пространстве по двумерной кривой сurve на плоскости place. \n + Построение выполняется на оригинале кривой. + \en Create a space curve from a two-dimensional curve 'curve' lying on plane 'place'. \n + The construction is performed on the source curve. \~ + \param[in] place - \ru Система координат плоскости. + \en The plane coordinate system. \~ + \param[in] curve - \ru Двумерная кривая + \en A two-dimensional curve \~ + \param[out] result - \ru Плоская кривая. + \en The planar curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) PlaneCurve( const MbPlacement3D & place, + const MbCurve & curve, + MbCurve3D *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Построить кривую на поверхности по двумерной кривой. + \en Create a curve on a surface given a two-dimensional curve. \~ + \details \ru Построить кривую на поверхности surface по двумерной кривой сurve. \n + Построение выполняется на оригиналах кривой и поверхности. + \en Create a curve on a surface 'surface' given a two-dimensional curve 'curve'. \n + The construction is performed on the original curve and surface. \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] curve - \ru Двумерная кривая + \en A two-dimensional curve \~ + \param[out] result - \ru Поверхностная кривая. + \en The curve on the specified surface. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SurfaceCurve( const MbSurface & surface, + const MbCurve & curve, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхностную кривую, если пространственная кривая лежит на поверхности. + \en Create a curve on a surface from a space curve lying on the surface. \~ + \details \ru Создать поверхностную кривую, если пространственная кривая лежит на поверхности. \n + Разбираются частные случае точной принадлежности кривой выбранной поверхности. + В общем случае пространственная кривая считается принадлежащей поверхности, если группа точек, + полученная шаганием по параметру кривой по угловому отклонению, принадлежит поверхности. + В этом случае создается двумерная проекционная кривая этой кривой на поверхности. \n + \en Create a curve on a surface from a space curve lying on the surface. \n + The special cases of curves exactly lying on the specified surfaces are treated. + In the general case a space curve is considered to lie on the surface if a group of points + obtained by sampling the curve with the given turning angle belongs to the surface. + In this case a two-dimensional curve is created as the projection of the curve on the surface. \n \~ + \param[in] curve - \ru Пространственная кривая. + \en A space curve. \~ + \param[in] surf - \ru Поверхность. + \en A surface. \~ + \param[in] sameSurf - \ru Использовать оригинал поверхности. + \en Whether to use the source surface. \~ + \param[in] extSurf - \ru Искать на расширенной поверхности. + \en Whether to use the extended surface. \~ + \param[in] strictOnSurface - \ru Все точки кривой лежат на поверхности (true) или часть точек лежит на поверхности (false). + \en All the points of the curve belong to the surface (true) or a part of the points belong to the surface (false). \~ + \param[out] result - \ru Поверхностная кривая. + \en The curve on the specified surface. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) CurveOnSurface( const MbCurve3D & curve, + const MbSurface & surf, + bool sameSurf, bool extSurf, + MbCurve3D *& result, + bool strictOnSurface = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежит ли кривая на поверхности. + \en Determine whether the curve lies on the surface. \~ + \details \ru Проверить, лежит ли кривая полностью на поверхности. \n + \en Determine whether the curve entirely lies on the surface. \n \~ + \param[in] curve - \ru Пространственная кривая. + \en A space curve. \~ + \param[in] surf - \ru Поверхность. + \en A surface. \~ + \param[in] ext - \ru Искать на расширенной поверхности. + \en Whether to use the extended surface. \~ + \param[in] strictOnSurface - \ru Все точки кривой лежат на поверхности (true) или часть точек лежит на поверхности (false). + \en All the points of the curve belong to the surface (true) or a part of the points belong to the surface (false). \~ + \return \ru Возвращает true, если кривая лежит на поверхности. + \en Returns true if the curve lies on the surface. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (bool) IsCurveOnSurface( const MbCurve3D & curve, + const MbSurface & surf, bool ext, + bool strictOnSurface = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив контуров по массиву кривых. + \en Create an array of contours given an array of curves. \~ + \details \ru Создать массив контуров по массиву кривых (на оригиналах кривых). \n + \en Create an array of contours given an array of curves (using the original curves). \n \~ + \param[in] curves - \ru Множество кривых. + \en An array of curves. \~ + \param[in] metricEps - \ru Радиус захвата для стыковки кривых. + \en The radius for curves joining. \~ + \param[out] result - \ru Множество контуров. + \en The array of contours. \~ + \param[in] onlySmoothConnected - \ru Добавлять в контур только гладко стыкующиеся сегменты. + \en Whether to add only smoothly connected segments. \~ + \param[in] version - \ru Версия исполнения. + \en Version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateContours( RPArray & curves, + double metricEps, + RPArray & result, + bool onlySmoothConnected = false, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать контуры по набору кривых с удалением вырожденных. + \en Create contours given a set of curves with elimination of degenerate ones. \~ + \details \ru Создать контуры по набору кривых с удалением вырожденных (на оригиналах кривых). \n + \en Create contours given a set of curves with elimination of degenerate ones (the original curves are used). \n \~ + \param[in, out] curves - \ru Множество кривых. + \en An array of curves. \~ + \param[in] metricAcc - \ru Радиус захвата для стыковки кривых. + \en The radius for curves joining. \~ + \param[in] onlySmoothConnected - \ru Добавлять в контур только гладко стыкующиеся сегменты. + \en Whether to add only smoothly connected segments. \~ + \param[in] version - \ru Версия исполнения. + \en Version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) CreateContours( RPArray & curves, + double metricAcc, + bool onlySmoothConnected = false, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать именованный трехмерный каркас. + \en Create a named three-dimensional wireframe. \~ + \details \ru Создать именованный трехмерный каркас по кривой. \n + \en Create a named three-dimensional wireframe from a curve. \n \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in] curveName - \ru Имя кривой. + \en The curve name. \~ + \param[in] mainName - \ru Главное имя операции. + \en The operation main name. \~ + \param[out] result - \ru Каркас. + \en The wireframe. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) WireFrame( const MbCurve3D & curve, + const MbName & curveName, + SimpleName mainName, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать именованный трехмерный каркас. + \en Create a named three-dimensional wireframe. \~ + \details \ru Создать именованный трехмерный каркас по массиву кривых. \n + \en Create a named three-dimensional wireframe from a given array of curves. \n \~ + \param[in] curves - \ru Множество кривых. + \en An array of curves. \~ + \param[in] curveNames - \ru Множество имен кривых. + \en An array of the curves names. \~ + \param[in] mainName - \ru Главное имя операции. + \en The operation main name. \~ + \param[out] result - \ru Каркас. + \en The wireframe. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) WireFrame( const RPArray & curves, + const RPArray & curveNames, + SimpleName mainName, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Аппроксимировать контур дугами и отрезками. + \en Approximate a contour with arcs and line segments. \~ + \details \ru Аппроксимировать контур дугами и отрезками. \n + Производится аппроксимация каждого из сегментов контура. \n + \en Approximate a contour with arcs and line segments. \n + The approximation is performed for each segment of the contour. \n \~ + \param[in] curve - \ru Кривая или контур, которую надо аппроксимировать. + \en A curve or a contour to approximate. \~ + \param[out] result - \ru Результат аппроксимации. + \en The approximation result. \~ + \param[in] eps - \ru Ошибка аппроксимации. + \en The approximation precision. \~ + \param[in] minRad - \ru Минимально допустимый радиус окружностей, используемых для аппроксимации. + \en The minimal acceptable radius of the circles used for the approximation. \~ + \param[in] maxRad - \ru Максимально допустимый радиус окружностей, используемых для аппроксимации. + \en The maximal acceptable radius of the circles used for the approximation. \~ + \return \ru - Возращает код результата операции. + \en - Returns operation result code. \~ +\ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreatePolyArcCurve3D( const MbCurve3D & curve, + MbCurve3D *& result, + double & eps, + double minRad = Math::minRadius, + double maxRad = Math::maxRadius ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить или создать пространственную кривую. + \en Get or create a space curve. \~ + \details \ru Получить или создать пространственную кривую из данных модельного объекта + c опциональным сохранением несущей плоскости в случае плоского объекта. \n + Двумерный контур на плоскости преобразуется не в контур на плоскости, + а в пространственный контур. \n + \en Get or create a space curve from a model object data. + with optional keeping of supporting plane in the case of a planar object. \n + A two-dimensional contour is to be converted not to a contour on a plane + but to a three-dimensional contour. \n \~ + \param[in] item - \ru Модельный объект. + \en A model object. \~ + \param[in] keepPlacement - \ru Сохранять несущую плоскость. + \en Whether to keep the supporting plane. \~ + \param[out] curve0 - \ru Пространственная кривая. + \en A space curve. \~ + \param[out] curves - \ru Дополнительные пространственные кривые (могут быть в объекте MbPlaneInstance). + \en Additional space curve (It's possible if a object "MbItem" is the object "MbPlaneInstance"). \~ + \return \ru - Возвращает успешность результата операции. + \en - Returns whether the result is successful. \~ +\ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (bool) GetSpaceCurve( const MbItem & item, + bool keepPlacement, + SPtr & curve0, + std::vector< SPtr > * curves = NULL ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Построить развертку кривой/контура на плоскость. + \en Construct a unwrapping curve/contour. \~ + \details \ru Построение развертки кривой/контура на плоскость. Контур разворачивается посегментно, функцией UnwrapCurve. + Первым разворачивается сегмент, который лежит в плоскости и находиться ближе всех к точке, + если лежащих в плоскости нет, то ближащий к точке из тех что пересекают контур, если и таких нет то просто ближайший к точке. + Первый сегмент разворачивается так, чтобы точка пересечения или ближайшей проекции была неподвижной. \n + \en Construction unwrapping of the curve/contour on a plane. Each segment of the contour is unwrapped by the function UnwrapCurve. + Unwrapping starting with a segment which lies in the plane or crosses the plane and which is closest to the given point. + Unwrapping of the first segment is constructed in the manner, that cross point or closest projection of the segment on the plane were stationary. \n \~ + \param[in] curve - \ru Разворачиваемая кривая/контур. + \en Original curve/contour. \~ + \param[in] placement - \ru Локальная система координат плоскости. + \en The placement of the plane. \~ + \param[in] point - \ru Точка для определения первого сегмента. + \en The point for determine first segment. \~ + \param[in] deviationAngle - \ru Параметру точности. + \en The parameter of accuracy. \~ + \return \ru Возвращает указатель на построенную кривую с нулевум счетчиком ссылок \n + или NULL, если не удалось построить развертку для заданных параметров. + \en The pointer to the constructed curve with zero counter of references\n + return NULL, if unwrap curve can't be construvted for this parameters +\ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCurve3D *) UnwrapCurve( const MbCurve3D & curve, + const MbPlacement3D & placement, + const MbCartPoint3D & point, + double deviationAngle = DEVIATION_SAG); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать сечение кинематического тела для заданного параметра на направляющей. + \en Create a section of evolution solid for defined parameter on the guide curve. \~ + \details \ru Создать сечение кинематического тела для заданного параметра на направляющей. + Если направляющая является контуром, то стыки между сегментами контура должны быть гладкими. \n + \en Create a section of evolution solid (sweep solid with guide curve) for defined parameter on guide curve. + If the guide curve is a contour, then this contour have to be smooth. \n \~ + \param[in] generCurves - \ru Множество плоских образующих. + \en An array of forming curves. \~ + \param[in] guideCurve - \ru Направляющая кривая (или контур). + \en An guide curve (or contour). \~ + \param[in] guideParam - \ru Параметр, заданный на направляющей кривой. + \en A parameter on the guide curve. \~ + \param[in] angleEpsilon - \ru Желаемая угловая точность параллельности касательных в точке стыка сегментов контура. + \en The desired angular precision parallel to the tangent at the point of junction path segments. \~ + \param[out] result - \ru Кривые сечения кинематического тела. + \en Curves of evolution solid section. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) EvolutionSection( const MbSweptData & generCurves, + const MbCurve3D & guideCurve, + double guideParam, + const EvolutionValues & params, + MbSweptData & result, + VERSION version = Math::DefaultMathVersion(), + double angleEpsilon = ANGLE_EPSILON ); + + +//------------------------------------------------------------------------------ +// Является ли кривая прямолинейной независимо от ее параметризации. +/** \brief \ru Является ли кривая прямолинейной независимо от ее параметризации. + \en Whether the curve is like straight-line regardless of its parameterisation. \~ + \details \ru Является ли кривая прямолинейной независимо от ее параметризации.\n + \en Whether the curve is like straight-line regardless of its parameterisation. \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[in] eps - \ru Точность. + \en Accuracy. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (bool) IsLikeStraightLine( const MbCurve & curve, double eps ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать осевые (центральные) линии для грани оболочки. + \en Create center lines of shell face. \~ + \details \ru Создать осевые (центральные) линии для грани оболочки. \n + \en Create center lines of shell face. \n \~ + \param[in] face - \ru Исходная грань. + \en The initial face. \~ + \param[out] clCurves - \ru Набор построенных осевых линий. + \en The set of created center lines. \~ + \return \ru Возвращает true, если осевые кривые удалось создать. + \en Returns true if the center lines was created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC( bool ) CreateCenterLineCurves( const MbFace & face, + std::vector & clCurves ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную B-сплайновую кривую на опорной ломаной. + \en Create a fair B-spline on base polyline. \~ + \details \ru Создать плавную V-кривую на опорной ломаной и аппроксимировать B-сплайновой кривой. + Степень сплайна m, (m = 3, 4, ... , 9, 10) устанавливается в переменной degreeBSpline. + Для гармоничного перераспределения точек значение переменной arrange == 1. В противном сучае == 0. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + Направление вектора в точках перегиба учитывается по значению переменной accountInflexVector (0 - как направление звена S-полигона, + 1 - как направление касательного вектора). \n + \en Create a fair V-curve on the base polyline and approximate by a B-spline curve. + The degree of spline m, (m = 3, 4, ... , 9, 10) is set by variable degreeBSpline. + For harmonious redistribution of points, the value of the variable arrange == 1. Otherwise, == 0. + To subdivide a curve, the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). + The direction of the vector at the inflection points is taken into account by the value of the variable InflexVector (0 - as the direction of the S-polygon segment, + 1 - as the direction of the tangent vector). \n \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateFairBSplineCurveOnBasePolyline( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную B-сплайновую кривую на касательной ломаной. + \en Create a fair B-spline on tangent polyline. \~ + \details \ru Создать плавную V-кривую на касательной ломаной и аппроксимировать B-сплайновой кривой. + Степень сплайна m, (m = 3, 4, ... , 9, 10) устанавливается в переменной degreeBSpline. + Для уплотнения кривой устанавливается значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + Направление вектора в точках перегиба кривой совпадает с направлением звена перегиба касательной ломаной. \n + \en Create a fair V-curve on the base polyline and approximate by a B-spline curve. + The degree of spline m, (m = 3, 4, ... , 9, 10) is set by variable degreeBSpline. + To subdivide a curve, the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). + The direction of the tangent vector at the inflection points coincides with the direction of the inflection segment of tangent polyline). \n \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateFairBSplineCurveOnTangentPolyline( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную кривую Безье на опорной ломаной. + \en Create a fair Bezier curve on base polyline. \~ + \details \ru Создать плавную V-кривую на опорной ломаной и аппроксимировать рациональной кубической кривой Безье. + Для гармоничного перераспределения точек значение переменной arrange == 1. В противном сучае == 0. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного).\n + \en Create a smooth V-curve on the reference polyline and approximate a rational cubic Bezier curve. + For harmonious redistribution of points, the value of the variable arrange == 1. Otherwise, == 0. + To subdivide a curve, the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). \n \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) CreateFairBezierCurveOnBasePolyline( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную кривую Безье на касательной ломаной. + \en Create a fair Bezier curve on tangent polyline. \~ + \details \ru Создать плавную V-кривую на касательной ломаной и аппроксимировать рациональной кубической кривой Безье. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). \n + \en Create a smooth V-curve on a tangent polyline and approximate a rational cubic Bezier curve. + To subdivide a curve, the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). \n \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number.from the message list of the MessageError method. \~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateFairBezierCurveOnTangentPolyline( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать ГО Эрмита на кривой Безье. + \en Create Hermite GD on a Bezier curve. \~ + \details \ru Создать геометрический определитель Эрмита в виде ломаной линии на рациональной сплайновой кривой Безье. \n + На кривой определяется опорная ломаная, вершины которой принадлежат узловым точкам сплайна. + Определяются векторы касательных и векторы кривизны. Вектор касательной может иметь произвольную длину. + Вектор кривизны должет иметь длину, равную значению кривизны в данной вершине опорной ломаной. + Если значение кривизны равно нулю в точке перегиба, то вектор кривизны откладывается по направлению касательного вектора в данной вершине + и имеет произвольную ненулевую длину, не превышающую длину касательного вектора. + Направленная ломаная ГО Эрмита последовательно обходит вершины опорной ломаной, концы касательных векторов и концы векторов кривизны. + Обход происходит следующим образом: от вершины опорной к концу касательного вектора, затем возврат к вершине опорной ломаной, + переход к концу вектора кривизны, возврат к вершине опорной ломаной, затем переход к следующей вершине опорной ломаной и т.д. + Вершина с номером 1 и вершины с номерами через 5 (1, 6, 11, ... ) принадлежат концам касательных векторов. + Вершина с номером 3 и вершины с номерами через 5 (3, 8, 13, ... ) принадлежат концам векторов кривизны. + \en Create a Hermite geometric determinant in the form of a polyline on a rational Bezier spline curve. \n + A base polyline is defined on the curve, the vertices of which belong to the nodal points of the spline. + The tangent vectors and the curvature vectors are determined. The tangent vector can be of arbitrary length. + The curvature vector must have a length equal to the value of curvature at a given vertex of the base polyline. + If the curvature value is zero at the inflection point, then the curvature vector is set in the direction of the tangent vector at the given vertex + and has an arbitrary nonzero length not exceeding the length of the tangent vector. \ n + A directional polyline of Hermite GD sequentially bypasses the vertices of the base polyline, the ends of the tangent vectors and the ends of the curvature vectors. + Bypass occurs as follows: from the vertex of the base polyline to the end of the tangent vector, then return to the vertex of the base polyline, + transition to the end of the curvature vector, return to the vertex of the base polyline, then transition to the next vertex of the base polyline, etc. + The vertex with number 1 and the vertices with numbers in 5 (1, 6, 11, ...) belong to the ends of the tangent vectors. + The vertex with number 3 and the vertices with numbers in 5 (3, 8, 13, ...) belong to the ends of the curvature vectors. \~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] polyline - \ru 3D ломаная ГО Эрмита. + \en 3D polyline of Hermite GD. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) KernelCreateHermiteGDOnBezierCurve( MbNurbs3D * curve, + MbFairCurveData & data, + MbCurve3D *& polyline ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать кривую Безье на ГО Эрмита. + \en Create a Bezier on Hermite GD. \~ + \details \ru Изогеометрически построить рациональную кубическую кривую Безье на ГО Эрмита второго порядка фиксации. + Используются все параметры ГО Эрмита второго порядка фиксации: точки, касательные векторы и значения кривизны. + \en Isogeometrically create a cubic rational Bezier curve on a Hermite GD of second-order fixation. + Used all params of Hermite GD of second-order fixation: points, tangent vectors and values of curvature. \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateBezierCurveOnHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать B-сплайновую кривую на ГО Эрмита. + \en Create a B-spline on Hermite GD. \~ + \details \ru Создать B-сплайную кривую на ГО Эрмита первого порядка фиксации. \n + Направления касательных векторов ГО Эрмита определяют направления звеньев S-полигона. + Направление вектора в точках перегиба учитывается по значению переменной accountInflexVector (0 - как направление звена S-полигона, \n + 1 - как направление касательного вектора). \n + Кривизна в концевых точках учитывается по значению accountCurvature (0 - не учитывается, 1 - в начальной точке, 2 - в конечной точке, 3 - учитываются на обоих концах). + \en Create a B-spline curve on Hermite's GD of first-order fixation. \ n +               The directions of the tangent vectors of the Hermite GD determine the directions of the S-polygon segmentss. \n +               The direction of the vector at the inflection points is taken into account by the value of the variable InflexVector (0 - as the direction of the S-polygon segment, +               1 - as the direction of the tangent vector). \n +               The curvature at the end points is taken into account by the value of accountCurvature (0 - not taken into account, 1 - at the start point, 2 - at the end point, 3 - are taken into account at both ends). \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) CreateBSplineCurveOnHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную кривую Безье на опорной ломаной ГО Эрмита. + \en Create a fair Bezier curve on base polyline of Hermite GD. \~ + \details \ru Создать плавную V-кривую на опорной ломаной ГО Эрмита и аппроксимировать рациональной кубической кривой Безье. \n + Учитываются концевые значения кривизны и направления касательных в точках перегиба ГО Эрмита. + Для гармоничного перераспределения точек значение переменной arrange == 1. В противном сучае == 0. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + \en Create a fair V-curve on the base polyline and approximate by a rational cubic Bezier curve. \ n + The end values of the curvature and directions of the tangents at the inflection points of the Hermite GO are taken into account. + For harmonious redistribution of points, the value of the variable arrange == 1. Otherwise, == 0. + To subdivide a curve, the value of the variable subdivision> 0 (1 for a single subdivision, 2 for a double subdivision).\~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) CreateFairBezierCurveOnBasePolylineOfHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную кривую Безье на касательных прямых ГО Эрмита. + \en Create a fair Bezier curve on tangent lines of Hermite GD. \~ + \details \ru Создать плавную V-кривую на касательных прямых ГО Эрмита и аппроксимировать рациональной кубической кривой Безье. \n + Учитываются концевые значения кривизны и положения точек перегиба ГО Эрмита. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + \en Create a fair V-curve on the base polyline and approximate by a rational cubic Bezier curve. \ n +  The end values of the curvature and directions of the tangents at the inflection points of the Hermite GO are taken into account. + To subdivide a curve, set the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision).\~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке \n + из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number \ n +              from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateFairBezierCurveOnTangentsOfHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную B-сплайновую кривую на опорной ломаной ГО Эрмита. + \en Create a fair B-spline curve on base polyline of Hermite GD. \~ + \details \ru Создать плавную V-кривую на опорной ломаной и аппроксимировать B-сплайновой кривой. \n + Степень сплайна m, (m = 3, 4, ... , 9, 10) устанавливается в переменной degreeBSpline. + Для гармоничного перераспределения точек значение переменной arrange == 1. В противном сучае == 0. + Для уплотнения кривой значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + Направление вектора в точках перегиба учитывается по значению переменной accountInflexVector (0 - как направление звена S-полигона, + 1 - как направление касательного вектора). \n + Кривизна в концевых точках учитывается по значению accountCurvature (0 - не учитывается, 1 - в начальной точке, 2 - в конечной точке, 3 - учитываются на обоих концах). + \en Create a fair V-curve on the base polyline and approximate by a B-spline curve. \ n + The degree of spline m, (m = 3, 4, ... , 9, 10) is set by variable degreeBSpline. + For harmonious redistribution of points, the value of the variable arrange == 1. Otherwise, == 0. + To subdivide a curve, the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). + The directions of the tangent vectors of the Hermite GD determine the directions of the S-polygon segmentss. \n + The direction of the vector at the inflection points is taken into account by the value of the variable InflexVector (0 - as the direction of the S-polygon segment, \ n + 1 - as the direction of the tangent vector). \n + The curvature at the end points is taken into account by the value of accountCurvature (0 - not taken into account, 1 - at the start point, 2 - at the end point, 3 - are taken into account at both ends). \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC (MbResultType) CreateFairBSplineCurveOnBasePolylineOfHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать плавную B-сплайновую кривую на касательных прямых ГО Эрмита. + \en Create a fair B-spline curve on tangent lines of Hermite GD. \~ + \details \ru Создать плавную V-кривую на касательных прямых ГО Эрмита и аппроксимировать B-сплайновой кривой. \n + Степень сплайна m, (m = 3, 4, ... , 9, 10) устанавливается в переменной degreeBSpline. + Для гармоничного перераспределения точек значение переменной arrange == 1. В противном сучае == 0. + Для уплотнения кривой установите значение переменной subdivision > 0 (1 - для однократного уплотнения, 2 - для двукратного). + Кривизна в концевых точках учитывается по значению accountCurvature (0 - не учитывается, 1 - в начальной точке, 2 - в конечной точке, 3 - учитываются на обоих концах). + \en Create a fair V-curve on the base polyline of Hermite GD and approximate by a B-spline curve. \ n + The degree of spline m, (m = 3, 4, ... , 9, 10) is set by variable degree. + For harmonious redistribution of points, the value of the variable arrange == 1. Otherwise, == 0. + To subdivide a curve, set the value of the variable subdivision > 0 (1 for a single subdivision, 2 for a double subdivision). + The curvature at the end points is taken into account by the value of accountCurvature (0 - not taken into account, 1 - at the start point, 2 - at the end point, 3 - are taken into account at both ends). \~ + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. 0 - при успешном построении кривой. При > 0 значение равно номеру сообщения об ошибке из списка сообщений метода MessageError. + \en Returns operation result value. 0 - upon successful creation of the curve. If > 0, the value is equal to the error message number from the message list of the MessageError method.\~ + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) CreateFairBSplineCurveOnTangentsOfHermiteGD( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать клотоиду. + \en Create a clothoid. \~ + \details \ru Создать начальный участок клотоиды. \n + В переменных data задаются параметры построения клотоиды. Максимальная длина начального участка клотоиды в переменной + clothoidMax и минимальный радиус на конце участка в переменной clothoidRMin. В переменной clothoidSegms задается количество + сегментов аппроксимирующей клотоиду сплайновой кривой Безье. + \en Create the starting part of the clothoid. \ n +             The parameters to create the clothoid are set in the data. The maximum length of the initial section of the clothoid in the variable clothoidMax and the minimum radius at the end of the section in the variable clothoidRMin. + The variable clothoidSegms sets the number of segments of the Bezier spline curve approximating the clothoid .\~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. + \en Returns operation result value. + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) KernelCreateClothoid( MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Создать сектрису. + \en Create a sectrix. \~ + \details \ru Создать сектрису Маклорена. \n + На касательной ломаной из двух звеньев генерируются точки сектрисы Маклорена - кривой с монотонным изменением кривизны. + Сектриса Маклорена изогеометрически с сохранением монотонности аппроксимируется сплайновой кривой Безье. + \en Create a sectrix of Maclourin. + On a tangent polyline of two links, points of the Maclaurin sectrix — a curve with a monotonic change in curvature — are generated. +             The Maclaurin sectrix is isometrically approximated with the preservation of monotony by the Bezier spline curve.\~ +            + \param[in] polyline - \ru Исходная ломаная. + \en An initial polyline. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. + \en Returns operation result value. + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) KernelCreateSectrix( MbCurve3D * polyline, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Увеличить степень NURBzS кривой. + \en Elevate the degree of the NURBzS curve. \~ + \details \ru Увеличить степень NURBzS кривой. \n + Степень кубической кривой увеличивается до шестой степени. + Степени больше 6 увеличиваются на единцу. Максимальная степень - 10. + \en The increasing the degree of the NURBzS curve. \n + The degree of the cubic curve increases to the sixth degree. +             Degrees greater than 6 increase by one. The maximum degree is 10.\~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] data - \ru Данные построения кривой. + \en The curve construction data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. + \en Returns operation result value. + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) ElevateDegreeNurbzs( MbNurbs3D * curve, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Уплотнить NURBS кривую. + \en Subdivide the NURBS curve. \~ + \details \ru Однократно уплотнить NURBS кривую. \n + \en Single subdivision of NURBS curve. \~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] data - \ru Данные построения и преобразования кривой. + \en Curve construction and transformation data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. + \en Returns operation result value. + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) SubdivideNurbs( MbNurbs3D * curve, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Выделить участок NURBS кривой / изменить формат NURBS кривой. + \en To extrct part of NURBS curve / change the format of the NURBS curve. \~ + \details \ru Выделить участок NURBS кривой / изменить формат NURBS кривой. \n + В data устанавливаются переменые преобразований. Выделямый участок определяется номером начального сегмента в переменной numSegment + и количеством сегментов в переменной numSegments. Выходной формат сплайна определяется в переменной outFormat. + При значении 2 - NURBS кривая с управляющим S-полигоном. При значении 3 - рациональная кривая Безье + с управляющим GB-полигоном. + \en To extrct part of NURBS curve / change the format of the NURBS curve. \n + Transformation variables are set in data. The extracting part is determined by the number of the starting segment in the variable numSegment and the number of segments in the variable numSegments. + The output spline format is defined in the outFormat variable.    If the value is 2 - NURBS curve with control S-polygon. If the value is 3 - rational Bezier curve with GB-control polygon.\~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] data - \ru Данные построения и преобразования кривой. + \en Curve construction and transformation data. \~ + \param[out] result - \ru Сплайновая кривая. + \en The spline curve. \~ + \return \ru Возвращает значение результата операции. + \en Returns operation result value. + \ingroup Curve3D_Modeling + */ +// --- +MATH_FUNC(MbResultType) ExtractChangeNurbs( MbNurbs3D * curve, + MbFairCurveData & data, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ + /** \brief \ru Вставить узел в NURBS. + \en Insert node in NURBS. \~ + \details \ru Вставить узел в NURBS. \n + В data устанавливаются переменые преобразований. Место вставки узла определяется переменными nSegment и tParam. + В переменной nSegment устанавливается номер сегмента, в переменной tParam (0.1 < tParam < 0.9) задается значение внутреннего параметра на сегменте сплайна. + \en Insert node in NURBS. Transformation variables are set in data. The insertion positon of the node is determined by the variables nSegment and tParam. +             The nSegment variable sets the segment number, the tParam variable (0.1 +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSplineSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; + + +//------------------------------------------------------------------------------ +/** \brief \ru Модифицировать тело по матрице. + \en Modify a solid by the matrix. \~ + \details \ru Выполнить трансформацию копии исходного тела по матрице, рассчитанной по габаритному кубу. \n + \en Transform a copy of the solid using the matrix calculated by bounding box of solid. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] p - \ru Параметры трансформации. + \en The transformation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) TransformedSolid( MbSolid & solid, + MbeCopyMode sameShell, + const TransformValues & p, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Собрать грани оболочки для методов прямого моделирования. + \en Modify a shell by the methods of direct modeling. \~ + \details \ru Функция собирает грани оболочки для методов прямого моделирования: \n + удаление из тела выбранных граней с окружением (way==dmt_Remove), \n + удаление выбранных граней скругления тела (way==dmt_Purify). \n + Для удаления граней собираются замкнутые цилиндрические, конические, тороидальные, сферические грани тела, + а также грани вращения, радиус которых не превосходит указанный радиус. + Для удаления граней скругления собираются незамкнутые цилиндрические, тороидальные, сферические грани, + а также грани скругления, радиус которых не превосходит указанный радиус. \n + \en The method collects the faces of the shell for direct modeling methods: \n + removal of the faces from a shell (way==dmt_Remove), \n + removal of the fillet faces from a shell (way==dmt_Purify). \n + The cylindrical, conical, toroidal, spherical, and revolution periodic faces are collect to remove way. + The cylindrical, toroidal, spherical non-periodic, and fillet faces are collect to purify way. \n \~ + \param[in] shell - \ru Исходная оболочка тела. + \en The initial faces set. \~ + \param[in] way - \ru Способ модификации. + \en Way of the modification. \~ + \param[in] radius - \ru Радиус собираемых граней. + \en Radius of collected faces. \~ + \param[in] faces - \ru Найденные грани для дальнейшей модификации. + \en Found faces to be modified. \~ + \return \ru Возвращает код результата действий. + \en Returns action result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CollectFacesForModification( MbFaceShell * shell, + MbeModifyingType way, + double radius, + RPArray & faces ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Модифицировать или построить тело методами прямого моделирования. + \en Modify a solid by the methods of direct modeling. \~ + \details \ru В зависимости от параметров модификации метод выполняет одно из следующих действий: \n + 1. Удаление из тела выбранных граней с окружением (param.way==dmt_Remove). \n + 2. Создание тела из выбранных граней с окружением (param.way==dmt_Create). \n + 3. Перемещение выбранных граней с окружением относительно оставшихся граней тела (param.way==dmt_Action). \n + 4. Замена выбранных граней тела эквидистантными гранями (param.way==dmt_Offset). \n + 5. Изменение радиуса выбранных граней скругления (param.way==dmt_Fillet). \n + 6. Замена выбранных граней тела деформируемыми гранями для редактирования (param.way==dmt_Supple). \n + 7. Удаление выбранных граней скругления тела (param.way==dmt_Purify). + \en The method is for one of listed actions below depends of parameters: \n + 1. Removal of the specified faces with the neighborhood from a solid (param.way==dmt_Remove). \n + 2. Creation of a solid from the specified faces with the neighborhood (param.way==dmt_Create). \n + 3. Translation of the specified faces with neighborhood relative to the other faces of the solid (param.way==dmt_Action). \n + 4. Replacement of the specified faces of a solid with the offset faces (param.way==dmt_Offset). \n + 5. Changing of the radius of the specified fillet faces (param.way==dmt_Fillet). \n + 6. Replacement of the specified faces of a solid with a deformable faces for editing (param.way==dmt_Supple). \n + 7. Removal of the specified fillet faces from a solid (param.way==dmt_Purify). \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] params - \ru Параметры модификации. + \en Parameters of the modification. \~ + \param[in] faces - \ru Изменяемые грани тела. + \en Faces to be modified. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FaceModifiedSolid( MbSolid & solid, + MbeCopyMode sameShell, + const ModifyValues & params, + const RPArray & faces, + const MbSNameMaker & names, + MbSolid *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Модифицировать или построить тело методами прямого моделирования. + \en Modify a solid by the methods of direct modeling. \~ + \details \ru Метод выполняет удаление указанных рёбер, слияние их вершин и модификацию окружающих граней (param.way==dmt_Merger). + По направлению вектора "param.direction" определяется: начальная ли вершина ребра будет слита с конечной вершиной, или конечная вершина ребра будет слита с начальной вершиной. \n + \en The method performs the deletion of selectsd edges, merging their vertices and modification of surrounding faces (param.way==dmt_Merger). + The direction of the vector "params.direction" determines whether the start vertex of an edge is merged with the end vertex, or whether the end vertex of an edge is merged with the start vertex. \n + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] params - \ru Параметры модификации, способ должен быть равен param.way==dmt_Merger. + \en Parameters of the modification, the way must be equal to param.way==dmt_Merger. \~ + \param[in] edges - \ru Удаляемые рёьра тела. + \en Edges to be removed. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- + +MATH_FUNC (MbResultType) EdgeModifiedSolid( MbSolid & solid, + MbeCopyMode sameShell, + const ModifyValues & params, + const RPArray & edges, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Заменить выбранные грани тела деформируемыми гранями. + \en Replace the specified faces of solid with deformable faces. \~ + \details \ru Заменить выбранные грани тела деформируемыми гранями (превращение в NURBS для редактирования). \n + \en Replace the specified faces of the solid with deformable faces (conversion to NURBS for editing). \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] p - \ru Параметры преобразования. + \en The transformation parameters. \~ + \param[in] faces - \ru Заменяемые грани тела. + \en Faces to replace. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ModifiedNurbsItem( MbSolid & solid, + MbeCopyMode sameShell, + const NurbsValues & p, + const RPArray & faces, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Заменить выбранную грань тела деформируемой гранью. + \en Replace the specified face of the solid by a deformable face. \~ + \details \ru Заменить выбранную грань тела деформируемой гранью (превращение в NURBS для редактирования). \n + \en Replace the specified face of the solid by a deformable face (conversion to NURBS for editing). \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] p - \ru Параметры преобразования. + \en The transformation parameters. \~ + \param[in] face - \ru Заменяемая грань тела. + \en A face to replace. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ModifiedNurbsItem( MbSolid & solid, + MbeCopyMode sameShell, + const NurbsValues & p, + const MbFace & face, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить NURBS-поверхности грани. + \en Get the NURBS-surfaces of a face. \~ + \details \ru Выполнить построение деформируемой поверхности для исходной грани. \n + \en Create a deformable surface for the initial face. \n \~ + \param[in] face - \ru Исходная грань. + \en The initial face. \~ + \return \ru Возвращает NURBS-поверхности грани. + \en Returns NURBS-surfaces of the face. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbSurface *) GetControlSurface( const MbFace & face ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить контрольные точки NURBS-поверхности грани. + \en Get the control points of the NURBS-surface of a face. \~ + \details \ru Получить множество контрольных точек NURBS-поверхности грани и множества их весов. \n + \en Get a set of the control points of a NURBS-surface of a face and a set of their weights. \n \~ + \param[in] face - \ru Исходная грань. + \en The initial face. \~ + \param[out] controlPoints - \ru Контрольные точки NURBS-поверхности грани. + \en The control points of the NURBS-surface of the face. \~ + \param[out] result - \ru Веса контрольных точек. + \en The weights of the control points. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FaceControlPoints( const MbFace & face, + Array2 & controlPoints, + Array2 & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Деформировать грань тела. + \en Deform a face of a solid. \~ + \details \ru Деформировать грань тела путём подстановки присланных контрольных точек NURBS-поверхности грани. \n + \en Deform a face of a solid by substitution the control points of NURBS-surface of the face with the given control points. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] face - \ru Изменяемая грань тела. + \en A face of a solid to be modified. \~ + \param[in] faceSurface - \ru Новая NURBS-поверхность для грани. + \en The new NURBS-surface of the face. \~ + \param[in] fixedPoints - \ru Неподвижные узлы. + \en The fixed points. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsModification( MbSolid & solid, + MbeCopyMode sameShell, + MbFace * face, + MbSurface & faceSurface, + Array2 & fixedPoints, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Деформировать грань тела. + \en Deform a face of a solid. \~ + \details \ru Деформировать грань тела путём подстановки присланных контрольных точек NURBS-поверхности грани. \n + \en Deform a face of a solid by substitution the control points of NURBS-surface of the face with the given control points. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the initial solid. \~ + \param[in] face - \ru Изменяемая грань тела. + \en A face of a solid to be modified. \~ + \param[in] controlPoints - \ru Контрольные точки NURBS-поверхности грани. + \en The control points of the NURBS-surface of the face. \~ + \param[in] weights - \ru Веса контрольных точек. + \en The weights of the control points. \~ + \param[in] fixedPoints - \ru Неподвижные узлы. + \en The fixed points. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Модифицированное тело. + \en The modified solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsModification( MbSolid & solid, + MbeCopyMode sameShell, + MbFace * face, + const Array2 & controlPoints, + const Array2 & weights, + Array2 * fixedPoints, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить деформируемую призму. + \en Create a deformable prism. \~ + \details \ru Построить тело в форме прямого параллелепипеда с деформируемыми гранями. \n + \en Create a solid as a right parallelepiped with deformable faces. \n \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] ax - \ru Размер по X. + \en The size in X-direction. \~ + \param[in] ay - \ru Размер по Y. + \en The size in Y-direction. \~ + \param[in] az - \ru Размер по Z. + \en The size in Z-direction. \~ + \param[in] outDir - \ru Ориентация нормалей наружу. + \en An outer orientation of the normals. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] name - \ru Главное имя. + \en The main name. \~ + \param[in] param - \ru Параметры NURBS-поверхностей граней параллелепипеда. + \en The parameters of NURBS-surfaces of the parallelepiped faces. \~ + \param[out] result - \ru Тело из NURBS-поверхностей. + \en The solid constructed from the NU|RBS-surfaces. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsBlockSolid( const MbPlacement3D & place, + double ax, + double ay, + double az, + bool outDir, + const MbSNameMaker & names, + SimpleName name, + NurbsBlockValues & param, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить согласованную поверхность. + \en Create a matched surface. \~ + \details \ru Для исходной поверхности выполнить построение изменённой поверхности + путем выставления сопряжения вдоль кривой. \n + \en Create a modified surface for the initial surface + by specifying the conjugation along the curve. \n \~ + \param[in] curve - \ru Кривая пересечения поверхностей ребра. + \en The intersection curve of the edge surfaces. \~ + \param[in] sences - \ru Ориентация кривой ребра в цикле. + \en The edge curve sense in the loop. \~ + \param[in] faceSences - \ru Ориентация нормали на смежной грани. + \en The adjacent face normal orientation. \~ + \param[in] surface - \ru Исходная сплайновая поверхность для изменяемой грани. + \en The initial spline surface of the face to be modified. \~ + \param[in] tension - \ru Натяжение. + \en The tension. \~ + \param[in] conType - \ru Тип сопряжения. + \en The conjugation type. \~ + \param[in] insertNum - \ru Вставляемый ряд. + \en The row number. \~ + \param[out] result - \ru NURBS-поверхность, полученная в результате преобразований. + \en The NURBS-surface obtained as a result of the modifications. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsFaceConjugation( const MbSurfaceIntersectionCurve & curve, + bool sences, + bool faceSences, + const MbSplineSurface & surface, + double tension, + MbeConjugationType conType, + size_t insertNum, + MbSplineSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить подобную поверхность. + \en Create a similar surface. \~ + \details \ru Для исходной поверхности выполнить построение подобной поверхности + по указанной поверхности-образцу. \n + \en Create a surface similar to the initial one + given the pattern surface. \n \~ + \param[in] originSurface - \ru Поверхность-образец. + \en A pattern surface. \~ + \param[in] surface - \ru Исходная сплайновая поверхность для изменяемой грани. + \en The initial spline surface of the face to be modified. \~ + \param[in] uToU - \ru Флаг сохранения параметрического направления как у поверхности-образца. + \en Whether to keep the parametric direction of the pattern surface. \~ + \param[in] normSence - \ru Флаг сохранения направления нормали поверхности-образца. + \en Whether to keep the normal direction of the pattern surface. \~ + \param[out] result - \ru NURBS-поверхность, полученная в результате преобразований. + \en The NURBS-surface obtained as a result of the modifications. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsFaceSimilarity( const MbSurface & originSurface, + const MbSplineSurface & surface, + bool uToU, + bool normSence, + MbSplineSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить сглаженную поверхность. + \en Create a smoothed surface. \~ + \details \ru Выполнить сглаживание копии исходной поверхности не изменяя ее порядок и количество контрольных точек. \n + \en Perform smoothing of a copy of the initial surface without changing its order and the number of control points. \n \~ + \param[in] surface - \ru Исходная сплайновая поверхность для изменяемой грани. + \en The initial spline surface of the face to be modified. \~ + \param[in] udegree - \ru Параметр сглаживания по первому параметру поверхности. + \en The smoothing surface degree for direction of first parameter of surface. \~ + \param[in] vdegree - \ru Параметр сглаживания по второму параметру поверхности. + \en The smoothing surface degree for direction of second parameter of surface. \~ + \param[out] result - \ru NURBS-поверхность, полученная в результате преобразований. + \en The NURBS-surface obtained as a result of the modifications. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Direct_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplineSurfaceSmoothing( const MbSplineSurface & surface, + size_t udegree, + size_t vdegree, + MbSplineSurface *& result ); + + +#endif // __ACTION_DIRECT_H diff --git a/C3d/Include/action_mesh.h b/C3d/Include/action_mesh.h new file mode 100644 index 0000000..5d03edb --- /dev/null +++ b/C3d/Include/action_mesh.h @@ -0,0 +1,279 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения полигональных геометрических объектов. + \en Functions for construction of the polygonal geometric object. \~ + \details \ru Полигональные геометрические объекты могут быть построены по набору точек или на базе других объектов. + \en Polygonal geometric objects can be constructed using a set of point or on the basis of other objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_MESH_H +#define __ACTION_MESH_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbMesh; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSolid; +class MATH_CLASS MbPlaneItem; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbFace; +class MATH_CLASS MbCollection; + + +//------------------------------------------------------------------------------ + /** \brief \ru Расчет полигона кривой. + \en Calculation of polygon of curve. \~ + \details \ru Расчет трехмерного полигона двумерной кривой в плоскости XOY локальная системы координат. + \en Calculation of three-dimensional polygon of two-dimensional curve located in the XOY-plane of a local coordinate system. \~ + \param[in] curve - \ru Двумерная кривая. + \en A two-dimensional curve. \~ + \param[in] plane - \ru Локальная система координат. + \en Local coordinate system. \~ + \param[in] sag - \ru Максимальное допустимое отклонение полигона от оригинала по прогибу или по углу между соседними элементами. + \en Maximum allowable deviation of polygon from the original by sag or by angle between neighboring elements. \~ + \param[out] polygon - \ru Рассчитанный полигон. + \en Calculated polygon. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) CalculatePolygon( const MbCurve & curve, + const MbPlacement3D & plane, + double sag, + MbPolygon3D & polygon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить полигональный двухмерный объект. + \en Create a polygonal two-dimensional object. \~ + \details \ru Построить полигональный объект для двумерного объекта в плоскости XOY + локальной системы координат. + \en Create a polygonal object for two-dimensional object in the XOY-plane + of the local coordinate system. \~ + \param[in] obj - \ru Двумерный объект (если NULL, то объект не создаётся). + \en Two-dimensional object (if NULL, object isn't created). \~ + \param[in] plane - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] sag - \ru Максимальное отклонение полигонального объекта от оригинала по прогибу. + \en The maximum deviation of polygonal object from the original object by sag. \~ + \param[out] mesh - \ru Полигональный объект. + \en Polygonal object. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (void) CalculateWire( const MbPlaneItem & obj, + const MbPlacement3D & plane, + double sag, + MbMesh & mesh ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить икосаэдр в виде полигональной модели. + \en Construct an icosahedron mesh. \~ + \details \ru Построить икосаэдр в виде полигональной модели. \n + \en Construct an icosahedron mesh. \n \~ + \param[in] place - \ru Местная система координат. + \en Local placement. \~ + \param[in] radius - \ru Радиус описанной сферы. + \en The radius of the sphere. \~ + \param[in] fn - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[out] result - \ru Результат построения. + \en The resulting mesh. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) CreateIcosahedron( const MbPlacement3D & place, + double radius, + const MbFormNote & fn, + MbMesh *& result ); + + +//------------------------------------------------------------------------------ +// . +/** \brief \ru Построить полигональную сферу. + \en Construct an spherical mesh. \~ + \details \ru Построить аппроксимацию сферы выпуклым многогранником. \n + \en Construct an approximation of the sphere by a convex polyhedron. \n \~ + \param[in] place - \ru Местная система координат. + \en Local placement. \~ + \param[in] radius - \ru Радиус сферы. + \en The radius of the sphere. \~ + \param[in] epsilon - \ru Параметр аппроксимации сферы. + \en The approximation parameter. \~ + \param[out] result - \ru Результат построения. + \en The resulting mesh. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) CreateSpherePolyhedron( const MbPlacement3D & place, + double radius, + double & epsilon, + MbMesh *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить выпуклую оболочку для множества точек. + \en Calculate a convex hull of a point set. \~ + \details \ru Вычислить сетку, представляющую выпуклой оболочку для множества точек. + \en Calculate mesh being a convex hull of a point set. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) CreateConvexPolyhedron( const SArray & points, + MbMesh *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить выпуклую оболочку для триангуляционной сетки. + \en Construct the convex hull of triangulation grid. \~ + \details \ru Построить сетку, представляющую собой выпуклую оболочку для тела, + заданного его триангуляционной сеткой. По заданному объекту MbMesh + строится охватывающая его вершины выпуклая триангуляционная сетка. + Расстояние offset задает смещение точек результирующей сетки относительно + заданной вдоль нормалей к её граням. Если offset = 0, то результирующая сетка + будет в точности охватывать все вершины заданной. Смещение по нормали может + быть как положительным, так и отрицательным (внутрь сетки). Используется для + определения пересечения с некоторым допуском (offset). \n + \en Construct the convex hull of triangulation grid. \n \~ + \param[in] mesh - \ru Исходная триангуляционная сетка. + \en Initial triangulated mesh. \~ + \param[in] offset - \ru Отступ по нормали для результирующей сетки. + \en The offset along a normal for the resulting grid. \~ + \param[out] resMesh - \ru Результирующая выпуклая триангуляционная сетка. + \en The resulting triangulation convex grid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) CreateConvexPolyhedron( const MbMesh & mesh, + double offset, + MbMesh *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить, пересекаются ли данные выпуклые сетки. + \en Whether there is intersection of convex grids. \~ + \details \ru Определить, пересекаются ли данные выпуклые оболочки, заданные + триангуляционными сетками. Пересечение определяется по алгоритму + Гильберта-Джонсона-Керти (Gilbert-Johnson-Keerthi). Заданные сетки + равноправны, их последовательность в алгоритме не важна. Сложность + алгоритма линейная, зависит от количества вершин сеток. \n + \en Whether there is intersection of convex grids. \n \~ + \param[in] mesh1 - \ru Первая выпуклая триангуляционная сетка. + \en The first convex grid. \~ + \param[in] mesh2 - \ru Вторая выпуклая триангуляционная сетка. + \en The second convex grid. \~ + \return \ru true - Выпуклые триангуляционные сетки пересекаются. + false - Выпуклые триангуляционные сетки не пересекаются. + \en true - true - there is an intersection, + false - there are no intersections. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (bool) AreIntersectConvexPolyhedrons( const MbMesh & mesh1, + const MbMesh & mesh2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезать часть полигонального объекта плоскостью. + \en Cut a part of a polygonal object by a plane. \~ + \details \ru Отрезать часть полигонального объекта плоскостью XY локальной системы координат. \n + part = 1 - оставляем часть объекта, расположенную сверху плоскости XY локальной системы координат, \n + part = -1 - оставляем часть объекта, расположенную снизу плоскости XY локальной системы координат. \n + \en Cut a part of a polygonal object off by a plane XY of local coordinate system. \n + part = 1 - a part of polygonal object above the XY plane is to be retained. \n + part = -1 - a part of polygonal object below the XY plane is to be retained. \n \~ + \param[in] mesh - \ru Исходный полигональный объект. + \en The source polygonal object. \~ + \param[in] sameShell - \ru Режим копирования исходного объекта. + \en The mode of copying of the source polygonal object. \~ + \param[in] place - \ru Секущая плоскость. + \en A cutting plane. \~ + \param[in] part - \ru Направление отсечения. + \en The direction of cutting off. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] onlySection - \ru Флаг режима отсечения: false - сечем как тело, true - сечем как оболочку. + \en The flag of the cutting off mode: false - cut as a solid, true - cut as a shell. \~ + \param[out] result - \ru Построенный полигональный объект. + \en The resultant polygonal object. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) MeshCutting( MbMesh & mesh, + MbeCopyMode sameShell, + const MbPlacement3D & place, + int part, + const MbSNameMaker & names, + bool onlySection, + MbMesh *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить контур сечения полигонального объекта плоскостью. + \en Create a section contour of a polygon figure. \~ + \details \ru Построить контур сечения присланного объекта плоскостью XY локальной системы координат. \n + \en Construct curves of the section of the mesh object lying on the XY plane of the local coordinate system. \n + \param[in] mesh - \ru Исходный полигональный объект. + \en The source polygonal object. \~ + \param[in] place - \ru Секущая плоскость. + \en A cutting plane. \~ + \param[out] polylines - \ru Построенные ломагные контура сечения объекта. + \en The resultant contours. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) MeshSection( const MbMesh & mesh, + const MbPlacement3D & place, + RPArray & polylines ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить триангуляцию по облаку точек на основе алгоритма поворотного шара. + \en Build a triangulation by point cloud with Ball Pivoting algorithm. \~ + \param[in] collection - \ru Коллекция трехмерных элементов. + \en Collection of 3d elements. \~ + \param[in] radius - \ru Радиус поворотного шара, если radius==0 будет предпринята попытка его автоопределения. + \en Radius of the pivoting ball, if radius==0 an autoguess for the ball pivoting radius is attempted \~ + \param[in] radiusMin - \ru Радиус кластеризации ( в % от радиуса поворотного шара ). + \en Clusterization radius ( % from radius value). \~ + \param[in] angle - \ru Максимальный угол между двумя соседними элементами сетки. + \en Max angle between two mesh faces \~ + \param[out] result - \ru Построенный полигональный объект. + \en The resultant polygonal object. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (MbResultType) CalculateBallPivotingGrid( const MbCollection & collection, + double radius, + double radiusMin, + double angle, + MbMesh *& result ); + + +#endif // __ACTION_MESH_H diff --git a/C3d/Include/action_phantom.h b/C3d/Include/action_phantom.h new file mode 100644 index 0000000..bd26ea5 --- /dev/null +++ b/C3d/Include/action_phantom.h @@ -0,0 +1,299 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение фантомов операций. + \en Creation of phantom operations. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_PHANTOM_H +#define __ACTION_PHANTOM_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фантомные поверхности скругления/фаски. + \en Create phantom surfaces of fillet/chamfer. \~ + \details \ru Построить фантомные поверхности скругления/фаски и сложить в контейнер surfaces. \n + По окончании работ поверхности можно и нужно удалить. \n + \en Create phantom surfaces of fillet/chamfer and store them in the container 'surfaces'. \n + After finish working with the surfaces they should be deleted. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер для скругления/фаски. + \en An array of edges for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[out] result - \ru Поверхности скругления/фаски. + \en The fillet/chamfer surfaces. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) SmoothPhantom( const MbSolid & solid, + RPArray & edges, + const SmoothValues & params, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фантомные поверхности скругления/фаски. + \en Create phantom surfaces of fillet/chamfer.\~ + \details \ru Построить фантомные поверхности скругления/фаски и сложить в контейнер surfaces. \n + По окончании работ поверхности можно и нужно удалить. + \en Create phantom surfaces of fillet/chamfer and store them in the container 'surfaces'. \n + After finish working with the surfaces they should be deleted. \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер и функций изменения радиуса для скругления/фаски. + \en An array of edges and radius laws for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[out] result - \ru Поверхности скругления/фаски. + \en The fillet/chamfer surfaces. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) SmoothPhantom( const MbSolid & solid, + SArray & edges, + const SmoothValues & params, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить последовательности гладко стыкующихся рёбер. + \en \~ + \details \ru Построить последовательности гладко стыкующихся рёбер, скругляемых одновременно, + а также поверхности скругления/фаски (массив surfaces). \n + По окончании работ поверхности можно и нужно удалить. + \en \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер для скругления/фаски. + \en An array of edges for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[in] createSurfaces - \ru Создавать ли поверхности скругления/фаски для фантома? + \en Create a fillet/chamfer surfaces for phantom. \~ + \param[out] sequences - \ru Последовательность гладко стыкующихся рёбер. + \en Sequence of smooth mating edges. \~ + \param[out] result - \ru Поверхности скругления/фаски. + \en The fillet/chamfer surfaces. \~ + \return \ru Возвращает код результата построения. + \en \~ + \ingroup Algorithms_3D +*/ + +// --- +MATH_FUNC (MbResultType) SmoothSequence( const MbSolid & solid, + RPArray & edges, + const SmoothValues & params, + bool createSurfaces, + RPArray & sequences, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить последовательности гладко стыкующихся рёбер. + \en \~ + \details \ru Построить последовательности гладко стыкующихся рёбер, скругляемых одновременно, + а также поверхности скругления/фаски (массив surfaces). \n + По окончании работ поверхности можно и нужно удалить. + \en \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер и функций изменения радиуса для скругления/фаски. + \en An array of edges and radius laws for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[in] createSurfaces - \ru Создавать ли поверхности скругления/фаски для фантома? + \en Create a fillet/chamfer surfaces for phantom. \~ + \param[out] sequences - \ru Последовательность гладко стыкующихся рёбер. + \en Sequence of smooth mating edges. \~ + \param[out] result - \ru Поверхности скругления/фаски. + \en The fillet/chamfer surfaces. \~ + \return \ru Возвращает код результата построения. + \en \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) SmoothSequence( const MbSolid & solid, + SArray & edges, + const SmoothValues & params, + bool createSurfaces, + RPArray & sequences, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фантомные эквидистантные поверхности для граней оболочки. + \en Create phantom offset surfaces for faces of a shell. \~ + \details \ru Построить фантомные эквидистантные поверхности для граней оболочки, \n + кроме имеющих перечислены кроме имеющих перечисленные индексы, и сложить в массив surfaces. \n + По окончании работ поверхности можно и нужно удалить. + \en Create phantom offset surfaces for faces of a shell, \n + except the faces with specified indices and store them in array 'surfaces'. \n + After finish working with the surfaces they should be deleted. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] outFaces - \ru Множество вскрываемых граней тела. + \en An array of shelling faces of the solid. \~ + \param[in] offFaces - \ru Множество граней, для которых заданы индивидуальные значения толщин. + \en An array of faces for which the individual values of thickness are specified. \~ + \param[in] offDists - \ru Множество индивидуальных значений толщин (должен быть синхронизирован с массивом offFaces). + \en An array of individual values of thickness (must be synchronized with the array 'offFaces'). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результат операции. + \en The operation result. \~ + \param[out] hpShellFaceInd - \ru Номер грани в исходной оболочки для построения хот-точки. + \en The face number in the initial shell for a hot-point creation. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetPhantom( const MbSolid & solid, + RPArray & outFaces, + RPArray & offFaces, + SArray & offDists, + const SweptValues & params, + const MbSNameMaker & operNames, + MbFaceShell *& result, + size_t * hpShellFaceInd = NULL ); // \ru Номер грани в исходной оболочки для построения хот-точки); \en The face number in the initial shell for a hot-point creation); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фантом габаритного куба в локальной системе координат. + \en Create a phantom of a bounding box in local coordinate system. \~ + \details \ru Построить фантом габаритного куба в локальной системе координат. \n + \en Create a phantom of a bounding box in local coordinate system. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] place - \ru Локальная система координат (ЛСК). + \en A local coordinate system (LCS). \~ + \param[in] bScale - \ru Является ли ЛСК масштабирующей. + \en Whether the LCS is scaling. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Фантом локального куба. + \en The phantom of the local bounding box. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LocalCubePhantom( const MbSolid & solid, + const MbPlacement3D & place, + bool bScale, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить фантомное направление усечения. + \en Determine a phantom direction of truncation. \~ + \details \ru Определить фантомное направление усечения по усеченной грани исходного тела. \n + \en Determine a phantom direction of truncation given the truncated face of the initial solid. \n \~ + \param[in] truncatingEdge - \ru Ребро усеченной грани исходного тела. + \en An edge of truncated face of the initial solid. \~ + \param[in] dirPlace - \ru Система координат направления усечения (Ось Z - направление усечения). + \en A coordinate system of truncation direction (Z-axis is a truncation direction). \~ + \return \ru Возвращает true, если получилось определить направление. + \en Returns true if the direction has been successfully determined. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) TruncatDirection( const MbCurveEdge & truncatingEdge, + MbPlacement3D & dirPlace ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить опорные точки размеров операции скругления/фаски. + \en Create support points of fillet/chamfer operation sizes. \~ + \details \ru Построить опорные точки размеров операции скругления/фаски и сложить в контейнер data. \n + Первые две точки лежат на краях поверхности скругления/фаски. + \en Create support points of fillet/chamfer operation sizes and store them in container 'data'. \n + The first two points lie on the fillet/chamfer surface boundary. \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер для скругления/фаски. + \en An array of edges for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[out] result - \ru Опорные точки размеров операции скругления/фаски. + \en Support points of the fillet/chamfer operation sizes. \~ + \param[in] edgeParam - \ru Параметр точки на ребре (0 <= edgeParam <= 1). + \en The parameter of a point on the edge (0 <= edgeParam <= 1). \~ + \param[in] dimensionEdge - \ru Ребро, на котором дать опорные точки. + \en The edge on which the support points are to be created. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) SmoothPositionData( const MbSolid & solid, + RPArray & edges, + const SmoothValues & params, + RPArray & result, + double edgeParam = 0.5, + const MbCurveEdge * dimensionEdge = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить опорные точки размеров операции скругления/фаски. + \en Create support points of fillet/chamfer operation sizes. \~ + \details \ru Построить опорные точки размеров операции скругления/фаски и сложить в контейнер data. \n + Первые две точки лежат на краях поверхности скругления/фаски. + \en Create support points of fillet/chamfer operation sizes and store them in container 'data'. \n + The first two points lie on the fillet/chamfer surface boundary. \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] edges - \ru Множество выбранных ребер для скругления/фаски и функций изменения радиуса для скругления/фаски. + \en The array of specified edges for fillet/chamfer and radius laws for fillet/chamfer. \~ + \param[in] params - \ru Параметры операции скругления/фаски. + \en Parameters of the fillet/chamfer operation. \~ + \param[out] result - \ru Опорные точки размеров операции скругления/фаски. + \en Support points of the fillet/chamfer operation sizes. \~ + \param[in] edgeParam - \ru Параметр точки на ребре (0 <= edgeParam <= 1). + \en The parameter of a point on the edge (0 <= edgeParam <= 1). \~ + \param[in] dimensionEdge - \ru Ребро, на котором дать опорные точки. + \en The edge on which the support points are to be created. \~ + \return \ru Возвращает код результата построения. + \en Returns the creation result code. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbResultType) SmoothPositionData( const MbSolid & solid, + SArray & edges, + const SmoothValues & params, + RPArray & result, + double edgeParam = 0.5, + const MbCurveEdge * dimensionEdge = NULL ); + + +#endif // __ACTION_PHANTOM_H diff --git a/C3d/Include/action_point.h b/C3d/Include/action_point.h new file mode 100644 index 0000000..304621b --- /dev/null +++ b/C3d/Include/action_point.h @@ -0,0 +1,820 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции создания точек. + \en Functions for points creation. \~ + \details \ru Функции, использующие в качестве выходных параметров точки или массивы точек. + \en Functions that take points or arrays of points as input parameters. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_POINT_H +#define __ACTION_POINT_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbLine3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив. + \en Create an array. \~ + \details \ru Создать массив с контролем выделения памяти. \n + \en Create an array with memory allocation control. \n \~ + \param[in] cnt - \ru Количество элементов массива. + \en Number of elements in the array. \~ + \param[out] res - \ru Результат операции. + \en The operation result. \~ + \return \ru Возвращает массив элементов, если он создан, или NULL в противном случае. + \en Returns an array of elements if it has been created, otherwise returns NULL. \~ + \ingroup Algorithms_3D +*/ +// --- +template +inline SArray * CreateArray( size_t cnt, MbResultType & res ) +{ + SArray * arr = new SArray ( cnt, 1 ); + if ( arr != NULL && arr->GetAddr() == NULL ) { + delete arr; + arr = NULL; + } + if ( arr == NULL ) + res = rt_TooManyPoints; + + return arr; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выделить в массиве память под n элементов. + \en Allocate memory in the array for n elements. \~ + \details \ru Выделить в массиве память под n элементов с контролем выделения памяти. \n + \en Allocate memory in the array for n elements with memory allocation control. \n \~ + \param[in, out] arr - \ru Массив. + \en An array. \~ + \param[in] n - \ru Количество элементов, под которые нужно выделить память. + \en Number of elements for allocation. \~ + \param[out] res - \ru Результат операции. + \en The operation result. \~ + \return \ru Возвращает true в случае успешного выделения памяти. + \en Returns true if the memory has been successfully allocated. \~ + \ingroup Algorithms_3D +*/ +// --- +template +inline bool ReserveArray( SArray & arr, size_t n, MbResultType & res ) +{ + arr.Reserve( n ); + if ( arr.GetAddr() == NULL ) { + res = rt_TooManyPoints; + return false; + } + return true; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить в массив элемент. + \en Add an element to the array. \~ + \details \ru Добавить в массив элемент с контролем выделения памяти. \n + \en Add an element to the array with memory allocation control. \n \~ + \param[in, out] arr - \ru Массив. + \en An array. \~ + \param[in] item - \ru Элемент, который нужно добавить. + \en The element to add. \~ + \param[out] res - \ru Результат операции. + \en The operation result. \~ + \return \ru Возвращает true в случае успешного добавления. + \en Returns true if the element has been successfully added. \~ + \ingroup Algorithms_3D +*/ +// --- +template +inline bool AddItem( SArray & arr, const Type & item, MbResultType & res ) +{ + arr.Add( item ); + if ( arr.GetAddr() == NULL ) { + res = rt_TooManyPoints; + return false; + } + return true; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Пространственно-параметрическая точка. + \en A space-parametric point. \~ + \details \ru Пространственно-параметрическая точка. \n + Содержит в себе трехмерную и двумерную точки. + \en A space-parametric point. \n + Contains a three-dimensional point and a two-dimensional point. \~ + \ingroup Point_Modeling +*/ +// --- +class MATH_CLASS MbSpaceParamPnt { +protected: + MbCartPoint3D spacePnt; ///< \ru Пространственная точка. \en A spatial point. + MbCartPoint paramPnt; ///< \ru Параметрическая точка. \en A parametric point. + +public: // \ru Конструкторы \en Constructors + /// \ru Конструктор по пространственной точке. \en A constructor that takes a space point. + explicit MbSpaceParamPnt( const MbCartPoint3D & sp ) : spacePnt( sp ), paramPnt( UNDEFINED_DBL, 0.0 ) {} + /// \ru Конструктор по пространственной и параметрической точкам. \en A constructor that takes a space point and a parametric point. + explicit MbSpaceParamPnt( const MbCartPoint3D & sp, const MbCartPoint & pp ) : spacePnt( sp ), paramPnt( pp ) {} + /// \ru Конструктор по пространственно-параметрической точке. \en A constructor that takes a space-parametric point. + explicit MbSpaceParamPnt( const MbSpaceParamPnt & cp ) : spacePnt( cp.spacePnt ), paramPnt( cp.paramPnt ) {} + ~MbSpaceParamPnt() {} + +public: // \ru Инициализация \en The initialization + /// \ru Инициализация по пространственно-параметрической точке. \en Initialization with a space-parametric point. + void Init( const MbSpaceParamPnt & cp ) { spacePnt = cp.spacePnt; paramPnt = cp.paramPnt; } + /// \ru Инициализация по пространственной и параметрической точкам. \en Initialization with a space point and a parametric point. + void Init( const MbCartPoint3D & sp, const MbCartPoint & pp ) { spacePnt = sp; paramPnt = pp; } +public: // \ru Функции \en Functions + /// \ru Установлена ли параметрическая точка? \en Whether the parametric point is speified. + bool IsParamPnt() const { return (paramPnt.x != UNDEFINED_DBL); } //-V550 + /// \ru Перевести параметрическую точку в неустановленное состояние. \en Reset a parametric point. + void ResetParamPnt() { paramPnt.x = UNDEFINED_DBL; } + /// \ru Проверка на равенство параметрических точек по X с заданной погрешностью. \en Check if parametric points are equal by X component with the specified tolerance. + bool IsParamEqualX( const MbSpaceParamPnt & cp, double eps ) const { return (::fabs(paramPnt.x - cp.paramPnt.x) < eps); } + /// \ru Проверка на равенство параметрических точек по Y с заданной погрешностью. \en Check if parametric points are equal by Y component with the specified tolerance. + bool IsParamEqualY( const MbSpaceParamPnt & cp, double eps ) const { return (::fabs(paramPnt.y - cp.paramPnt.y) < eps); } + + /// \ru Получить ссылку на пространственную точку. \en Get a reference to the space point. + const MbCartPoint3D & GetSpacePnt() const { return spacePnt; } + /// \ru Получить ссылку на параметрическую точку. \en Get a reference to the parametric point. + const MbCartPoint & GetParamPnt() const { return paramPnt; } + +private: // \ru Нереализованные \en Not implemented + MbSpaceParamPnt(); + MbSpaceParamPnt( const MbCartPoint & ); + void operator = ( const MbCartPoint3D & ); + void operator = ( const MbCartPoint & ); + void operator = ( const MbSpaceParamPnt & ); + bool operator == ( const MbSpaceParamPnt & ) const; +}; + + +typedef std::pair MbLocPnt; ///< \ru Пространственно-параметрическая точка с индексированным положением. \en A space-parametric point with indexed position. + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать точки на поверхности. + \en Create points on a surface. \~ + \details \ru Создать группу точек на поверхности. \n + \en Create a group of points on a surface. \n \~ + \param[in] surface - \ru Поверхность-источник. + \en The source surface. \~ + \param[in] stepType - \ru Тип шага по поверхности. + \en Type of spacing on a surface. \~ + \param[in] uValue - \ru Величина шага по u или количество точек по u при шаге по параметру + \en U-spacing value or number of points in u-direction while sampling by parameter \~ + \param[in] vValue - \ru Величина шага по v или количество точек по v при шаге по параметру. + \en V-spacing value or number of points in v-direction while sampling by parameter. \~ + \param[in] truncateByBounds - \ru Усечь границами поверхности. + \en Whether to truncate by surface boundary. \~ + \param[out] result - \ru Индексированные пространственно-параметрические точки. + \en Indexed space-parametric points. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (MbResultType) PointsOnSurface( const MbSurface & surface, + MbeStepType stepType, + double uValue, + double vValue, + bool truncateByBounds, + RPArray< SArray > & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать точки на поверхности. + \en Create points on a surface. \~ + \details \ru Создать группу точек на поверхности. \n + \en Create a group of points on a surface. \n \~ + \param[in] surface - \ru Поверхность-источник. + \en The source surface. \~ + \param[in] gridType - \ru Тип cетки на поверхности. + \en A type of a grid on a surface. \~ + \param[in] uv0 - \ru Центральная точка сетки + \en The central point of the grid. \~ + \param[in] angle - \ru Угол поворота сетки относительно направления U (в радианах) + \en Rotaion angle of the grid relative to U direction (in radians). \~ + \param[in] stepType - \ru Тип шага по поверхности. + \en Type of spacing on a surface. \~ + \param[in] step1 - \ru Величина шага по первому направлению + \en A spacing value in the first direction \~ + \param[in] step2 - \ru Величина шага по второму направлению + \en A spacing value in the second direction \~ + \param[in] truncateByBounds - \ru Усечь границами поверхности. + \en Whether to truncate by surface boundary. \~ + \param[out] result - \ru Индексированные пространственно-параметрические точки. + \en Indexed space-parametric points. \~ + \param[in] maxPntsCnt - \ru Максимально допустимое количество точек. + \en The maximal acceptable number of points. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (MbResultType) PointsOnSurface( const MbSurface & surface, + MbeItemGridType & gridType, + const MbCartPoint & uv0, + double angle, + MbeStepType stepType, + double step1, + double step2, + bool truncateByBounds, + RPArray< SArray > & result, + size_t maxPntsCnt = c3d::ARRAY_MAX_COUNT ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить умолчательную разбивку поверхности. + \en Define the default sampling of a surface. \~ + \details \ru Определить умолчательную разбивку поверхности \n + (вспомогательная функция для функции PointsOnSurface). + \en Define the default sampling of a surface \n + (an auxillary function for function PointsOnSurface). \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[out] uPntsCnt - \ru Количество разбиений по u. + \en The points number in U direction. \~ + \param[out] vPntsCnt - \ru Количество разбиений по v. + \en The points number in V direction. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (void) DefinePointsOnSurfaceCounts( const MbSurface & surface, + size_t & uPntsCnt, + size_t & vPntsCnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точку пересечения трех поверхностей. + \en Calculate the intersection point of three surfaces. \~ + \details \ru Найти точку пересечения трех поверхностей по начальным приближениям. \n + \en Calculate the intersection point of three surfaces given the initial estimates. \n \~ + \param[in] surf0 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] ext0 - \ru Флаг поиска на продолжении первой поверхности. + \en Whether to use the extension of the first surface. \~ + \param[in] surf1 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] ext1 - \ru Флаг поиска на продолжении второй поверхности. + \en Whether to use the extension of the second surface. \~ + \param[in] surf2 - \ru Третья поверхность. + \en The third surface. \~ + \param[in] ext2 - \ru Флаг поиска на продолжении третьей поверхности. + \en Whether to use the extension of the third surface. \~ + \param[in,out] uv0 - \ru Началальное приближение и результат на поверхности surf0. + \en The initial approximation and the result on surface surf0. \~ + \param[in,out] uv1 - \ru Началальное приближение и результат на поверхности surf1. + \en The initial approximation and the result on surface surf1. \~ + \param[in,out] uv2 - \ru Началальное приближение и результат на поверхности surf2. + \en The initial approximation and the result on surface surf2. \~ + \return \ru Возвращает код результата итерационного поиска точки пересечения. + \en Returns the result code of the intersection point iterative search. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (MbeNewtonResult) IntersectionPoint( const MbSurface & surf0, bool ext0, + const MbSurface & surf1, bool ext1, + const MbSurface & surf2, bool ext2, + MbCartPoint & uv0, + MbCartPoint & uv1, + MbCartPoint & uv2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти все точки пересечения поверхности и кривой. + \en Calculate all the points of intersection of a surface and a curve. \~ + \details \ru Найти все точки пересечения поверхности и кривой. \n + \en Calculate all the points of intersection of a surface and a curve. \n \~ + \param[in] surf - \ru Поверхность. + \en A surface. \~ + \param[in] surfExt - \ru Искать на продолжении поверхности. + \en Use the surface extension. \~ + \param[in] curv - \ru Кривая. + \en The curve. \~ + \param[in] curveExt - \ru Искать на продолжении кривой. + \en Use the curve extension. \~ + \param[out] uv - \ru Параметры точек пересечения на поверхности. + \en Parameters of the intersection points on the surface. \~ + \param[out] tt - \ru Параметры точек пересечения на кривой. + \en Parameters of the intersection points on the curve. \~ + \param[in] touchInclude - \ru Считать касания пересечениями. + \en Consider tangencies as intersections. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (void) IntersectionPoints( const MbSurface & surf, bool surfExt, + const MbCurve3D & curv, bool curveExt, + SArray & uv, + SArray & tt, + bool touchInclude = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить параметры ближайших точек прямых. + \en Determine the parameters of the nearest points of lines. \~ + \details \ru Определить параметры ближайших точек прямых, заданных точкой и вектором направления. + \en Determine the parameters of the nearest points of lines which are defined by the given point and direction vector. \~ + \param[in] origin1, direction1 - \ru Точка и направление первой прямой. + \en A point and direction of the first line. \~ + \param[in] origin2, direction2 - \ru Точка и направление второй прямой. + \en A point and direction of the second line. \~ + \param[out] t1 - \ru Параметр на первой прямой. + \en Parameter on the first line. \~ + \param[out] t2 - \ru Параметр на второй прямой. + \en Parameter on the second line. \~ + \return \ru Возвращает true, если есть прямые не параллельны. \n + \en Returns true, if lines are not parallel. \n \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) LineLineNearestParams( const MbCartPoint3D & origin1, const MbVector3D & direction1, + const MbCartPoint3D & origin2, const MbVector3D & direction2, + double & t1, double & t2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение расстояния между ближайшими точками p1 и p2 прямых line1 и line2 + \en Determination of the distance between the nearest points p1 and p2 of lines line1 and line2 \~ + \details \ru Определение расстояния между ближайшими точками p1 и p2 прямых line1 и line2 + \en Determination of the distance between the nearest points p1 and p2 of lines line1 and line2 \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (double) LineLineNearestPoints( const MbLine3D & line1, const MbLine3D & line2, + MbCartPoint3D & p1, MbCartPoint3D & p2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить параметры ближайших точек прямых. + \en Determine the parameters of the nearest points of lines. \~ + \details \ru Определить параметры ближайших точек прямых, заданных точкой и вектором направления. + \en Determine the parameters of the nearest points of lines which are defined by the given point and direction vector. \~ + \param[in] origin1, direction1 - \ru Точка и направление первой прямой. + \en A point and direction of the first line. \~ + \param[in] origin2, direction2 - \ru Точка и направление второй прямой. + \en A point and direction of the second line. \~ + \param[out] t1 - \ru Параметр на первой прямой. + \en Parameter on the first line. \~ + \param[out] t2 - \ru Параметр на второй прямой. + \en Parameter on the second line. \~ + \return \ru Возвращает true, если есть прямые не параллельны. \n + \en Returns true, if lines are not parallel. \n \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) LineLineNearestParams( const MbCartPoint & origin1, const MbVector & direction1, + const MbCartPoint & origin2, const MbVector & direction2, + double & t1, double & t2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точку пересечения двух прямых. + \en Calculate the point of two lines intersection. \~ + \details \ru Найти точку пересечения двух точно пересекающихся прямых без проверки параллельности. \n + \en Calculate the intersection point of two exactly intersecting lines without check. \n \~ + \param[in] line1 - \ru Первая прямая. + \en The first line. \~ + \param[in] line2 - \ru Вторая прямая. + \en The second line. \~ + \param[out] result - \ru Точка пересечения. + \en The intersection point. \~ + \ingroup Point_Modeling +*/ +// --- +inline void FastLineLine( const MbLine & line1, + const MbLine & line2, + MbCartPoint & result ) +{ + const MbDirection & dir1 = line1.GetDirection(); + const MbDirection & dir2 = line2.GetDirection(); + const MbCartPoint & pnt1 = line1.GetOrigin(); + const MbCartPoint & pnt2 = line2.GetOrigin(); + + double t = ( dir1.ax * (pnt2.y - pnt1.y) - dir1.ay * (pnt2.x - pnt1.x )) / + ( dir1.ay * dir2.ax - dir1.ax * dir2.ay ); + + result.x = pnt2.x + dir2.ax * t; + result.y = pnt2.y + dir2.ay * t; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точку пересечения двух прямых. + \en Calculate the point of two lines intersection. \~ + \details \ru Найти точку пересечения двух прямых. \n + Прямые могут быть параллельны или совпадать. \n + \en Calculate the point of two lines intersection. \n + The curves can be parallel or coincident. \n \~ + \param[in] line1 - \ru Первая прямая. + \en The first line. \~ + \param[in] line2 - \ru Вторая прямая. + \en The second line. \~ + \param[out] result - \ru Точка пересечения. + \en The intersection point. \~ + \return \ru Возвращает результат пересечения: \n + 1 - Прямые пересекаются. \n + 0 - Прямые параллельны или совпадают. + \en Returns the result of intersection: \n + 1 - The lines intersect at a point. \n + 0 - The lines are parallel or coincident. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (int) LineLine( const MbLine & line1, + const MbLine & line2, + MbCartPoint & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точку пересечения двух прямых. + \en Calculate the point of two lines intersection. \~ + \details \ru Найти точку пересечения двух прямых. \n + Прямые могут быть параллельны или совпадать. \n + \en Calculate the point of two lines intersection. \n + The curves can be parallel or coincident. \n \~ + \param[in] line1 - \ru Первая прямая. + \en The first line. \~ + \param[in] line2 - \ru Вторая прямая. + \en The second line. \~ + \param[out] result - \ru Точка пересечения. + \en The intersection point. \~ + \return \ru Возвращает результат пересечения: \n + 1 : прямые пересекаются; \n + 0 : прямые параллельны; \n + 1 : прямые совпадают - касательная точка пересечения. + \en Returns the result of intersection: \n 1 : the curves intersect at a point; \n 0 : the curves are parallel; \n 1 : the curves are coincident - the tangent intersection point. \~\ingroup Point_Modeling +*/ +// --- +MATH_FUNC (int) LineLine( const MbLine & line1, + const MbLine & line2, + MbCrossPoint & result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точку пересечения прямой и отрезка. + \en Calculate the intersection point of a line and a line segment. \~ + \details \ru Найти точку пересечения прямой и отрезка. \n + Отрезок может быть параллелен прямой или лежать на ней. \n + \en Calculate the intersection point of a line and a line segment. \n + The line segment can be parallel to the curve or lie on it. \n \~ + \param[in] line - \ru Прямая. + \en The line. \~ + \param[in] lseg - \ru Отрезок. + \en The segment. \~ + \param[out] result - \ru Точка пересечения. + \en The intersection point. \~ + \return \ru Возвращает результат пересечения: \n + 1 : прямая и отрезок пересекаются; \n + 0 : прямая и отрезок параллельны; \n + 1 : отрезок лежит на прямой - касательная точка пересечения. + \en Returns the result of intersection: \n 1 : the line and the line segment intersect at a point; \n 0 : the line and a line segment are parallel; \n 1 : the segment lies on the curve - a tangent intersection point. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (int) LineLineSeg( const MbLine & line, + const MbLineSegment & lseg, + MbCrossPoint & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки пересечения прямой и окружности. + \en Calculate intersection points of a line and a circle. \~ + \details \ru Найти параметры точек пересечения прямой и окружности. \n + \en Calculate the parameters of intersection points of a line and a circle. \n \~ + \param[in] line - \ru Прямая. + \en The line. \~ + \param[in] centre - \ru Центр окружности. + \en The circle center. \~ + \param[in] radius - \ru Радиус окружности. + \en The circle radius. \~ + \param[out] result - \ru Точки пересечения (указатель на массив из двух(!) элементов). + \en The intersection points (a pointer to the array of two (!) elements). \~ + \return \ru Возвращает количество найденных пересечений. + \en Returns the number of intersections. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (int) LineCircle( const MbLine & line, + const MbCartPoint & centre, + double radius, + MbCrossPoint * result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки пересечения двух кривых. + \en Calculate intersection points of two curves. \~ + \details \ru Найти параметры точек пересечения двух произвольных кривых. \n + Общий метод вызывается, если нет частной функции пересечения. \n + \en Calculate the parameters of intersection points of two arbitrary curves. \n + The general method is used if there is no special function for intersection. \n \~ + \param[in] pCurve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] pCurve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] result - \ru Множество точек пересечения. + \en The array of intersection points. \~ + \param[in] touchInclude - \ru Считать касания пересечениями. + \en Consider tangencies as intersections. \~ + \param[in] epsilon - \ru Точность совпадения точек пересечения кривых. + \en The accuracy of coincidence points of intersection. \~ + \param[in] allowInaccuracy - \ru Разрешить понижать входную точность. + \en Allow lowering input accuracy. \~ + \return \ru Количество найденных пересечений. + \en The number of intersections. \~ + \warning \ru Применяется для двумерных построений, аналог CurveCurveIntersection. + \en Used for two-dimensional constructions, the analogue of CurveCurveIntersection. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) IntersectTwoCurves( const MbCurve & pCurve1, + const MbCurve & pCurve2, + SArray & result, + bool touchInclude = true, + double epsilon = Math::LengthEps*c3d::METRIC_DELTA, + bool allowInaccuracy = true ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки пересечения двух кривых. + \en Calculate intersection points of two curves. \~ + \details \ru Найти параметры точек пересечения двух произвольных кривых. \n + Общий метод вызывается, если нет частной функции пересечения. \n + \en Calculate the parameters of intersection points of two arbitrary curves. \n + The general method is used if there is no special function for intersection. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] result1 - \ru Параметры пересечений первой кривой. + \en The parameters of intersections for the first curve. \~ + \param[out] result2 - \ru Параметры пересечений второй кривой. + \en The parameters of intersections for the second curve. \~ + \param[in] xEpsilon - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEpsilon - \ru Точность по y. + \en Tolerance in y direction. \~ + \param[in] touchInclude - \ru Считать касания пересечениями. + \en Consider tangencies as intersections. \~ + \param[in] allowInaccuracy - \ru Разрешить нахождение решения с меньшей точностью при невозможности удовлетворить указанной. + \en Allow to find a solution with less precision when we can't get a solution with given precision. \~ + \return \ru Количество найденных пересечений. + \en The number of intersections. \~ + \warning \ru Применяется для трехмерных построений, аналог IntersectTwoCurves. + \en Used for three-dimensional constructions, the analogue of IntersectTwoCurves. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CurveCurveIntersection( const MbCurve & curve1, + const MbCurve & curve2, + SArray & result1, + SArray & result2, + double xEpsilon, + double yEpsilon, + bool touchInclude, bool allowInaccuracy = true ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки самопересечения кривой. + \en Calculate the points of curve self-intersection. \~ + \details \ru Найти параметры точек самопересечения кривой с заданной точностью. \n + \en Calculate the self-intersection points parameters with the given tolerance. \n \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in] xEpsilon - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEpsilon - \ru Точность по y. + \en Tolerance in y direction. \~ + \param[out] result1 - \ru Множество параметров самопересечения. + \en The self-intersection parameters array. \~ + \param[out] result2 - \ru Множество параметров самопересечения. + \en The self-intersection parameters array. \~ + \param[in] version - \ru Версия операции. + \en The version of the operation. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (void) CurveSelfIntersect( const MbCurve & curve, + double xEpsilon, + double yEpsilon, + SArray & result1, + SArray & result2, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить точки касания. + \en Remove touch points. \~ + \details \ru Удалить все точки касания кривых вне зависимости от положения параметра на кривой + (внутри области определения или на границах кривой). + \en Remove all curves touch points regardless the position on the curve + (in the domain or on the borders). \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in, out] result - \ru Множество точек пересечения. + \en The array of intersection points. \~ + \param[in] eps - \ru Погрешность для функции проверки параллельности касательных RoundColinear. + \en Accuracy for the function RoundColinear of testing the parallelism of tangents. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (void) RemoveAllTouchParams( const MbCurve & curve1, + const MbCurve & curve2, + SArray & result, + double eps = PARAM_NEAR ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки пересечения двух кривых. + \en Calculate intersection points of two curves. \~ + \details \ru Найти параметры точек пересечения двух произвольных кривых. \n + \en Calculate the parameters of intersection points of two arbitrary curves. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] result1 - \ru Параметры точек пересечения для первой кривой. + \en The intersection points parameters for the first curve. \~ + \param[out] result2 - \ru Параметры точек пересечения для второй кривой. + \en The intersection points parameters for the second curve. \~ + \param[in] mEps - \ru Возможная максимальная погрешность найденных пересечений. + \en The intersection tolerance. \~ + \return \ru Количество найденных пересечений. + \en The number of intersections. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CurveCurveIntersection( const MbCurve3D & curve1, + const MbCurve3D & curve2, + SArray & result1, + SArray & result2, + double mEps = Math::metricRegion ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить кривую на самопересечение. + \en Determine if the curve has self-intersections. \~ + \details \ru Проверить заданную кривую на самопересечение. \n + \en Determine if the given curve has self-intersections. \n \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in] mEps - \ru Возможная максимальная погрешность найденных самопересечений. + \en The tolerance of self-intersections. \~ + \return \ru Возвращает true, если кривая самопересекается. + \en Returns true if the curve has self-intersections. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (bool) IsSelfIntersect( const MbCurve3D & curve, + double mEps = Math::metricRegion ); + + + +//------------------------------------------------------------------------------ +/** \brief \ru Убрать касательные точки пересечения. + \en Remove the tangent intersection points. \~ + \details \ru Убрать параметры касательных точек пересечения внутри областей определения кривых. \n + \en Remove the tangent intersection points parameters inside the domains of curves. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] result1 - \ru Параметры точек пересечения для первой кривой. + \en The intersection points parameters for the first curve. \~ + \param[out] result2 - \ru Параметры точек пересечения для второй кривой. + \en The intersection points parameters for the second curve. \~ + \param[in] mEps - \ru Возможная максимальная погрешность найденных пересечений. + \en The intersection tolerance. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (void) FilterTouchParams( const MbCurve3D & curve1, + const MbCurve3D & curve2, + SArray & result1, + SArray & result2, + double mEps = Math::metricRegion ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки скрещения двух кривых. + \en Calculate the points of two curves crossing. \~ + \details \ru Найти параметры точек скрещения двух кривых. \n + \en Calculate parameters of the points of two curves crossing. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] result1 - \ru Параметры точек скрещения для первой кривой. + \en Parameters of the points of crossing for the first curve. \~ + \param[out] result2 - \ru Параметры точек скрещения для второй кривой. + \en Parameters of the points of crossing for the second curve. \~ + \return \ru Количество найденных скрещений. + \en The points of crossing number. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CurveCurveCrossing( const MbCurve3D & curve1, + const MbCurve3D & curve2, + SArray & result1, + SArray & result2, + double epsilon = Math::metricRegion ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти проекцию точки на поверхность относительно внешнего контура поверхности. + \en Find the projection of a point on a surface relative to the outer contour of the surface. \~ + \details \ru Найти проекцию пространственной точки на поверхность в виде двумерной точки на поверхности + относительно внешнего контура поверхности. \n + \en Calculate the projection of a space point on a surface as a two-dimensional point on the surface. + relative to the outer contour of the surface. \n \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] pnt - \ru Пространственная точка. + \en A space point. \~ + \param[in] byOuterRectOnly - \ru Классифицировать проекцию только относительно внешнего габаритного прямоугольника. + \en Whether to classify the projection relative to the outer bounding box only. \~ + \param[out] result - \ru Двумерная параметрическая точка на поверхности. + \en A two-dimensional parametric point on the surface. \~ + \return \ru Возвращает true, если найдена нормальная проекция точки на поверхность. + \en Returns true if a normal projection of the point on the surface has been calculated. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (bool) PointProjectionRelativeOuterLoop( const MbSurface & surface, + const MbCartPoint3D & pnt, + bool byOuterRectOnly, + MbCartPoint & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Является ли проекция точки точно неоднозначной. + \en Determine whether the point projection is multiple-valued. \~ + \details \ru Является ли проекция точки неоднозначной при проецировании + в области определения поверхности. \n + \en Determine whether the point projection is multiple-valued while projecting + inside the surface domain. \n \~ + \param[in] surface - \ru Поверхность. + \en A surface. \~ + \param[in] result - \ru Пространственная точка. + \en A space point. \~ + \return \ru Возвращает true, если проекция точки является неоднозначной. + \en Returns true if the point projection is multiple-valued \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC (bool) IsMultipleProjection( const MbSurface & surface, + const MbCartPoint3D & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки касания двух поверхностей. + \en Calculate the touch points of two surfaces. \~ + \details \ru Найти параметры точек касания двух поверхностей. \n + \en Calculate the parameters of touch points of two surfaces. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en A first surface. \~ + \param[in] ext1 - \ru Искать на продолжении первой поверхности. + \en Use the first surface extension. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en A second surface. \~ + \param[in] ext2 - \ru Искать на продолжении второй поверхности. + \en Use the second surface extension. \~ + \param[in] uv1arr - \ru Параметры точек касания первой поверхности. + \en Parameters of touch points of first surface. \~ + \param[in] uv2arr - \ru Параметры точек касания второй поверхности. + \en Parameters of touch points of second surface. \~ + \return \ru Возвращает true, если найдены точки касания. + \en Returns true if the touch points has be calculate. \~ + \warning \ru В разработке. + \en Under development. \~ + \ingroup Point_Modeling +*/ +// --- +MATH_FUNC ( bool) TouchIntersectionPoints( const MbSurface & surf1, bool ext1, + const MbSurface & surf2, bool ext2, + std::vector & uv1arr, + std::vector & uv2arr ); + + +#endif // __ACTION_POINT_H + diff --git a/C3d/Include/action_sheet.h b/C3d/Include/action_sheet.h new file mode 100644 index 0000000..1c59799 --- /dev/null +++ b/C3d/Include/action_sheet.h @@ -0,0 +1,2352 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции для работы с телом из листового металла. + \en Functions for operating with a sheet metal solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ACTION_SHEET_H +#define __ACTION_SHEET_H + + +#include +#include +#include +#include +#include +#include + + +class MbLineSegment; +class MbLineSegment3D; +class MbLine3D; +class MbSolid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способ сегментации эскиза. + \en The method of contour segmentation. \~ + \details \ru Способ сегментации эскиза. \n + \en The method of contour segmentation. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +enum MbeSegmentationMethod { + sm_Quantity, ///< \ru По количеству сегментов. \en By quantity of segments. + sm_Length, ///< \ru По длине сегментов. \en By length of segments + sm_Angle, ///< \ru По углу. \en By angle + sm_Height ///< \ru По величине отклонения от хорды. \en By the deviation from the chord. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способ задания ширины сгиба. + \en The method of bend width definition. \~ + \details \ru Способ задания ширины сгиба. \n + \en The method of bend width definition. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +enum MbeBendWidthType { + bwt_KFactor, ///< \ru Ширина сгиба рассчитывается через коэффициент нейтрального слоя. \en The bending width is computed using neutral layer coefficient. + bwt_Allowance, ///< \ru Ширина сгиба задана непосредственно. \en The bend width is defined explicitly. + bwt_Deduction, ///< \ru Задано уменьшение сгиба. \en The bend tapering is defined. + bwt_Table ///< \ru Ширина сгиба рассчитывается по таблице. \en The bend width is computed from a table. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вспомогательные функции для построения комбинированного сгиба (сгиба по эскизу). + \en Auxiliary functions for a composite bend (a bend from a sketch). \~ + \details \ru Вспомогательные функции для построения комбинированного сгиба (сгиба по эскизу). \n + \en Auxiliary functions for a composite bend (a bend from a sketch). \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbJointBendUtils { + double thickness; ///< \ru Толщина листа. \en The sheet thickness. + SPtr contour; ///< \ru Эскиз присоединяемых сгибов. \en A sketch of attachable bends. + MbOrientedEdge * orEdge; ///< \ru Ориентированное ребро, к которому присоединяются сгибы. \en An oriented edge to attach the bends to. + bool offsetToLeft; ///< \ru Придавать толщину слева от эскиза. \en Whether to thicken to the left from the sketch. + bool edgePlaceCoorient; ///< \ru Совпадение направления ребра orEdge и оси Z локальной системы координат эскиза. \en Whether the direction of edge orEdge is equal to the direction of Z-axis of the sketch local coordinate system. + +public: + /// \ru Способ построения комбинированного сгиба. \en The method of a composite bend construction. + enum MbeConstructionMethod { + cmToEnd, ///< \ru До конца ребра \en To the edge end. + cmByWidth, ///< \ru На определённую ширину \en With a specified width. + cmByManyEdges ///< \ru По нескольким рёбрам \en From several edges. + }; + + /** \brief \ru Конструктор. + \en Constructor. \~ + \param[in] placement - \ru Локальная система координат эскиза. + \en The local coordinate system of the sketch. \~ + \param[in] contour - \ru Эскиз создаваемых сгибов. + \en The sketch of bends to create. \~ + \param[in] curveEdge - \ru Неориентированное ребро к которому прикрепляются создаваемые сгибы. + \en A non-oriented edge to attach the created bend to. \~ + */ + MbJointBendUtils( const MbPlacement3D & placement, + const MbContour & contour, + const MbCurveEdge & curveEdge ); + ~MbJointBendUtils(); + + /** \brief \ru Рассчитать отступы от концов ребра. + \en Calculate the distances from the edge ends. \~ + \details \ru Отступы имеют положительное значение в случае расширения сгибов относительно исходного тела, отрицательное - в случае сужения. + \en The distances are positive if the bends extend relative to the source solid and negative if they narrow. \~ + \param[in] method - \ru Способ построения комбинированного сгиба. + \en The method of a composite bend construction. \~ + \param[in] widthAlongPlaceNorm - \ru Ширина сгиба в направлении нормали ЛСК контура для способа cmByWidth. + \en The bend width in the direction of contour LCS normal for method cmByWidth. \~ + \param[in] widthRevPlaceNorm - \ru Ширина сгиба в направлении, противоположном нормали ЛСК контура для способа cmByWidth. + \en The bend width in the opposite direction of contour LCS normal for method cmByWidth. \~ + \param[in] alongPlaceNorm - \ru Направление придания ширины сгиба для способа cmToEnd. + \en The direction in which to thicken the bend for method cmToEnd. \~ + \param[out] begDistance - \ru Возвращаемое значение отступа сгиба от начала ориентированного ребра. + \en Returned value of the distance from the start of oriented edge to the bend. \~ + \param[out] endDistance - \ru Возвращаемое значение отступа сгиба от конца ориентированного ребра. + \en Returned value of the distance from the end of oriented edge to the bend. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + */ + bool CalculateDistances( MbeConstructionMethod method, // \ru Способ построения комбинированного сгиба \en The method of the composite bend construction + const double widthAlongPlaceNorm, // \ru Ширина сгиба в направлении нормали ЛСК контура для способа cmByWidth \en The bend width in the direction of contour LCS normal for method cmByWidth + const double widthRevPlaceNorm, // \ru Ширина сгиба в направлении, противоположном нормали ЛСК контура для способа cmByWidth \en The bend width in the opposite direction of contour LCS normal for method cmByWidth + const bool alongPlaceNorm, // \ru Направление придания ширины сгиба для способа cmToEnd \en The direction in which to thicken the bend for method cmToEnd + double & begDistance, // \ru Возвращаемое значение отступа сгиба от начала ориентированного ребра \en Returned value of the distance from the start of oriented edge to the bend + double & endDistance ) const; // \ru Возвращаемое значение отступа сгиба от конца ориентированного ребра \en Returned value of the distance from the end of oriented edge to the bend + /** \brief \ru Рассчитать угол стыковки эскиза с листовым телом. + \en Compute the angle of connection of a sketch with a sheet solid. \~ + \param[out] angle - \ru Угол стыковки эскиза с листовым телом. + \en The angle of connection of a sketch with a sheet solid. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + */ + bool GetConnectionAngle( double & angle ) const; + /** \brief \ru Построить дугу, содержащую хот-точку радиуса сгиба. + \en Create an arc that contains a hot point of the bend radius. \~ + \details \ru Дуга проходит по центру ширины присоединяемой пластины. + \en The arc passes through the center (by width) of the sheet being attached. \~ + \param[in] curveEdge - \ru Неориентированное ребро присоединения. + \en A non-oriented edge of the joint. \~ + \param[in] begDistance - \ru Отступ от начального края соответствующего curveEdge ориентированного ребра. + \en The distance from the start point of the oriented edge corresponding to curveEdge. \~ + \param[in] endDistance - \ru Отступ от конечного края соответствующего curveEdge ориентированного ребра. + \en The distance from the end point of the oriented edge corresponding to curveEdge. \~ + \param[in] radius - \ru Радиус создаваемой дуги. + \en The arc radius. \~ + \param[in] bendIndex - \ru Порядковый номер присоединяемого сгиба, ноль обозначает сгиб, которым формируемая пластина присоединяется к листовому телу. + \en The index of the bend to be attached. Zero value indicates the bend by which the sheet being constructed is attached to the sheet solid. \~ + \return \ru Построенную дугу. + \en The created arc. \~ + */ + MbCurve3D * CreateHotPointArc ( const MbCurveEdge & curveEdge, + const double begDistance, + const double endDistance, + const double radius, + const size_t bendIndex ) const; + + /** \brief \ru Построить контур в системе координат, связанной с ребром. + \en Create a contour in the coordinate system associated with the edge. \~ + */ + static MbContour * CreateInitialContour ( const MbCurveEdge & curveEdge, + const bool orient, + const MbContour & contour, + const MbPlacement3D & placement ); + /** \brief \ru Построить связанную с ребром систему координат. + \en Create a coordinate system associated with the edge. \~ + \details \ru Связанная с ребром система координат начинается в точке ребра, находящейся на расстоянии begDistance от начала ребра в случае begOrient равным true или + от конца в случае begOrient равном false. Расстояние отсчитывается внутрь ребра, если begDistance меньше нуля, и наружу, если begDistance больше нуля. + Ось Z направлена вдоль ребра curveEdge и сонаправлена с осью Z modifiedPlacement. Ось X совпадает с нормалью к листовой грани, содержащей ребро curveEdge. + Ось Y дополняет систему до правой. + \en The coordinate system associated with the edge has the origin at the edge point located at distance begDistance from the edge start point if begOrient is equal to true or + at distance begDistance from edge end point if begDistance is equal to false. The distance is measured to inside of the edge if begDistance is negative and outside the edge if begDistance is positive. + Z-axis is directed along edge curveEdge and codirected with Z-axis of modifiedPlacement. X-axis is equal to the normal of the sheet face that contains edge curveEdge. + Y-axis makes the system right-handed. \~ + \param[in] curveEdge - \ru Неориентированное ребро присоединения сгибов. + \en The non-oriented edge of bends joint. \~ + \param[in] edgeOrient - \ru Ориентация ориентированного ребра, принадлежащего листовой грани и содержащего curveEdge. + \en The orientation of the oriented edge that belongs to the sheet face and contains curveEdge. \~ + \param[in] begDistance - \ru Расстояние от начала ориентированного ребра, определяемого параметрами curveEdge и edgeOrient. + \en The distance from the beginning of the oriented edge defined by parameters curveEdge and edgeOrient. \~ + \param[in,out] modifiedPlacement - \ru Искомая система координат. + \en The required coordinate system. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + */ + static bool SetPlacementToEdge ( const MbCurveEdge & curveEdge, + const bool edgeOrient, + const double begDistance, + MbPlacement3D & modifiedPlacement ); + +private: + MbCurve * CreateTwoSegmentsArc ( const MbLineSegment & prevSegment, + const MbLineSegment & nextSegment, + const double radius ) const; + + bool GetBendFormingCurves ( const size_t bendIndex, + MbCurve *& prevCurve, + MbCurve *& nextCurve ) const; + + bool ContourConnectionPoint( const double t ) const; + + bool PointOnOrientedEdge ( const MbCartPoint3D & point ) const; + + + static bool SmoothConnection ( const MbLineSegment & prevSegment, + const MbLineSegment & nextSegment ); + + MbJointBendUtils( const MbJointBendUtils & ); // \ru Не реализовано \en Not implemented + MbJointBendUtils & operator = ( const MbJointBendUtils & ); // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик зависимого параметра буртика. + \en The calculator of the dependent parameter of a bead. \~ + \details \ru Расчётчик зависимого параметра буртика по ширине основания и остальным параметрам. \n + \en The calculator of the dependent parameter of a bead from the base width and the other parameters. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbBeadParamCalculator { +public: + /// \ru Рассчитать зависимый параметр буртика. \en Compute the dependent parameter of the bead. + static bool CalculateBeadParam ( const double baseWidth, MbBeadValues & parameters ); + +private: + static bool CalculateHight ( const double baseWidth, MbBeadValues & parameters ); + static bool CalculateBottomRadius( const double baseWidth, MbBeadValues & parameters ); + static bool CalculateAngle ( const double baseWidth, MbBeadValues & parameters ); + static bool CalculateBottomWidth ( const double baseWidth, MbBeadValues & parameters ); + static bool CheckConsistency ( const double baseWidth, MbBeadValues & parameters ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик коэффициента нейтрального слоя. + \en Calculator of the neutral layer coefficient. \~ + \details \ru Расчётчик коэффициента нейтрального слоя для различных способов задания ширины разогнутого сгиба. \n + \en Calculator of the neutral layer coefficient for different methods of the unbended bend width definition. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbKCalculator { + double thickness; ///< \ru Толщина сгиба. \en The width of the bend. + double radius; ///< \ru Внутренний радиус сгиба. \en The internal radius of the bend. + double angle; ///< \ru Угол сгиба. \en The bend angle. + +public: + /// \ru Конструктор. \en Constructor. + MbKCalculator( double thick, double rad, double ang ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbKCalculator( const MbKCalculator & init ) + : thickness( init.thickness ) + , radius( init.radius ) + , angle( init.angle ) + {} + /// \ru Оператор присваивания. \en An assignment operator. + MbKCalculator & operator = ( const MbKCalculator &init ) { + thickness = init.thickness; radius = init.radius; angle = init.angle; return *this; } + + /// \ru Рассчитать коэффициент нейтрального слоя с возвратом кода ошибки. \en Calculate the neutral layer coefficient and return the error code. + MbResultType CalcK( const double l, const MbeBendWidthType type, double & k ) const; + /// \ru Рассчитать коэффициент нейтрального слоя. \en Calculate the neutral layer coefficient. + double CalcK( double l, MbeBendWidthType type ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик смещения сгиба. + \en The bend displacement calculator. \~ + \details \ru Расчётчик смещения сгиба. \n + \en The bend displacement calculator. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbDisplacementCalculator { +public: + /// \ru Тип смещения. \en A displacement type. + enum MbeDisplacementType { + dt_InIn, ///< \ru Пересечение касательных к внутренним сторонам сгиба. \en Intersection of the tangents to the bend inner sides. + dt_OutIn, ///< \ru Пересечение касательных к внешней и внутренней сторонам сгиба. \en Intersection of the tangents to the outer and the inner sides of the bend. + dt_InOut, ///< \ru Пересечение касательных к внутренней и внешней сторонам сгиба. \en Intersection of the tangents to the inner and the outer sides of the bend. + dt_OutOut, ///< \ru Пересечение касательных к внешним сторонам сгиба. \en Intersection of the tangents to the outer sides of the bend. + dt_OutProj, ///< \ru Проекция внешней стороны на касательную к внутренней стороне сгиба. \en The projection of the outer side onto the tangent to the inner side of the bend. + dt_InProj, ///< \ru Проекция внутренней стороны не касательную к внутренней стороне сгиба. \en The projection of the inner side onto the tangent to the outer side of the bend. + dt_Center ///< \ru Сгиб по осевой линии. \en Bend Centerline. + }; + +private: + double thickness; ///< \ru Толщина листа. \en The sheet thickness. + double radius; ///< \ru Внутренний радиус сгиба. \en The internal radius of the bend. + double angle; ///< \ru Угол сгиба. \en The bend angle. + double k; ///< \ru Коэффициент нейтрального слоя. \en K-Factor value. + +public: + /// \ru Конструктор. \en Constructor. + MbDisplacementCalculator( double thick, double rad, double ang, double coef = 0.4 ) + : thickness( ::fabs(thick) ) + , radius ( ::fabs(rad) ) + , angle ( ::fabs(ang) ) + , k ( coef ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbDisplacementCalculator( const MbDisplacementCalculator &init ) + : thickness( init.thickness ) + , radius( init.radius ) + , angle( init.angle ) + , k( init.k ) + {} + /// \ru Оператор присваивания. \en An assignment operator. + MbDisplacementCalculator & operator = ( const MbDisplacementCalculator &init ) { + thickness = init.thickness; radius = init.radius; angle = init.angle; k = init.k; return *this; } + + /// \ru Рассчитать смещение сгиба. \en Calculate the bend displacement. + double CalcDisplacement( MbDisplacementCalculator::MbeDisplacementType type ); + /// \ru Рассчитать радиус по смещению сгиба. \en Calculate the radius by bend displacement. + double CalcRadiusByDisplacement( MbeDisplacementType type, double displacement ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик параметров подрезанных жалюзи. + \en The calculator of trimmed jalousie parameters. \~ + \details \ru Расчётчик параметров подрезанных жалюзи. \n + \en The calculator of trimmed jalousie parameters. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbJalousieParamCalculator { + MbJalousieValues parameters; ///< \ru Параметры жалюзи. \en Jalousie parameters. + double thickness; ///< \ru Толщина. \en The thickness. + +public: + /// \ru Конструктор. \en Constructor. + MbJalousieParamCalculator( const MbJalousieValues & params, const double thick ) : parameters( params ), thickness( ::fabs(thick) ) {} + + /// \ru Инициализация. \en Initialization. + void Init ( const MbJalousieValues & params, const double thick ) { parameters = params; thickness = ::fabs(thick); } + /// \ru Рассчитать высоту подрезанных жалюзи по высоте зазора. \en Calculate the height of trimmed jalousie given the gap height. + bool CalculateHeight ( const double gapHeight, + double & height ) const; + /// \ru Рассчитать угол наклона жалюзи. \en Calculate the slope angle of jalousie. + bool CalculateAngle ( double & angle ) const; + /// \ru Проверить возможность построения жалюзи с заданным углом наклона. \en Check if the construction of jalousie with the given slope angle is possible. + bool CanCreateJalousieWithAngle( const double angle ) const; + +private: + bool CalculateAngle ( const double height, + const bool heightIsGap, + double & angle ) const; + + bool CalcAngleFunction( const double angle, + const double height, + const bool heightIsGap, + double & f, + double & df ) const; + + MbJalousieParamCalculator( const MbJalousieParamCalculator & ); // \ru Не реализовано \en Not implemented + MbJalousieParamCalculator & operator = ( const MbJalousieParamCalculator & ); // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик расположения хот-точки для зазора замыкания углов. + \en Calculator of hot point location for the gap of corner closure. \~ + \details \ru Расчётчик расположения хот-точки для зазора замыкания углов. \n + \en Calculator of hot point location for the gap of corner closure. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbCloseCornerGapHotPointCalc { + const MbCurveEdge & curveEdge; ///< \ru Ребро. \en The edge. + const MbClosedCornerValues & parameters; ///< \ru Параметры замыкания сгиба. \en The bend closure parameters. + +public: + /// \ru Конструктор. \en Constructor. + MbCloseCornerGapHotPointCalc( const MbCurveEdge & edge, const MbClosedCornerValues & params ) + : curveEdge( edge ), parameters( params ) {} + /// \ru Рассчитать положение "хот"-точки. \en Calculate the hot point location. + bool CalcHotPoint( MbCartPoint3D & point ) const; + +private: + bool FindAlongOrEdge( const bool plus, + MbOrientedEdge *& alongOrEdge, + bool & begin ) const; + + bool SetPlacement ( const MbOrientedEdge & baseOrEdge, + const MbOrientedEdge & refOrEdge, + const bool refBegin, + MbPlacement3D & placement ) const; + + static bool SetLines ( const MbOrientedEdge & orEdge, + const bool begin, + MbLine3D & line1, + MbLine3D & line2 ); + + MbCloseCornerGapHotPointCalc( const MbCloseCornerGapHotPointCalc & ); // \ru Не реализовано \en Not implemented + MbCloseCornerGapHotPointCalc & operator = ( const MbCloseCornerGapHotPointCalc & ); // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик расположения хот-точки для зазора замыкания углов. + \en Calculator of hot point location for the gap of corner closure. \~ + \details \ru Расчётчик расположения хот-точки для зазора замыкания углов. \n + \en Calculator of hot point location for the gap of corner closure. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbRuledShellGapCalc { + const MbRuledSolidValues & parameters; ///< \ru Параметры обечайки. \en The ruled shell parameters. + +public: + /// \ru Конструктор. \en Constructor. + MbRuledShellGapCalc( const MbRuledSolidValues & params ) : parameters( params ) {} + /// \ru Рассчитать хот-точки зазора. \en Calculate hot points of the gap. + bool CalcHotPoints ( const MbContour & filletedContour, + const MbPlacement3D & placement, + MbAxis3D & centerAxis, + MbAxis3D & oppositeAxis, + MbCartPoint3D & edgePoint ); + /// \ru Рассчитать новое значение зазора по "хот"-точке. \en Calculate the new value of the gap given the hot point. + double CalcGapValue ( const MbContour & filletedContour, + const MbPlacement3D & placement, + const MbCartPoint3D & point ) const; + /// \ru Рассчитать новое расположение зазора. \en Calculate new position of the gap. + double CalcGapPosition ( const MbContour & filletedContour, + const MbPlacement3D & placement, + const MbCartPoint3D & newPoint ) const; + /// \ru Рассчитать новое расположение зазора. \en Calculate new position of the gap. + double CalcGapPosition ( const MbContour & filletedContour, + const MbPlacement3D & placement, + const MbCartPoint3D & oldPoint, + const MbVector3D & moveVector ) const; + /// \ru Найти параметр центра зазора. \en Calculate the parameters of the gap center. + double FindGapParameter( const MbContourOnPlane & contourOnPlane ) const; + /// \ru Найти параметры границ зазора. \en Calculate the gap boundary parameters. + bool FindGapLimits ( const MbContourOnPlane & contourOnPlane, + const double tGapMiddle, + double & tGapMin, + double & tGapMax ) const; + +private: + MbRuledShellGapCalc( const MbRuledShellGapCalc & ); // \ru Не реализовано \en Not implemented + MbRuledShellGapCalc & operator = ( const MbRuledShellGapCalc & ); // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сгиб листового тела по линии. + \en The bend of a sheet solid along a line. \~ + \details \ru Линией может быть отрезок, лежащий на плоских гранях bendingFaces, либо прямая. + Грани bendingFaces располагаются на общей для них плоскости.\n + \en The line is a line segment on the planar faces bendingFaces or a line. + Faces bendingFaces lies on the common plane.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] bendingFaces - \ru Изгибаемые грани. + \en The faces to bend. \~ + \param[in] curve - \ru Прямолинейная кривая, вдоль которой гнуть. + \en A straight line along which to bend. \~ + \param[in] unbended - \ru Флаг построения элемента в разогнутом состоянии. + \en Whether to construct the element unbended. \~ + \param[in] params - \ru Параметры листового тела. + \en A sheet solid parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BendSheetSolidOverSegment( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & bendingFaces, + MbCurve3D & curve, + bool unbended, + const MbBendOverSegValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Подсечка. + \en A jog. \~ + \details \ru Линией может быть отрезок, лежащий на плоских гранях bendingFaces, либо прямая. + Грани bendingFaces располагаются на общей для них плоскости. Подсечка выполняется + в виде двух смещённых друг относительно друга сгиба по линии. + Формируемые при этом листовые грани сгибов возвращаются в массивах:\n + firstBendFaces - грани сгибов, примыкающие к неподвижной части базовых граней,\n + secondBendFaces - грани сгибов, поднятых над базовыми гранями.\n + \en The line is a line segment on the planar faces bendingFaces or a line. + Faces bendingFaces lies on the common plane. A jog is performed + as two bends by a line shifted relative to each other. + The sheet faces of bends generated during this operation are returned in the arrays: \n + firstBendFaces - the bend faces adjacent to the fixed part of the base faces,\n + secondBendFaces - the bend faces raised above the base faces.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] bendingFaces - \ru Изгибаемые грани. + \en The faces to bend. \~ + \param[in] curve - \ru Прямолинейная кривая, вдоль которой гнуть. + \en A straight line along which to bend. \~ + \param[in] unbended - \ru Флаг построения элемента в разогнутом состоянии. + \en Whether to construct the element unbended. \~ + \param[in] jogParams - \ru Параметры подсечки и первого сгиба. + \en The parameters of a jog and the first bend. \~ + \param[in] secondBendParams - \ru Параметры второго сгиба. + \en The second bend parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] firstBendFaces - \ru Грани первого сгиба подсечки. + \en The faces of the first bend of the jog. \~ + \param[out] secondBendFaces - \ru Грани второго сгиба подсечки. + \en The faces of the second bend of the jog. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetSolidJog( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & bendingFaces, + MbCurve3D & curve, + bool unbended, + const MbJogValues & jogParams, + const MbBendValues & secondBendParams, + MbSNameMaker & nameMaker, + RPArray & firstBendFaces, + RPArray & secondBendFaces, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Согнуть сгибы листового тела. + \en Rebend the sheet solid bends. \~ + \details \ru Сгибаются разогнутые сгибы bends относительно неподвижной грани fixedFace. + Если fixedFace - это листовая грань, принадлежащая одному из сгибов bends, + то сгиб осуществляется так, чтобы неподвижной осталась плоскость, касательная + к поверхности, лежащей под fixedFace, в точке fixedPoint.\n + \en The unbended bends 'bends' are bended relative to the fixed face 'fixedFace'. + If 'fixedFace' is a sheet face that belongs to one of bends 'bends', + then bending is performed such that the plane tangent to + the underlying surface of 'fixedFace' at point 'fixedPoint' remains fixed.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] bends - \ru Множество сгибов, состоящих из пар граней - внутренней и внешней граней сгиба. + \en An array of bends which consist of face pairs - inner and outer faces of the bend. \~ + \param[in] fixedFace - \ru Грань, остающаяся неподвижной. + \en The face that remains fixed. \~ + \param[in] fixedPoint - \ru Точка в параметрической области поверхности, лежащей под гранью fixedFace, в случае, если она сгибовая. + \en A point in the domain of the underlying surface of face 'fixedFace' if this face is a face of the bend. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BendSheetSolid( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & bends, + const MbFace & fixedFace, + const MbCartPoint & fixedPoint, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разогнуть сгибы листового тела. + \en Unbend the bends of a sheet solid. \~ + \details \ru Разгибаются сгибы bends относительно неподвижной грани fixedFace. + Если fixedFace - это листовая грань, принадлежащая одному из сгибов bends, + то разгиб осуществляется так, чтобы неподвижной осталась плоскость, касательная + к поверхности, лежащей под fixedFace, в точке fixedPoint.\n + \en Bends 'bends' are to be unbended relative to the fixed face 'fixedFace'. + If 'fixedFace' is a sheet face that belongs to one of bends 'bends', + unbending is performed such that the plane tangent to + the underlying surface of 'fixedFace' at point 'fixedPoint' remains fixed.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] bends - \ru Множество сгибов, состоящих из пар граней - внутренней и внешней граней сгиба. + \en An array of bends which consist of face pairs - inner and outer faces of the bend. \~ + \param[in] fixedFace - \ru Грань, остающаяся неподвижной. + \en The face that remains fixed. \~ + \param[in] fixedPoint - \ru Точка в параметрической области грани fixedFace, в случае, если она сгибовая. + \en A point in the domain of face 'fixedFace' if it is a face of the bend. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \param[out] ribContours - \ru Набор контуров содержащих кривые границ ребер жесткости(при их наличии) в разогнутом виде. + \en The set of contours, which are containing edges of stamp rib in unfolded state. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) UnbendSheetSolid( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & bends, + const MbFace & fixedFace, + const MbCartPoint & fixedPoint, + MbSNameMaker & nameMaker, + MbSolid *& result, + RPArray * ribContours = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать листовое тело. + \en Create a sheet solid. \~ + \details \ru Листовое тело создаётся выдавливанием одного незамкнутого контура или нескольких замкнутых контуров.\n + В случае замкнутых контуров, один контур должен быть внешним, а остальные внутренними, и выдавливание + производится на толщину листового тела.\n + В случае незамкнутого контура, ему придаётся толщина листового тела в ту или иную в зависимости от параметров сторону, + а затем результат выдавливается на заданные расстояния.\n + \en A sheet solid is created by extrusion of one open contour or several closed contours.\n + In the case of several closed contours one contour should be outer, the others should be inner; extrusion + is performed by a distance equal to the sheet solid thickness.\n + In the case of open contour it is supplied with the sheet solid thickness in one or another direction subject to the parameters, + then the result is extruded by the specified distances.\n \~ + \param[in] placement - \ru Плейсмент эскиза. + \en A sketch placement. \~ + \param[in] contours - \ru Контуры листового тела. + \en The sheet solid contours. \~ + \param[in] unbended - \ru Флаг построения элемента в разогнутом состоянии. + \en Whether to construct the element unbended. \~ + \param[in] params - \ru Параметры листового тела. + \en A sheet solid parameters. \~ + \param[in] nameMakers - \ru Именователи. + \en Objects for naming the new objects. \~ + \param[out] resultBends - \ru Формируемые сгибы. + \en The resultant bends. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateSheetSolid( const MbPlacement3D & placement, + RPArray & contours, + bool unbended, + const MbSheetMetalValues & params, + RPArray * nameMakers, + RPArray & resultBends, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавление пластины к листовому телу. + \en Addition of a plate to the sheet solid. \~ + \details \ru Пластина строится по одному или нескольким замкнутым непересекающимся контурам, + Причём среди них может быть несколько внешних. \n + \en A plate is constructed from one or several closed non-intersecting contours; + And several contours can be outer. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] placement - \ru Локальная система координат эскиза. + \en The local coordinate system of the sketch. \~ + \param[in] contours - \ru Замкнутый контур пластины. + \en The closed contour of the plate. \~ + \param[in] params - \ru Параметры листового тела. + \en A sheet solid parameters. \~ + \param[in] nameMakers - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetSolidPlate( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & placement, + RPArray & contours, + const MbSheetMetalValues & params, + RPArray * nameMakers, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вырез отверстия в листовом теле. + \en Create a hole in a sheet solid. \~ + \details \ru Вырез строится по замкнутому контуру. \n + \en A hole is constructed by a closed contour. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] placement - \ru Плейсмент эскиза. + \en A sketch placement. \~ + \param[in] contours - \ru Замкнутый контур выреза/пересечения. + \en A closed contour of a hole/intersection. \~ + \param[in] params - \ru Параметры листового тела. + \en A sheet solid parameters. \~ + \param[in] diff - \ru Отверстие (diff = true), пересечение (diff = false). + \en The hole (diff = true), the intersection (diff = false). \~ + \param[in] nameMakers - \ru Именователи. + \en Objects for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetSolidHole( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & placement, + RPArray & contours, + const MbSheetMetalValues & params, + bool diff, + RPArray * nameMakers, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сгиб на ребре. + \en A bend on an edge. \~ + \details \ru Сгиб строится на одном или нескольких рёбрах, принадлежащих плоской листовой грани, + согласно заданным параметрам. \n + \en A bend is constructed on one or several edges that belong to a planar sheet face + from the specified parameters. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] edges - \ru Рёбра сгибов. + \en The edges of bends. \~ + \param[in] unbended - \ru Флаг построения элемента в разогнутом состоянии. + \en Whether to construct the element unbended. \~ + \param[in] params - \ru Параметры сгибов. + \en The bends parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in,out] resultBends - \ru Параметры формируемых сгибов и имена созданных граней. + \en Bends parameters and names of the bends faces. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BendSheetSolidByEdges( MbSolid & solid, + const MbeCopyMode sameShell, + const RPArray & edges, + const bool unbended, + const MbBendByEdgeValues & params, + MbSNameMaker & nameMaker, + RPArray & resultBends, + MbSolid *& result ); + + +// устаревшая +MATH_FUNC (MbResultType) BendSheetSolidByEdges( MbSolid & solid, + const MbeCopyMode sameShell, + const RPArray & edges, + const bool unbended, + const MbBendByEdgeValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Комбинированный сгиб листового тела. + \en A composite bend of a sheet solid. \~ + \details \ru Комбинированный сгиб листового тела или другими словами сгиб по эскизу может строиться + на одном или нескольких соседних прямолинейных рёбрах одной листовой грани или нескольких, + расположенных через сгиб. Эскиз, состоящий из отрезков и дуг должен лежать в плоскости, + перпендикулярной одному из рёбер построения и одним концом располагаться на его проекции на эту плоскость. + Данный эскиз применяется к каждому ребру, участвующему в построении. По нему и его копиям для всех рёбер + строятся листовые тела со скруглениями негладких стыковок прямолинейных сегментов контура и гладкой стыковкой к + базовой листовой грани. Построенные тела объединяются с базовым (исходным) телом, и затем + осуществляются замыкания углов согласно заданным параметрам. После выполнения операции в массиве resultBends + записаны все созданные ей сгибы.\n + \en A composite bend of a sheet solid or, in the other words, a bend from a sketch can be constructed + on one or several neighboring linear edges of one or several sheet faces + from the different sides of the bend. A sketch consisting of line segments and arcs should lie on a plane + perpendicular to one of edges of the construction; one of its ends should lie on the edge projection onto this plane. + The specified sketch is applied to each edge involved in the construction. From this sketch and its copies for all the edges + sheet solids are created with rounding of non-smooth (G0) joints of line segments of the contour and smoothly connecting with + the base sheet face. The constructed faces are united with the base (source) solid, and, then + the corners are to be closed according to the specified parameters. After finishing the operation + all the created edges are stored in array 'resultBends'.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] placement - \ru Плейсмент контура сгиба. + \en The bend contour placement. \~ + \param[in] contour - \ru Контур сгиба. + \en The bend contour. \~ + \param[in] edges - \ru Рёбра сгиба. + \en The bend edges. \~ + \param[in] unbended - \ru Флаг построения элемента в разогнутом состоянии. + \en Whether to construct the element unbended. \~ + \param[in] params - \ru Параметры сгиба. + \en The bend parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] resultBends - \ru Формируемые сгибы. + \en The resultant bends. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetSolidJointBend( MbSolid & solid, + const MbeCopyMode sameShell, + const MbPlacement3D & placement, + const MbContour & contour, + const RPArray & edges, + const bool unbended, + const MbJointBendValues & params, + MbSNameMaker & nameMaker, + RPArray< RPArray > & resultBends, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Замыкание угла. + \en A corner enclosure. \~ + \details \ru Если на соседних рёбрах листовой грани построены два сгиба, то между ними образуется угол, + который можно затянуть материалом, расширив соответствующие стороны этих сгибов, + что и осуществляет данная операция. В параметрах можно выставить величину зазора и + виды замыкания отдельно для сгибов и отдельно для их плоских продолжений.\n + \en If two bends are created on the neighboring edges of a sheet face, a corner appears between them + which can be covered by the material by extending the corresponding sides of these bends, + that's what the operation does. The specified parameters can include a gap size and + types of enclosure separately for the bends and for their planar extensions.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] curveEdgePlus - \ru Ребро сгиба, условно принятое за положительное. + \en The bend edge assumed to be positive. \~ + \param[in] curveEdgeMinus - \ru Ребро сгиба, условно принятое за отрицательное. + \en The bend edge assumed to be negative. \~ + \param[in] params - \ru Параметры замыкания. + \en The enclosure parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CloseCorner( MbSolid & solid, + MbeCopyMode sameShell, + MbCurveEdge * curveEdgePlus, + MbCurveEdge * curveEdgeMinus, + const MbClosedCornerValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Подрезка массива тела solidArray контурами плоских листовых граней тела sheetSolid. + \en Cutting the solidArray with contours of plane sheet faces of sheetSolid. \~ + \details \ru Для подрезания используются только грани, компланарые хотя бы одной ЛСК из массива placements. + Контурные тела граней строятся выдавливанием ограничивающих контуров в обе стороны на величину depth.\n + \en For cutting are used only those faces whose placements are complanar to the ones from placements array. + The faces contours solids is built by extrusion of bounding contours of the faces in both directions on "depth" value.\n \~ + \param[in] solidArray - \ru Подрезаемое тело. + \en The solid to be cut. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] sheetSolid - \ru Листовое тело, границами гранями которого подрезать. + \en The sheet solid by which faces to cut. \~ + \param[in] placements - \ru Массив локальных систем координат для определения подрезающих граней. + \en The array of placements to select the cutting faces. \~ + \param[in] depth - \ru Глубина выдавливания. + \en The extrusion depth. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en Result solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CutSolidArrayByBorders( MbSolid & solidArray, + const MbeCopyMode sameShells, + const MbSolid & sheetSolid, + const SArray & placements, + const double depth, + const MbSNameMaker & nameMaker, + MbSolid *& resultSolid ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание составляющих частей штамповки. + \en Creation of stamping's components. \~ + \details \ru Штамповка строится посредством добавления к пластине выпуклой части и последующим вычитанием вогнутой. + Данная функция возвращает обе эти части в качестве отдельных тел. Подрезка краями пластины, на которой находятся эскизы, не производится.\n + \en The spherical stamp is created by adding a convex part to the plate and subtructing a concave part from it. This function returns these parts as separate solids. + It does not cut them with the edges of the face on which the contours lay.\n \~ + \param[in] face - \ru Грань, контуром которой надо подрезать штамповку. + \en A face by which bounding contours the stamp should be cutted. \~ + \param[in] placement - \ru Локальная система координат центра штамповки. + \en A local coordinate system of the center. \~ + \param[in] contour - \ru Контур штамповки. + \en The stamping contour. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] thickness - \ru Толщина листа. + \en The sheet metal thickness. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] partToAdd - \ru Добавляемая часть штамповки. + \en Added part of the stamp. \~ + \param[out] partToSubtract - \ru Вычитаемая часть штамповки. + \en Deductible part of the stamp. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateStampParts( const MbFace * face, + const MbPlacement3D & placement, + const MbContour & contour, + const MbStampingValues & params, + const double thickness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +// устаревшая +// --- +MATH_FUNC (MbResultType) CreateStampParts( const MbPlacement3D & placement, + const MbContour & contour, + const MbStampingValues & params, + const double thickness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Штамповка. + \en Stamping. \~ + \details \ru Штамповка строится по одному замкнутому или незамкнутому контуру, лежащему на плоской листовой грани. + Замкнутый эскиз может лежать на листовой грани полностью или частично, + а незамкнутый должен начинаться и заканчиваться за пределами грани. + Штамповка подрезается границами листовой грани, на которой располагается эскиз.\n + \en The stamping is created from one closed or open contour lying on a flat sheet face. + A closed sketch can lie on the sheet face entirely or partially, + and an open sketch must have the start and the end points outside the face. + The stamping is trimmed by the boundary of the sheet face which contains the sketch.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] face - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] placement - \ru Локальная система координат контура. + \en A local coordinate system of the contour. \~ + \param[in] contour - \ru Контур штамповки. + \en The stamping contour. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) Stamp( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & face, + const MbPlacement3D & placement, + const MbContour & contour, + const MbStampingValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Штамповка телом-инструментом (пуансоном или матрицей). + \en Stamping by tool solid (punch or die). \~ + \details \ru Штамповка строится на основе произвольного тела-инструмента и заданной плоской листовой грани. + Штамповка подрезается границами листовой грани, которую перескает тело.\n + \en The stamping is created based on a tool body and a flat sheet face. + The stamping is trimmed by the boundary of the sheet face which contains the sketch.\n \~ + \param[in] solid - \ru Исходное листовое тело. + \en The source sheet solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] targetFace - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] toolSolid - \ru Оболочка тела-инструмента. + \en A shell of tool solid. \~ + \param[in] sameShellTool - \ru Флаг удаления оболочки тела-инструмента. + \en Whether to delete the shell of the tool solid. \~ + \param[in] punch - \ru Является тело-инструмент пуансоном или матрицей. + \en Is tool body a punch or a die. \~ + \param[in] pierceFaces - \ru Вскрываемые для вырубки грани инструмента, + \en Pierce faces of tool body. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC( MbResultType ) StampBySolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & targetFace, + MbSolid & toolSolid, + MbeCopyMode sameShellTool, + bool punch, + const RPArray & openingFaces, + const MbUserStampingValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание составляющих частей сферической штамповки. + \en Creation of spherical stamping's components. \~ + \details \ru Штамповка строится посредством добавления к пластине выпуклой части и последующим вычитанием вогнутой. + Данная функция возвращает обе эти части в качестве отдельных тел. Подрезка краями пластины, на которой находятся эскизы, не производится.\n + \en The spherical stamp is created by adding a convex part to the plate and subtructing a concave part from it. This function returns these parts as separate solids. + It does not cut them with the edges of the face on which the contours lay.\n \~ + \param[in] face - \ru Грань, контуром которой надо подрезать штамповку. + \en A face by which bounding contours the stamp should be cutted. \~ + \param[in] placement - \ru Локальная система координат центра штамповки. + \en A local coordinate system of the center. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] thickness - \ru Толщина листа. + \en The sheet metal thickness. \~ + \param[in] center - \ru Центр сферической штамповки. + \en The center of the stamping. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] partToAdd - \ru Добавляемая часть штамповки. + \en Added part of the stamp. \~ + \param[out] partToSubtract - \ru Вычитаемая часть штамповки. + \en Deductible part of the stamp. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateSphericalStampParts( const MbFace * face, + const MbPlacement3D & placement, + const MbStampingValues & params, + const double thickness, + const MbCartPoint & center, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +// устаревшая +// --- +MATH_FUNC (MbResultType) CreateSphericalStampParts( const MbPlacement3D & placement, + const MbStampingValues & params, + const double thickness, + const MbCartPoint & center, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сферическая штамповка. + \en Spherical stamping. \~ + \details \ru Штамповка строится по параметрам и центру, лежащему на плоской листовой грани. + Штамповка подрезается границами листовой грани, на которой располагается центр.\n + \en The stamping is created by the parameters and a center lying on a flat sheet face. + The stamping is trimmed by the boundary of the sheet face which contains the sketch.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] face - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] placement - \ru Локальная система координат центра штамповки. + \en A local coordinate system of the center. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] center - \ru Центр сферической штамповки. + \en The center of the stamping. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SphericalStamp( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & face, + const MbPlacement3D & placement, + const MbStampingValues & params, + const MbCartPoint & center, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание составляющих частей буртика. + \en Creation of bead's components. \~ + \details \ru Буртик строится посредством добавления к пластине выпуклой части и последующим вычитанием вогнутой. + Данная функция возвращает обе эти части в качестве отдельных тел. Подрезка краями пластины, на которой находятся эскизы, не производится.\n + \en A bead is created by adding a convex part to the plate and subtructing a concave part from it. This function returns these parts as separate solids. + It does not cut them with the edges of the face on which the contours lay.\n \~ + \param[in] face - \ru Грань, контуром которой надо подрезать буртик. + \en A face by which bounding contours the bead should be cutted. \~ + \param[in] placement - \ru Локальная система координат контуров. + \en The local coordinate system of the contours. \~ + \param[in] contours - \ru Контуры буртика. + \en The bead contours. \~ + \param[in] centers - \ru Центры сферических штамповок. + \en The spherical stamps centers. \~ + \param[in] params - \ru Параметры буртика. + \en The bead parameters. \~ + \param[in] thickness - \ru Толщина листа. + \en The sheet metal thickness. \~ + \param[in] nameMaker - \ru Имена контуров. + \en The contours names. \~ + \param[out] partToAdd - \ru Добавляемая часть буртика. + \en Added part of the bead. \~ + \param[out] partToSubtract - \ru Вычитаемая часть буртика. + \en Deductible part of the bead. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateBeadParts( const MbFace * face, + const MbPlacement3D & placement, + const RPArray & contours, + const SArray & centers, + const MbBeadValues & params, + const double thinkness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +// устаревшая +// --- +MATH_FUNC (MbResultType) CreateBeadParts( const MbPlacement3D & placement, + const RPArray & contours, + const SArray & centers, + const MbBeadValues & params, + const double thinkness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Буртик. + \en A bead. \~ + \details \ru Буртик строится по одному или нескольким замкнутым или незамкнутым эскизам, лежащим на плоской листовой грани, а также по точкам. + Если эскиз выходит за пределы этой грани, то буртик подрезается её границами. + Буртик по незамкнутому эскизу на в начале и конце имеет законцовки, вид которых задаётся в параметрах операции. Буртик по точке имеет вид сферической штамповки.\n + \en A bead is created from one or several closed or open sketches lying on a flat sheet face, as well as by points. + If the sketch goes out of the face, the bead is trimmed by its boundary. + A bead from an open sketch has two tips at the start and at the end points; the tips type is specified in the operation parameters. The bead by point looks like spherical stamp.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] face - \ru Грань буртика. + \en The bead face. \~ + \param[in] placement - \ru Локальная система координат контуров. + \en The local coordinate system of the contours. \~ + \param[in] contours - \ru Контуры буртика. + \en The bead contours. \~ + \param[in] centers - \ru Центры сферических штамповок. + \en The spherical stamps centers. \~ + \param[in] params - \ru Параметры буртика. + \en The bead parameters. \~ + \param[in] nameMaker - \ru Имена контуров. + \en The contours names. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateBead( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & face, + const MbPlacement3D & placement, + const RPArray & contours, + const SArray & centers, + const MbBeadValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +// устаревшая +MATH_FUNC (MbResultType) CreateBead( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & face, + const MbPlacement3D & placement, + const RPArray & contours, + const MbBeadValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание составляющих частей жалюзи. + \en Creation of jalousie's components. \~ + \details \ru Вытянутые жалюзи строятся посредством добавления к пластине выпуклой части и последующим вычитанием вогнутой. Подрезанные жалюзи - наоборот + сначала вычитанием прямоугольной заготовки из пластины, а затем добавлением к ней отогнутой части. + Данная функция возвращает обе эти части в качестве отдельных тел. При выходе за края пластины жалюзи не строятся.\n + \en A stratched jalousie is created by adding a convex part to the plate and subtructing a concave part from it. + A cutted jalousie - vice versa by subtracting the rectangular part from the plate and then by adding the bent part to it. + This function returns these parts as separate solids. If any part of the jalousie lay outside the plate it does not build.\n \~ + \param[in] face - \ru Грань, контуром которой надо подрезать буртик. + \en A face by which bounding contours the bead should be cutted. \~ + \param[in] placement - \ru Локальная система координат отрезка. + \en A local coordinate system of the segment. \~ + \param[in] segments - \ru Отрезки жалюзи. + \en The segments of jalousie. \~ + \param[in] params - \ru Параметры жалюзи. + \en The parameters of jalousie. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] partToAdd - \ru Добавляемая часть жалюзи. + \en Added part of the jalousie. \~ + \param[out] partToSubtract - \ru Вычитаемая часть жалюзи. + \en Deductible part of the jalousie. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateJalousieParts( const MbFace * face, + const MbPlacement3D & placement, + const RPArray & segments, + const MbJalousieValues & params, + const double thickness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +// устаревшая +// --- +MATH_FUNC (MbResultType) CreateJalousieParts( const MbPlacement3D & placement, + const RPArray & segments, + const MbJalousieValues & params, + const double thickness, + MbSNameMaker & nameMaker, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Жалюзи. + \en Jalousie. \~ + \details \ru Жалюзи строятся на одном или нескольких отрезках, лежащих на плоской листовой грани. + Жалюзи не могут выходить за пределы грани и пересекаться сами с собой. Жалюзи бывают двух видов: + вытяжка и подрезка. Вытяжка имеет вид половины, разрезанного вдоль прямолинейного буртика, + а подрезка имеет вид отогнутой пластины.\n + \en Jalousie are crated from one or several line segments on a flat sheet face. + Jalousie can't go out of the face boundary and can't crossed with itself. Jalousie can be of two types: + stretch and cutting. A stretch looks like a half of a linear bead splitted lengthwise, + and a cutting looks like a deflected slice.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] face - \ru Грань жалюзи. + \en A face of jalousie. \~ + \param[in] placement - \ru Локальная система координат отрезка. + \en A local coordinate system of the segment. \~ + \param[in] segments - \ru Отрезки жалюзи. + \en The segments of jalousie. \~ + \param[in] params - \ru Параметры жалюзи. + \en The parameters of jalousie. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateJalousie( MbSolid & solid, + MbeCopyMode sameShell, + const MbFace & face, + const MbPlacement3D & placement, + const RPArray & segments, + const MbJalousieValues & params, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Обечайка по контуру. + \en A ruled shell from a contour. \~ + \details \ru Обечайка строится по одному плоскому контуру выдавливанием с уклоном до, в общем случае, линейчатой поверхности + и дальнейшим приданием её толщины.\n + \en A ruled shell is created from a planar contour by extrusion with a slope to form a ruled surface in the general case, + and then by supplying it with a thickness.\n \~ + \param[in] parameters - \ru Параметры обечайки. + \en A ruled shell parameters. \~ + \param[in] nameMaker - \ru Именователь с главным именем операции. + \en An object defining the main name of the operation. \~ + \param[out] resultBends - \ru Формируемые сгибы. + \en The resultant bends. \~ + \param[out] resultContour - \ru Contour, скруглённый по параметрам из resultBends. + \en 'Contour' rounded according to the parameters from 'resultBends'. \~ + \param[out] resultSolid - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateRuledSolid( MbRuledSolidValues & parameters, + const MbSNameMaker & nameMaker, + RPArray & resultBends, + MbContour *& resultContour, + MbSolid *& resultSolid ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Объединение листовых тел по торцевой грани. + \en A union of sheet solids by a side face. \~ + \details \ru Объединяет два листовых тела, если они касаются друг друга одной единственной боковинкой.\n + \en Connects the two sheet solids, if they touch each other by an only side face.\n \~ + \param[in] solid1 - \ru Первое листовое тело. + \en The first sheet solid. \~ + \param[in] sameShell1 - \ru Способ использования первого листового тела. + \en Whether to delete the shell of the first source solid. \~ + \param[in] solid2 - \ru Второе листовое тело. + \en The second sheet solid. \~ + \param[in] sameShell2 - \ru Способ использования второго листового тела. + \en Whether to delete the shell of the second source solid. \~ + \param[in] names - \ru Именователь с версией операции. + \en An object defining the main name of the operation. \~ + \param[out] result - \ru Объединённое листовое тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetSolidUnion( MbSolid & solid1, + const MbeCopyMode sameShell1, + MbSolid & solid2, + const MbeCopyMode sameShell2, + const MbSNameMaker & names, + MbSolid *& result ); + + + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверяет, что тела листовые и их можно объединить по торцевой грани. + \en Checks that solids are sheet and they can be connected by a side face. \~ + \details \ru Функция завершается успешно, если находит единственную совпадающую в пространстве пару боковинок первого и второго тела. + \en The function completed successfully if it finds an only overlapping in space pair of side faces belonging to the first and the second solids. \~ + \param[in] solid1 - \ru Первое листовое тело. + \en The first sheet solid. \~ + \param[in] solid2 - \ru Второе листовое тело. + \en The second sheet solid. \~ + \result \ru - true, если листовые тела можно объединить, false - в противном случае. + \en - true if the sheet solids can be connected, false - otherwise. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) CanUnionSheetSolids( const MbSolid & solid1, + const MbSolid & solid2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Восстановить боковые рёбра сгибов. + \en Restore the side edges of the bends. \~ + \details \ru Операция служит для восстановления боковых границ сгибов после построений, которые могли их удалить, + таких как вырез или скругление.\n + \en The operation is used for restoring of the side boundaies of bends after the constructions which could delete them, + such as cutting or fillet.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] outerFaces - \ru Внешние грани сгибов, у которых восстанавливаем боковые рёбра. + \en The external faces whose side edges are to be restored. \~ + \param[in] strict - \ru При false - восстанавливаем боковые рёбра только там, где возможно без сообщений об ошибке. + \en If 'strict' = false, the side edges are to be restored only when the error message is not generated during the operation. \~ + \param[out] bends - \ru Сгибы, у которых восстановили боковые рёбра. + \en The bends for which the side edges has been restored. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RestoreSideEdges( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & outerFaces, + const bool strict, + RPArray & bends, + MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить сгибы по подоболочкам. + \en Disjoint the bends by the common subshells. \~ + \details \ru Сгибы из bends группируются по принадлежности разным подоболочкам листового тела solid. + В результате работы функции формируется взаимно однозначное соответствие групп сгибов + и соответствующих этим группам неподвижных граней.\n + \en The bends form 'bends' are grouped by belonging to different subshells of sheet solid 'solid'. + As a result of the function a one-to-one correspondence is formed for the groups of bends + and fixed faces corresponding to the groups.\n \~ + \param[in] solid - \ru Листовое тело. + \en A sheet solid. \~ + \param[in] bends - \ru Сгибы. + \en The bends. \~ + \param[in] fixedFaceName - \ru Имя неподвижной грани. + \en A fixed face name. \~ + \param[out] bendsGroups - \ru Сгибы, разделённые на группы по принадлежности разным подоболочкам. + \en The bends subdivided into groups by belonging to different subshells. \~ + \param[out] fixedFaces - \ru Соответствующие этим подоболочкам неподвижные грани. + \en The fixed faces corresponding to these subshells. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) SeparateBendsBySubshells( const MbSolid & solid, + const RPArray & bends, + const MbName & fixedFaceName, + RPArray< RPArray > & bendsGroups, + RPArray & fixedFaces ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разбить грани сгибов по парам. + \en Collect the pairs of faces of the bends. \~ + \details \ru Ищутся составляющие сгиб внутренняя и внешняя грань среди + неупорядоченного набора внешних и внутренних граней сгибов, + по ним формируется сгиб, который добавляется в массив bends.\n + \en The inner and the outer faces of a bend are searched among + unordered set of external and internal faces of the bends; + given these faces a bend is constructed and added to array 'bends'.\n \~ + \param[in] faceShell - \ru Набор граней листового тела. + \en A face set of the sheet solid. \~ + \param[in] innerFaces - \ru Внутренние грани сгибов. + \en The inner faces of the bends. \~ + \param[in] outerFaces - \ru Внешние грани сгибов. + \en The outer faces of the bends. \~ + \param[out] result - \ru Найденные пары граней, составляющие сгибы. + \en The face pairs forming the bends. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) CollectBends( const MbFaceShell & faceShell, + const RPArray & innerFaces, + const RPArray & outerFaces, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить, что грань может быть выбрана в качестве фиксированной при сгибе/разгибе. + \en Determine whether a face can be chosen as a fixed face for bending/unbending. \~ + \details \ru Проверяется, что указанная грань при сгибе/разгибе всех сгибов не изменится. \n + \en The specified face is checked to be invariant while bending/unbending of all the bends. \n \~ + \param[in] - \ru Проверяемая грань. + \en A face to check. \~ + \return \ru true - грань может быть выбрана в качестве фиксированной, false - в противном случае. + \en True - the face can be chosen as a fixed face, false - otherwise. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) IsSuitableForFixed( const MbFace & face ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти грани, на которых лежит кривая. + \en Find the faces containing the specified curve. \~ + \details \ru Кривая curve должна быть прямолинейной.\n + \en The curve 'curve' should be linear.\n \~ + \param[in] faces - \ru Набор граней для поиска. + \en A face set for search. \~ + \param[in] curve - \ru Кривая, лежащая на некоторых из них. + \en A curve lying on some of the faces. \~ + \param[out] result - \ru Грани, на которых лежит кривая curve. + \en The faces containing the curve. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (void) FindCurveFaces( const RPArray & faces, + const MbCurve3D & curve, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти верхнюю/нижнюю грань листового тела, содержащую ребро. + \en Find the upper/lower face of a sheet solid that contains the specified edge. \~ + \details \ru Поиск среди двух стыкующихся в ребре edge граней верхней или нижней грани листового тела. \n + \en Find the upper or the lower face of a sheet solid among two faces adjacent by edge 'edge'. \n \~ + \param[in] edge - \ru Неориентированное ребро листовой грани. + \en A non-oriented edge of a sheet face. \~ + \return \ru Найденную листовую грань. + \en A sheet face that has been found. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) FindSheetFace( const MbCurveEdge & edge ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти парную грань сгиба. + \en Find the pair face of a bend. \~ + \details \ru Поиск по листовой грани сгиба противоположной ей листовой грани.\n + \en Find a sheet face opposite to the specified sheet face of a bend.\n \~ + \param[in] face - \ru Листовая грань сгиба. + \en A sheet face of a bend. \~ + \return \ru Искомую парную ей грань. + \en The required pair face. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) FindPairBendFace( const MbFace & face ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти плоскую парную листовую грань по ребру. + \en Find a planar pair sheet face given en edge. \~ + \details \ru Функция поиска парной листовой грани для операции сгиб на ребре. + Применяется для многотолщинных листовых тел в условиях, + когда выбранной листовой грани соответствует несколько парных ей граней, + находящихся на разном расстоянии от неё. + Положительные расстояния begDistance и endDistance означают отступ наружу от ребра, а отрицательные - внутрь.\n + \en The function of searching of a pair sheet face for the bend-on-edge operation. + It is applied for multithickness sheet faces if + the specified face corresponds to several pair faces + at the different distances from it. + The positive distances 'begDistance' and 'endDistance' mean that the distance is measured outside the edge, the negative ones means the distance inside the edge.\n \~ + \param[in] curveEdge - \ru Ребро, по которому искать. + \en The edge for which to search. \~ + \param[in] begDistance - \ru Расстояние от начала ребра. + \en The distance from the beginning of the edge. \~ + \param[in] endDistance - \ru Расстояние от конца ребра. + \en The distance from the edge end. \~ + \return \ru Искомую грань. + \en The required face. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) GetPairPlanarFaceByEdge( const MbCurveEdge & curveEdge, + const double begDistance, + const double endDistance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти плоскую парную листовую грань по трёхмерной кривой. + \en Find a planar pair sheet face given a three-dimensional curve. \~ + \details \ru Функция поиска парной листовой грани для операции сгиб по линии. + Применяется для многотолщинных листовых тел в условиях, + когда выбранной листовой грани соответствует несколько парных ей граней, + находящихся на разном расстоянии от неё. + \en The function of searching of a pair sheet face for the bend-along-a-line operation. + It is applied for multithickness sheet faces if + the specified face corresponds to several pair faces + at the different distances from it. \~ + \param[in] sheetFace - \ru Плоская листовая грань. + \en A planar sheet face. \~ + \param[in] curve - \ru Лежащая на ней прямолинейная кривая. + \en A linear curve lying on the face. \~ + \return \ru Искомую грань. + \en The required face. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) GetPairPlanarFaceByCurve( const MbFace & sheetFace, + const MbCurve3D & curve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти плоскую парную листовую грань по контуру. + \en Find a planar pair sheet face given a contour. \~ + \details \ru Функция поиска парной листовой грани для операций базирующихся на контурах. + Применяется для многотолщинных листовых тел в условиях, + когда выбранной листовой грани соответствует несколько парных ей граней, + находящихся на разном расстоянии от неё. + \en The function of searching of a pair sheet face for the operations based on contours. + It is applied for multithickness sheet faces if + the specified face corresponds to several pair faces + at the different distances from it. \~ + \param[in] shell - \ru Оболочка листового тела. + \en A shell of a sheet solid. \~ + \param[in] sheetFace - \ru Базовая листовая грань. + \en A base sheet face. \~ + \param[in] place - \ru Локальная система координат, лежащая на грани sheetFace. + \en A local coordinate system on the face sheetFace. \~ + \param[in] segments - \ru Кривые, лежащие в плоскости XY локальной системы координат placement. + \en Curves on XY-plane of the local coordinate system 'placement'. \~ + \return \ru Искомую грань. + \en The required face. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) GetPairPlanarFaceByContour( const MbFaceShell & shell, + const MbFace & sheetFace, + const MbPlacement3D & place, + const RPArray & segments ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти плоскую парную листовую грань. + \en Find the planar pair sheet face. \~ + \details \ru Поиск осуществляется сначала через рёбра внешнего цикла грани sheetFace, + в случае неудачи - через вершины этого цикла, и если грань не найдена, + то перебором по всем связным граням или граням из набора faceShell. + В последнем случае предпочтение отдаётся более близко расположенным граням.\n + \en The search is firstly performed among the faces adjacent by the edges of outer loop of face 'sheetFace', + and, if it fails, among the faces adjacent by the vertices of the loop, and, if the face is not found again, + the search among all the connected faces or faces from set 'faceShell' is used. + In the last case the closest faces are preferable.\n \~ + \param[in] faceShell - \ru Набор граней для поиска. + \en A face set for search. \~ + \param[in] sheetFace - \ru Исходная плоская грань. + \en The source planar face. \~ + \return \ru - Искомую плоскую грань. + \en - The required planar face. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbFace *) GetPairPlanarFace( const MbFaceShell * faceShell, + const MbFace & sheetFace ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать расстояние между гранями. + \en Compute the distance between faces. \~ + \details \ru Определяет расстояние между парой подобных граней. + Подобными считаются пары плоских, цилиндрических и конических граней, + у которых нормали коллинеарны и противоположно направлены. + Расстояние считается положительным, если грани располагаются со стороны, + противоположной направлению нормали, и отрицательным в противном случае. + В случае ошибки возвращается 0.0.\n + \en Determines the distance between a pair of a similar faces. + Similar faces is a pair of a planar, cylindrical or conic faces + which normals are collinear and have the opposite directions. + The distance is considered to be positive if the faces are located on the side + opposite to the normal direction, and to be negative otherwise. + If an error occurred, returns 0.0.\n \~ + \param[in] face1 - \ru Первая грань. + \en The first face. \~ + \param[in] face2 - \ru Вторая грань. + \en The second face. \~ + \result \ru - Значение расстояния между гранями. + \en - The distance between the faces. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (double) GetDistanceIfSameAndOpposite( const MbFace & face1, + const MbFace * face2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти подобные сгибы. + \en Find the similar bends. \~ + \details \ru В листовом теле shell ищутся согнутые цилиндрические/конические сгибы, + которые надо добавить к сгибам из bends, чтобы они могли разогнуться, то есть + сгибы разгибаемые только совместно.\n + \en Bended cylindrical/conic bends are searched in sheet solid 'shell' + which have to be added to bends 'bends' such that it will be possible to unbend the bends, i.e. + the bends can be unbend only together.\n \~ + \param[in] shell - \ru Набор граней поиска. + \en The face set for the search. \~ + \param[in,out] bends - \ru Множество подобных сгибов. + \en An array of similar bends. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (void) GetSimilarCylindricBends( const MbFaceShell & shell, + RPArray & bends ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать касательную точку для сгиба/разгиба. + \en Compute a tangent point for bend/unbend. \~ + \details \ru В точке tangentPoint либо координаты точки касания внутри грани, то есть 0.0<=x<=1.0 и 0.0<=y<=1.0, или за её пределами. + В первом случае точка касания пересчитывается в координаты лежащей под гранью поверхности, + во втором находится одна из точек касания поверхности, лежащей под гранью face и плоскости plane.\n + \en The tangent point is inside the face, i.e. 0.0<=x<=1.0 and 0.0<=y<=1.0, or outside the face. + In the first case the tangent point is recomputed in the coordinates of the underlying surface of the face, + in the second case one of the touching points of underlying surface of face 'face' and plane 'plane' is calculated.\n \~ + \param[in] face - \ru Грань, содержащая точку касания. + \en The face containing the tangent point. \~ + \param[in] plane - \ru Касательная плоскость. + \en The tangent plane. \~ + \param[in,out] tangentPoint - \ru Точка касания. + \en The tangent point. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) CalculateTangentPoint( const MbFace & face, + const MbPlane & plane, + MbCartPoint & tangentPoint ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать осевую линию разогнутого конического сгиба. + \en Calculate the centerline of an unbended conic bend. \~ + \details \ru Возвращает осевую линию в координатах параметрической области плоскости, лежащей под гранью face.\n + \en Returns the centerline in the coordinates of the parametric domain of the underlying plane of the face 'face'.\n \~ + \param[in] face - \ru Листовая грань разогнутого конического сгиба. + \en A sheet face of the unbended conic bend. \~ + \param[out] axisLineSegment - \ru Искомая осевая линия. + \en The required centerline. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) CalculateConicAxisLine( const MbFace & face, + MbLineSegment & axisLineSegment ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать осевую линию разогнутых сгибов. + \en Calculate the centerline of an unbent bend. \~ + \details \ru Возвращает трёхмерную осевую линию, лежащую на разогнутой грани сгиба.\n + \en Returns the 3D centerline that lies on the unbent face of the bend.\n \~ + \param[in] bendFaces - \ru Грани разогнутых сгибов, для которых строить линии сгиба. + \en Sheet faces of unfolded bends, that need constraction of the axis lines. \~ + \param[out] axisLineSegments - \ru Искомая осевая линия. + \en The required centerline. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) BuildBends3DAxisLines( const RPArray & bendFaces, + RPArray & axisLineSegments ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать параметры для замыкания угла. + \en Calculate the parameters for the corner closure. \~ + \details \ru Находит общее ребро угла или пару рёбер для замыканий через сгиб. Рассчитывает параметры замыкания для данных пар граней.\n + \en Find common edge for corner closure or two basic edges for corner closure across bend. + Calculate the parameters for the corner closure of selected faces.\n \~ + \param[in] facesPlus - \ru Выбранные торцевые грани стороны угла, условно принятой за положительную. + \en Selected butt faces from the side of angle assumed to be positive.\~ + \param[in] facesMinus - \ru Выбранные торцевые грани стороны угла, условно принятой за отрицательную. + \en Selected butt faces from the side of angle assumed to be negative. \~ + \param[out] parameters - \ru Параметры замыкания. + \en The closure parameters. \~ + \param[out] edgePlus - \ru Ребро сгиба, условно принятое за положительное. + \en The bend edge assumed to be positive. \~ + \param[out] edgeMinus - \ru Ребро сгиба, условно принятое за отрицательное. + \en The bend edge assumed to be negative. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) GetParamsForCloseCorner( const RPArray & facesPlus, + const RPArray & facesMinus, + MbClosedCornerValues & parameters, + MbCurveEdge *& edgePlus, + MbCurveEdge *& edgeMinus ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать параметры для замыкания угла. + \en Calculate the parameters for the corner closure. \~ + \details \ru Находит общее ребро угла или пару рёбер для замыканий через сгиб.\n + \en Find common edge for corner closure or two basic edges for corner closure across bend.\n \~ + \param[in] selectedEdgePlus - \ru Выбранное ребро стороны угла, условно принятой за положительную. + \en Selected edge from the side of angle assumed to be positive.\~ + \param[in] selectedEdgeMinus - \ru Выбранное ребро стороны угла, условно принятой за отрицательную. + \en Selected edge from the side of angle assumed to be negative. \~ + \param[out] parameters - \ru Параметры замыкания. + \en The closure parameters. \~ + \param[out] edgePlus - \ru Ребро сгиба, условно принятое за положительное. + \en The bend edge assumed to be positive. \~ + \param[out] edgeMinus - \ru Ребро сгиба, условно принятое за отрицательное. + \en The bend edge assumed to be negative. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) GetParamsForCloseCorner( const MbCurveEdge & selectedEdgePlus, + const MbCurveEdge & selectedEdgeMinus, + MbClosedCornerValues & parameters, + MbCurveEdge *& edgePlus, + MbCurveEdge *& edgeMinus ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметр сегментации кривой. + \en Calculate parameter of segmentation. \~ + \details \ru Вычислить параметр сегментации для заданного метода. + При изменении метода результат сегментации не меняется.\n + \en Calculate parameter of segmentation for the new method. + Result of the segmentation doesn't change. \n \~ + \param[in] curve - \ru Кривая (дуга). + \en Curve (arc).\~ + \param[in] method - \ru Метод сегментации. + \en Segmentation method.\~ + \param[in] param - \ru Параметр сегментации. + \en Segmentation parameter.\~ + \param[in] newMethod - \ru Метод сегментации, для которого нужно вычислить значение параметра. + \en Segmentation method to calculate parameter for.\~ + \result newParam - \ru Вычисленный параметр. + \en Calculated parameter. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (double) CalculateSegmentationParameter( const MbCurve & curve, + const MbeSegmentationMethod method, + const double param, + const MbeSegmentationMethod newMethod ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Аппроксимировать кривую (дугу) ломаной. + \en Split a curve (an arc) into segments. \~ + \details \ru Аппроксимировать кривую (дугу) ломаной.\n + \en Split a curve (an arc) into segments.\n \~ + \param[in] contour - \ru Кривая (дуга). + \en Curve (arc).\~ + \param[in] segmNumber - \ru Количество сегментов аппроксимации. + \en Number of segments after splitting.\~ + \param[out] resultContour - \ru Аппроксимированный отрезками контур. + \en Segmented contour. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplitContourIntoSegments( const MbCurve & curve, + const size_t segmNumb, + MbContour *& resultContour ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Аппроксимировать участки контуров (дуги) ломаной. + \en Split a part of a contours (an arc) into segments. \~ + \details \ru Аппроксимировать участки контуров (дуги) ломаной.\n + \en Split a part of a contours (an arc) into segments.\n \~ + \param[in] contour1 - \ru Первый контур. + \en First contour.\~ + \param[in] breaks1 - \ru Массив параметров разбиения первого контура. + \en Parameters of a partition of the first contour. \~ + \param[in] contour2 - \ru Второй контур. + \en Second contour.\~ + \param[in] breaks2 - \ru Массив параметров разбиения второго контура. + \en Parameters of a partition of the second contour. \~ + \param[in] segmNumber - \ru Количество сегментов аппроксимации. + \en Number of segments after splitting.\~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplitContoursIntoSegments( MbContour & contour1, + SArray & breaks1, + MbContour & contour2, + SArray & breaks2, + MbSNameMaker & names, + const SArray & segmNumbers1, + const SArray & segmNumbers2, + const size_t defSegmNumb, + const double gapValue ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Заполнить массив сгибов. + \en Fill the array of MbSMBendNames. \~ + \details \ru Заполнить массив сгибов. + \en Fill the array of MbSMBendNames. \~ + \param[in] contour1 - \ru Первый контур. + \en First contour. \~ + \param[in] placement1 - \ru ЛСК первого контура. + \en Placement if the first contour. \~ + \param[in] breaks1 - \ru Массив параметров разбиения первого контура. + \en Parameters of a partition of the first contour. \~ + \param[in] contour2 - \ru Второй контур. + \en Second contour. \~ + \param[in] placement2 - \ru ЛСК второго контура. + \en Placement if the second contour. \~ + \param[in] breaks2 - \ru Массив параметров разбиения второго контура. + \en Parameters of a partition of the second contour. \~ + \param[in] nameMaker - \ru Массив имён граней линейчатой поверхности. + \en Names of the faces of the ruled surface. \~ + \param[out] bendNames - \ru Массив параметров сгибов. + \en Array of the bends parameters. \~ + \return \ru true - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (bool) FillBendNamesArray( const MbContour & contour1, + const MbPlacement3D & placement1, + const SArray & breaks1, + const MbContour & contour2, + const MbPlacement3D & placement2, + const SArray & breaks2, + const MbSNameMaker & nameMaker, + RPArray & bendNames ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать трехмерный контур по двумерному с учётом разбиения. + \en To create 3D contour by 2D contour with splitting. \~ + \details \ru Разбивает присланный контур точками, заданными параметрами breaks, + и по нему создаёт трёхмерный контур, лежащий на плоскости, заданной ЛСК placement. + \en Splits the contour by points corresponding parameters breaks and makes 3D contour that lies on the placement. \~ + \param[in] placement - \ru ЛСК контура. + \en Placement of the contour. \~ + \param[in] contour - \ru Контур. + \en The contour. \~ + \param[in] breaks - \ru Массив параметров разбиения контура. + \en Parameters of a partition of the contour. \~ + \param[in,out] names - \ru Массив имён сегментов контура. + \en Names of the segments of the contour. \~ + \return \ru Разбитый с помощью массива breaks на сегменты трёхмерный контур. + \en Splitted with array breaks 3D contour. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbContour3D *) MakeContour ( const MbPlacement3D & placement, + const MbContour & contour, + const SArray & breaks, + MbSNameMaker & names ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать контур ребра жесткости по двум сторонам. + \en Create the contour of rib by side distances. \~ + \details \ru Создать двумерный контур ребра жесткости и его ЛСК по двум сторонам.\n + Начало координат ЛСК лежит на прямой пересечения плоских внутренних сторон сгиба. + \en Create the 2D contour of rib and placement by side distances. \n + The placement origin is placed on intersection of plane internal sides of bend.\~ + \param[in] bendEdge - \ru Ребро на внутренней грани сгиба. + \en The edge on internal bend face. \~ + \param[in] bendAngle - \ru Угол сгиба листового тела. + \en The bend anlge. \~ + \param[in] l1 - \ru Длина отступа вдоль первой стороны угла профиля. + \en The lenght along first side of rib section. \~ + \param[in] l2 - \ru Длина отступа вдоль второй стороны угла профиля. + \en The lenght along second side of rib section. \~ + \param[in] bRatio - \ru Относительная глубина прогиба контура в диапазоне от 0 до 1 (0 - нет прогиба, 1 - максимальный прогиб). + \en Relative value of contour bending defined in the range from 0 to 1 (0 - no bend, 1 - maximum bend). \~ + \param[in] rad - \ru Радиус скругления при прогибе профиля. + \en The contour fillet radius. \~ + \param[in] dir - \ru Направление выбора первой стороны угла профиля. + \en Direction of first side of rib section. \~ + \param[in] t - \ru Параметр точки на ребре сгиба. + \en Parameter on internal bend edge. \~ + \param[out] placement - \ru ЛСК контура. + \en Placement of the contour. \~ + \param[out] contour - \ru Контур листового ребра усиления. + \en The contour of sheet rib solid. \~ + \param[out] bMax - \ru Расстояние по биссектрисе угла сгиба от контура без прогиба до листового тела. + \en The distance along bisectrix of bend angle between unbended contour and sheet solid. \~ + \return \ru True - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC( bool ) MakeSheetRiContourByTwoSides( const MbCurveEdge & bendEdge, + const double bendAngle, + const double l1, + const double l2, + const double bRatio, + const double rad, + const bool dir, + const double t, + MbPlacement3D & placement, + MbContour & contour, + double & bMax ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать контур ребра жесткости по стороне и углу. + \en Create the contour of rib by distance and slope angle. \~ + \details \ru Создать двумерный контур ребра жесткости и его ЛСК по стороне и углу наклона.\n + Начало координат ЛСК лежит на прямой пересечения плоских внутренних сторон сгиба. \~ + \en Create the 2D contour of rib and placement by distance and slope angle. \n + The placement origin is placed on intersection of plane internal sides of bend.\~ + \param[in] bendEdge - \ru Ребро на внутренней грани сгиба. + \en The edge on internal bend face. \~ + \param[in] bendAngle - \ru Угол сгиба листового тела. + \en The bend anlge. \~ + \param[in] l1 - \ru Длина отступа вдоль первой стороны угла профиля. + \en The lenght along first side of rib section. \~ + \param[in] a - \ru Угол наклона профиля. + \en The contour slope angle. \~ + \param[in] bRatio - \ru Относительная глубина прогиба контура в диапазоне от 0 до 1 (0 - нет прогиба, 1 - максимальный прогиб). + \en Relative value of contour bending defined in the range from 0 to 1 (0 - no bend, 1 - maximum bend). \~ + \param[in] rad - \ru Радиус скругления при прогибе профиля. + \en The contour fillet radius. \~ + \param[in] dir - \ru Направление выбора первой стороны угла профиля. + \en Direction of first side of rib section. \~ + \param[in] t - \ru Параметр точки на ребре сгиба. + \en Parameter on internal bend edge. \~ + \param[out] placement - \ru ЛСК контура. + \en Placement of the contour. \~ + \param[out] contour - \ru Контур листового ребра усиления. + \en The contour of sheet rib solid. \~ + \param[out] bMax - \ru Расстояние по биссектрисе угла сгиба от контура без прогиба до листового тела. + \en The distance along bisectrix of bend angle between unbended contour and sheet solid. \~ + \return \ru True - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC( bool ) MakeSheetRiContourBySideAndAngle( const MbCurveEdge & bendEdge, + const double bendAngle, + const double l1, + const double a, + const double bRatio, + const double rad, + const bool dir, + const double t, + MbPlacement3D & placement, + MbContour & contour, + double & bMax ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать контур ребра жесткости по глубине и углу. + \en Create the contour of rib by depth and slope angle. \~ + \details \ru Создать двумерный контур ребра жесткости и его ЛСК по глубине и углу наклона.\n + Начало координат ЛСК лежит на прямой пересечения плоских внутренних сторон сгиба. \~ + \en Create the 2D contour of rib and placement by depth and slope angle. \n + The placement origin is placed on intersection of plane internal sides of bend.\~ + \param[in] bendEdge - \ru Ребро на внутренней грани сгиба. + \en The edge on internal bend face. \~ + \param[in] bendAngle - \ru Угол сгиба листового тела. + \en The bend anlge. \~ + \param[in] h - \ru Глубина профиля ребра. + \en The depth of rib section. \~ + \param[in] a - \ru Угол наклона профиля. + \en The contour slope angle. \~ + \param[in] bRatio - \ru Относительная глубина прогиба контура в диапазоне от 0 до 1 (0 - нет прогиба, 1 - максимальный прогиб). + \en Relative value of contour bending defined in the range from 0 to 1 (0 - no bend, 1 - maximum bend). \~ + \param[in] rad - \ru Радиус скругления при прогибе профиля. + \en The contour fillet radius. \~ + \param[in] dir - \ru Направление выбора первой стороны угла профиля. + \en Direction of first side of rib section. \~ + \param[in] t - \ru Параметр точки на ребре сгиба. + \en Parameter on internal bend edge. \~ + \param[out] placement - \ru ЛСК контура. + \en Placement of the contour. \~ + \param[out] contour - \ru Контур листового ребра усиления. + \en The contour of sheet rib solid. \~ + \param[out] bMax - \ru Расстояние по биссектрисе угла сгиба от контура без прогиба до листового тела. + \en The distance along bisectrix of bend angle between unbended contour and sheet solid. \~ + \return \ru True - в случае успеха операции, false - в противном случае. + \en True if the operation succeeded, otherwise false. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC( bool ) MakeSheetRiContourByDepthAndAngle( const MbCurveEdge & bendEdge, + const double bendAngle, + const double h, + const double a, + const double bRatio, + const double rad, + const bool dir, + const double t, + MbPlacement3D & placement, + MbContour & contour, + double & bMax ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчётчик расположения хот-точек для ребра жесткости листового тела. + \en Calculator of hot point location for the sheet rib. \~ + \details \ru Расчётчик расположения хот-точек для ребра жесткости листового тела.\n + Контур должен быть расчитан с помощью одной из функций MakeSheetRiContourByTwoSides, \n + MakeSheetRiContourBySideAndAngle или MakeSheetRiContourByDepthAndAngle. + \en Calculator of hot point location for the metal sheet rib. \n + The contour should be generated by functions MakeSheetRiContourByTwoSides, \n + MakeSheetRiContourBySideAndAngle or MakeSheetRiContourByDepthAndAngle. \n \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +class MATH_CLASS MbSheetRibHotPointCalculator { + MbPlaneCurve planeCurve; ///< \ru Образующий контур ребра жесткости. \en The generating contour of a sheet rib. + SheetRibValues parameters; ///< \ru Параметры листового ребра жёсткости. \en Parameters of a sheet rib. + MbPlacement3D secPlace; ///< \ru ЛСК плоскости, проходящей через ось сгиба перпендикулярно контуру. \en Placement of the plane passing throught the bend axis orthogonally to the contour. + MbPlacement3D rightFlankPlace; ///< \ru ЛСК боковой плоской грани ребра жёсткости. \en Placement of the flank plane face of a sheet rib. + MbCartPoint3D begPoint; ///< \ru Начальная точка контура ребра жесткости. \en The begin point of the generating contour. + MbCartPoint3D endPoint; ///< \ru Концевая точка контура ребра жесткости. \en The end point of the generating contour. + MbCartPoint3D rightCornerPoint; ///< \ru Правая вершина ребра жесткости. \en The right vertex of rib. + double sheetThickness; ///< \ru Толщина листа. \en The sheet thickness. + double depth; ///< \ru Глубина профиля ребра. \en The depth of rib section. + bool isContourStraight; ///< \ru Прямолинейная форма контура . \en The straight contour form. + bool isContourBent; ///< \ru Прогнутая форма контура . \en The bent contour form. + bool isContourValid; ///< \ru Корректность контура . \en The contour validness. + +public: + /// \ru Конструктор. \en Constructor. + MbSheetRibHotPointCalculator( const MbPlacement3D & place, const MbContour & contour, const SheetRibValues & params, double thickness, bool first = true ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSheetRibHotPointCalculator( const MbSheetRibHotPointCalculator &init ); + /// \ru Оператор присваивания. \en An assignment operator. + MbSheetRibHotPointCalculator & operator = ( const MbSheetRibHotPointCalculator &init ); + /// \ru Рассчитать положение "хот"-точки : длина отступа вдоль первой стороны угла профиля (L1). \en Calculate the hot point location : the lenght along first side of rib section. + bool CalcContourL1HotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : длина отступа вдоль второй стороны угла профиля (L2). \en Calculate the hot point location : the lenght along second side of rib section. + bool CalcContourL2HotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : угол наклона профиля в способе «По стороне и углу» (a). \en Calculate the hot point location: the contour slope angle. + bool CalcContourAngleHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : глубина профиля (H) в способе «По глубине и углу». \en Calculate the hot point location : the depth of rib section. + bool CalcContourDepthHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : радиус скругления ребра (дна формы) в сечении (R). \en Calculate the hot point location : fillet radius of convex part of rib. + bool CalcRibRadHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : радиус скругления основания. \en Calculate the hot point location : fillet radius of base part of rib. + bool CalcRibRadBaseHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : ширина ребра в сечении. \en Calculate the hot point location : width of base of rib. + bool CalcRibWidthHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : угол наклона боковой грани. \en Calculate the hot point location : the slope angle of flank face of rib. + bool CalcRibSlopeHotPoint( MbCartPoint3D & point, MbAxis3D & rotationAxis ) const; + /// \ru Рассчитать положение "хот"-точки : глубина прогиба профиля. \en Calculate the hot point location : the contour bending depth. + bool CalcContourBendDepthHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + /// \ru Рассчитать положение "хот"-точки : радиус скругления при прогибе профиля. \en Calculate the hot point location : the contour fillet radius. + bool CalcContourRadHotPoint( MbCartPoint3D & point, MbVector3D & dir ) const; + +private: + bool CalcFilletHotPoint( const MbCartPoint & p0, + const MbCartPoint & p1, + const MbCartPoint & p2, + double rad, + MbCartPoint & hotPoint, + MbVector & hotDir ) const; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание элементов ребра жёсткости листового тела. + \en Create rib parts of a sheet solid. \~ + \details \ru Создание элементов ребра жёсткости листового тела. \n + По заданному контуру функция строит ребро жёсткости а затем вычленяет составляющие его элементы, заделывая места разрыва. \n + \en Create rib parts of a sheet solid. \n + The function creates a rib from a given contour and then extructs its elements from the body, healing rip borders with patches. \n \~ + \param[in] solid - \ru Исходное листовое тело. + \en The source sheet solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Формообразующий контур на плоскости XY системы координат place. + \en The generating contour on XY-plane of coordinate system 'place'. \~ + \param[in] index - \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. + \en Index of a segment in the contour at which the inclination direction will be set. \~ + \param[in] pars - \ru Параметры листового ребра жёсткости. + \en Parameters of a sheet rib. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] partToAdd - \ru Добавляемый элемент ребра. + \en The adding rib element. \~ + \param[out] partToSubtract - \ru Вычитаемый элемент ребра. + \en The subtracting rib element. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetRibParts( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + SheetRibValues & pars, + const MbSNameMaker & names, + MbSolid *& partToAdd, + MbSolid *& partToSubtract ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание тела с листовым ребром жесткости. + \en Create a sheet solid with rib. \~ + \details \ru Создать тело с листовым ребром жёсткости. \n + По заданному контуру функция строит ребро жёсткости и объединяет его с исходным телом. + Сегмент контура с указанным номером устанавливает вектор уклона. \n + \en Create a sheet solid with a sheet rib. \n + The function creates a rib from a given contour and unites it with the source solid. + The segment of the contour with the given number determines the slope vector. \n \~ + \param[in] solid - \ru Исходное листовое тело. + \en The source sheet solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Формообразующий контур на плоскости XY системы координат place. + \en The generating contour on XY-plane of coordinate system 'place'. \~ + \param[in] index - \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. + \en Index of a segment in the contour at which the inclination direction will be set. \~ + \param[in] pars - \ru Параметры листового ребра жёсткости. + \en Parameters of a sheet rib. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SheetRibSolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + SheetRibValues & pars, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрезать тело секущими плоскостями и согнуть получившиеся сегменты согласно заданным параметрам. + \en Cut the solid with the cutting planes and bend the resulting parts according to given parameters. \~ + \details \ru \n + \en \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] bends - \ru Множество сгибов, состоящих из секущей плоскости и параметров сгиба. + \en An array of bends which consist of cutting plane and bend parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BendAnySolid( MbSolid & solid, + const MbeCopyMode sameShell, + const MbPlane & cutPlane, + const SArray & bends, + const MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Упростить развёртку листового тела. + \en Simplify flattened sheet solid. \~ + \details \ru Упростить развёртку листового тела. \n + \en Simplify flattened sheet solid. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SimplifyFlatPattern( MbSolid & solid, + const MbeCopyMode sameShell, + const MbSimplifyFlatPatternValues & params, + const MbSNameMaker & nameMaker, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить из тела результат операции с главным именем mainName. + \en Remove the result of the operation with main name "mainName" from the solid. \~ + \details \ru Операция удаляет грани с главным именем mainName и потом заделывает образовавшиеся дыры.\n + \en The operation deletes the faces that have main name equal to "mainName" and then closes up the holes that remain after the first stage of the operation.\n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] removeName - \ru Главное имя удаляемой операции. + \en Main name of the operation to delete. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RemoveOperationResult( MbSolid & solid, + const MbeCopyMode sameShell, + const SimpleName removeName, + const MbSNameMaker & nameMaker, + MbSolid *& result ); + + +#endif // __ACTION_SHEET_H + + diff --git a/C3d/Include/action_shell.h b/C3d/Include/action_shell.h new file mode 100644 index 0000000..6633933 --- /dev/null +++ b/C3d/Include/action_shell.h @@ -0,0 +1,842 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения незамкнутых тел. + \en Functions for open solids construction. \~ + \details \ru Геометрическое ядро C3D поддерживает поверхностное моделирование. + Результатом поверхностного моделирования являются элементы геометрической модели, + которые будем называть незамкнутыми телами. Незамкнутые тела характерны тем, + что они описывают не всю поверхность моделируемого объекта, а только часть её. + Часто незамкнутое тело состоит из одной грани. В незамкнутом теле всегда присутствуют + краевые рёбра. Незамкнутое тело описывает множество точек, принадлежащих только граням + этого тела, тогда как замкнутое тело описывает множество точек, располагающихся + на поверхности моделируемого объекта и внутри него. + \en The geometric kernel C3D supports the surface modeling. + The result of surface modeling are elements of geometric model + which are called open solids here. Open solids + describe not the whole surface of an object of modeling but only a part of it. + An open solid often consists of one face. An open solid always contains + boundary edges. An open solid describes a point set that belong to faces of the solid only, + whereas a closed solid describes a point set + on the surface of the modeled object and inside it. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_SHELL_H +#define __ACTION_SHELL_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbPatchCurve; +class IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить заплатку. + \en Create a patch. \~ + \details \ru Построить заплатку по выбранным ребрам. \n + \en Create a patch from the specified edges. \n \~ + \param[in] initEdges - \ru Набор ребер. + \en A set of edges. \~ + \param[in] p - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] n - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная заплатка. + \en The required patch. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) PatchShell( const RPArray & initEdges, + const PatchValues & p, + const MbSNameMaker & n, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить заплатку. + \en Create a patch. \~ + \details \ru Построить заплатку по выбранным кривым. \n + \en Create a patch from the specified curves. \n \~ + \param[in] initCurves - \ru Набор кривых. + \en A set of curves. \~ + \param[in] p - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] n - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная заплатка. + \en The required patch. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) PatchShell( const RPArray & initCurves, + const PatchValues & p, + const MbSNameMaker & n, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить незамкнутое тело по множеству групп точек. + \en Create an open solid given a set of point groups. \~ + \details \ru Построить незамкнутое тело по сечениям, образованным сплайнами, построенными по группе контрольных точек. \n + \en Create an open lofted solid whose profiles are defined by splines created from the specified groups of points. \n \~ + \param[in] points - \ru Набор точек. + \en A point set. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] name - \ru Идентификатор. + \en An identifier. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedShell( const RPArray< SArray > & points, + const MbSNameMaker & names, + SimpleName name, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить незамкнутое тело по множеству кривых. + \en Create an open solid from a set of curves. \~ + \details \ru Построить незамкнутое тело по сечениям, образованным кривыми. \n + \en Create an open lofted solids whose profiles are defined by the curves. \n \~ + \param[in] curves - \ru Набор кривых. + \en A set of curves. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] name - \ru Идентификатор. + \en An identifier. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedShell( const RPArray & curves, + const MbSNameMaker & names, + SimpleName name, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить незамкнутое эквидистантное тело. + \en Create an open offset solid. \~ + \details \ru Построить незамкнутое эквидистантное тело на базе указанных в initFaces граней. \n + \en Create an open offset solid on the basis of the faces 'initFaces'. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] initFaces - \ru Грани исходного тела для построения. + \en Faces of the initial solid for construction. \~ + \param[in] checkFacesConnection - \ru Необходимость проверки связности выбранных граней. + \en Whether to check connectivity of the specified faces. \~ + \param[in] p - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] result - \ru Эквидистантная оболочка. + \en The offset shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetShell( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & initFaces, + bool checkFacesConnection, + SweptValues & p, + const MbSNameMaker & operNames, + bool copyFaceAttrs, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить незамкнутое тело по множеству точек. + \en Create an open solid from a point set. \~ + \details \ru Построить незамкнутое тело по множеству точек, заданных в параметрах построения. \n + \en Create an open solid from a point set specified in parameters. \n \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \param[in,out] progBar - \ru Индикатор прогресса выполнения операции. + \en A progress indicator of the operation. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsSurfacesShell( NurbsSurfaceValues & params, + const MbSNameMaker & operNames, + bool isPhantom, + MbSolid *& result, + IProgressIndicator * progBar ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить незамкнутое тело по сети кривых. + \en Create an open solid from a set of curves. \~ + \details \ru Построить незамкнутое тело по сети кривых, заданных в параметрах построения. \n + \en Create an open solid from a set of curves specified in the parameters. \n \~ + \param[in] pars - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) MeshShell( MeshSurfaceValues & pars, + const MbSNameMaker & operNames, + bool isPhantom, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Усечь (обрезать) незамкнутое тело. + \en Truncate an open solid. \~ + \details \ru Выполнить построение незамкнутого тела путём усечения исходного тела. \n + \en Create an open solid by truncation the initial solid. \n \~ + \param[in] initSolid - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] selIndices - \ru Номера выбранных граней (если массив пуст, то вся оболочка). + \en The numbers of selected faces (if the array is empty, the whole shell is selected). \~ + \param[in] initCopyMode - \ru Режим копирования исходных оболочек. + \en Whether to copy the initial shells. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] truncatingItems - \ru Усекающие объекты. + \en Truncating objects. \~ + \param[in] truncatingOrients - \ru Ориентация усекающих объектов. + \en The truncating objects orientation. \~ + \param[in] truncatingSplitMode - \ru Кривые используются как линии разъема. + \en The curves are used as parting lines. \~ + \param[in] truncatingCopyMode - \ru Режим копирования усекающих оболочек. + \en Whether to copy the truncating shells. \~ + \param[in] mergeFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] result - \ru Усеченная оболочка. + \en The truncated shell. \~ + \param[out] resultPlace - \ru Фантомное направление усечения. + \en A phantom direction of truncation. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) TruncateShell( MbSolid & initSolid, + SArray & selIndices, + MbeCopyMode initCopyMode, + const MbSNameMaker & operNames, + RPArray & truncatingItems, + SArray & truncatingOrients, + bool truncatingSplitMode, + MbeCopyMode truncatingCopyMode, + const MbMergingFlags & mergeFlags, + MbSolid *& result, + MbPlacement3D *& resultPlace ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить линейчатое незамкнутое тело. + \en Create an open ruled solid. \~ + \details \ru Построить линейчатое незамкнутое тело по двум кривым, заданным в параметрах. \n + \en Create an open ruled solid from two curves specified in parameters. \n \~ + \param[in] pars - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RuledShell( RuledSurfaceValues & pars, + const MbSNameMaker & operNames, + bool isPhantom, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить кривую для построения линейчатого тела. + \en Check the curve for a ruled solid creation. \~ + \details \ru Проверить вторую кривую на согласованность с первой кривой для построения + линейчатого незамкнутого тела и выполнить необходимую модификацию второй кривой. \n + \en Check the second curve for consistency with the first curve for creation + of the open ruled solid and make the necessary modification of the second curve. \n \~ + \param[in] curve0 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve1 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] isInverted1 - \ru Была ли вторая кривая инвертирована. + \en Whether the second curve was inverted. \~ + \param[out] isShifted1 - \ru Было ли смещено начало второй кривой. + \en Whether the beginning of the first curve was shifted. \~ + \param[in] version - \ru Версия операции. + \en The version of the operation. \~ + \warning \ru Вспомогательная функция операции RuledShell. + \en An auxiliary function of operation 'RuledShell'. \~ + \ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (void) CheckRuledCurve( const MbCurve3D & curve0, + const MbCurve3D & curve1, + bool & isInverted1, + bool & isShifted1, + VERSION version ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры кривой для построения линейчатого тела. + \en Check the curve parameters for creation of a ruled solid. \~ + \details \ru Проверить параметры кривой и выполнить нормализацию параметров замкнутой кривой. \n + \en Check the curve parameters and perform the normalization of a closed curve parameters. \n \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in,out] params - \ru Множество параметров кривой. + \en An array of the curve parameters. \~ + \param[in] isAscending - \ru Будет ли порядок параметров возрастающим. + \en Whether the parameters are specified in the ascending order. \~ + \return \ru Возвращает true, если удалось нормализовать массив параметров. + \en Returns true if the parameter array has been successfully normalized. \~ + \warning \ru Вспомогательная функция операции RuledShell. + \en An auxiliary function of operation 'RuledShell'. \~ + \ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (bool) CheckRuledParams( const MbCurve3D & curve, + SArray & params, + bool isAscending ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить продолжение незамкнутого тела выдавливанием. + \en Create an extension of an open solid by extrusion. \~ + \details \ru Построить продолжение незамкнутого тела путём выдавливания указанных краевых рёбер заданной грани тела. \n + \en Create an extension of an open solid by extrusion of specified boundary edges of the given face of the solid. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования оболочки. + \en Whether to copy the shell. \~ + \param[in] face - \ru Продляемая грань в исходной оболочке. + \en A face of the initial shell to be extended. \~ + \param[in] edges - \ru Множество ребер продляемой грани, через которые выполняется продление. + \en An array of edges through which to extend the face. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtensionShell( MbSolid & solid, + MbeCopyMode sameShell, + MbFace & face, + const RPArray & edges, + const ExtensionValues & params, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить тело соединения по двум кривым. + \en Create a joint solid from two curves. \~ + \details \ru Построить незамкнутое тело соединения по двум кривым на поверхности. \n + \en Create an open joint solid from two curves on a surface. \n \~ + \param[in] curve1 - \ru Первая поверхностная кривая. + \en The first curve on a surface. \~ + \param[in] curve2 - \ru Вторая поверхностная кривая. + \en The second curve on a surface. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (MbResultType) JoinShell( MbSurfaceCurve & curve1, + MbSurfaceCurve & curve2, + JoinSurfaceValues & parameters, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить тело соединения по двум множествам рёбер. + \en Create a joint solid from two sets of edges. \~ + \details \ru Построить незамкнутое тело соединения по двум множествам ребер. \n + \en Create an open joint solid from two sets of edges. \n \~ + \param[in] edges1 - \ru Первая группа ребер. + \en The first group of edges. \~ + \param[in] orients1 - \ru Ориентации ребер в первой группе. + \en The edges senses in the first group. \~ + \param[in] edges2 - \ru Вторая группа ребер. + \en The second group of edges. \~ + \param[in] orients2 - \ru Ориентация ребер во второй группе. + \en The edges senses in the second group. \~ + \param[in] matr1 - \ru Матрица преобразования первой группы ребер в единую систему координат. + \en The matrix of transformation of the first group of edges to the common coordinate system. \~ + \param[in] matr2 - \ru Матрица преобразования второй группы ребер в единую систему координат. + \en The matrix of transformation of the second group of edges to the common coordinate system. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \param[in] isPhantom - \ru Режим фантома операции. + \en The operation phantom mode. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (MbResultType) JoinShell( const RPArray & edges1, + const SArray & orients1, + const RPArray & edges2, + const SArray & orients2, + const MbMatrix3D & matr1, + const MbMatrix3D & matr2, + JoinSurfaceValues & parameters, + const MbSNameMaker & operNames, + MbSolid *& result, + bool isPhantom = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить оболочку на части по заданному набору ребер. + \en Divide a shell into parts using a given set of edges. \~ + \details \ru Разделить оболочку на части по заданному набору ребер. \n + \en Divide shell into parts using a given set of edges. \n \~ + \param[in] solid - \ru Оболочка. + \en A shell. \~ + \param[in] sameShell - \ru Режим копирования оболочки. + \en Whether to copy the shell. \~ + \param[in] edges - \ru Набор ребер. + \en Set of edges. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ +\ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (MbResultType) DivideShell( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & edges, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить кривую для построения тела соединения. + \en Check a curve for creation a joint solid. \~ + \details \ru Проверить вторую кривую на согласованность с первой кривой для построения + незамкнутого тела соединения и выполнить необходимую модификацию второй кривой. \n + \en Check the second curve for consistency with the first curve for creation + of the open joint solid and make the necessary modification of the second curve. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] isInverted1 - \ru Была ли вторая кривая инвертирована. + \en Whether the second curve was inverted. \~ + \param[out] isShifted1 - \ru Было ли смещено начало второй кривой. + \en Whether the beginning of the first curve was shifted. \~ + \param[in] version - \ru Версия операции. + \en The version of the operation. \~ + \warning \ru Вспомогательная функция операции JoinShell. + \en An auxiliary function of operation JoinShell. \~ + \ingroup Shell_Modeling +*/ +//--- +MATH_FUNC (void) CheckJoinedCurve( const MbCurve3D & curve1, + const MbCurve3D & curve2, + bool & isInverted1, + bool & isShifted1, + VERSION version ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры кривой для построения тела соединения. + \en Check the curve parameters for creation of a joint solid. \~ + \details \ru Проверить параметры кривой и нормализовать параметры замкнутой кривой. \n + \en Check the curve parameters and normalize a closed curve parameters. \n \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in,out] params - \ru Множество параметров кривой. + \en An array of the curve parameters. \~ + \param[in] isAscending - \ru Будет ли порядок параметров возрастающим. + \en Whether the parameters are specified in the ascending order. \~ + \return \ru Возвращает true, если удалось нормализовать массив параметров. + \en Returns true if the parameter array has been successfully normalized. \~ + \warning \ru Вспомогательная функция операции JoinShell. + \en An auxiliary function of operation JoinShell. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (bool) CheckJoinedParams( const MbCurve3D & curve, + SArray & params, + bool isAscending ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить кривую по множеству рёбер. + \en Create a curve from a set of edges. \~ + \details \ru Создать кривую для поверхности соединения по списку ребер. \n + \en Create a curve for a surface of the joint from a list of edges. \n \~ + \param[in] edges - \ru Набор ребер. + \en A set of edges. \~ + \param[in] orients - \ru Ориентации ребер. + \en Edges senses. \~ + \param[in] matr - \ru Матрица преобразования ребер. + \en Edges transformation matrix. \~ + \param[out] res - \ru Результат операции. + \en The operation result. \~ + \return \ru Возвращает указатель на кривую, если ее получилось создать, + иначе возвращает ноль. + \en Returns a pointer to the curve if it has been successfully created, + otherwise it returns null. \~ + \warning \ru Вспомогательная функция операции JoinShell. + \en An auxiliary function of operation JoinShell. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCurve3D *) CreateJoinedCurve( const RPArray & edges, + const SArray & orients, + const MbMatrix3D & matr, + MbResultType & res ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить тело сопряжения несвязанных граней. + \en Create a solid of two non-connected faces. \~ + \details \ru Построить незамкнутое тело, состоящее из грани скругления между двумя несвязанными гранями. \n + \en Create an open solid that consists of a fillet face between two non-connected faces. \n \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] face1 - \ru Сопрягаемая грань первого тела. + \en The first solid face to fillet. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] face2 - \ru Сопрягаемая грань второго тела. + \en The second solid face to fillet. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FacesFillet( const MbSolid & solid1, + const MbFace & face1, + const MbSolid & solid2, + const MbFace & face2, + const SmoothValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить тело на базе элементарной поверхности. + \en Create a solid given an elementary surface. \~ + \details \ru Построить тело, состоящее из одной грани, на базе исходной элементарной поверхности. \n + \en Create a solid which consists of a face with the specified underlying elementary surface. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка. + \en The resultant shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ElementaryShell( const MbSurface & surface, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить тело на базе поверхности. + \en Create a solid given a surface. \~ + \details \ru Построить тело, состоящее из одной грани, на базе исходной поверхности. + Поверхность должна быть без самопересечений, с корректной ориентацией + ограничивающих кривых в случае поверхности MbCurveBoundedSurface. \n + \en Create a solid which consists of a face with the specified underlying surface. + The surface should have no self-intersections, + the bounding curves should be correctly oriented in case of surface MbCurveBoundedSurface. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка. + \en The resultant shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SurfaceShell( const MbSurface & surface, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрезать тело силуэтным контуром. + \en Cut a solid by a silhouette contour. \~ + \details \ru Построить оболочки, полученные в результате разрезания тела его силуэтным контуром. \n + \en Create solids as a result of cutting a solids by its silhouette contour.\n\~ + \param[in] shell - \ru Исходное тело. + \en The solid\~ + \param[in] sameShell - \ru Способ передачи данных при копировании оболочек. + \en Methods of transferring data while copying shells \~ + \param[in] eye - \ru Направление взгляда. + \en Eye's direction. \~ + \param[out] outlineCurves - \ru Кривые, входящие в силуэтный контур. + - \en Curves of the silhouette contour. \~ + \param[out] result - \ru Тела, полученные в результате применения операции. + - \en The resultant solids.\~ + \return \ru Возвращает код результата операции.\~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CutShellSilhouetteContour( MbSolid & solid, + MbeCopyMode sameShell, + const MbVector3D & eye, + const VERSION version, + RPArray & outlineCurves, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сшить грани нескольких тел в одно тело. + \en Stitch faces of several solids into single solid. \~ + \details \ru Сшить стыкующиеся друг с другом грани нескольких тел в одно тело. Ориентация граней может быть изменена. \n + \en Stitch faces of several solids with coincident edges into single solid. The faces orientation can be changed. \n \~ + \param[in] initialSolids - \ru Множество тел для сшивки. + \en An array of solids for stitching. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] formSolidBody - \ru Флаг формирования твердого тела из результирующей оболочки. + \en Whether to form a solid solid from the resultant shell. \~ + \param[in] stitchPrecision - \ru Точность сшивки. + \en Stitching accuracy. \~ + \param[out] resultSolid - \ru Результирующая оболочка или тело (в зависимости от флага). + \en The resultant shell or solid (depends on the flag). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbeStitchResType) StitchToOneSheetSolid( const RPArray & initialSolids, + const MbSNameMaker & operNames, + bool formSolidBody, + double stitchPrecision, + MbSolid *& resultSolid ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение оси токарного сечения и построение кривых сечения для тела. + \en Search for lathe axis and construction of lathe elements for the solid. \~ + \details \ru Функция выполняет поиск токарной оси граней вращения и строит токарное сечение в некоторой плоскости. \n + \en The function searches for lathe axis of rotation faces and builds the curves of lathe-section in a plane. \n \~ + \param[in] solid - \ru Тело. \en Solid. \~ + \param[in] axis - \ru Ось токарного сечения может быть нуль). \en Lathe axis, may be null. \~ + \param[in] angle - \ru Угол, управляющий построением перпендикулярных оси сечения отрезками, рекомендуется M_PI_4-M_PI. \en The angle, managing the construction of segments which perpendicular to the axis, recomended M_PI_4-M_PI. \~ + \param[out] position - \ru Плоскость, в плоскости XY которой лежат кривые сечения, а ось X является осью токарного сечения. \en Plane position of section, axis X is a axis of section. \~ + \param[out] curves - \ru Кривые токарного сечения располагаются в плоскости XY position. \en The curves of section located on plane XY of position. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LatheCurves( const MbSolid & solid, + const MbAxis3D * axis, + double angle, + MbPlacement3D & position, + RPArray & curves ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение следа кривой при её вращении вокруг оси токарного сечения. + \en Building of curves for lathe section for given curve. \~ + \details \ru Функция выполняет построение следа ребра в плоскости XY локальной системы координат при его вращении вокруг оси X. \n + \en The function builds the generatrix track in the XY plane of the local coordinate system as it rotates around the axis X. \n \~ + \param[in] generatrix - \ru Кривая. \en Curve \~ + \param[in] position - \ru Плоскость, ось X которой является осью токарного сечения. \en Plane position of section, axis X is a axis of section. \~ + \param[out] curves - \ru Контейр кривых, в который будет добавлен след в плоскости XY position от вращения кривой generatrix вокруг оси X. \en The curve on plane XY of position will be added to contaner curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LatheCurve( const MbCurve3D & generatrix, + const MbPlacement3D & position, + RPArray & curves ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить срединную оболочку по граням тела, основанным на + эквидистантных поверхностях. + \en Create a median shell by solid faces, based on equidistant + surfaces. \~ + \details \ru Построить срединную оболочку по парам граней тела, основанным на + эквидистантных поверхностях. Пары граней либо выбираются пользователем, + либо находятся автоматически по заданному расстоянию между гранями. + Грани должны принадлежать одному и тому же телу.\n + \en Construct a median shell between pair of faces, based on equidistant + surfaces. Pair of faces are selected by user or are found by given distance + between faces. The faces must belong to the same body. \n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] faceIndexes - \ru Выбранные пары граней. + \en Selected face pairs. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующая оболочка. + \en The required shell. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC( MbResultType ) MedianShell( MbSolid & solid, + MbeCopyMode sameShell, + const c3d::IndicesPairsVector & faceIndexes, + const MedianShellValues & params, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение развёртки грани на плоскость. + \en Construction of a face sweep on a plane. \~ + \details \ru Построение развёртки грани на плоскость.\n + \en Construction of a face sweep on a plane.\n \~ + \param[in] face - \ru Исходная грань. + \en The initial face. \~ + \param[in] values - \ru Параметры построения: локальная система координат развернутой поверхности грани, данные для вычисления шага при триангуляции, коэффициент Пуассона материала грани. + \en The parameters: Local coordinate system for result surface, Data for step calculation during triangulation, the Poisson's ratio of face material. \~ + \param[out] result - \ru Тело - плоская развертка исходной грани. + \en The built solid unbend face on plane. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \warning \ru В разработке. + \en Under development. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RectifyFace( const MbFace & face, + const RectifyValues values, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать решетчатую оболочку. + \en Create a lattice shell. \~ + \details \ru Создать решетчатую оболочку по трем управляющим точкам, параметрам решетки и количеству элементов. \n + \en Create a lattice shell on the three control points of the lattice parameters and the number of elements. \~ + \param[in] point0 - \ru Точка, определяющая начало локальной системы координат поверхности. + \en The origin of the surface local coordinate system. \~ + \param[in] point1 - \ru Точка, определяющая направление оси X локальной системы и размер элемента. + \en A point specifying the direction of X-axis of the local system and the size of element. \~ + \param[in] point2 - \ru Точка, определяющая направление оси Y локальной системы. + \en A point specifying the direction of Y-axis of the local system. \~ + \param[in] xRadius - \ru Шаг вдоль первой оси локальной системы координат. + \en The step along the first axis of the local coordinate system. \~ + \param[in] yRadius - \ru Шаг вдоль второй оси локальной системы координат. + \en The step along the second axis of the local coordinate system. \~ + \param[in] zRadius - \ru Шаг вдоль третьей оси локальной системы координат. + \en The step along the third axis of the local coordinate system. \~ + \param[in] xCount - \ru Количество ячеек вдоль первой оси локальной системы координат. + \en The number of cells along a first axis of the local coordinate system. \~ + \param[in] yCount - \ru Количество ячеек вдоль второй оси локальной системы координат. + \en The number of cells along a second axis of the local coordinate system. \~ + \param[in] zCount - \ru Количество ячеек вдоль третьей оси локальной системы координат. + \en The number of cells along a third axis of the local coordinate system. \~ + \param[out] result - \ru Построенная тело. + \en The constructed solid. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OctaLattice( const MbCartPoint3D & point_0, + const MbCartPoint3D & point_1, + const MbCartPoint3D & point_2, + double xRadius, + double yRadius, + double zRadius, + size_t xCount, + size_t yCount, + size_t zCount, + const MbSNameMaker & names, + MbSolid *& result ); + + +#endif // __ACTION_SHELL_H diff --git a/C3d/Include/action_solid.h b/C3d/Include/action_solid.h new file mode 100644 index 0000000..4394a2c --- /dev/null +++ b/C3d/Include/action_solid.h @@ -0,0 +1,2239 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции создания тел, операции с телами. + \en Functions for creation of solids, operations on solids. \~ + \details \ru Процесс построения тел в геометрическом моделировании похож на процесс + изготовления моделируемого объекта. Сначала создаются тела простой формы, а далее + выполняется набор действий, позволяющих из тел простой формы получить более сложные тела. + При необходимости создаются вспомогательные объекты. Редактировать и создавать подобные + тела можно путём изменения параметров с последующим повторением процесса построения тел.\n + Все функции создания тел содержат в качестве входного параметр MbSNameMaker, + обеспечивающий именование граней, рёбер и вершин. + Первым параметром конструктора генератора имён MbSNameMaker служит главное имя операции. + По главному имени можно определить, в какой функции рождена та или иная грань, ребро, вершина. + Главное имя выдаёт метод GetMainName().\n + \en The process of solids creation in geometric modeling is similar to the process + of the modeled object manufacturing. Firstly solids of a simple form are created, and then + a set of operations are performed to obtain a more complex solids from solids of a simple form. + Auxiliary objects are created if necessary. The similar solids can be edited and created + by modifying of the parameters and further repeating the process of the solids creation.\n + All of the function contain input parameter MbSNameMaker, + providing the naming of faces, edges and vertices. + The first parameter to the constructor MbSNameMaker is the main name of the function. + You can determine which function is born one or the other face, edge, vertex by main name. + GetMainName() gives the main name of the function (face.GetMainName(), edge.GetMainName(), vertex.GetMainName()).\~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_SOLID_H +#define __ACTION_SOLID_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbItem; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbPartSolidIndices; +class MATH_CLASS MbSpine; +class MATH_CLASS MbMesh; +class MATH_CLASS MbGrid; +class MATH_CLASS MbCollection; +class MATH_CLASS IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать элементарное тело. + \en Create an elementary solid. \~ + \details \ru Создать одно из элементарных тел по заданным точкам и типу: \n + solidType = et_Sphere - шар (3 точки), \n + solidType = et_Torus - тор (3 точки), \n + solidType = et_Cylinder - цилиндр (3 точки), \n + solidType = et_Cone - конус (3 точки), \n + solidType = et_Block - блок (4 точки), \n + solidType = et_Wedge - клин (4 точки), \n + solidType = et_Prism - призма (количество вершин основания+1 точка), \n + solidType = et_Pyramid - пирамида (количество вершин основания+1 точка), \n + solidType = et_Plate - плита (4 точки), + solidType = et_Icosahedron - икосаэдр (3 точки), \n + solidType = et_Polyhedron - многогранник (3 точки), \n + solidType = et_Tetrapipe - тетра-труба (3 точки), \n + solidType = et_Octapipe - окта-труба (3 точки). \n + \en Create one of elementary solids from the specified points and type: \n + solidType = et_Sphere - a sphere (3 points), \n + solidType = et_Torus - a torus (3 points), \n + solidType = et_Cylinder - a cylinder (3 points), \n + solidType = et_Cone - a cone (3 points), \n + solidType = et_Block - a block (4 points), \n + solidType = et_Wedge - a wedge (4 points), \n + solidType = et_Prism - a prism (points count is equal to the base vertices count + 1), \n + solidType = et_Pyramid - a pyramid (points count is equal to the base vertices count + 1), \n + solidType = et_Plate - a plate (4 points), \n + solidType = et_Icosahedron - an icosahedron (3 points), \n + solidType = et_Polyhedron - a polyhedron (3 points), \n + solidType = et_Tetrapipe - a tetra-pipe (3 points), \n + solidType = et_Octapipe - an octa-pipe (3 points). \n \~ + \param[in] points - \ru Набор точек. \n + points[0] определяет начало локальной системы координат. \n + Для сферы, тора, цилиндра и конуса: \n + points[1] определяет направление оси Z локальной системы. \n + points[2] определяет направление оси X локальной системы. \n + Для блока, клина и плиты: \n + points[1] определяет направление оси X локальной системы. \n + points[2] определяет направление оси Y локальной системы. \n + Кроме того, \n + points[1] определяет высоту цилиндра, высоту конуса, + большой радиус тора, длину блока, длину клина. \n + points[2] определяет радиус цилиндра, угол конуса как угол между векторами v1(points[0],points[1]) и v2(points[0],points[2]), + радиус сферы, малый радиус тора, ширину блока, ширину клина. \n + В случае конуса вектора v1(points[0],points[1]) и v2(points[0],points[2]) не должны быть параллельны или перпендикулярны друг другу. \n + Последняя точка определяет высоту блока, клина, плиты, вершину пирамиды. + \en A point set. \n + points[0] determines a local coordinate system origin. \n + For a sphere, a torus, a cylinder or a cone: \n + points[1] determines the direction of Z-axis of a local coordinate system. \n + points[2] determines the direction of X-axis of a local coordinate system. \n + For a block, a plate or a wedge: \n + points[1] determines the direction of X-axis of a local coordinate system. \n + points[2] determines the direction of Y-axis of a local coordinate system. \n + Also, \n + points[1] determines the height of a cylinder or a cone, + the major radius of a torus, the length of a block or a wedge. \n + points[2] determines the radius of a cylinder, cone angle as angle between vectors v1(points[0],points[1]) and v2(points[0],points[2]), + radius of a sphere, the minor radius of a torus, the width of a block or a wedge. \n + In the case of the cone of the vector v1(points [0], points [1]) and v2(points [0], points [2]) must not be parallel or perpendicular to each other. \n + The last point determines the height of a block, a wedge or a plate, the vertex of a pyramid. \~ + \param[in] solidType - \ru Тип создаваемого тела. + \en The solid type. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ElementarySolid( const SArray & points, + ElementaryShellType solidType, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по поверхности. + \en Create a solid from a surface. \~ + \details \ru Создать тело по элементарной поверхности. \n + Допускается только тип поверхности - цилиндр, конус, сфера, тор. + \en Create a solid from an elementary surface. \n + The only acceptable surface types are cylinder, cone, sphere, torus. \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ElementarySolid( const MbSurface & surface, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело на основе полигональной модели. + \en Create a solid on the basis of a polygonal geometric object. \~ + \details \ru Создать тело #MbSolid на основе полигональной модели #MbMesh. \n + \en Create a solid #MbSolid on the basis of a polygonal geometric object #MbMesh. \n \~ + \param[in] mesh - \ru Полигональная модель. + \en The polygonal geometric object. \~ + \param[in] params - \ru Параметры операции. + \en Operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) MeshSolid( const MbMesh & mesh, + const GridsToShellValues & params, + const MbSNameMaker & names, + MbSolid *& result, + IProgressIndicator * prog = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело на основе триангуляции. + \en Create a solid on the basis of a triangulation. \~ + \details \ru Создать тело #MbSolid на основе триангуляции #MbGrid. \n + \en Create a solid #MbSolid on the basis of a triangulation #MbGrid. \n \~ + \param[in] grid - \ru Полигональная модель. + \en The polygonal geometric object. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) GridSolid( const MbGrid & grid, + const MbSNameMaker & names, + MbSolid *& result, + IProgressIndicator * prog = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело на основе коллекции элементов. + \en Create a solid on the basis of elements. \~ + \details \ru Создать тело #MbSolid на основе коллекции элементов #MbCollection. \n + \en Create a solid #MbSolid on the basis of elements #MbCollection. \n \~ + \param[in] grid - \ru Коллекция элементов. + \en The elements collection. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CollectionSolid( const MbCollection & grid, + const MbSNameMaker & names, + MbSolid *& result, + IProgressIndicator * progBar = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело c заданной оболочкой. + \en Create a solid with a given shell. \~ + \details \ru Создать тело без истории построения с заданной оболочкой. \n + \en Create a solid with a given shell without a history. \n \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \return \ru Возвращает тело без истории. + \en Returns a solid without the history. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbSolid *) CreateSolid( MbFaceShell & shell, + const MbSNameMaker & names ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать глубину выдавливания или угол вращения. + \en Compute the extrusion depth or the rotation angle. \~ + \details \ru Рассчитать value - глубину выдавливания или угол вращения (0.0 : M_PI2) + для последующего построения тела путем выдавливания или вращения образующей кривой. \n + \en Compute 'value' - the extrusion depth or the rotation angle (0.0 : M_PI2) + for the further construction of a solid by extrusion or revolution of the generating curve. \n \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] rotation - \ru Вращение или выдавливание. + \en Rotation or extrusion. \~ + \param[in] operationDirection - \ru Вперед\назад. + \en Forward or backward direction. \~ + \param[in] point - \ru Точка, до которой требуется вращать или выдавливать поверхность. + \en The point to rotate or extrude the surface up to. \~ + \param[out] value - \ru Глубина выдавливания или угол вращения. + \en The extrusion depth or the rotation angle. \~ + \return \ru Возвращает true, если расчет выполнен успешно. + \en Returns true if the value has been successfully calculated. \~ + \warning \ru Вспомогательная функция операций ExtrusionSolid, RevolutionSolid, ExtrusionResult и RevolutionResult. + \en An auxiliary function of operations ExtrusionSolid, RevolutionSolid, ExtrusionResult and RevolutionResult. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (bool) GetSweptValue( const MbSweptData & sweptData, + const MbAxis3D & axis, + const MbVector3D & direction, + const bool rotation, + const bool operationDirection, + const MbCartPoint3D & point, + double & value ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить начальное приближение для нахождения образа при вращении/выдавливании. + \en Get the initial approximation for image calculation while rotating/extruding. \~ + \details \ru Вычислить положение образа точки образующей кривой на поверхности для последующего + построения тела путем выдавливания или вращения образующей кривой до заданной поверхности. \n + \en Compute the position of a generating curve point image on a surface for further + solid construction by extrusion or revolution of the generating curve up to the specified surface. \n \~ + \param[in] generatrix - \ru Кривая. + \en The curve. \~ + \param[in] surface - \ru Поверхность, до которой строим операцию. + \en The surface to construct up to. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] rotation - \ru Вращение (true) или выдавливание (false) + \en Rotation (true) or extrusion (false) \~ + \param[out] imagePosition - \ru Точка образа на поверхности. + \en The image point on the surface. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \warning \ru Вспомогательная функция операций ExtrusionSolid, RevolutionSolid, ExtrusionResult и RevolutionResult. + \en An auxiliary function of operations ExtrusionSolid, RevolutionSolid, ExtrusionResult and RevolutionResult. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (void) GetSweptImagePosition( const MbCurve3D & generatrix, + const MbSurface & surface, + const MbVector3D & direction, + const MbAxis3D & axis, + const bool rotation, + MbCartPoint & imagePosition, + MbResultType & resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти расстояния/углы от образующей до поверхности при вращении/выдавливании. + \en Calculate the distances/angles from generating curve to the surface while rotating/extruding. \~ + \details \ru Вычислить глубины выдавливания в прямом и обратном направлениях или углы вращения + в прямом и обратном направлениях для последующего построения тела путем выдавливания или вращения + образующей кривой до заданной поверхности, а также и габарит образа кривой. \n + \en Calculate the extrusion depths in forward and backward directions or the rotating angles + in forward and backward directions for further solid construction by extrusion or revolution + of the generating curve up to the specified surface; and also calculate the bounding box of the curve image. \n \~ + \param[in] surface - \ru Поверхность, до которой строим операцию. + \en The surface to construct up to. \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] rotation - \ru Вращение (true) или выдавливание (false). + \en Revolution (true) or extrusion (false). \~ + \param[in] operationDirection - \ru Направление движения: вперед (true) или назад (false). + \en The motion direction: forward (true) or backward (false). \~ + \param[out] imagePosition - \ru Точка на части поверхности, в которой лежит образ. + \en A point on a surface part that contains the image. \~ + \param[out] range - \ru Расстояния до поверхности в обратном и прямом направлениях. + \en The distance to surface in the backward and the forward directions. \~ + \param[out] rectOnSurface - \ru Габарит образа на поверхности. + \en The bounding box of image on the surface. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \warning \ru Вспомогательная функция операций ExtrusionSolid, RevolutionSolid, ExtrusionResult и RevolutionResult. + \en An auxiliary function of operations ExtrusionSolid, RevolutionSolid, ExtrusionResult and RevolutionResult. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (void) GetRangeToSurface( const MbSurface & surface, + const MbCurve3D & curve, + const MbVector3D & direction, + const MbAxis3D & axis, + const bool rotation, + const bool operationDirection, + const MbCartPoint & imagePosition, + double range[2], + MbRect & rectOnSurface, + MbResultType & resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить площадь проекции кривой на виртуальную координатную плоскость. + \en Compute the area of a curve projection onto a virtual coordinate plane. \~ + \details \ru Вычислить площадь проекции кривой на виртуальную координатную плоскость \n + для определения ориентации образующей кривой в оболочке выдавливания и вращения. \n + Параметры direction и axis определяют направление выдавливания и ось вращения, + а параметр rotation определяет тип операции: \n + - выдавливание, вычисляется площадь проекции на плоскость XOY, \n + - вращение, вычисляется площадь "проекции" на "плоскость" ROZ. + Для незамкнутой кривой в расчет добавляется "замыкание отрезком". + \en Compute the area of a curve projection onto a virtual coordinate plane \n + to determine the generating curve orientation in the shell of extrusion and revolution. \n + Parameters 'direction' and 'axis' determine the extrusion direction and the rotation axis, + and parameter 'rotation' determines the operation type: \n + - extrusion, the area of projection onto the plane XOY is computed, \n + - revolution, the area of "projection" to the "plane" ROZ is computed. + For an open curve "enclosure by a segment" is considered. \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] rotation - \ru Вращение (true) или выдавливание (false). + \en Revolution (true) or extrusion (false). \~ + \return \ru Возвращает площадь проекции. + \en Returns the projection area. \~ + \warning \ru Вспомогательная функция операций ExtrusionSolid, RevolutionSolid, ExtrusionResult и RevolutionResult. + \en An auxiliary function of operations ExtrusionSolid, RevolutionSolid, ExtrusionResult and RevolutionResult. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (double) AreaSign( const MbCurve3D & curve, + const MbAxis3D & axis, + const MbVector3D & direction, + bool rotation ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить ориентацию секущей грани относительно тела выдавливания/вращения. + \en Determine the orientation of a cutting surface relative to the extrusion/revolution solid. \~ + \details \ru Определить ориентацию секущей поверхности относительно тела, которое будет строиться + путём выдавливания или вращения образующей кривой до заданной поверхности. \n + \en Determine the orientation of a cutting surface relative to the solid which is to be constructed + by extrusion or revolution the generation curve up to the specified surface. \n \~ + \param[in] cuttingSurface - \ru Поверхность для анализа. + \en A surface to analyze. \~ + \param[in] imagePosition - \ru Место образа на поверхности. + \en An image location on the surface. \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] rotation - \ru Вращение (true) или выдавливание (false). + \en Revolution (true) or extrusion (false). \~ + \param[in] operationDirection - \ru Направление движения: вперед (true) или назад (false). + \en The motion direction: forward (true) or backward (false). \~ + \param[out] relativeSense - \ru Ориентация поверхности по отношению к операции. + \en The surface orientation relative to the operation. \~ + \param[out] resType - \ru Код результата операции. + \en Operation result code. \~ + \warning \ru Вспомогательная функция операций ExtrusionSolid, RevolutionSolid, ExtrusionResult и RevolutionResult. + \en An auxiliary function of operations ExtrusionSolid, RevolutionSolid, ExtrusionResult and RevolutionResult. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (void) AnalyzeSurfaceRelationToSweptOperation( const MbSurface & cuttingSurface, + const MbCartPoint & imagePosition, + const MbCurve3D & curve, + const MbVector3D & direction, + const MbAxis3D & axis, + const bool rotation, + bool operationDirection, + bool & relativeSense, + MbResultType& resType ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти сегменты контура на поверхности, соответствующие швам и полюсам. + \en Find contour segments corresponding to the seams and poles. \~ + \details \ru Найти сегменты контура на поверхности, соответствующие швам и полюсам. \n + \en Find contour segments corresponding to the seams and poles. \n \~ + \param[in] surface - \ru Поверхность. + \en Surface. \~ + \param[in] contour - \ru Контур. + \en Contour. \~ + \param[out] seamsAndPoles - \ru Номера сегментов, соответствующих швам и полюсам. + \en Segment numbers corresponding to the seams and poles. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (void) FindPolesAndSeamsInContour( const MbSurface & surface, + const MbContour & contour, + c3d::IndicesVector & seamsAndPoles ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело выдавливания. + \en Create an extrusion solid. \~ + \details \ru Создать тело выдавливания. \n + solid1 и solid2 используются с опцией "До ближайших граней" этих тел. \n + \en Create an extrusion solid. \n + solid1 and solid2 are used with option "Up to the closest faces" of these solids. \n \~ + \param[in] sweptData - \ru Данные об образующей кривой. + \en The generating curve data. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] solid1 - \ru До ближайших граней этого тела в прямом направлении. + \en Up to the closest faces of this solid in the forward direction. \~ + \param[in] solid2 - \ru До ближайших граней этого тела в обратном направлении. + \en Up to the closest faces of this solid in the backward direction. \~ + \param[in] checkIntersection - \ru Объединять тела solid1 и solid2 с проверкой пересечения. + \en Whether to union the solids solid1 and solid2 with the check for intersections. \~ + \param[in, out] params - \ru Параметры выдавливания. + Возвращают информацию для построения элементов массива операций до поверхности. + \en The extrusion parameters. + Returns the information for construction of the up-to-surface operation array elements. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователи сегментов образующего контура. + \en An objects defining a names of the generating contour segments. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtrusionSolid( const MbSweptData & sweptData, + const MbVector3D & direction, + const MbSolid * solid1, + const MbSolid * solid2, + bool checkIntersection, + const ExtrusionValues & params, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело вращения. + \en Create a solid of revolution. \~ + \details \ru Создать тело вращения по данным об образующей. \n + \en Create a solid of revolution by the generating curve data. \n \~ + \param[in] sweptData - \ru Данные об образующей кривой. + \en The generating curve data. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in, out] params - \ru Параметры вращения. + Возвращают информацию для построения элементов массива операций до поверхности. + \en The revolution parameters. + Returns the information for construction of the up-to-surface operation array elements. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователи сегментов образующего контура. + \en An objects defining a names of the generating contour segments. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RevolutionSolid( const MbSweptData & sweptData, + const MbAxis3D & axis, + const RevolutionValues & params, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическое тело. + \en Create a sweeping solid. \~ + \details \ru Создать кинематическое тело путем движения образующей кривой вдоль направляющей кривой. \n + \en Create a sweeping solid by moving the generating curve along the guide curve. \n \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров образующей. + \en An object defining the names of generating curve contours. \~ + \param[in] spineNames - \ru Именователь направляющей. + \en An object defining the name of a guide curve. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) EvolutionSolid( const MbSweptData & sweptData, + const MbCurve3D & spine, + const EvolutionValues & params, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическое тело. + \en Create a sweeping solid. \~ + \details \ru Создать кинематическое тело путем движения образующей кривой вдоль направляющей кривой c дополнительной информацией. \n + \en Create a sweeping solid by moving the generating curve along the guide curve with additional data. \n \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] spine - \ru Направляющая кривая c дополнительной информацией. + \en The spine curve with additional data. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров образующей. + \en An object defining the names of generating curve contours. \~ + \param[in] spineNames - \ru Именователь направляющей. + \en An object defining the name of a guide curve. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) EvolutionSolid( const MbSweptData & sweptData, + const MbSpine & spine, + const EvolutionValues & params, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по плоским сечениям. + \en Create a solid from a planar sections. \~ + \details \ru Создать тело по плоским сечениям c направляющей линией. \n + \en Create a solid from a planar sections with a guide curve. \n \~ + \param[in] pl - \ru Множество систем координат образующих контуров. + \en An array of generating contours coordinate systems. \~ + \param[in] c - \ru Множество образующих контуров. + \en An array of generating contours. \~ + \param[in] spine - \ru Направляющая кривая (может быть NULL). + \en A guide curve (can be NULL). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] ps - \ru Множество точек на образующих контурах, задающий их начальные точки. + \en A point array on the generating contours which determines the start points of the contours. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] ns - \ru Именователи образующих контуров. + \en The objects defining the names of generating contours. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedSolid( SArray & pl, + RPArray & c, + const MbCurve3D * spine, + const LoftedValues & params, + SArray * ps, + const MbSNameMaker & names, + RPArray & ns, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по пространственным сечениям. + \en Create a solid from a space sections. \~ + \details \ru Создать тело по пространственным сечениям c направляющей линией. \n + \en Create a solid from a space sections with a guide curve. \n \~ + \param[in] pl - \ru Множество систем координат образующих контуров. + \en An array of generating contours coordinate systems. \~ + \param[in] c - \ru Множество образующих контуров. + \en An array of generating contours. \~ + \param[in] spine - \ru Осевая кривая (может быть NULL). + \en A guide curve (can be NULL). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] guideCurves - \ru Множество направляющих кривых, задающих траектории соответствующих точек контуров. + \en An array of the guide curves that determines the trajectories of the corresponding points of the contours. \~ + \param[in] ps - \ru Множество точек на образующих контурах, задающее соответствующие точки (цепочки точек). + \en A point array on the generating contours which determines the corresponding points of the contours (chains of points). \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] ns - \ru Именователи образующих контуров. + \en The objects defining the names of generating contours. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedSolid( SArray & pl, + RPArray & c, + const MbCurve3D * spine, // осевая линия может быть NULL + const LoftedValues & params, + RPArray * guideCurves, + SArray * ps, + const MbSNameMaker & names, + RPArray & ns, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по пространственным сечениям. + \en Create a solid from a space sections. \~ + \details \ru Создать тело по пространственным сечениям c направляющей линией. \n + \en Create a solid from a space sections with a guide curve. \n \~ + \param[in] surfs - \ru Множество поверхностей образующих контуров. + \en An array of surfaces of generating contours. \~ + \param[in] c - \ru Множество образующих контуров. + \en An array of generating contours. \~ + \param[in] spine - \ru Осевая кривая (может быть NULL). + \en A guide curve (can be NULL). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] guideCurves - \ru Множество направляющих кривых, задающих траектории соответствующих точек контуров. + \en An array of the guide curves that determines the trajectories of the corresponding points of the contours. \~ + \param[in] ps - \ru Множество точек на образующих контурах, задающее соответствующие точки (цепочки точек). + \en A point array on the generating contours which determines the corresponding points of the contours (chains of points). \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] ns - \ru Именователи образующих контуров. + \en The objects defining the names of generating contours. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedSolid( RPArray & surfs, + RPArray & c, + const MbCurve3D * spine, // осевая линия может быть NULL + const LoftedValues & params, + RPArray * guideCurves, + SArray * ps, + const MbSNameMaker & names, + RPArray & ns, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело выдавливания и выполнить булеву операцию. + \en Create an extrusion solid and perform a boolean operation. \~ + \details \ru Создать тело выдавливания и выполнить булеву операцию типа oType с телом solid. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. + \en Create an extrusion solid and perform a boolean operation of type 'oType' with solid 'solid'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \~ + \param[in] solid - \ru Первое тело для булевой операции. + \en The first solid for a boolean operation. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] sweptData - \ru Данные об образующих кривых. + \en The generating curve data. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in, out] params - \ru Параметры выдавливания. + Возвращают информацию для построения элементов массива операций до поверхности. + \en The extrusion parameters. + Returns the information for construction of the up-to-surface operation array elements. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователи образующих кривых. + \en The objects defining the names of generating lines. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtrusionResult( MbSolid & solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbVector3D & direction, + const ExtrusionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело вращения и выполнить булеву операцию. + \en Create a revolution solid and perform a boolean operation. \~ + \details \ru Создать тело вращения и выполнить булеву операцию типа oType с телом solid. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. + \en Create a revolution solid and perform a boolean operation of type oType with solid 'solid'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \~ + \param[in] solid - \ru Первое тело для булевой операции. + \en The first solid for a boolean operation. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] sweptData - \ru Данные об образующих кривых. + \en The generating curve data. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in, out] params - \ru Параметры вращения. + Возвращают информацию для построения элементов массива операций до поверхности. + \en The revolution parameters. + Returns the information for construction of the up-to-surface operation array elements. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователи образующих кривых. + \en The objects defining the names of generating lines. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RevolutionResult( MbSolid & solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbAxis3D & axis, + const RevolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сориентировать образующий контур и направляющую кинематики. + \en Determine the orientation for a generating contour and for a guide curve of kinematics (evolution). \~ + \details \ru Выполнить ориентацию образующего контура и направляющей кривой для построения кинематического тела. \n + \en Orientate the generating contour and the guide curve for a sweeping solid construction. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] contours - \ru Образующие контуры. + \en Generating contours. \~ + \param[in] guide - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[out] axis - \ru Ось доворота образующей. + \en The axis for the generating curve additional turn. \~ + \param[out] angle - \ru Угол доворота образующей. + \en The additional turn for generating line. \~ + \param[in] version - \ru Версия операции. + \en The version of the operation. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \warning \ru Вспомогательная функция операций EvolutionSolid и EvolutionResult. + \en An auxiliary function of operations EvolutionSolid and EvolutionResult. \~ + \ingroup Shell_Modeling +*/ +// --- +MATH_FUNC (MbResultType) EvolutionNormalize( const MbSurface & surface, + const RPArray & contours, + const MbCurve3D & guide, + const EvolutionValues & parameters, + MbAxis3D & axis, + double & angle, + VERSION version ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать усеченную замкнутую кривую на копии кривой. + \en Create a trimmed closed curve on a curve copy. \~ + \details \ru Выполнить построение копии замкнутой кривой с началом в точке, определяемой параметром t. \n + \en Create a copy of a closed curve starting at a point with parameter t. \n \~ + \param[in] curve - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] t - \ru Параметр кривой. + \en A curve parameter. \~ + \return \ru При удачной работе функция возвращает построенную копию кривой + с началом в заданной точке, в противном случае функция возвращает ноль. + \en Returns a constructed curve copy starting at the specified point if it has been successfully created, + otherwise it returns null. \~ + \warning \ru Вспомогательная функция операций EvolutionSolid и EvolutionResult. + \en An auxiliary function of operations EvolutionSolid and EvolutionResult. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCurve3D *) TrimClosedSpine( const MbCurve3D & curve, + double t ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическое тело и выполнить булеву операцию. + \en Create an evolution solid and perform a boolean operation. \~ + \details \ru Создать кинематическое тело и выполнить булеву операцию типа oType с телом solid. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. + \en Create an evolution solid and perform a boolean operation of type oType with solid 'solid'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \~ + \param[in] solid - \ru Первое тело для булевой операции. + \en The first solid for a boolean operation. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] contoursNames - \ru Именователь контуров образующей. + \en An object defining the names of generating curve contours. \~ + \param[in] spineNames - \ru Именователь направляющей. + \en An object defining the name of a guide curve. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC(MbResultType) EvolutionResult( MbSolid & solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbCurve3D & spine, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по плоским сечениям и выполнить булеву операцию. + \en Create a solid from the planar sections and perform a boolean operation. \~ + \details \ru Создать тело по плоским сечениям и выполнить булеву операцию типа oType с телом solid. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. + \en Create a solid from a planar sections and perform a boolean operation of type oType with solid 'solid'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \~ + \param[in] solid - \ru Первое тело для булевой операции. + \en The first solid for a boolean operation. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] pl - \ru Множество систем координат образующих контуров. + \en An array of generating contours coordinate systems. \~ + \param[in] c - \ru Множество образующих контуров. + \en An array of generating contours. \~ + \param[in] spine - \ru Направляющая кривая (может быть NULL). + \en A guide curve (can be NULL). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] ps - \ru Множество точек на образующих контурах, задающий их начальные точки. + \en A point array on the generating contours which determines the start points of the contours. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] ns - \ru Именователи образующих контуров. + \en The objects defining the names of generating contours. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC(MbResultType) LoftedResult( MbSolid & solid, + MbeCopyMode sameShell, + SArray & pl, + RPArray & c, + const MbCurve3D * spine, + const LoftedValues & params, + OperationType oType, + SArray * ps, + const MbSNameMaker & names, + RPArray & ns, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по пространственным сечениям и выполнить булеву операцию. + \en Create a solid from the space sections and perform a boolean operation. \~ + \details \ru Создать тело по пространственным сечениям и выполнить булеву операцию типа oType с телом solid. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. + \en Create a solid from a space sections and perform a boolean operation of type oType with solid 'solid'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \~ + \param[in] solid - \ru Первое тело для булевой операции. + \en The first solid for a boolean operation. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] surfs - \ru Множество поверхностей контуров. + \en An array of generating contours surfaces. \~ + \param[in] c - \ru Множество образующих контуров. + \en An array of generating contours. \~ + \param[in] spine - \ru Осевая кривая (может быть NULL). + \en A guide curve (can be NULL). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] guideCurves - \ru Массив направляющих кривых. + \en An array of the guide curves. \~ + \param[in] ps - \ru Множество точек на образующих контурах, задающий их начальные точки. + \en A point array on the generating contours which determines the start points of the contours. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] ns - \ru Именователи образующих контуров. + \en The objects defining the names of generating contours. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC(MbResultType) LoftedResult( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & surfs, + RPArray & c, + const MbCurve3D * spine, + const LoftedValues & params, + OperationType oType, + RPArray * guideCurves, + SArray * ps, + const MbSNameMaker & names, + RPArray & ns, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выполнить булеву операцию. + \en Perform a Boolean operation. \~ + \details \ru Функция выполняет указанную булеву операцию над двумя телами с возможностью управления слиянием граней и рёбер.\n + \en The function performs the specified Boolean operation on two solids with faces and edges merging control.\n \~ + \param[in] solid1 - \ru Набор граней первого тела. + \en The set of faces of the first solid. \~ + \param[in] sameShell1 - \ru Способ копирования граней первого тела. + \en Method of copying the faces of the first solid. \~ + \param[in] solid2 - \ru Набор граней второго тела. + \en The second solid face set. \~ + \param[in] sameShell2 - \ru Способ копирования граней второго тела. + \en Method of copying the faces of the second solid. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] flags - \ru Управляющие флаги булевой операции. + \en Control flags of the Boolean operation. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] result - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BooleanResult( MbSolid & solid1, + MbeCopyMode sameShell1, + MbSolid & solid2, + MbeCopyMode sameShell2, + OperationType oType, + const MbBooleanFlags & flags, + const MbSNameMaker & operNames, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело путем булевой операции. + \en Create a solid using a boolean operation. \~ + \details \ru Создать тело путем булевой операции типа oType для тел solid1 и solid2. + Принимаемые значения OperationType для тел: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. \n + Функция работает только с замкнутыми телами, сливает подобные грани и рёбра. + Функция выполняет одноимённую булеву операцию над множествами точек, + расположенными внутри и на поверхности тел. + \en Create a solid by applying a boolean operation of type oType to solids 'solid1' and 'solid2'. + The possible values of 'OperationType' for solids: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \n + The function accepts only closed solids, similar faces and similar edges will be merged. + The function performs a boolean operation of the same name with a point sets + located inside the solids and on their boundary. \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] sameShell1 - \ru Режим копирования первого тела. + \en Whether to copy the first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] sameShell2 - \ru Режим копирования второго тела. + \en Whether to copy the second solid. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BooleanSolid( MbSolid & solid1, + MbeCopyMode sameShell1, + MbSolid & solid2, + MbeCopyMode sameShell2, + OperationType oType, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело путем булевой операции. + \en Create a solid using a boolean operation. \~ + \details \ru Создать тело путем булевой операции типа oType для оболочек solid1 и solid2. + Один из операндов solid1 или solid2 - незамкнутая оболочка. + Принимаемые значения OperationType для оболочек: \n + bo_Variety - объединение, \n + bo_Internal - пересечение, \n + bo_External - вычитание. + \en Create a solid applying a boolean operation of type oType to shells 'solid1' and solid2'. + One of the operands 'solid1' and 'solid2' should be an open shell. + Possible values of 'OperationType' for a shells are: \n + bo_Variety - a union, \n + bo_Internal - an intersection, \n + bo_External - a subtraction. \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] sameShell1 - \ru Режим копирования первого тела. + \en Whether to copy the first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] sameShell2 - \ru Режим копирования второго тела. + \en Whether to copy the second solid. \~ + \param[in] oType - \ru Тип булевой операции. + \en A boolean operation type. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BooleanShell( MbSolid & solid1, + MbeCopyMode sameShell1, + MbSolid & solid2, + MbeCopyMode sameShell2, + OperationType oType, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезать часть тела поверхностью. + \en Cut a part of a solid off by a surface. \~ + \details \ru Отрезать часть тела пересекающей его поверхностью. \n + part = 1 - оставляем часть тела, расположенную сверху поверхности. \n + part = -1 - оставляем часть тела, расположенную снизу поверхности. \n + \en Cut a part of a solid off by a surface that intersects the solid. \n + part = 1 - a part of solid above the surface is to be retained. \n + part = -1 - a part of solid below the surface is to be retained. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the source solid. \~ + \param[in] surface - \ru Секущая поверхность. + \en A cutting plane. \~ + \param[in] retainedPart - \ru Направление отсечения. + \en The direction of cutting off. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] closed - \ru Флаг режима отсечения: true - сечем как тело, false - сечем как оболочку. + \en The flag of the cutting off mode: true - cut as a solid, false - cut as a shell. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SolidCutting( MbSolid & solid, + MbeCopyMode sameShell, + const MbSurface & surface, + int retainedPart, + const MbSNameMaker & names, + bool closed, + const MbMergingFlags & flags, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезать часть тела выдавленным плоским контуром. + \en Cut a part of a solid off with an extruded planar contour. \~ + \details \ru Отрезать часть тела оболочкой, полученной выдавливанием плоского контура. \n + part = 1 - оставляем часть тела, расположенную сверху поверхности выдавливания. \n + part = -1 - оставляем часть тела, расположенную снизу поверхности выдавливания. \n + \en Cut a part of a solid by a shell of planar contour extrusion. \n + part = 1 - a part of solid above the extrusion surface is to be retained. \n + part = -1 - a part of solid below the extrusion surface is to be retained. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Образующий контур. + \en The generating contour. \~ + \param[in] direction - \ru Направление выдавливания образующего контура. + \en An extrusion direction of the generating contour. \~ + \param[in] retainedPart - \ru Направление отсечения. + \en The direction of cutting off. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] closed - \ru Флаг режим отсечения: true - сечем как тело, false - сечем как оболочку. + \en The cutting off mode flag: true - cut as a solid, false - cut as a shell. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SolidCutting( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + const MbVector3D & direction, + int retainedPart, + const MbSNameMaker & names, + bool closed, + const MbMergingFlags & flags, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрезать тело поверхностью. + \en Cut a solid off by a surface. \~ + \details \ru Разрезать тело поверхностью с построением всех отрезанных частей. \n + \en Cut a solid off by a surface, keep all parts of the solid. \n + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. При sameShell != cm_Copy построенные тела нельзя перемещать относительно друг друга. + \en Whether to copy the source solid. Built bodies can not move relative to each other when sameShell != Vm_Copy. \~ + \param[in] surface - \ru Секущая поверхность. + \en A cutting plane. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] closed - \ru Флаг режима отсечения: true - сечем как тело, false - сечем как оболочку. + \en The flag of the cutting off mode: true - cut as a solid, false - cut as a shell. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] result - \ru Построенные тела. + \en The resultant solids. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +DEPRECATE_DECLARE +MATH_FUNC (MbResultType) SolidCutting( MbSolid & solid, + MbeCopyMode sameShell, + const MbSurface & surface, + const MbSNameMaker & names, + bool closed, + const MbMergingFlags & flags, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрезать тело выдавленным плоским контуром. + \en Cut a solid off with an extruded planar contour. \~ + \details \ru Разрезать тело оболочкой, полученной выдавливанием плоского контура, с построением всех отрезанных частей. \n + \en Cut a solid by a shell of planar contour extrusion, keep all parts of the solid. \n + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. При sameShell != cm_Copy построенные тела нельзя перемещать относительно друг друга. + \en Whether to copy the source solid. Built bodies can not move relative to each other when sameShell != Vm_Copy. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Образующий контур. + \en The generating contour. \~ + \param[in] direction - \ru Направление выдавливания образующего контура. + \en An extrusion direction of the generating contour. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] closed - \ru Флаг режим отсечения: true - сечем как тело, false - сечем как оболочку. + \en The cutting off mode flag: true - cut as a solid, false - cut as a shell. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] result - \ru Построенные тела. + \en The resultant solids. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +DEPRECATE_DECLARE +MATH_FUNC (MbResultType) SolidCutting( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + const MbVector3D & direction, + const MbSNameMaker & names, + bool closed, + const MbMergingFlags & flags, + RPArray & result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрезать тело на части. + \en Cut a solid into parts. \~ + \details \ru Разрезать тело на части. \n + \en Cut a solid into parts. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования исходного тела. + \en The mode of copying of the source solid. \~ + \param[in] cuttingParams - \ru Параметры операции. + \en Operation parameters. \~ + \param[out] results - \ru Построенные тела. + \en The resultant solids. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SolidCutting( MbSolid & solid, + MbeCopyMode sameShell, + const MbShellCuttingParams & cuttingParams, + RPArray & results ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать симметричное тело относительно плоскости. + \en Create a symmetric solid relative to a plane. \~ + \details \ru Создать симметричное тело относительно плоскости XY локальной системы координат. \n + Функция создаёт симметричное тело с заданной плоскостью симметрии следующим образом. + Исходное тело режется плоскостью XY локальной системы координат, берётся часть исходного тела, + расположенная сверху режущей плоскости, строится зеркальная копия выбранной части исходного тела + и объединяется с выбранной частью исходного тела. \n + \en Crate a symmetric solid relative to XY-plane of a local coordinate system. \n + The function creates a symmetric solid with the specified plane of symmetry in the following way. + The source solid is cut off by the plane XY of the local coordinate system; a part of the source solid above the cutting plane + is retained. A mirror copy of the chosen part is created + and then is united with the chosen part of the source solid. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования оболочки. + \en Whether to copy the shell. \~ + \param[in] place - \ru Система координат плоскости симметрии. + \en The symmetry plane coordinate system. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SymmetrySolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать зеркальную копию тела относительно плоскости. + \en Create a mirror copy of a solid relative to a plane. \~ + \details \ru Создать зеркальную копию тела относительно плоскости XY локальной системы координат. \n + \en Create a mirror copy of a solid relative to the XY-plane of a local coordinate system. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] place - \ru Система координат плоскости симметрии. + \en The symmetry plane coordinate system. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) MirrorSolid( const MbSolid & solid, + const MbPlacement3D & place, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело с ребром жёсткости. + \en Create a solid with a rib. \~ + \details \ru Создать тело с ребром жёсткости. \n + По заданному контуру функция строит ребро жёсткости и объединяет его с исходным телом. + Сегмент контура с указанным номером устанавливает вектор уклона. \n + \en Create a solid with a rib. \n + The function creates a rib from a given contour and unites it with the source solid. + The segment of the contour with the given number determines the slope vector. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Формообразующий контур на плоскости XY системы координат place. + \en The generating contour on XY-plane of coordinate system 'place'. \~ + \param[in] index - \ru Номер сегмента в контуре. + \en The segment number in the contour. \~ + \param[in] pars - \ru Параметры ребра жёсткости. + \en Parameters of a rib. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RibSolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + RibValues & pars, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать отдельное ребро жёсткости. + \en Create a separate rib. \~ + \details \ru Создать отдельное ребро жёсткости для исходного тела без приклеивания. \n + \en Create a separate rib for source solid without gluing. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] place - \ru Система координат образующего контура. + \en The generating contour coordinate system. \~ + \param[in] contour - \ru Образующий контур. + \en The generating contour. \~ + \param[in] index - \ru Номер сегмента в контуре. + \en The segment number in the contour. \~ + \param[in] pars - \ru Параметры ребра жёсткости. + \en Parameters of a rib. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RibElement( const MbSolid & solid, + const MbPlacement3D & place, + MbContour & contour, + size_t index, + RibValues & pars, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скруглить ребра постоянным радиусом. + \en Fillet edges with a constant radius. \~ + \details \ru Скруглить указанные рёбра тела постоянным радиусом. \n + Функция выполняет замену указанных рёбер исходного тела гранями, + гладко сопрягающими смежные грани указанных рёбер. В поперечном сечении + сопрягающие грани могут иметь форму дуги окружности, эллипса, гиперболы, параболы. \n + \en Fillet the specified edges of the solid with a constant radius. \n + The function performs the replacement of the specified edges of the source solid by faces + smoothly connecting the adjacent faces of the specified edges. The cross-section + of the connecting faces can be of the form of a circle, an ellipse, a hyperbola or a parabola. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] initCurves - \ru Множество скругляемых ребер тела. + \en A set of edges of the solid to fillet. \~ + \param[in] initBounds - \ru Множество граней для обрезки торцов. + \en A set of faces for trimming of the butt-ends. \~ + \param[in] params - \ru Параметры скругления рёбер. + \en Parameters of edges fillet. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FilletSolid( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & initCurves, + RPArray & initBounds, + const SmoothValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скруглить ребра переменным радиусом. + \en Fillet edges with a variable radius. \~ + \details \ru Скруглить указанные ребра тела переменным радиусом, задаваемым MbEdgeFunction.function. \n + Функция выполняет замену указанных рёбер исходного тела гранями, + гладко сопрягающими смежные грани указанных рёбер. В поперечном сечении + сопрягающие грани могут иметь форму дуги окружности, эллипса, гиперболы, параболы. + Параметры поперечного сечения могут изменяться по заданному закону. \n + \en Fillet the given edges of the solid with a variable radius specified by MbEdgeFunction.function. \n + The function performs the replacement of the specified edges of the source solid by faces + smoothly connecting the adjacent faces of the specified edges. The cross-section + of the connecting faces can be of the form of a circle, an ellipse, a hyperbola or a parabola. + The parameters of the cross-section can vary by the specified law. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] initCurves - \ru Множество скругляемых ребер тела с функциями изменения радиуса. + \en An array of edges of the solid to fillet together with the radius laws. \~ + \param[in] initBounds - \ru Множество граней для обрезки торцов. + \en A set of faces for trimming of the butt-ends. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FilletSolid( MbSolid & solid, + MbeCopyMode sameShell, + SArray & initCurves, + RPArray & initBounds, + const SmoothValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скруглить вершины и примыкающие к ней рёбра постоянным радиусом. + \en Create fillets on vertices and the edges adjacent to these vertices with a constant radius. \~ + \details \ru Скруглить вершины и примыкающие к ней рёбра тела постоянным радиусом. \n + В вершинах должно стыковаться три ребра. + Функция выполняет замену указанных вершин и рёбер исходного тела гранями, + гладко сопрягающими смежные грани указанных вершин и рёбер. В поперечном сечении + сопрягающие грани могут иметь форму дуги окружности, эллипса, гиперболы, параболы. \n + \en Create fillets on vertices and the edges of the solid adjacent to these vertices with a constant radius. \n + Three edges must be incident to each vertex. + The functions performs replacement of the specified vertices and edges of the source solid by faces of the solid + smoothly connecting the faces adjacent to the specified vertices and edges. The cross-section + of the connecting faces can be of the form of a circle, an ellipse, a hyperbola or a parabola. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] initCurves - \ru Множество скругляемых ребер тела. + \en A set of edges of the solid to fillet. \~ + \param[in] initBounds - \ru Множество граней для обрезки торцев. + \en A set of faces for trimming of the butt-ends. \~ + \param[in] initVertices - \ru Множество скругляемых вершин. + \en A set of vertices to fillet. \~ + \param[in] params - \ru Параметры скругления рёбер. + \en Parameters of edges fillet. \~ + \param[in] cornerData - \ru Параметры скругления вершин. + \en Parameters of vertices fillet. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FilletSolid( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & initCurves, + RPArray & initBounds, + RPArray & initVertices, + const SmoothValues & params, + const CornerValues & cornerData, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Скруглить цепочку граней тела. + \en Create a fillet of faces of the solid. \~ + \details \ru Скруглить указанные грани тела. \n + Функция выполняет замену указанных граней исходного тела гранями, + гладко сопрягающими грани, связанные с указанными гранью. + В поперечном сечении сопрягающие грани имеют форму + дуги окружности, касающейся трёх граней исходного тела. \n + \en Create a fillet on the specified faces of the solid. \n + The function performs replacement of the specified faces of the source solid with faces + smoothly connecting the faces adjacent to the specified faces. + The cross-section of the connecting faces has a form of + a circle arc tangent to three faces of the source solid. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] initFaces - \ru Набор граней для скругления. + \en A set of faces to fillet. \~ + \param[in] initFacesLeft - \ru Набор ограничивающих слева граней. + \en A set of left bounding faces. \~ + \param[in] initFacesRight - \ru Набор ограничивающих справа граней. + \en A set of right bounding faces. \~ + \param[in] params - \ru Параметры скругления. + \en Parameters of fillet. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FullFilletSolid( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & initFaces, + const RPArray & initFacesLeft, + const RPArray & initFacesRight, + const FullFilletValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фаски ребер тела. + \en Create chamfers for edges of the solid. \~ + \details \ru Построить фаски указанных ребер тела. \n + Функция выполняет замену указанных рёбер исходного тела гранями фасок. \n + \en Create chamfers for the specified edges of the solid. \n + The function performs replacement of the specified edges of the source solid with faces of chamfers. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] initCurves - \ru Множество скругляемых ребер тела. + \en An array of edges to create chamfer on. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ChamferSolid( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & initCurves, + const SmoothValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантное тело. + \en Create а equidistant solid. \~ + \details \ru Создать эквидистантное тело или оболочку. \n + \en Create an offset solid by equidistant faces or create an equidistant shell. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] offset - \ru Расстояние смещения граней. + \en The equidistant parameter. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetSolid( MbSolid & solid, + MbeCopyMode sameShell, + double offset, + const MbSNameMaker & names, + MbSolid *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тонкостенное тело исключением граней. + \en Create a thin-walled solid by exclusion of faces. \~ + \details \ru Создать тонкостенное тело исключением граней outFaces \n + и приданием одинаковой толщины оставшимся граням \n + или создание незамкнутой оболочки. \n + \en Create a thin-walled solid by exclusion of faces outFaces \n + and supplying the rest of faces with the same thickness \n + or create an open shell. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] outFaces - \ru Вскрываемые грани тела. + \en Faces of the solid to open. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ThinSolid( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & outFaces, + SweptValues & params, + const MbSNameMaker & names, + bool copyFaceAttrs, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тонкостенное тело исключением граней. + \en Create a thin-walled solid by exclusion of faces. \~ + \details \ru Создать тонкостенное тело исключением граней outFaces \n + и приданием различной толщины оставшимся граням \n + или создание незамкнутой оболочки. \n + \en Create a thin-walled solid by exclusion of faces outFaces \n + and supplying the rest of faces with different thickness \n + or create an open shell. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] outFaces - \ru Вскрываемые грани тела. + \en Faces of the solid to open. \~ + \param[in] offFaces - \ru Множество граней, для которых заданы индивидуальные значения толщин. + \en An array of faces for which the individual values of thickness are specified. \~ + \param[in] offDists - \ru Множество индивидуальных значений толщин (должен быть синхронизирован с массивом offFaces). + \en An array of individual values of thickness (must be synchronized with the array 'offFaces'). \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling + \warning \ru Операция ПОЛНОЦЕННО НЕ РЕАЛИЗОВАНА! + \en The operation is NOT COMPLETELY IMPLEMENTED! \~ +*/ +// --- +MATH_FUNC (MbResultType) ThinSolid( MbSolid & solid, + MbeCopyMode sameShell, + RPArray & outFaces, + RPArray & offFaces, + SArray & offDists, + SweptValues & params, + const MbSNameMaker & names, + bool copyFaceAttrs, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выполнить разбиение граней оболочки. + \en Perform splitting of a shell faces. \~ + \details \ru Выполнить разбиение граней оболочки поверхностями выдавливания контуров. \n + Функция создаёт копию тела и разбивает указанные грани поверхностями выдавливания контуров. \n + \en Perform splitting of a shell faces with surfaces of the contours extrusion. \n + The function creates a copy of a solid and splits the specified faces with surfaces of the contours extrusion. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] spPlace - \ru Система координат контуров. + \en The coordinate system of the contours. \~ + \param[in] spType - \ru Направление вытягивания. + \en The extrusion direction. \~ + \param[in] spContours - \ru Контура разбиения. + \en The contours of splitting. \~ + \param[in] spSame - \ru Использовать оригиналы или копии кривых. + \en Whether to use the originals or copies of curves. \~ + \param[in] selFaces - \ru Выбранные грани входного тела. + \en The chosen faces of the input solid. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplitSolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & spPlace, + MbeSenseValue spType, + const RPArray & spContours, + bool spSame, + RPArray & selFaces, + const MbMergingFlags & flags, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выполнить разбиение граней оболочки. + \en Perform splitting of a shell faces. \~ + \details \ru Выполнить разбиение граней оболочки пространственными кривыми, поверхностями и оболочками. \n + Функция создаёт копию тела и разбивает указанные грани пространственными кривыми, поверхностями и оболочками. \n + Пространственные элементы разбиения не должны иметь полных или частичных наложений, а также - самопересечений. \n + \en Perform splitting of the shell faces with space curves, surfaces and shells. \n + The function creates a copy of the solid and splits the specified faces with space curves, surfaces and shells. \n + The spatial elements of a splitting must not have complete or partial overlaps, and also self-intersections. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] spItems - \ru Пространственные элементы разбиения. + \en A spatial elements of splitting. \~ + \param[in] spSame - \ru Использовать оригиналы или копии кривых. + \en Whether to use the originals or copies of curves. \~ + \param[in] selFaces - \ru Выбранные грани входного тела. + \en The chosen faces of the input solid. \~ + \param[in] flags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplitSolid( MbSolid & solid, + MbeCopyMode sameShell, + const RPArray & spItems, + bool spSame, + RPArray & selFaces, + const MbMergingFlags & flags, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Уклонить указанные грани тела. + \en Slope the specified faces of the solid. \~ + \details \ru Уклонить указанные грани тела от нейтральной изоплоскости на заданный угол. \n + \en Slope the specified faces of the solid at the specified angle relative to the neutral isoplane. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования входного тела. + \en Whether to copy the input solid. \~ + \param[in] neutralPlace - \ru Нейтральная плоскость. + \en The neutral plane. \~ + \param[in] angle - \ru Угол уклона. + \en The slope angle. \~ + \param[in] faces - \ru Уклоняемые грани во входном теле. + \en The faces of input solid to be sloped. \~ + \param[in] fp - \ru Признак захвата граней, гладко стыкующихся с уклоняемыми гранями. + \en Whether to capture the faces smoothly connected with the faces being sloped. \~ + \param[in] reverse - \ru Флаг обратного направления уклона. + \en Whether to slope in the reverse direction. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) DraftSolid( MbSolid & solid, + MbeCopyMode sameShell, + const MbPlacement3D & neutralPlace, + double angle, + const RPArray & faces, + MbeFacePropagation fp, + bool reverse, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выполнить объединение пересекающихся тел. + \en Perform the union of intersecting solids. \~ + \details \ru Выполнить объединение пересекающихся тел и булеву операцию oType с телом solid, если оно не нулевое: \n + bo_Union - объединение, \n + bo_Intersect - пересечение, \n + bo_Difference - вычитание. \n + Если флаг проверки пересечения checkIntersect == true, то выполняется проверка на пересечение тел + и булева операция объединения пересекающихся тел заданного множества в одно тело. В противном случае + объединение тел заданного множества выполняется простым перекладыванием граней всех тел в одно новое тело. \n + Если флаг регулярности множества тел isArray == true, то тела множества расположены в узлах + прямоугольной или круговой сетки и позиции тел заданы в именах граней. \n + \en Perform the union of intersecting solids and a boolean operation oType with solid 'solid' if it is not null: \n + bo_Union - union, \n + bo_Intersect - intersection, \n + bo_Difference - subtraction. \n + If the flag of intersection check checkIntersect == true, check for solids intersection is performed + and the boolean operation of union the intersection solids of the specified set into one solid is performed. Otherwise + the union of solids from the given set is performed by simple moving the faces of all the solids into a new solid. \n + If the flag of solid set regularity isArray == true, the solids are located at the nodes + of rectangular or circular grid and positions of solids are specified in the names of faces. \n \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] solids - \ru Множество тел. + \en An array of solids. \~ + \param[in] sameShells - \ru Режим копирования тел. + \en Whether to copy the solids. \~ + \param[in] oType - \ru Тип булевой операции между телом и массивом тел. + \en The type of the boolean operation for the solid and the set of solids. \~ + \param[in] checkIntersect - \ru Проверять пересечение тел. + \en Whether to check the solids intersection. \~ + \param[in] mergeFaces - \ru Сливать подобные грани. + \en \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isArray - \ru Флаг регулярности множества тел. + \en A flag of solid set regularity. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \param[out] notGluedSolids - \ru Множество тел, которые не получилось приклеить. + \en An array of solids which was not glued. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) UnionResult( MbSolid * solid, + MbeCopyMode sameShell, + RPArray & solids, + MbeCopyMode sameShells, + OperationType oType, + bool checkIntersect, + bool mergeFaces, + const MbSNameMaker & names, + bool isArray, + MbSolid *& result, + RPArray * notGluedSolids = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать одно тело из присланных тел. + \en Create a solid from the specified solids. \~ + \details \ru Создать тело с объединением или без объединения пересекающихся тел. \n + Если флаг проверки пересечения checkIntersect == true, то выполняется проверка на пересечение тел + и булева операция объединения пересекающихся тел заданного множества в одно тело. В противном случае + объединение тел заданного множества выполняется простым перекладыванием граней всех тел в одно новое тело. \n + Если флаг регулярности множества тел isArray == true, то тела множества расположены в узлах + прямоугольной или круговой сетки и позиции тел заданы в именах граней. \n + \en Create a solid with or without union of the intersecting solids. \n + If the flag of intersection check checkIntersect == true, check for solids intersection is performed + and the boolean operation of union the intersection solids of the specified set into one solid is performed. Otherwise + the union of solids from the given set is performed by simple moving the faces of all the solids into a new solid. \n + If the flag of solid set regularity isArray == true, the solids are located at the nodes + of rectangular or circular grid and positions of solids are specified in the names of faces. \n \~ + \param[in] solids - \ru Множество тел. + \en An array of solids. \~ + \param[in] sameShells - \ru Режим копирования тел. + \en Whether to copy the solids. \~ + \param[in] checkIntersect - \ru Проверять пересечение тел. + \en Whether to check the solids intersection. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isArray - \ru Флаг регулярности множества тел. + \en A flag of solid set regularity. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \param[out] notGluedSolids - \ru Множество тел, которые не получилось приклеить. + \en An array of solids which was not glued. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) UnionSolid( RPArray & solids, + MbeCopyMode sameShells, + bool checkIntersect, + const MbSNameMaker & names, + bool isArray, + MbSolid *& result, + RPArray * notGluedSolids = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать одно тело из присланных тел. + \en Create a solid from the specified solids. \~ + \details \ru Создать одно тело из присланных тел, не меняя их. \n + Объединение тел заданного множества выполняется простым перекладыванием + граней всех тел в одно новое тело. \n + \en Create a solid from the specified solids without the modification of the given solids. \n + The union of solids from the specified set is performed by simple moving + the faces of all the solids into a new solid. \n \~ + \param[in] solids - \ru Множество тел. + \en An array of solids. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) UnionSolid( const RPArray & solids, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить тело на отдельные части. + \en Split the solid into separate parts. \~ + \details \ru Если исходное тело распадается на части, то наибольшая часть остаётся в исходном теле, + а остальные части части будут сложены в присланный контейнер тел. \n + Если флаг сортировки sort == true, то в исходном теле останется часть с наибольшим габаритом, + а отделённые части будут сортированы по убыванию габарита. В противном случае в исходном теле + останется часть, топологически связанная с первой гранью, а отделённые части будут сортированы + по номеру начальной грани в исходном теле. \n + \en If the source solid is decomposed, the greatest part remains in the source solid, + and the other parts are put into the given array of solids. \n + If 'sort' == 'true', the part with the greatest bounding box will remain in the source solid, + and separated parts will be sorted by bounding box size in descending order. Otherwise a part topologically connected with the first face will remain in the source solid + and the separated parts will be sorted + by the number of the initial face in the source solid. \n \~ + \param[in,out] solid - \ru Исходное модифицируемое тело. + \en The source solid to be modified. \~ + \param[out] parts - \ru Отделённые части тела. + \en The separated parts of the solid. \~ + \param[in] sort - \ru Сортировать по убыванию габарита. + \en Whether to sort by the bounding box size in descending order. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \return \ru Возвращает количество отделенных частей. + \en Returns the number of the separated parts. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (size_t) DetachParts( MbSolid & solid, + RPArray & parts, + bool sort, + const MbSNameMaker & names ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить тело на отдельные части. + \en Split the solid into separate parts. \~ + \details \ru Если исходное тело распадается на части, то все его части будут сложены в присланный контейнер тел. \n + Исходное тело остаётся неизменённым. \n + \en If the source solid is decomposed, all the parts of the solid will be put into the given array of solids. \n + The source solid remains unchanged. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[out] parts - \ru Части тела. + \en The parts of the solid. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \return \ru Возвращает количество созданных частей. + \en Returns the number of created parts. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (size_t) CreateParts( const MbSolid & solid, + RPArray & parts, + const MbSNameMaker & names ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку тела по поверхности и толщине. + \en Create a shell of the solid from a surface and a thickness. \~ + \details \ru Выполнить построение тела путём придания толщины заданной поверхности. \n + \en Create a solid by supplying the surface with a thickness. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] faceSense - \ru Ориентация нормали поверхности. + \en The surface normal orientation. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] name - \ru Основное простое имя. + \en The main simple name. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ThinSolid( const MbSurface & surface, + bool faceSense, + SweptValues & params, + const MbSNameMaker & names, + SimpleName name, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздать отверстие, карман, фигурный паз в теле. + \en Create a hole, a pocket, a groove in the solid. \~ + \details \ru Cоздать отверстие, карман, фигурный паз в теле или создать cверло, бобышку, если solid==NULL. \n + \en Create a hole, a pocket, a groove in the solid or create a drill, a boss if 'solid' == NULL. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Режим копирования тела. + \en Whether to copy the solid. \~ + \param[in] place - \ru Местная система координат для операции. + \en A local coordinate system for the operation. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) HoleSolid( MbSolid * solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const HoleValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выделить в отдельное тело указанную часть распадающегося на части тела. + \en Extract the specified part of decomposing solid to a separate solid. \~ + \details \ru Создать тело, из указанной части тела, распадающегося на части. + Исходное тело должно состоять из отдельных частей. \n + \en Create a solid from the specified part of decomposing solid. + The source solid should consist of separate parts. \n \~ + \param[in] solid - \ru Разделяемое на части тело. + \en A decomposing solid. \~ + \param[in] id - \ru Номер выбранной части тела + \en The number of selected part of the solid. \~ + \param[in] path - \ru Идентификатор для выбранной части. + \en An identifier for the selected part. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in,out] partIndices - \ru Индексы частей тела. + \en Indices of the parts of the solid. \~ + \param[out] result - \ru Построенная оболочка (тело). + \en The resultant shell (solid). \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ShellPart( const MbSolid & solid, + size_t id, + const MbPath & path, + const MbSNameMaker & names, + MbPartSolidIndices & partIndices, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Размножить тело. + \en Duplicate the solid. \~ + \details \ru Размножить тело согласно параметрам и объединить копии в одно тело.\n + \en Duplicate the solid by the parameters and unite copies in one solid. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] params - \ru Параметры размножения. + \en The parameters of duplication. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] result - \ru Результирующее тело. + \en The result solid. \~ + \return \ru Возвращает код результата операции. + \en . \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) DuplicationSolid( const MbSolid & solid, + const DuplicationValues & params, + const MbSNameMaker & names, + MbSolid *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздать одно тело слиток из присланных объектов. + \en Create an ingot solid from the specified objects. \~ + \details \ru Cоздать одно тело слиток из присланных объектов. \n + Среди присланных объектов используются тела, вставки тел и сборки тел, из которых строится одно тело, + которое по внешности совпадает с присланными телами и служит их упрощенным заменителем по внешним параметрам. \n + \en Create an ingot solid from the specified solids without the modification of the given solids. \n + Among the objects sent using the body, insert bodies and assembling bodies of which is built the same body, + which in appearance coincides with the bodies had been sent and serves as a substitute for their simplistic external parameters. \n \~ + \param[in] solids - \ru Множество тел. + \en An array of solids. \~ + \param[in] names - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] makeCopy - \ru Флаг копирования тел перед использованием: true - копировать, false - не копировать. + \en The flag of the copying solid before using: true - copy solid, false - not copy. \~ + \param[out] result - \ru Построенное тело. + \en The resultant solid. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IngotSolid( RPArray & solids, + bool makeCopy, + const MbSNameMaker & names, + MbSolid *& result ); + + +#endif // __ACTION_SOLID_H diff --git a/C3d/Include/action_surface.h b/C3d/Include/action_surface.h new file mode 100644 index 0000000..f8b285c --- /dev/null +++ b/C3d/Include/action_surface.h @@ -0,0 +1,798 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения поверхностей. + \en Functions for surfaces creation. \~ + \details \ru Поверхности являются основным элементом описания формы моделируемых объектов. + На базе поверхностей строятся грани, которые используются в твёрдых телах. + \en Surfaces is a basic element of the modeled objects shape description. + Faces are constructed on the basis of surfaces and then are used in solid solids. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_SURFACE_H +#define __ACTION_SURFACE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbGrid; +class MATH_CLASS MbRegion; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать элементарную поверхность. + \en Create an elementary surface. \~ + \details \ru Создать одну из элементарных поверхностей по трем управляющим точкам и типу: \n + surfaceType == st_Plane - плоскость \n + surfaceType == st_ConeSurface - коническая поверхность \n + surfaceType == st_CylinderSurface - цилиндрическая поверхность \n + surfaceType == st_SphereSurface - сферическая поверхность \n + surfaceType == st_TorusSurface - поверхность тора \n + \en Create one of elementary surfaces from three points and a type: \n + surfaceType == st_Plane - a plane \n + surfaceType == st_ConeSurface - a conical surface \n + surfaceType == st_CylinderSurface - a cylindrical surface \n + surfaceType == st_SphereSurface - a spherical surface \n + surfaceType == st_TorusSurface - a torus surface \n \~ + \param[in] point0 - \ru Точка, определяющая начало локальной системы координат поверхности. + \en The origin of the surface local coordinate system. \~ + \param[in] point1 - \ru Точка, определяющая направление оси X локальной системы и радиус поверхности. + \en A point specifying the direction of X-axis of the local system and the surface radius. \~ + \param[in] point2 - \ru Точка, определяющая направление оси Y локальной системы. + \en A point specifying the direction of Y-axis of the local system. \~ + \param[in] surfaceType - \ru Тип поверхности. + \en The surface type. \~ + \param[out] result - \ru Построенная поверхность. + \en The constructed surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ElementarySurface( const MbCartPoint3D & point0, + const MbCartPoint3D & point1, + const MbCartPoint3D & point2, + MbeSpaceType surfaceType, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать плоскую NURBS - поверхность. + \en Create a planar NURBS - surface. \~ + \details \ru Создать плоскую NURBS - поверхность по угловым точкам. \n + \en Create a planar NURBS - surface given the corner points. \n \~ + \param[in] pUMinVMin - \ru Угловая точка поверхности. + \en A corner point of a surface. \~ + \param[in] pUMaxVMin - \ru Угловая точка поверхности. + \en A corner point of a surface. \~ + \param[in] pUMaxVMax - \ru Угловая точка поверхности. + \en A corner point of a surface. \~ + \param[in] pUMinVMax - \ru Угловая точка поверхности. + \en A corner point of a surface. \~ + \param[in] uCount - \ru Количество точек по U. + \en A number of points by U direction. \~ + \param[in] vCount - \ru Количество точек по V. + \en A number of points by V direction. \~ + \param[in] uDegree - \ru Порядок сплайнов по U. + \en Splines degree by U. \~ + \param[in] vDegree - \ru Порядок сплайнов по V. + \en Splines degree by V. \~ + \param[out] result - \ru Cплайновая поверхность. + \en The spline surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplineSurface( const MbCartPoint3D & pUMinVMin, const MbCartPoint3D & pUMaxVMin, + const MbCartPoint3D & pUMaxVMax, const MbCartPoint3D & pUMinVMax, + size_t uCount, size_t vCount, + size_t uDegree, size_t vDegree, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать NURBS - поверхность. + \en Create a NURBS - surface. \~ + \details \ru Создать NURBS - поверхность по массивам точек и весов. \n + контейнер weightList может быть пустым. \n + контейнер uKnotList может быть пустым. \n + контейнер vKnotList может быть пустым. \n + \en Create a NURBS - surface given arrays of points and weights. \n + container 'weightList' can be empty. \n + container 'uKnotList' can be empty. \n + container 'vKnotList' can be empty. \n \~ + \param[in] pointList - \ru Множество точек. + \en An array of points. \~ + \param[in] weightList - \ru Множество весов + \en An array of weights. \~ + \param[in] uCount - \ru Размерность массива точек по U. + \en The size of point array by U. \~ + \param[in] vCount - \ru Размерность массива точек по V. + \en The size of point array by V. \~ + \param[in] uDegree - \ru Порядок сплайнов по U. + \en Splines degree by U. \~ + \param[in] uKnotList - \ru Узловой вектор по U. + \en A knot vector by U. \~ + \param[in] uClosed - \ru Замкнутость по U. + \en Closedness by U. \~ + \param[in] vDegree - \ru Порядок сплайнов по V. + \en Splines degree by V. \~ + \param[in] vKnotList - \ru Узловой вектор по V. + \en A knot vector by V. \~ + \param[in] vClosed - \ru Замкнутость по V. + \en Closedness by V. \~ + \param[out] result - \ru Cплайновая поверхность. + \en The spline surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SplineSurface( const SArray & pointList, + const SArray & weightList, + size_t uCount, size_t vCount, + size_t uDegree, const SArray & uKnotList, bool uClosed, + size_t vDegree, const SArray & vKnotList, bool vClosed, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность выдавливания. + \en Create an extrusion surface. \~ + \details \ru Создать поверхность выдавливания кривой. \n + \en Create a surface of a curve extrusion. \n \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] direction - \ru Вектор выдавливания. + \en An extrusion vector. \~ + \param[in] simplify - \ru Упрощать поверхность, если возможно. + \en Simplify a surface if it's possible. \~ + \param[out] result - \ru Поверхность выдавливания. + \en An extrusion surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtrusionSurface( MbCurve3D & curve, const MbVector3D & direction, + bool simplify, MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность вращения. + \en Create a revolution surface. \~ + \details \ru Создать поверхность вращения кривой. \n + \en Create a curve revolution surface. \n \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] origin - \ru Точка положения оси вращения. + \en The rotation axis origin. \~ + \param[in] axis - \ru Направление оси вращения. + \en The rotation axis direction. \~ + \param[in] angle - \ru Угол вращения. + \en A rotation angle. \~ + \param[in] simplify - \ru Упрощать поверхность, если возможно. + \en Simplify a surface if it's possible. \~ + \param[out] result - \ru Поверхность вращения. + \en The revolution surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RevolutionSurface( MbCurve3D & curve, const MbCartPoint3D & origin, const MbVector3D & axis, double angle, + bool simplify, MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность движения. + \en Create an expansion surface. \~ + \details \ru Создать поверхность движения кривой. \n + \en Create a surface of a curve sweeping. \n \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[out] result - \ru Поверхность движения с доворотами. + \en The expansion surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExpansionSurface( MbCurve3D & curve, MbCurve3D & spine, + MbCurve3D * curve1, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \details \ru Создать кинематическую поверхность по образующей и направляющей. \n + В случае, если spine имеет тип st_ConeSpiral, результатом построения + является спиральная поверхность. \n + \en Create an evolution surface from the generating curve and the guide curve. \n + If 'spine' has type st_ConeSpiral, the result of the construction + is a spiral surface. \n \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[out] result - \ru Кинематическая поверхность или спиральная поверхность. + \en The evolution surface or a spiral surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) EvolutionSurface( MbCurve3D & curve, MbCurve3D & spine, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать спиральную поверхность. + \en Create a spiral surface. \~ + \details \ru Создать спиральную поверхность по образующей и 3 точкам. \n + \en Create a spiral surface from a generating line and three points. \n \~ + \param[in] curve - \ru Образующая кривая спирали. + \en The generating curve of a spiral. \~ + \param[in] p0 - \ru Начало локальной системы координат (ЛСК). + \en The origin of local coordinate system (LCS). \~ + \param[in] p1 - \ru Точка для формирования оси Z ЛСК. + \en A point specifying Z-axis of LCS. \~ + \param[in] p2 - \ru Точка для формирования оси X ЛСК. + \en A point specifying X-axis of LCS. \~ + \param[in] step - \ru Шаг спирали. + \en A pitch. \~ + \param[out] result - \ru Спиральная поверхность. + \en A spiral surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SpiralSurface( MbCurve3D & curve, + const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, + double step, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать секториальную поверхность. + \en Create a sectorial surface. \~ + \details \ru Создать секториальную поверхность по кривой и точке. \n + \en Create a sectorial surface from a curve and a point. \n \~ + \param[in] curve - \ru Образующая кривая. + \en The generating curve. \~ + \param[in] point - \ru Точка. + \en A point. \~ + \param[out] result - \ru Линейчатая поверхность в виде сектора. + \en The ruled surface in a form of a sector. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SectorSurface( MbCurve3D & curve, const MbCartPoint3D & point, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать линейчатую поверхность. + \en Create a ruled surface. \~ + \details \ru Создать линейчатую поверхность по двум кривым. \n + \en Create a ruled surface from two curves. \n \~ + \param[in] curve1 - \ru Первая образующая кривая. + \en The first generating curve. \~ + \param[in] curve2 - \ru Вторая образующая кривая. + \en The second generating curve. \~ + \param[in] simplify - \ru Упрощать поверхность, если возможно. + \en Simplify a surface if it's possible. \~ + \param[out] result - \ru Линейчатая поверхность. + \en The ruled surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) RuledSurface( MbCurve3D & curve1, MbCurve3D & curve2, + bool simplify, MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать треугольную поверхность. + \en Create a triangular surface. \~ + \details \ru Создать треугольную поверхность по трем кривым. \n + \en Create a triangular surface from three curves. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] curve3 - \ru Третья кривая. + \en The third curve. \~ + \param[out] result - \ru Треугольная поверхность по трём кривым. + \en The triangular surface by three curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CornerSurface( MbCurve3D & curve1, + MbCurve3D & curve2, + MbCurve3D & curve3, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать билинейную поверхность. + \en Create a bilinear surface. \~ + \details \ru Создать билинейную поверхность по четырем кривым. \n + \en Create a bilinear surface from four curves. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] curve3 - \ru Третья кривая. + \en The third curve. \~ + \param[in] curve4 - \ru Четвертая кривая. + \en The fourth curve. \~ + \param[out] result - \ru Билинейная поверхность по четырём кривым. + \en The bilinear surface from four curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CoverSurface( MbCurve3D & curve1, + MbCurve3D & curve2, + MbCurve3D & curve3, + MbCurve3D & curve4, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность по семейству кривых. + \en Create a surface by a set of curves. \~ + \details \ru Создать поверхность по семейству кривых. \n + begDirection направление в начале поверхности может быть нулевой длины. \n + endDirection направление в конце поверхности может быть нулевой длины. \n + \en Create a surface by a set of curves. \n + begDirection direction at the begining of the surface can be of zero length. \n + endDirection direction at the end of the surface can be of zero length. \n \~ + \param[in] curveList - \ru Семейство образующих кривых вдоль U-направления. + \en A set of generating curves along U direction. \~ + \param[in] closed - \ru Замкнутость вдоль V-направления. + \en Closedness by V direction. \~ + \param[in] begDirection - \ru Вектор направления в начале поверхности. + \en The vector of direction at the beginning of the surface. \~ + \param[in] endDirection - \ru Вектор направления в конце поверхности. + \en The vector of direction at the end of the surface. \~ + \param[out] result - \ru Поверхность по семейству кривых. + \en The surface from the set of curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedSurface( const RPArray & curveList, bool closed, + const MbVector3D & begDirection, const MbVector3D & endDirection, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность по семейству кривых и направляющей. + \en Create a surface from a set of curves and a spine curve. \~ + \details \ru Создать поверхность по семейству кривых и направляющей. \n + \en Create a surface from a set of curves and a spine curve. \n \~ + \param[in] curveList - \ru Семейство образующих кривых вдоль U-направления. + \en A set of generating curves along U direction. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[out] result - \ru Поверхность по семейству кривых и направляющей. + \en The surface from a set of curves and a spine curve. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) LoftedSurface( const RPArray & curveList, + MbCurve3D & spine, + MbSurface *& result, + bool isSimToEvol = true ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность на сетке кривых. + \en Create a surface constructed by the grid curves. \~ + \details \ru Создать поверхность на сетке кривых по двум семействам кривых. \n + \en Create a surface constructed by the grid curves given two sets of curves. \n \~ + \param[in] uCurveList - \ru Семейство кривых вдоль U-направления. + \en A curve set along U direction. \~ + \param[in] vCurveList - \ru Семейство кривых вдоль V-направления. + \en A curve set along V direction. \~ + \param[out] result - \ru Поверхность на сетке кривых. + \en The surface constructed by the grid curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) MeshSurface( const RPArray & uCurveList, + const RPArray & vCurveList, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную поверхность. + \en Create an offset surface. \~ + \details \ru Создать эквидистантную поверхность к исходной поверхности. \n + \en Create an offset surface to a given surface. \n \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] distance - \ru Величина эквидистанты (знаковая). + \en The offset distance (signed). \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \param[out] result - \ru Эквидистантная поверхность. + \en The offset surface. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetSurface( MbSurface & surface, + double distance, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную поверхность. + \en Create an offset surface. \~ + \details \ru Создать эквидистантную поверхность по исходной поверхности. \n + \en Create an offset surface from the initial surface. \n \~ + \param[in] surface - \ru Базовая поверхность. + \en The base surface. \~ + \param[in] offsetUminVmin - \ru Смещение в точке Umin Vmin базовой поверхности. + \en Offset distance on point Umin Vmin of base surface. \~ + \param[in] offsetUmaxVmin - \ru Смещение в точке Umax Vmin базовой поверхности. + \en Offset distance on point Umax Vmin of base surface. \~ + \param[in] offsetUminVmax - \ru Смещение в точке Umin Vmax базовой поверхности. + \en Offset distance on point Umin Vmax of base surface. \~ + \param[in] offsetUmaxVmax - \ru Смещение в точке Umax Vmax базовой поверхности. + \en Offset distance on point Umax Vmax of base surface. \~ + \param[in] type - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[out] result - \ru Эквидистантная поверхность. + \en The offset surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetSurface( MbSurface & surface, + double offsetUminVmin, + double offsetUmaxVmin, + double offsetUminVmax, + double offsetUmaxVmax, + MbeOffsetType type, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать продленную поверхность. + \en Create an extended surface. \~ + \details \ru Создать продленную поверхность по исходной поверхности. \n + \en Create an extended surface from the initial surface. \n \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] uMin - \ru Минимальное значение по U. + \en The minimal parameter value by U. \~ + \param[in] uMax - \ru Максимальное значение по U. + \en The maximal parameter value by U. \~ + \param[in] vMin - \ru Минимальное значение по V. + \en The minimal parameter value by V. \~ + \param[in] vMax - \ru Максимальное значение по V. + \en The maximal parameter value by V. \~ + \param[out] result - \ru Продлённая поверхность. + \en The extended surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ExtendedSurface( MbSurface & surface, + double uMin, + double uMax, + double vMin, + double vMax, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать деформированную поверхность. + \en Create a deformed surface. \~ + \details \ru Создать деформированную поверхность по исходной поверхности. \n + \en Create a deformed surface from the initial surface. \n \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] uCount - \ru Количество точек по U. + \en A number of points by U direction. \~ + \param[in] vCount - \ru Количество точек по V. + \en A number of points by V direction. \~ + \param[in] uDegree - \ru Порядок сплайнов по U. + \en Splines degree by U. \~ + \param[in] vDegree - \ru Порядок сплайнов по V. + \en Splines degree by V. \~ + \param[in] dist - \ru Величина сдвига вдоль нормали. + \en Shift along the normal. \~ + \param[out] result - \ru Деформированная поверхность. + \en The deformed surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) DeformedSurface( MbSurface & surface, + size_t uCount, size_t vCount, + size_t uDegree, size_t vDegree, + double dist, + MbSurface *& result); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность с заданной границей. + \en Create a surface with the given boundary. \~ + \details \ru Создать поверхность с заданной границей по массиву двумерных кривых. \n + Контейнер boundList может быть пустым. \n + \en Create a surface with the given boundary from an array of two-dimensional curves. \n + Container 'boundList' can be empty. \n \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] boundList - \ru Множество двумерных границ в виде кривых (первая кривая - внешний контур). + \en An array of two-dimensional boundaries in the form of curves (the first curve is an outer contour). \~ + \param[out] result - \ru Поверхность, ограниченная кривыми. + \en The surface bounded by the curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BoundedSurface( MbSurface & surface, + const RPArray & boundList, + MbSurface *& result ); + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность с заданной границей. + \en Create a surface with the given boundary. \~ + \details \ru Создать поверхность с заданной границей по массиву двумерных контуров. \n + \en Create a surface with the given boundary from an array of two-dimensional curves. \n \~ + \param[in] place - \ru Локальная система координат плоскости. + \en The local coordinate system of a plane. \~ + \param[in] region - \ru Множество двумерных границ в виде региона (первая контур - внешний). + \en An array of two-dimensional boundaries in the form of region (the first contour is outer). \~ + \param[out] result - \ru Поверхность, ограниченная кривыми. + \en The surface bounded by the curves. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BoundedSurface( const MbPlacement3D & place, const MbRegion & region, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать NURBS копию поверхности, ограниченную двумерными границами. + \en Create a NURBS surface copy with two-dimensional boundaries. \~ + \details \ru Создать NURBS копию поверхности, ограниченную двумерными границами проецированием пространственных границ \n + (предполагается, что пространственные граничные кривые лежат на поверхности). \n + \en Create a NURBS surface copy with two-dimensional boundaries by projecting of the spatial boundaries \n + (the boundary space curves are considered to belong to the surface) \n \~ + \param[in] surf - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] version - \ru Версия исполнения. + \en The version. \~ + \param[out] resSurface - \ru Сплайновая поверхность (ограниченная кривыми). + \en The spline surface (bounded by the curves). \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) NurbsSurface( const MbSurface & surf, VERSION version, MbSurface *& resSurface ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность симплексного сплайна. + \en Create a simplex spline surface. \~ + \details \ru Создать поверхность симплексного сплайна по массиву вершин. \n + \en Create a simplex spline surface from a point array. \n \~ + \param[in] pList - \ru Множество вершин. + \en An array of points. \~ + \param[out] resSurface - \ru Поверхность симплексного сплайна. + \en The simplex spline surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) SimplexSplineSurface( SArray & pList, MbSurface *& resSurface ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать треугольную поверхность Безье. + \en Create a triangular Bezier surface. \~ + \details \ru Создать треугольную поверхность Безье по 3 точкам. \n + \en Create a triangular Bezier surface from three points. \n \~ + \param[in] k - \ru Порядок поверхности. + \en The surface order. \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point. \~ + \param[in] p3 - \ru Третья точка. + \en The third point. \~ + \param[out] resSurface - \ru Треугольная поверхность Безье. + \en The triangular Bezier surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) TriBezierSurface( ptrdiff_t k, MbCartPoint3D & p1, MbCartPoint3D & p2, MbCartPoint3D & p3, + MbSurface *& resSurface ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать треугольную В-сплайн поверхность. + \en Create a triangular B-spline surface. \~ + \details \ru Создать треугольную В-сплайн поверхность по 3 точкам. \n + \en Create a triangular B-spline surface from three points. \n \~ + \param[in] p0 - \ru Первая точка. + \en The first point. \~ + \param[in] p1 - \ru Вторая точка. + \en The second point. \~ + \param[in] p2 - \ru Третья точка. + \en The third point. \~ + \param[in] d - \ru Порядок поверхности. + \en The surface order. \~ + \param[out] resSurface - \ru Треугольная В-сплайн поверхность. + \en The triangular B-spline surface. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) TriSplineSurface( const MbCartPoint3D & p0, + const MbCartPoint3D & p1, + const MbCartPoint3D & p2, + const MbCartPoint3D & p3, + ptrdiff_t d, ptrdiff_t count, + MbSurface *& resSurface ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить характеристическую ломаную сплайновой поверхности. + \en Create a characteristic polyline of a spline surface. \~ + \details \ru Построить характеристическую ломаную сплайновой поверхности. \n + Функция работает с поверхностями типа st_SplineSurface, st_HermitSurface, + st_TriBezierSurface, st_TriSplineSurface. \n + \en Create a characteristic polyline of a spline surface. \n + The function accepts the surfaces of types st_SplineSurface, st_HermitSurface, + st_TriBezierSurface, st_TriSplineSurface. \n \~ + \param[in] surf - \ru Поверхность. + \en The surface. \~ + \param[out] segments - \ru Сегменты характеристической ломаной. + \en The characteristic polyline. \~ + \result \ru Возвращает true - если характеристическая ломаная получена. + \en Returns true - if the characteristic polyline is obtained. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) GetLineSegmentNURBSSurface( MbSurface & surf, RPArray & segments ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание поверхности на сетке точек. + \en Create a surface from a points grid. \~ + \details \ru Создание поверхности на сетке точек и триангуляции. \n + Множество треугольников должен представлять собой правильную триангуляцию. + \en Create a surface from a points grid and triangulation. \n + The triangles array should form a regular triangulation. \~ + \param[in] grid - \ru Триангуляция. + \en A triangulation. \~ + \param[out] result - \ru Поверхность на сетке точек. + \en The surface on a point set. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) GridSurface( MbGrid & grid, MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать средние плоскости. + \en Create median planes. \~ + \details \ru Создать средние плоскости по двум кривым.\n + \en Create median planes from two curves.\n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] places - \ru Набор систем координат, задающих плоскости. + \en The set of coordinate systems which determine the planes. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \warning \ru В разработке. + \en Under development. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) MiddlePlaces( const MbCurve3D & curve1, + const MbCurve3D & curve2, + std::vector & places ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение поверхности Кунса. + \en Construction of a Coons surface. \~ + \details \ru Построение бикубической поверхности Кунса на четырех кривых и их поперечных производных, касательной к четырём кривым на прверхностях. \n + \en The construction of Coons surface, which will be tangent to four surfaces and coincide with four curves on this surfaces on it sides.\n \~ + \param[in] surfaceCurve0 - \ru Кривая на поверхности 0. + \en The curve on surface0. \~ + \param[in] surfaceCurve1 - \ru Кривая на поверхности 1. + \en The curve on surface1. \~ + \param[in] surfaceCurve2 - \ru Кривая на поверхности 2. + \en The curve on surface2. \~ + \param[in] surfaceCurve3 - \ru Кривая на поверхности 3. + \en The curve on surface3. \~ + \param[out] result - \ru Построенная поверхность. + \en The constructed surface. \~ + \result \ru Возвращает код результата построения. + \en Returns operation result code. \~ + \warning \ru В разработке. + \en Under development. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateCoonsSurface( const MbSurfaceCurve & surfaceCurve0, + const MbSurfaceCurve & surfaceCurve1, + const MbSurfaceCurve & surfaceCurve2, + const MbSurfaceCurve & surfaceCurve3, + MbSurface *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение поверхности-заплатки для заданных рёбер. + \en Construction of a surface-patch by the edges. \~ + \details \ru Построение поверхности-заплатки, гладко стыкующейся с поверхностями ребер. \n + \en Construction of a surface-patch, smoothly joining with the surfaces of the edges. \n \~ + \param[in] edges - \ru Ребра, с которыми требуется стыковать новую поверхность. + \en Edges to join the new surface. \~ + \param[out] result - \ru Построенные поверхности. + \en The constructed surfaces. \~ + \result \ru Возвращает код результата построения. + \en Returns operation result code. \~ + \warning \ru В разработке. + \en Under development. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateSplinePatch( const std::vector & edges, + std::vector & result ); + + +#endif // __ACTION_SURFACE_H diff --git a/C3d/Include/action_surface_curve.h b/C3d/Include/action_surface_curve.h new file mode 100644 index 0000000..d49cfc1 --- /dev/null +++ b/C3d/Include/action_surface_curve.h @@ -0,0 +1,1083 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Методы построения трехмерных кривых. + \en Functions for three-dimensional curves construction. \~ + \details \ru На базе кривых строятся рёбра. Рёбра используются в твёрдотельной и каркасной модели. + Кроме того, кривые используются для построения поверхностей, а также могут служить + вспомогательными элементами модели. + \en Edges are created on the basis of curves. Edges are used in solid and wireframe model. + In addition curves are used for construction of surfaces as well as can be used + as auxiliary elements of a model. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ACTION_SURFACE_CURVE_H +#define __ACTION_SURFACE_CURVE_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCurve; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbContour3D; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbElementarySurface; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbWireFrame; +class MATH_CLASS MbSNameMaker; + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать вершины ломаной. + \en Compute the vertices of a polyline. \~ + \details \ru Рассчитать вершины ломаной point1 и point2, соединяющей точки origin1 и origin2, + сдвинутые в направлениях direction1 и direction2 на расстояния length1 и length2, + которую можно скруглить радиусами radius1 и radius2. \n + \en Compute the vertices 'point1' and 'point2' of a polyline connecting points 'origin1' and 'origin2' + translated in the directions 'direction1' and 'direction2' by distances 'length1' and 'length2' + which can be rounded with radius 'radius1' and 'radius2'. \n \~ + \param[in] origin1 - \ru Первая точка. + \en The first point. \~ + \param[in] direction1 - \ru Направление сдвига первой точки. + \en The direction of the first point translation. \~ + \param[in] length1 - \ru Величина сдвига первой точки. + \en The distance of the first point translation. \~ + \param[in] radius1 - \ru Радиус скругления для первой точки. + \en The rounding radius for the first point. \~ + \param[in] origin2 - \ru Вторая точка. + \en The second point. \~ + \param[in] direction2 - \ru Направления сдвига для второй точки. + \en The direction of the second point translation. \~ + \param[in] length2 - \ru Величина сдвига для второй точки. + \en The distance of the second point translation. \~ + \param[in] radius2 - \ru Радиус скругления для второй точки. + \en The rounding radius for the second point. \~ + \param[out] result1 - \ru Первая точка ломаной. + \en The first point of the polyline. \~ + \param[out] result2 - \ru Вторая точка ломаной. + \en The second point of the polyline. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CalculatePipePoints( const MbCartPoint3D & origin1, + const MbVector3D & direction1, + double length1, double radius1, + const MbCartPoint3D & origin2, + const MbVector3D & direction2, + double length2, double radius2, + MbCartPoint3D & result1, MbCartPoint3D & result2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную кривую. + \en Create an offset curve. \~ + \details \ru Создать эквидистантную кривую по плоской кривой. \n + \en Create an offset curve from a planar curve. \n \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] d - \ru Величина эквидистанты. + \en The offset distance. \~ + \param[out] result - \ru Эквидистантная кривая. + \en The offset curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) OffsetPlaneCurve( const MbCurve3D & curve, + double d, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную кривую. + \en Create an offset curve. \~ + \details \ru Создать эквидистантную кривую по трехмерной кривой и вектору направления. \n + \en Create an offset curve from a three-dimensional curve and a direction vector. \n \~ + \param[in] initCurve - \ru Постранственная кривая, к которой строится эквидистантная. + \en A space curve for which to construct the offset curve. \~ + \param[in] offsetVect - \ru Вектор, задающий смещение в точке кривой. + \en The displacement vector at a point of the curve. \~ + \param[in] useFillet - \ru Если true, то разрывы заполнять скруглением, иначе продолженными кривыми. + \en If 'true', the gaps are to be filled with fillet, otherwise with the extended curves. \~ + \param[in] keepRadius - \ru Если true, то в существующих скруглениях сохранять радиусы. + \en If 'true', the existent fillet radii are to be kept. \~ + \param[in] bluntAngle - \ru Если true, то в притуплять острые углы. + \en If 'true', sharp corners are to be blunt. \~ + \param[in] fromBeg - \ru Вектор смещения привязан к началу. + \en The translation vector is associated with the beginning. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) OffsetCurve( const MbCurve3D & initCurve, + const MbVector3D & offsetVect, + const bool useFillet, + const bool keepRadius, + const bool bluntAngle, + const bool fromBeg, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную кривую. + \en Create an offset curve. \~ + \details \ru Создать эквидистантную кривую по поверхностной кривой и значению смещения. \n + \en Create an offset curve from a curve on a surface and a shift value. \n \~ + \param[in] curve - \ru Кривая на поверхности грани face. + \en A curve on face 'face' surface. \~ + \param[in] face - \ru Грань, на которой строится эквидистанта. + \en The edge on which to build the offset curve. \~ + \param[in] dirAxis - \ru Направление смещения с точкой приложения. + \en The offset direction with a point of application. \~ + \param[in] dist - \ru Величина смещения. + \en The offset distance. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) OffsetCurve( const MbCurve3D & curve, + const MbFace & face, + const MbAxis3D & dirAxis, + double dist, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать проекцию кривой на поверхность. + \en Create a curve projection onto the surface. \~ + \details \ru Создать проекцию кривой curve на поверхность surface (направление проецирования direction может быть NULL). \n + \en Create the projection of a curve onto surface 'surface' (the projection direction 'direction' can be NULL). \n \~ + \param[in] surface - \ru Поверхность для проецирования. + \en The surface to project onto. \~ + \param[in] curve - \ru Проецируемая кривая. + \en The curve to project. \~ + \param[in] direction - \ru Направление проецирования (если не указано то проецирование по нормали). + \en The projection direction (if not specified, the projection along the normal). \~ + \param[in] createExact - \ru Создавать проекционную кривую при необходимости. + \en Create a projection curve if necessary. \~ + \param[in] truncateByBounds - \ru Усекать границами поверхности. + \en Truncate by the surface bounds. \~ + \param[in] version - \ru Версия исполнения. + \en The version. \~ + \param[out] result - \ru Множество кривых на поверхности. + \en An array of curves on the surface. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CurveProjection( const MbSurface & surface, + const MbCurve3D & curve, + MbVector3D * direction, + bool createExact, + bool truncateByBounds, + RPArray & result, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать пространственную кривую по двум плоским проекциям. + \en Create a space curve from two planar projections. \~ + \details \ru Создать пространственную кривую по двум плоским проекциям. \n + \en Create a space curve from two planar projections. \n \~ + \param[in] place1 - \ru Локальная система координат 1. + \en A local coordinate system 1. \~ + \param[in] curve1 - \ru Двумерная кривая 1. + \en A two-dimensional curve 1. \~ + \param[in] place2 - \ru Локальная система координат 2. + \en A local coordinate system 2. \~ + \param[in] curve2 - \ru Двумерная кривая 2. + \en A two-dimensional curve 2. \~ + \param[out] result - \ru Множество трехмерных кривых. + \en The array of three-dimensional curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) CurveByTwoProjections( const MbPlacement3D & place1, + const MbCurve & curve1, + const MbPlacement3D & place2, + const MbCurve & curve2, + RPArray & result, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать проекционную кривую по нормали или по направлению. + \en Create a projection curve from a normal or from a direction. \~ + \details \ru Создать проекционную кривую по нормали или по направлению. \n + Если проекция на конструктивную плоскость (плоскость без границ), + то создать на ее основе грань и прислать, а за ее удалением следит приславший. \n + \en Create a projection curve from a normal or from a direction. \n + If the projection is onto the constructive plane (a plane without bounds), + create a face on the basis of this projection. \n \~ + \param[in] curve - \ru Проецируемая кривая. + \en The curve to project. \~ + \param[in] faces - \ru Связный набор граней. + \en A connected set of faces. \~ + \param[in] dir - \ru Вектор направления (если его нет, проекция по нормали). + \en The direction vector (if it is absent, the normal projection). \~ + \param[in] createExact - \ru Создавать проекционную кривую при необходимости. + \en Create a projection curve if necessary. \~ + \param[in] truncateByBounds - \ru Усечь границами. + \en Truncate by bounds. \~ + \param[in] snMaker - \ru Именователь с версией. + \en An object defining the names with the version. \~ + \param[out] result - \ru Проекционные кривые. + \en The projection curves. \~ + \param[out] resultIndices - \ru Индексы соответствия (номера граней в исходном массиве). + \en The indices of faces in the initial array. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) ProjectionCurve( const MbCurve3D & curve, + const RPArray & faces, + const MbVector3D * dir, + const bool createExact, + const bool truncateByBounds, + const MbSNameMaker & snMaker, + RPArray & result, + SArray * resultIndices ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать проекционный проволочный каркас по нормали или по направлению. + \en Create a projection wireframe from a normal or from a direction. \~ + \details \ru Создать проекционный проволочный каркас по нормали или по направлению. \n + Если проекция на конструктивную плоскость (плоскость без границ), + то создать на ее основе грань и прислать, а за ее удалением следит приславший. \n + \en Create a projection curve from a normal or from a direction. \n + If the projection is onto the constructive plane (a plane without bounds), + create a face on the basis of this projection. \n \~ + \param[in] wireFrame - \ru Проецируемый проволочный каркас. + \en The wireframe to project. \~ + \param[in] sameWireFrame - \ru Использовать тот же экземпляр проволочного каркаса, или создать копию. + \en Flag whether to use the same wireframe or make a copy of it. \~ + \param[in] solid - \ru Тело. + \en Solid. \~ + \param[in] same - \ru Использовать ли тот же экземпляр журнала тела или создать копию. + \en Flag whether to use the same creators of the body or make a copy. \~ + \param[in] faceIndices - \ru Номера граней в первой оболочке. + \en The numbers of faces in the first shell. \~ + \param[in] dir - \ru Вектор направления (если его нет, проекция по нормали). + \en The direction vector (if it is absent, the normal projection). \~ + \param[in] createExact - \ru Создавать проекционную кривую при необходимости. + \en Create a projection curve if necessary. \~ + \param[in] truncateByBounds - \ru Усечь границами. + \en Truncate by bounds. \~ + \param[in] snMaker - \ru Именователь с версией. + \en An object defining the names with the version. \~ + \param[out] resFrame - \ru Результирующий проволочный каркас, в котором в атрибутах ребер лежат имена соответствующих граней. + \en The resulting wireframe, the attributes of the edges contain the names of corresponding faces. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) ProjectionCurve( const MbWireFrame & wireFrame, + const bool sameWireFrame, + const MbSolid & solid, + const bool same, + const SArray & faceIndices, + const MbVector3D * dir, + const bool createExact, + const bool truncateByBounds, + const MbSNameMaker & snMaker, + MbWireFrame *& resFrame ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Устранить наложение сегментов проекционной кривой. + \en Eliminate the projection curve segments overlay. \~ + \details \ru Устранить наложение сегментов проекционной кривой (вспомогательная функция для функции ProjectionCurve). \n + \en Eliminate the projection curve segments overlay (an auxiliary function for function ProjectionCurve). \n \~ + \param[in,out] curves - \ru Множество кривых. + \en An array of curves. \~ + \param[in,out] indices - \ru Множество индексов, синхронный с массивом кривых. + \en An array of indices synchronized with the array of curves. \~ + \return \ru Возвращает true, если что-то изменилось в наборе кривых. + \en Returns true if something has modified in the curve set. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (bool) EliminateProjectionCurveOverlay( RPArray & curves, + SArray * indices ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив линий очерка поверхности. + \en Create an array of isocline curves of the surface. \~ + \details \ru Создать массив линий очерка поверхности с обрезкой по области определения. \n + \en Create an array of isocline curves of the surface with truncation by the definition domain. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] eye - \ru Вектор взгляда. + \en The direction of view. \~ + \param[in] perspective - \ru Является ли проекция перспективной. + \en Whether the projection is perspective. \~ + \param[in] removeOnSurfaceBounds - \ru Удалить линии очерка, совпадающие с границами поверхности. + \en Remove the isocline curves coincident with the surface bounds. \~ + \param[out] result - \ru Выходной массив линий очерка. + \en The output array of isocline curves. \~ + \param[in] version - \ru Версия построения. + \en The version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (MbResultType) SilhouetteCurve( const MbSurface & surface, + const MbVector3D & eye, + bool perspective, + bool removeOnSurfaceBounds, + RPArray & result, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив линий очерка грани. + \en Create an array of isocline curves of the face. \~ + \details \ru Создать массив линий очерка грани с обрезкой по области определения. \n + \en Create an array of isocline curves of the face with truncation by the definition domain. \n \~ + \param[in] face - \ru Грани. + \en The face. \~ + \param[in] eye - \ru Вектор взгляда. + \en The direction of view. \~ + \param[in] perspective - \ru Является ли проекция перспективной. + \en Whether the projection is perspective. \~ + \param[out] result - \ru Выходной массив линий очерка. + \en The output array of isocline curves. \~ + \param[in] version - \ru Версия построения. + \en The version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (MbResultType) SilhouetteCurve( const MbFace & face, + const MbVector3D & eye, + bool perspective, + RPArray & result, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив линий очерка поверхности при вращательном движении вокруг оси. + \en Create an array of isocline curves of the rotated surface. \~ + \details \ru Создать массив линий очерка поверхности с обрезкой по области определения. \n + \en Create an array of isocline curves of the surface with truncation by the definition domain. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] axis - \ru Ось кругового взгляда (ось токарного сечения). + \en The axis of lathe section. \~ + \param[in] removeOnSurfaceBounds - \ru Удалить линии очерка, совпадающие с границами поверхности. + \en Remove the isocline curves coincident with the surface bounds. \~ + \param[out] result - \ru Выходной массив линий очерка. + \en The output array of isocline curves. \~ + \param[in] version - \ru Версия построения. + \en The version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (MbResultType) SilhouetteCurve( const MbSurface & surface, + const MbAxis3D & axis, + bool removeOnSurfaceBounds, + RPArray & curves, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать массив линий очерка грани при вращательном движении вокруг оси. + \en Create an array of isocline curves of the rotated face. \~ + \details \ru Создать массив линий очерка грани с обрезкой по области определения. \n + \en Create an array of isocline curves of the face with truncation by the definition domain. \n \~ + \param[in] face - \ru Грани. + \en The face. \~ + \param[in] axis - \ru Ось кругового взгляда (ось токарного сечения). + \en The axis of lathe section. \~ + \param[out] result - \ru Выходной массив линий очерка. + \en The output array of isocline curves. \~ + \param[in] version - \ru Версия построения. + \en The version. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (MbResultType) SilhouetteCurve( const MbFace & face, + const MbAxis3D & axis, + RPArray & curves, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривые пересечения двух поверхностей. + \en Create the intersection curves of two surfaces. \~ + \details \ru Создать кривые пересечения двух поверхностей. Результат - массив кривых пересечения поверхностей. \n + \en Create the intersection curves of two surfaces. The result is an array of intersection curves of surfaces. \n \~ + \param[in] surface1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] surface2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \warning \ru Лучше использовать IntersectionCurve на гранях, т.к. границы поверхностей могут бы неточные, \n + что приведет к неточному положению концов кривых пересечения в результате операции. \n + В гранях же границы поверхности точные, т.к. хранятся в виде кривых пересечения, + а не виде двумерных кривых. \n + \en It is better to use IntersectionCurve on faces since the surfaces bounds can be inexact, \n + and it will result in inexact position of intersection curves ends. \n + But the surface bounds in faces are exact since they are stored in the form of intersection curves, + not in the form of two-dimensional curves. \n \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IntersectionCurve( const MbSurface & surface1, + const MbSurface & surface2, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривые пересечения двух граней. + \en Create intersection curves of two faces. \~ + \details \ru Создать кривые пересечения двух граней. Результат - массив кривых пересечения поверхностей. \n + \en Create intersection curves of two faces. The result is an array of intersection curves of surfaces. \n \~ + \param[in] face1 - \ru Первая грань оболочки. + \en The first face of the shell. \~ + \param[in] face2 - \ru Вторая грани оболочки. + \en The second face of the shell. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IntersectionCurve( MbFace & face1, MbFace & face2, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривые пересечения граней двух оболочек. + \en Create intersection curves of two shells faces. \~ + \details \ru Создать кривые пересечения граней двух оболочек. Результат - массив кривых пересечения поверхностей. \n + \en Create intersection curves of two shells faces. The result is an array of intersection curves of surfaces. \n \~ + \param[in] solid1 - \ru Первая оболочка. + \en The first shell. \~ + \param[in] faceIndices1 - \ru Номера граней в первой оболочке. + \en The numbers of faces in the first shell. \~ + \param[in] solid2 - \ru Вторая оболочка. + \en The second shell. \~ + \param[in] faceIndices2 - \ru Номера граней во второй оболочке. + \en The numbers of faces in the second shell. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IntersectionCurve( const MbSolid & solid1, const SArray & faceIndices1, + const MbSolid & solid2, const SArray & faceIndices2, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривые пересечения граней двух оболочек. + \en Create intersection curves of two shells faces. \~ + \details \ru Создать кривые пересечения граней двух оболочек. Результат - массив кривых пересечения поверхностей. \n + \en Create intersection curves of two shells faces. The result is an array of intersection curves of surfaces. \n \~ + \param[in] solid1 - \ru Первая оболочка. + \en The first shell. \~ + \param[in] faceIndices1 - \ru Номера граней в первой оболочке. + \en The numbers of faces in the first shell. \~ + \param[in] same1 - \ru Использовать ли тот же журнал построителей первого тела или сделать копию. + \en Flag whether to use the same creators of the first body or make a copy. \~ + \param[in] solid2 - \ru Вторая оболочка. + \en The second shell. \~ + \param[in] faceIndices2 - \ru Номера граней во второй оболочке. + \en The numbers of faces in the second shell. \~ + \param[in] same2 - \ru Использовать ли тот же самый журнал построителей второго тела или сделать копию. + \en Flag whether to use the same creators of the second body or make a copy. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IntersectionCurve( const MbSolid & solid1, const SArray & faceIndices1, const bool same1, + const MbSolid & solid2, const SArray & faceIndices2, const bool same2, + const MbSNameMaker & snMaker, MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать линию пересечения поверхностей. + \en Create an intersection curve of surfaces. \~ + \details \ru Создать линию пересечения поверхностей surf1 и surf2 по известным началу и концу линии пересечения. \n + \en Create an intersection curve of surfaces 'surf1' and 'surf2' from the specified start point and end point of the intersection curve. \n \~ + \param[in] surface1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] ext1 - \ru На расширенной первой поверхности. + \en Whether to create on the extended surface. \~ + \param[in] uv1beg - \ru Начальная точка на первой поверхности. + \en The start point on the first surface. \~ + \param[in] uv1end - \ru Конечная точка на первой поверхности. + \en The end point on the first surface. \~ + \param[in] surface2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] ext2 - \ru На расширенной второй поверхности. + \en Whether to create on the extended second surface. \~ + \param[in] uv2beg - \ru Начальная точка на второй поверхности. + \en The start point on the second surface. \~ + \param[in] uv2end - \ru Конечная точка на второй поверхности. + \en The end point on the second surface. \~ + \param[in] dir - \ru Начальное направление создания линии пересечения. + \en The start direction for intersection curve creation. \~ + \param[out] result1 - \ru Двумерная кривая на первой поверхности. + \en The two-dimensional curve on the first surface. \~ + \param[out] result2 - \ru Двумерная кривая на второй поверхности. + \en The two-dimensional curve on the second surface. \~ + \param[out] label - \ru Тип полученной кривой пересечения. + \en The resultant intersection curve type. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) IntersectionCurve( const MbSurface & surface1, bool ext1, + const MbCartPoint & uv1beg, + const MbCartPoint & uv1end, + const MbSurface & surface2, bool ext2, + const MbCartPoint & uv2beg, + const MbCartPoint & uv2end, + const MbVector3D & dir, + MbCurve *& result1, + MbCurve *& result2, + MbeCurveBuildType & label ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать линию пересечения поверхностей. + \en Create an intersection curve of surfaces. \~ + \details \ru Создать линию пересечения поверхностей surf1 и surf2 по известным началу и концу линии пересечения и вспомогательной кривой. \n + \en Create an intersection curve of surfaces 'surf1' and 'surf2' from the specified start point and end point of the intersection curve + and guide curve that approximates the desired curve. \n \~ + \param[in] surface1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] ext1 - \ru На расширенной первой поверхности. + \en Whether to create on the extended surface. \~ + \param[in] uv1beg - \ru Начальная точка на первой поверхности. + \en The start point on the first surface. \~ + \param[in] uv1end - \ru Конечная точка на первой поверхности. + \en The end point on the first surface. \~ + \param[in] surface2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] ext2 - \ru На расширенной второй поверхности. + \en Whether to create on the extended second surface. \~ + \param[in] uv2beg - \ru Начальная точка на второй поверхности. + \en The start point on the second surface. \~ + \param[in] uv2end - \ru Конечная точка на второй поверхности. + \en The end point on the second surface. \~ + \param[in] guideCurve - \ru Направляющая кривая, приближенно описывающая искомую кривую. + \en The guide curve that approximates the desired curve. \~ + \param[in] useRedetermination - \ru Флаг, определяющий нужно ли уточнять шаг построения следующей точки по сравнению с функцией DeviationStep. + \en The flag that determines whether it is necessary to specify the next point build step as compared to the DeviationStep function. \~ + \param[in] checkPoles - \ru Флаг необходимости проверки и корректировки полюсных точек. + \en The flag that determines whether it is necessary to check and correct pole points. \~ + \param[out] result1 - \ru Двумерная кривая на первой поверхности. + \en The two-dimensional curve on the first surface. \~ + \param[out] result2 - \ru Двумерная кривая на второй поверхности. + \en The two-dimensional curve on the second surface. \~ + \param[out] label - \ru Тип полученной кривой пересечения. + \en The resultant intersection curve type. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC( MbResultType ) IntersectionCurve( const MbSurface & surf1, bool ext1, + const MbCartPoint & uv1beg, + const MbCartPoint & uv1end, + const MbSurface & surf2, bool ext2, + const MbCartPoint & uv2beg, + const MbCartPoint & uv2end, + const MbCurve3D * guideCurve, + bool useRedetermination, + bool checkPoles, + MbCurve *& pCurve1, + MbCurve *& pCurve2, + MbeCurveBuildType & label ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать пространственный сплайн через точки и с сопряжениями. + \en Create a spatial spline through points and with the given derivatives. \~ + \details \ru Создать пространственный сплайн через точки и с сопряжениями. \n + Примечания: \n + Если есть сопряжения, то количество сопряжений должно быть равно количеству точек. \n + Отсутствующие сопряжения должны быть представлены нулевыми указателями в массиве \n + \en Create a spatial spline through points and with the given derivatives. \n + Notes: \n + If derivatives are specified, the number of derivatives should be equal to the number of points. \n + Missing derivatives should be represented by null pointers in the array \n \~ + \param[in] points - \ru Точки. + \en Points. \~ + \param[in] paramType - \ru Тип параметризации. + \en The parametrization type. \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline degree. \~ + \param[in] closed - \ru Замкнутость сплайна. + \en The spline closedness. \~ + \param[in] transitions - \ru Заданные сопряжения. + \en The specified derivatives. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) SpaceSplineThrough( const SArray & points, + MbeSplineParamType paramType, + size_t degree, + bool closed, + RPArray< MbPntMatingData > & transitions, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать пространственный сплайн по точкам и с сопряжениями. + \en Create a spatial spline from points and derivatives. \~ + \details \ru Создать пространственный сплайн по точкам и с сопряжениями. \n + \en Create a spatial spline from points and derivatives. \n \~ + \param[in] points - \ru Множество точек. + \en An array of points. \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline degree. \~ + \param[in] closed - \ru Строить замкнутый сплайн. + \en Create a closed spline. \~ + \param[in] weights - \ru Множество весов точек. + \en An array of points weights. \~ + \param[in] knots - \ru Узловой вектор сплайна. + \en A knot vector of the spline. \~ + \param[in] begData - \ru Сопряжение в начале. + \en The start derivative. \~ + \param[in] endData - \ru Сопряжение в конце. + \en The end derivative. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) SpaceSplineBy( const SArray & points, + size_t degree, + bool closed, + const SArray * weights, + const SArray * knots, + MbPntMatingData * begData, + MbPntMatingData * endData, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую на поверхности. + \en Create a curve on a surface. \~ + \details \ru Создать кривую на поверхности. \n + Примечания: \n + 1. Если есть сопряжения, то количество сопряжений должно быть равно количеству точек. \n + Отсутствующие сопряжения должны быть представлены нулевыми указателями в массиве \n + 2. Если сплайн строится через точки, то сопряжения могуть быть заданы произвольно. \n + 2. Если сплайн строится по полюсам и он незамкнут, то сопряжения могут быть только на концах. \n + 3. Если сплайн строится по полюсам и он замкнут, то сопряжения должны отсутствовать. \n + 4. Множество весов должен быть пуст или синхронизирован с массивом точек по количеству + (с опцией throughPoints веса игнорируются). \n + \en Create a curve on a surface. \n + Notes: \n + 1. If derivatives are specified, the number of derivatives should be equal to the number of points. \n + Missing derivatives should be represented by null pointers in the array \n + 2. If the spline is created from points, arbitrary derivatives can be defined. \n + 2. If the spline is created from poles and it is open, only the end derivatives can be specified. \n + 3. If the spline is constructed from poles and it is closed, the derivatives cannot be specified. \n + 4. An array of weights should be empty or synchronized with the point array by size + (with option throughPoints weights are ignored). \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] throughPoints - \ru Провести сплайн через точки. + \en Create a spline through points. \~ + \param[in] paramPnts - \ru Множество параметрических точек. + \en An array of parametric points. \~ + \param[in] paramWts - \ru Множество весов параметрических точек. + \en An array of parametric point weights. \~ + \param[in] paramClosed - \ru Строить замкнутый параметрический сплайн. + \en Create a closed parametric spline. \~ + \param[in] spaceTransitions - \ru Сопряжения в точках. + \en Derivatives in the points. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) SurfaceSpline( const MbSurface & surface, + bool throughPoints, + SArray & paramPnts, + SArray & paramWts, + bool paramClosed, + RPArray< MbPntMatingData > & spaceTransitions, + const MbSNameMaker & snMaker, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать изопараметрическую кривую. + \en Create an isoparametric curve. \~ + \details \ru Создать изопараметрическую кривую на поверхности surface. \n + \en Create an isoparametric curve on surface 'surface'. \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] x - \ru Значение по первому параметру. + \en A value of the first parameter. \~ + \param[in] isU - \ru Первый параметр есть U. + \en Whether the first parameter is U. \~ + \param[in] yRange - \ru Диапазон по второму параметру (если не задан, используются параметрические границы поверхности). + \en A range of the second parameter (if not defined, the parametric bounds of the surface are used). \~ + \param[out] result - \ru Изопараметрическая кривая. + \en The isoparametric curve. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) IsoparametricCurve( const MbSurface & surface, + double x, bool isU, const MbRect1D * yRange, + MbCurve3D *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую - мостик, соединяющую кривые curve1 и curve2. + \en Create a transition curve connecting curves 'curve1' and 'curve2'. \~ + \details \ru Создать кривую - мостик, соединяющую кривые curve1 и curve2 кубическим сплайном Эрмита. \n + \en Create a transition curve connecting curves 'curve1' and 'curve2' by a cubic Hermite spline. \n \~ + \param[in] curve1 - \ru Сопрягаемая кривая 1. + \en A curve 1 to be connected. \~ + \param[in] t1 - \ru Параметр точки на сопрягаемой кривой 1. + \en A point parameter on the curve 1. \~ + \param[in] sense1 - \ru Начало мостика совпадает с направлением кривой curve1 (true). + \en The beginning of the transition curve is equal to the direction of 'curve1' (true). \~ + \param[in] curve2 - \ru Сопрягаемая кривая 2. + \en A curve 2 to be connected. \~ + \param[in] t2 - \ru Параметр точки на сопрягаемой кривой 2. + \en A point parameter on the curve 2. \~ + \param[in] sense2 - \ru Конец мостика совпадает с направлением кривой curve2 (true). + \en The end of the transition curve is equal to the direction of 'curve2' (true). \~ + \param[in] names - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) BridgeCurve( const MbCurve3D & curve1, double t1, bool sense1, + const MbCurve3D & curve2, double t2, bool sense2, + const MbSNameMaker & names, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать составную кривую плавного соединения концов двух кривых. + \en Create a composite curve smoothly connecting two curves ends. \~ + \details \ru Создать составную кривую плавного соединения концов двух кривых. \n + Полученная кривая состоит из трёхмерной дуги радиуса radius1, + отрезка (в определенных случаях отрезок отсутствует), + трёхмерной дуги радиуса radius2. + \en Create a composite curve smoothly connecting two curves ends. \n + The constructed curve consists of a three-dimensional arc of radius 'radius1', + a segment (in specific cases a segment is absent), + a three-dimensional arc of radius 'radius2'. \~ + \param[in] curve1 - \ru Соединяемая кривая 1. + \en A curve 1 to be connected. \~ + \param[in] isBegin1 - \ru Начало соединяемой кривой 1 (true). + \en The beginning of the curve 1 (true). \~ + \param[in] radius1 - \ru Радиус сопряжения у соединяемой кривой 1. + \en The conjugation raidus of curve 1. \~ + \param[in] curve2 - \ru Соединяемая кривая 2. + \en A curve 2 to be connected. \~ + \param[in] isBegin2 - \ru Начало соединяемой кривой 2 (true). + \en The beginning of the curve 2 (true). \~ + \param[in] radius2 - \ru Радиус сопряжения у соединяемой кривой 2. + \en The conjugation raidus of curve 2. \~ + \param[in] names - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) ConnectingCurve( const MbCurve3D & curve1, bool isBegin1, double radius1, + const MbCurve3D & curve2, bool isBegin2, double radius2, + const MbSNameMaker & names, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать соединительную NURBS кривую для кривых curve1 и curve2. + \en Create a connecting NURBS curve for curves 'curve1' and 'curve2'. \~ + \details \ru Создать соединительную NURBS кривую для кривых curve1 и curve2. \n + t1 и t2 - параметры кривых curve1 и curve2, в точках которых начинается и заканчивается соединение.\n + \en Create a connecting NURBS curve for curves 'curve1' and 'curve2'. \n + t1 and t2 are parameters of curves 'curve1' and 'curve2' which correspond to the start point and the end point of the connecting curve.\n \~ + \param[in] curve1 - \ru Соединяемая кривая 1. + \en A curve 1 to be connected. \~ + \param[in] t1 - \ru Параметр точки на кривой 1. + \en A point parameter on curve 1. \~ + \param[in] mating1 - \ru Тип соединения кривой 1. + \en The connection type for curve 1. \~ + \param[in] curve2 - \ru Соединяемая кривая 2. + \en A curve 2 to be connected. \~ + \param[in] t2 - \ru Параметр точки на кривой 2. + \en A point parameter on curve 2. \~ + \param[in] mating2 - \ru Тип соединения кривой 2. + \en The connection type for curve 2. \~ + \param[in] tension1 - \ru Параметр "натяжение" соединительной кривой на стыке с кривой 1 ( 0<= tension1 <=1). + \en The "tension" parameter of the connecting curve at the intersection with the curve 1 (0 <= tension1 <=1). \~ + \param[in] tension2 - \ru Параметр "натяжение" соединительной кривой на стыке с кривой 2( 0<= tension2 <=1). + \en The "tension" parameter of the connecting curve at the intersection with the curve 2 (0 <= tension2 <=1). \~ + \param[in] names - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbResultType) ConnectingSpline( const MbCurve3D & curve1, double t1, MbeMatingType mating1, + const MbCurve3D & curve2, double t2, MbeMatingType mating2, + double tension1, double tension2, + const MbSNameMaker & names, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую для плавного соединения (скругления) кривых. + \en Create a fillet curve for curves. \~ + \details \ru Создать кривую для плавного соединения (скругления) кривых. \n + Для плавного сопряжения кривых curve1 и curve2 строится кривая filletCurve. \n + При входе t1 и t2 - начальные приближения, определяющие сектор построения скругления, + w1 и w2 - не используются. \n + При входе type - тип скругления (обычное или на поверхности). \n + На выходе t1 и t2 - будут равны параметрам касания кривых curve1 и curve2 с кривой filletCurve. \n + На выходе t1 и w1 - определяют параметры сохраняемого участка при обрезке кривой curve1. \n + На выходе t2 и w2 - определяют параметры сохраняемого участка при обрезке кривой curve2. \n + Параметр radius - радиус дуги или цилиндра. \n + Если радиус radius не задан (равен нулю), то он вычисляется из условия, + что начало кривой сопряжения будет находится в точке с параметором t1, + t1 и t2 - параметры кривых curve1 и curve2, в соответствующих точках которых начинается и заканчивается скругление. \n + Параметр sense - прямое или обратное направление кривой скругления. \n + Кривая filletCurve - это кривая сопряжения, дуга (когда surface == NULL) или кривая на поверхности цилиндра surface. \n + Поверхность surface - это цилиндрическая поверхность, на которой строится кривая сопряжения в общем случае. + Поверхность surface нельзя удалять, на этой поверхности построена кривая сопряжения filletCurve, + при удалении filletCurve удалится surface, если не был дополнительно выполнен surface->AddRef(). \n + \en Create a fillet curve for curves. \n + Curve 'filletCurve' is created for smooth connection of curves 'curve1' and 'curve2'. \n + On input t1 and t2 are the initial estimations which determine a sector for fillet construction, + w1 and w2 are not used. \n + On input 'type' is a fillet type (ordinary or on a surface). \n + On output t1 and t2 are the parameters of touching of curves 'curve1' and 'curve2' with curve 'filletCurve'. \n + On output t1 and w1 determines parameters of a part to be kept while trimming curve1. \n + On output t2 and w2 determines parameters of a part to be kept while trimming curve2. \n + Parameter 'radius' is a radius of an arc or a cylinder. \n + If radius 'radius' is not defined (equal to zero), it is computed from the condition + that the fillet curve start is at the point with parameter t1, + t1 and t2 are parameters of curves 'curve1' and 'curve2' which correspond to the start point and the end point of the fillet. \n + Parameter 'sense' determines forward or backward orientation of the fillet curve. \n + Curve filletCurve is a fillet curve, an arc (when 'surface' == NULL) or a curve on a cylindric surface 'surface'. \n + Surface 'surface' is a cylindric surface on which the fillet curve is constructed in general case. + Surface 'surface' must not be deleted since the fillet curve 'filletCurve' is created on this surface; + 'surface' will be deleted while deleting 'filletCurve' if surface->AddRef() was not additionally used. \n \~ + \param[in] curve1 - \ru Соединяемая кривая 1. + \en A curve 1 to be connected. \~ + \param[in/out] t1 - \ru Параметр точки на кривой 1 соединения с кривой соединения. + \en A point parameter on curve 1 of connection with fillet curve. \~ + \param[out] w1 - \ru Параметр края на кривой 1. + \en The parameter of curve 1 end point. \~ + \param[in] curve2 - \ru Соединяемая кривая 2. + \en A curve 2 to be connected. \~ + \param[in/out] t2 - \ru Параметр точки на кривой 2 соединения с кривой соединения. + \en A point parameter on curve 2 of connection with fillet curve. \~ + \param[out] w2 - \ru Параметр края на кривой 2. + \en The parameter of curve 2 end point. \~ + \param[in/out] radius - \ru Радиус дуги или цилиндра. + \en The radius of an arc or a cylinder. \~ + \param[in] sense - \ru Прямое (true) или обратное (false) направление кривой скругления. + \en The forward (true) or the backward (false) direction of the fillet curve. \~ + \param[out] unchanged - \ru Не изменился радиус соединения (true) или изменился (false). + \en The fillet radius has not changed (true) or has changed (false). \~ + \param[in] type - \ru Тип скругления. + \en The fillet type. \~ + \param[in] names - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] surface - \ru Поверхность, на которой базируется соединительная кривая, (может быть NULL). + \en A surface on which the fillet curve is based on (can be NULL). \~ + \param[out] result - \ru Каркас с построенными кривыми. + \en The frame with the constructed curves. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) FilletCurve( const MbCurve3D & curve1, double & t1, double & w1, + const MbCurve3D & curve2, double & t2, double & w2, + double & radius, bool sense, bool & unchanged, + const MbeConnectingType type, + const MbSNameMaker & names, + MbElementarySurface *& surface, + MbWireFrame *& result ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить изменение радиуса при перемещении средней точки кривой скругления. + \en Determine the radius variation while translating the middle point of the fillet curve. \~ + \details \ru Определить изменение радиуса при перемещении средней точки кривой скругления \n + от центра на расстояние len (с учётом знака len). \n + \en Determine the radius variation while translating the middle point of the fillet curve \n + from the centre on distance 'len' (signed). \n \~ + \param[in] filletCurve - \ru Кривая скругления. + \en The fillet curve. \~ + \param[in] radius - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] sense - \ru Направления смещения средней точки кривой скругления. + \en A direction of the middle point of the fillet curve translation. \~ + \param[in] len - \ru Величина смещения средней точки кривой скругления. + \en A value of translation of the fillet curve middle point. \~ + \param[in] curve1 - \ru Первая сопрягаемая кривая. + \en The first curve to fillet. \~ + \param[in] t1 - \ru Параметр начала кривой скругления на первой сопрягаемой кривой. + \en The parameter of fillet curve start point on the first curve. \~ + \param[in] curve2 - \ru Вторая сопрягаемая кривая. + \en The second curve to fillet. \~ + \param[in] t2 - \ru Параметр конца кривой скругления на второй сопрягаемой кривой. + \en The parameter of fillet curve end point on the second curve. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (double) GetFilletRadiusDelta( const MbCurve3D & filletCurve, + double radius, bool sense, double len, + const MbCurve3D & curve1, double t1, + const MbCurve3D & curve2, double t2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить изменение радиуса при перемещении средней точки кривой скругления. + \en Determine the radius variation while translating the middle point of the fillet curve. \~ + \details \ru Определить изменение радиуса при перемещении средней точки кривой скругления \n + от центра на расстояние len (с учётом знака len). \n + \en Determine the radius variation while translating the middle point of the fillet curve \n + from the centre on distance 'len' (signed). \n \~ + \param[in] filletCurve - \ru Кривая скругления. + \en The fillet curve. \~ + \param[in] radius - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] sense - \ru Направления смещения средней точки кривой скругления. + \en A direction of the middle point of the fillet curve translation. \~ + \param[in] len - \ru Величина смещения средней точки кривой скругления. + \en A value of translation of the fillet curve middle point. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (double) GetFilletRadiusDelta( const MbCurve3D & filletCurve, + double radius, bool sense, double len ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую для плавного соединения (скругления) всех кривых контура. + \en Create a curve for fillet of all the curves of a contour. \~ + \details \ru Создать кривую для плавного соединения (скругления) всех кривых контура contour. \n + type - тип скругления (обычное или на поверхности). \n + radiuses - радиусы скругления, i-й радиус соответствует стыку i-го и i+1-го сегмента. \n + Если две кривых в контуре гладко стыкуются, в этом стыке скругление не делается, радиус игнорируется. \n + \en Create a curve for fillet of all the curves of a contour 'contour'. \n + 'type' is a fillet type (ordinary or on a surface). \n + 'radiuses' are the fillet radii, the i-th radius corresponds to the joint of the i-th and the i+1-th segments. \n + If two curves in contours are smoothly connected, the fillet is not created at this joint, the radius is ignored. \n \~ + \param[in] contour - \ru Исходный контур. + \en The initial contour. \~ + \param[in] radiuses - \ru Множество радиусов скругления. + \en An array of fillet radii. \~ + \param[out] result - \ru Контур со скруглениями. Имя сегмента скругления - Hash32SN() имен исходных сегменов. + \en The contour with the fillets. The name of the fillet segment - Hash32SN() of initial segments names. \~ + \param[in] type - \ru Тип выполняемых скруглений. + \en The type of fillets. \~ + \return \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbResultType) CreateContourFillets( const MbContour3D & contour, + SArray & radiuses, + MbCurve3D *& result, + const MbeConnectingType type ); + + +#endif // __ACTION_SURFACE_CURVE_H diff --git a/C3d/Include/alg_base.h b/C3d/Include/alg_base.h new file mode 100644 index 0000000..6f8e9d7 --- /dev/null +++ b/C3d/Include/alg_base.h @@ -0,0 +1,1102 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вспомогательные общие функции. + \en Common auxiliary functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ALG_BASE_H +#define __ALG_BASE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbMatrix3D; + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить угол между прямой и осью 0X. + \en Calculate angle between line and 0X-axis. \~ + \details \ru Прямая задается приращениями dx, dy. Угол лежит в интервале [0, 2*M_PI). + \en Line is set by dx and dy increments. Angle is in range [0, 2*M_PI). \~ + \param[in] dx - \ru Приращение по X. + \en Increment along X. \~ + \param[in] dy - \ru Приращение по Y. + \en Increment along Y. \~ + \return \ru Искомый угол. + \en The required angle. \~ + \ingroup Algorithms_2D +*/ +// --- +inline +double CalcAngle0X( double dx, double dy ) +{ + if ( ::fabs(dx) < NULL_EPSILON && ::fabs(dy) < NULL_EPSILON ) + return 0.0; + + double angle = atan2( dy, dx ); + if ( ::fabs(angle) < DOUBLE_REGION ) + angle = 0.0; + return angle < 0.0 ? M_PI2 + angle : angle; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить угол между прямой и осью 0X. + \en Calculate the angle between a line and 0X-axis. \~ + \details \ru Прямая задается приращениями dx, dy. Угол лежит в интервале [0, 2*M_PI). + \en A line is defined by dx and dy increments. The angle is in range [0, 2*M_PI). \~ + \param[in] dx - \ru Приращение по X. + \en Increment along X. \~ + \param[in] dy - \ru Приращение по Y. + \en Increment along Y. \~ + \return \ru Искомый угол. + \en The required angle. \~ + \ingroup Algorithms_2D +*/ +// --- +inline +long double CalcAngle0X( long double dx, long double dy ) +{ + if ( ::fabsl(dx) < NULL_EPSILON && ::fabsl(dy) < NULL_EPSILON ) + return 0.0; + + long double angle = atan2( dy, dx ); + if ( ::fabsl(angle) < DOUBLE_REGION ) + angle = 0.0; + return angle < 0.0 ? M_PI2 + angle : angle; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить угол между прямой и осью 0X. + \en Calculate the angle between a line and 0X-axis. \~ + \details \ru Прямая задается двумя точками. Угол лежит в интервале [0, 2*M_PI]. + \en Line is defined by two points. The angle is in range [0, 2*M_PI]. \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point \~ + \return \ru Искомый угол. + \en The required angle. \~ + \ingroup Algorithms_2D +*/ +// --- +inline +double CalcAngle0X( const MbCartPoint & p1, const MbCartPoint & p2 ) { + return c3d::CalcAngle0X( p2.x - p1.x, p2.y - p1.y ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Нормализовать угол. + \en Normalize an angle. \~ + \details \ru Исходный угол, если требуется, загоняется в интервал [0, 2*M_PI). + \en Draw the source angle in range [0, 2*M_PI) if necessary. \~ + \param[out] angle - \ru Исходный угол, который требуется нормализовать. + \en The source angle to normalize. \~ + \param[in] angleEpsilon - \ru Погрешность угла. + \en Angular tolerance. \~ + \ingroup Base_Algorithms +*/ +// --- +inline +double & NormalizeAngle( double & angle, double angleEpsilon = Math::AngleEps ) +{ + if ( ::fabs( angle ) < angleEpsilon || ::fabs( angle - M_PI2 ) < angleEpsilon ) + angle = 0.0; + else { + while ( angle > M_PI2 ) angle -= M_PI2; + while ( angle < 0 ) angle += M_PI2; + } + return angle; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Перевести параметр окружности в параметр кривой. + \en Transform a circle angle to the curve parameter. \~ + \param[in] dir - \ru Угол между осью X окружности и осью X системы координат. + \en Angle between X-axes of a circle and of the coordinate system. \~ + \param[in] left - \ru Если true, то левая система координат, иначе - правая. + \en If true, then the coordinate system is left, otherwise it is right. \~ + \param[out] t - \ru Параметр, который требуется преобразовать. + \en Parameter to transform. \~ + \ingroup Algorithms_2D +*/ +// --- +inline +void AngleToParam( double dir, bool left, double & t ) +{ + if ( ::fabs(dir) > EPSILON || left ) + t = left ? M_PI2 - ( t - dir ) : t - dir; + c3d::NormalizeAngle( t ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить угол между двумя векторами. + \en Calculate the angle between two vectors. \~ + \details \ru Шаблонная функция. Применима для любых векторов. + \en Template function. Applicable for any vectors. \~ + \param[in] v1 - \ru Вектор 1. + \en The first vector. \~ + \param[in] v2 - \ru Вектор 2. + \en The second vector. \~ + \return \ru Величину угла. + \en The angle. \~ + \ingroup Base_Algorithms +*/ +// --- +template +double AngleBetweenVectors( const Type & v1, const Type & v2 ) +{ + double dy = v1 | v2; + double dx = v1 * v2; + + if ( ::fabs(dx) < NULL_EPSILON && ::fabs(dy) < NULL_EPSILON ) + return 0; + + double angle = ::atan2( dy, dx ); + if ( ::fabs(angle) < DOUBLE_REGION ) + angle = 0.0; + + return angle; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить минимальный угол между прямыми. + \en Calculate the minimal angle between lines. \~ + \details \ru Прямые задаются следующим образом: l1( centre, p1 ) и l2( centre, p3 ). + \en Lines are specified as follows: l1( centre, p1 ) and l2( centre, p3 ). \~ + \param[in] p1 - \ru Точка прямой 1. + \en A point on the first line. \~ + \param[in] centre - \ru Общая точка двух прямых. + \en The common point of two lines. \~ + \param[in] p3 - \ru Точка прямой 2. + \en A point on the second line. \~ + \return \ru Результат со знаком: \n + "+" - p3 находится слева от вектора ( centre, p1 ); + "-" - p3 находится справа от вектора ( centre, p1 ). + \en Signed result: \n + "+" - p3 lies to the left of vector ( centre, p1 ); + "-" - p3 lies to the right of vector ( centre, p1 ). \~ + \ingroup Algorithms_2D +*/ +// --- +inline +double CalcAngle3Points( const MbCartPoint & p1, const MbCartPoint & centre, const MbCartPoint & p3 ) { + return c3d::AngleBetweenVectors( MbVector( centre, p1 ), MbVector( centre, p3 ) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти параметр в массиве. + \en Find a parameter in the array. \~ + \details \ru Находится индекс заданного параметра в массиве. Входной массив должен быть + отсортирован по возрастанию параметров. Если задать начальное значение индекса + близко к предполагаемому нахождению искомого параметра, поиск будет выполняться быстрее. + Если в массиве нет параметра равного заданному, то найденным будет считаться + первый параметр массива больший заданного. Если в массиве будет 1 элемент, + то он будем считаться равным заданному. + \en Locating the index of a given parameter in the array. Input array is to be + sorted in ascending order. If the initial value of the index is set + to be close to the expected location of the sought parameter, the search will be faster. + If there is no parameter in the array equal to the given one, then + the first parameter in the array greater than the given one will be chosen. If there is only 1 element in the array, + then it will be considered as equal to the given one. \~ + \param[in] arParam - \ru Множество параметров. + \en An array of parameters. \~ + \param[in] t - \ru Значение параметра, которое требуется найти в массиве. + \en The parameter value to be found in the array. \~ + \param[out] id - \ru Индекс найденного параметра в массиве. + \en The index of the parameter found in the array. \~ + \return \ru - true, если в массиве есть элементы, \n иначе false + \en - true, if there are elements in the array, \n otherwise false \~ + \ingroup Base_Algorithms +*/ +// --- +template +inline bool ArFind( const Vector & arParam, double t, ptrdiff_t & id ) +{ + bool bRes = (arParam.size() > 0); + + if ( bRes ) { // \ru Если массив не пуст \en If the array is not empty + ptrdiff_t idLeft, idRight, rangeId; + + if ( id >= 0 && ((size_t)id < arParam.size()) ) { // \ru Если предыдущий индекс нормальный \en If the previous index is normal, + + // \ru Используем эту информацию для оптимизации \en Use this information for optimization + if ( arParam[id] < t ) { // \ru Если значение в таблице строго меньше t \en If value in table strictly less than t + idLeft = id; // \ru Установить левую границу \en Set the left bound + idRight = id + 8; // \ru Установить правую вблизи левой \en Set the right bound close to the left one + rangeId = 8; // \ru Установить диапазон по умолчанию \en Set the default range + + if ( idRight > (ptrdiff_t)arParam.size() ) { // \ru Если правая больше или ровна максимальной \en If the right bound is greater than or equal to the maximum + idRight = arParam.size(); // \ru Установить правую максимальной \en Set the right bound to maximum + rangeId = idRight - idLeft; // \ru Вычислить новый диапазон \en Calculate the new range + } + else { + // \ru Если ближайшая правая не правая \en If the nearest right bound is not right + if ( idRight != (ptrdiff_t)arParam.size() && arParam[idRight] < t ) { + idLeft = idRight; // \ru Установить новую левую \en Set the new left bound + idRight = arParam.size(); // \ru Установить правую равной максимальной \en Set right bound to maximum + rangeId = idRight - idLeft; // \ru Вычислить новый диапазон \en Calculate the new range + } + } + } + else { + idLeft = id - 8; // \ru Установить левую вблизи правой \en Set the left bound close to the right one + idRight = id; // \ru Установить правую \en Set the right bound + rangeId = 8; // \ru Установить диапазон по умолчанию \en Set the default range + + if ( idLeft < 0 ) { // \ru Если локальная левая меньше минимальной \en If the local left bound is less than minimum + idLeft = 0; // \ru Сделать левую минимальной \en Set the left bound to minimum + rangeId = id; // \ru Вычислить новый диапазон \en Calculate the new range + } + else { + if ( arParam[idLeft] >= t ) { // \ru Если локальная левая не левая \en If the local left bound is not the left + idRight = idLeft; // \ru Установить новую правую \en Set new right bound + idLeft = 0; // \ru Установить левую минимальной \en Set the left bound to minimum + rangeId = idLeft; // \ru Вычислить новый диапазон \en Calculate the new range + } + } + } + } + else { + idLeft = 0; // \ru Левая минимальная \en The left bound is minimum + idRight = arParam.size(); // \ru Правая максимальная \en The right bound is maximum + rangeId = arParam.size(); // \ru Выч. новый диапазон \en Calculate the new range + } + + while ( rangeId > 8 ) { // \ru До тех пор пока диапазон больше восьми \en Until the range contains more than eight elements + ptrdiff_t mIndex = ( rangeId / 2 ) + idLeft; // \ru Найти индекс в середине диапазона \en Find the index in the middle of the range + + if ( arParam[mIndex] < t ) // \ru Если t больше серединного параметра \en If t is greater than the middle parameter + idLeft = mIndex; // \ru Установить левую границу \en Set the left bound + else + idRight = mIndex; // \ru Иначе правую \en Otherwise the right one + + rangeId = idRight - idLeft; // \ru Найти новый диапазон \en Find the new range + } + + id = idRight; // \ru Установить индекс \en Set the index + + // \ru Пройти от левой до правой границы \en Pass from the left bound to the right bound + for ( ptrdiff_t i = idLeft; i < idRight; i++ ) { + if ( arParam[i] < t ) // \ru Если текущий параметр меньше искомого \en If the current parameter is less than the required one, + continue; // \ru Продолжить цикл \en Continue the loop + id = i; + break; + } + } + + return bRes; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить отрезок пополам. + \en Split segment by the middle. \~ + \param[in] p1 - \ru Координаты начала отрезка. + \en Coordinates of the segment's start point. \~ + \param[in] p2 - \ru Координаты конца отрезка. + \en Coordinates of the segment's end point. \~ + \return \ru Координаты середины отрезка. + \en Coordinates of the segment's middle point. \~ + \ingroup Algorithms_2D +*/ +// --- +inline +MbCartPoint LineSegDivide( const MbCartPoint & p1, const MbCartPoint & p2 ) { + return MbCartPoint( (p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5 ); +} + + +//------------------------------------------------------------------------------ +/// \ru i по модулю n (циклический вариант). \en I by modulo n (cyclic case). +// --- +inline +ptrdiff_t mod( ptrdiff_t i, ptrdiff_t n ) +{ + ptrdiff_t m = i % n; + return ( m >= 0 ) ? m : m + n; +} + + +//------------------------------------------------------------------------------ +/// \ru Определение знака вещественного числа. \en Determination of the sign of a real number. +// --- +inline int Sign( double a ) { return (a > 0) ? +1 : -1; } + + +//------------------------------------------------------------------------------ +/// \ru Округление вещественного числа. \en Round-off the real number. +// --- +inline int Round( double x ) { return (int)( x + ( (x > 0) ? 0.5 : - 0.5 ) ); } + + +//------------------------------------------------------------------------------ +/// \ru Округление вещественного числа. \en Round-off the real number. +// --- +inline int32 LRound( double x ) { return (int32)( x + ( (x > 0) ? 0.5 : - 0.5 ) ); } + + +//------------------------------------------------------------------------------ +/// \ru Округление вещественного числа с проверкой \en Round-off the real number with validation. +// --- +inline int32 CheckLRound( double x ) { return (x > SYS_MAX_INT32) ? SYS_MAX_INT32 : ((x < SYS_MIN_INT32) ? SYS_MIN_INT32 : LRound(x)); } + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежит ли число в интервале [x1, x2]. + \en Check if the number is in range [x1, x2]. \~ + \details \ru x1 может быть как началом, так и концом интервала, как и x2. + \en x1 can be both the start and the end of the range, just as x2. \~ + \param[in] x1 - \ru Начало или конец исходного интервала. + \en The start or the end of the source range. \~ + \param[in] x2 - \ru Начало или конец исходного интервала. + \en The start or the end of the source range. \~ + \param[in] x - \ru Исходное число, которое надо проверить. + \en The input number which should be checked. \~ + \return \ru true, если x лежит внутри интервала, \n иначе false. + \en True if x lies inside range, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +inline +bool InRange( double x1, double x2, double x ) +{ + if ( x1 > x2 ) + return ( x2 - FLT_EPSILON < x ) && ( x < x1 + FLT_EPSILON ); + + return ( x1 - FLT_EPSILON < x ) && ( x < x2 + FLT_EPSILON ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Находится ли параметр в диапазоне кривой. + \en Check if parameter is in the range of the curve. \~ + \details \ru Диапазон кривой дается областью определения ее параметра [tmin, tmax]. + \en Range of the curve is given by domain of curve parameters [tmin, tmax]. \~ + \param[in] tmin - \ru Минимальное значение параметра. + \en Minimal value of parameter. \~ + \param[in] tmax - \ru Максимальное значение параметра. + \en Maximal value of parameter. \~ + \param[in] t - \ru Исходный параметр + \en Source parameter \~ + \param[in] treg - \ru Точность задания параметра. + \en Accuracy of parameter. \~ + \return \ru true, если t лежит внутри интервала [tmin, tmax], \n иначе false. + \en True if t lies inside the range [tmin, tmax], \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +inline +bool IsParamOn( double tmin, double tmax, double t, double treg ) { + return ( ((tmin - treg) < t) && (t < (tmax + treg)) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежит ли число в диапазоне [0, x1). + \en Check if the number is in range [0, x1). \~ + \details x1 >= 0 + \param[in] x1 - \ru Конец исходного интервала. + \en End of the source range. \~ + \param[in] x - \ru Исходное число, которое надо проверить. + \en The input number which should be checked. \~ + \param[in] eps - \ru Точность. + \en Tolerance. \~ + \return \ru true, если x лежит внутри интервала, \n иначе false. + \en True if x lies inside range, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +inline +bool InRangePlus( double x1, double x, double eps = FLT_EPSILON ) { + return ( - eps < x ) && (x < x1 + eps ); +} + + +//------------------------------------------------------------------------------ +// +/** \brief \ru Нормализован ли массив объектов по возрастанию или убыванию. + \en Whether vector of objects is ascending or descending. \~ + \details \ru Нормализован ли массив объектов по возрастанию или убыванию. \n + \en Whether vector of items are ascending or descending. \n \~ + \param[in] items - \ru Одномерный массив объектов. + \en Vector of objects. \~ + \param[in] isAscending - \ru Проверять на возрастание. + \en Check for ascending. \~ + \param[in] allowEqual - \ru Допускать равенство объектов. + \en Allow for equality of objects. \~ + \return \ru true, если массив объектов отсортировано по возрастанию (убыванию), \n иначе false + \en True if vector is ascending (descending), \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +//--- +template +bool IsMonotonic( const TypeVector & items, bool isAscending, bool allowEqual = false ) +{ + bool isOk = false; + + size_t cnt = items.size(); + + if ( cnt > 1 ) { + isOk = true; + + if ( allowEqual ) { + for ( size_t k = 1; k < cnt; k++ ) { + if ( isAscending && items[k] < items[k-1] ) { + isOk = false; + break; + } + else if ( !isAscending && items[k] > items[k-1] ) { + isOk = false; + break; + } + } + } + else { + for ( size_t k = 1; k < cnt; k++ ) { + if ( isAscending && items[k] <= items[k-1] ) { + isOk = false; + break; + } + else if ( !isAscending && items[k] >= items[k-1] ) { + isOk = false; + break; + } + } + } + } + + return isOk; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежат ли точки на линии. + \en Whether points lie on the line. \~ + \details \ru Лежат ли точки на линии (улучшенный вариант IsPointOnLine). \n + \en Whether points lie on the line (improved variant of IsPointOnLine). \n \~ + \param[in] pnts - \ru Набор точек. + \en Point set. \~ + \param[in] metricEps - \ru Точность проверки. + \en Check accuracy. \~ + \return \ru true, если точки лежат на линии, \n иначе false + \en True if points lie on line, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool ArePointsOnLine( const SArray & pnts, double metricEps = METRIC_EPSILON ) +{ + bool onLine = false; + + size_t cnt = pnts.size(); + double lenEps = std_min( LENGTH_EPSILON, metricEps ); + lenEps = std_max( EXTENT_EQUAL, lenEps ); + + if ( cnt > 2 ) { + const Point & pnt0 = pnts[0]; + + Vector tau( pnt0, pnts[1] ); + double tauLen = tau.Length(); + if ( tauLen <= lenEps ) { + for ( size_t k = 2; k < cnt; k++ ) { + const Point & pntk = pnts[k]; + tau.Init( pnt0, pntk ); + tauLen = tau.Length(); + if ( tauLen > lenEps ) + break; + } + } + if ( tauLen > lenEps ) { + onLine = true; + tau /= tauLen; + Vector vect; + Point pnt; + for ( size_t k = 1; k < cnt; k++ ) { + const Point & pntk = pnts[k]; + vect.Init( pnt0, pntk ); + vect = tau * (vect * tau); + pnt = pnt0 + vect; + if ( pntk.DistanceToPoint( pnt ) > metricEps ) { + onLine = false; + break; + } + } + } + } + else if ( cnt == 2 ) { + if ( pnts[0].DistanceToPoint( pnts[1] ) > lenEps ) + onLine = true; + } + + return onLine; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежат ли точки на линии. + \en Whether points lie on the line. \~ + \details \ru Лежат ли точки на линии (улучшенный вариант IsPointOnLine). \n + \en Whether points lie on the line (improved variant of IsPointOnLine). \n \~ + \param[in] pnts - \ru Набор точек. + \en Point set. \~ + \param[in] metricEps - \ru Точность проверки. + \en Check accuracy. \~ + \return \ru true, если точки лежат на линии, \n иначе false + \en True if points lie on line, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool ArePointsOnLine( const std::vector & pnts, double metricEps = METRIC_EPSILON ) +{ + bool onLine = false; + + size_t cnt = pnts.size(); + double lenEps = std_min( LENGTH_EPSILON, metricEps ); + lenEps = std_max( EXTENT_EQUAL, lenEps ); + + if ( cnt > 2 ) { + const Point & pnt0 = pnts[0]; + + Vector tau( pnt0, pnts[1] ); + double tauLen = tau.Length(); + if ( tauLen <= lenEps ) { + for ( size_t k = 2; k < cnt; k++ ) { + const Point & pntk = pnts[k]; + tau.Init( pnt0, pntk ); + tauLen = tau.Length(); + if ( tauLen > lenEps ) + break; + } + } + if ( tauLen > lenEps ) { + onLine = true; + tau /= tauLen; + Vector vect; + Point pnt; + for ( size_t k = 1; k < cnt; k++ ) { + const Point & pntk = pnts[k]; + vect.Init( pnt0, pntk ); + vect = tau * (vect * tau); + pnt = pnt0 + vect; + if ( pntk.DistanceToPoint( pnt ) > metricEps ) { + onLine = false; + break; + } + } + } + } + else if ( cnt == 2 ) { + if ( pnts[0].DistanceToPoint( pnts[1] ) > lenEps ) + onLine = true; + } + + return onLine; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежит ли набор точек на плоскости. + \en Whether the set of points lies on plane. \~ + \details \ru Лежит ли набор точек на плоскости. \n + \en Whether the set of points lies on plane. \n \~ + \param[in] pnts - \ru Набор точек. + \en Point set. \~ + \param[in,out] place - \ru Система координат, в которой лежат точки. + \en Points coordinate system. \~ + \param[in] mEps - \ru Точность проверки. + \en Check accuracy. \~ + \return \ru true, если точки лежат на плоскости, \n иначе false + \en True if points lie on plane, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool IsPlanar( const PointsVector & pnts, MbPlacement3D * place, double mEps = METRIC_EPSILON ) +{ + bool isPlanar = false; + mEps = ::fabs( mEps ); + const size_t pntsCnt = pnts.size(); + + if ( pntsCnt > 2 ) { + MbCartPoint3D pnt0( pnts[0] ), pnt_i, pnt_j; + MbVector3D vx, vy; + + bool noPlace = true; + for ( size_t i = 1; i < pntsCnt && noPlace; i++ ) { + pnt_i = pnts[i]; + if ( !c3d::EqualPoints( pnt_i, pnt0, mEps ) ) { + for ( size_t j = 1; j < pntsCnt && noPlace; j++ ) { + pnt_j = pnts[j]; + if ( !c3d::EqualPoints( pnt_j, pnt0, mEps ) && !c3d::EqualPoints( pnt_j, pnt_i, mEps ) ) { + vx.Init( pnt0, pnt_i ); + vy.Init( pnt0, pnt_j ); + if ( !vx.Colinear( vy ) ) + noPlace = false; + } + } + } + } + + if ( !noPlace ) { + isPlanar = true; + MbPlacement3D wrkPlace( vx, vy, pnt0 ); + + if ( pntsCnt > 3 ) { + MbCartPoint3D pnt; + for ( size_t k = 1; k < pntsCnt; k++ ) { + pnt = pnts[k]; + wrkPlace.PointProjection( pnt, pnt0 ); + if ( !c3d::EqualPoints( pnt, pnt0, mEps ) ) { + isPlanar = false; + break; + } + } + } + if ( isPlanar && place != NULL ) + place->Init( wrkPlace ); + } + } + + return isPlanar; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Лежит ли набор точек на плоскости. + \en Whether the set of points lies on plane. \~ + \details \ru Лежит ли набор точек на плоскости. \n + \en Whether set of points lies on plane. \n \~ + \param[in] pnts - \ru Набор точек. + \en Point set. \~ + \param[in,out] place - \ru Система координат, в которой лежат точки. + \en Points coordinate system. \~ + \param[in] mEps - \ru Точность проверки. + \en Check accuracy. \~ + \return \ru true, если точки лежат на плоскости, \n иначе false + \en True if points lie on plane, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool IsPlanar2( const Array2 & pnts, MbPlacement3D * place, double mEps = METRIC_EPSILON ) +{ + bool isPlanar = false; + const size_t lCnt = pnts.Lines(); + const size_t cCnt = pnts.Columns(); + const size_t pCnt = lCnt * cCnt; + + if ( pCnt > 2 ) { + std::vector tmpPnts; + tmpPnts.reserve( pCnt ); + + bool isFailed = false; + + for ( size_t i = 0; i < lCnt; i++ ) { + for ( size_t j = 0; j < cCnt; j++ ) { + tmpPnts.push_back( pnts( i, j ) ); + if ( !c3d::IsValidPoint( pnts( i, j ) ) ) { + isFailed = true; + break; + } + } + if ( isFailed ) + break; + } + + C3D_ASSERT( !isFailed ); + + if ( !isFailed ) + isPlanar = c3d::IsPlanar( tmpPnts, place, mEps ); + } + + return isPlanar; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить область изменения параметра. + \en Set the range of parameter. \~ + \details \ru Установить (репараметризовать) область изменения параметра в массиве. \n + \en Set (reparametrize) range of parameter in the array. \n \~ + \param[in,out] params - \ru Множество параметров, упорядоченный по возрастанию параметра. + \en The array of parameters sorted in ascending order. \~ + \param[in] pmin - \ru Минимальное значение параметра. + \en Minimal value of parameter. \~ + \param[in] pmax - \ru Максимальное значение параметра. + \en Maximal value of parameter. \~ + \ingroup Base_Algorithms +*/ +// --- +template +void SetLimitParam( DoubleVector & tarr, double tmin, double tmax, double teps = Math::paramEpsilon ) +{ + if ( tarr.size() < 2 ) + return; + if ( tarr.front() == tmin && tarr.back() == tmax ) + return; + + double trange = tmax - tmin; // New parametric range. + + if ( trange < teps ) + return; + + double tmin0 = tarr.front(); // Old minimal parameter. + double trange0 = tarr.back() - tmin0; // Old parametric range. + + if ( trange0 > teps ) { + // Set new limits. + tarr.front() = tmin; + tarr.back() = tmax; + // Reverse slope coefficient. + double rsc = trange / trange0; + // Transform values. + ptrdiff_t mxInd = (ptrdiff_t)tarr.size() - 1; + for ( ptrdiff_t i = 1; i < mxInd; i++ ) { + tarr[i] = (tarr[i] - tmin0) * rsc + tmin; + } + } +} + +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Отсортировать массив. + \en Sort the array. \~ + \details \ru Первый массив сортируется по возрастанию параметра. Элементы второго массива + переставляются синхронно с элементами первого. Если установлен соответствующий флаг, + то проводится проверка на наличие в массиве tt0 совпадающих параметров. Если они есть, + то оставляется один и соответствующий ему в tt2. При этом в tt0 оставляется тот параметр, + для которого соответствующий элемент в tt2 имеет минимальное значение. + \en First array is sorted in ascending order. Elements of the second array + are rearranged synchronously with elements of the first one. If the corresponding flag is set, + then the array is checked for duplications. If they exist, + then only one of them is kept with the corresponding parameter in tt2. Meanwhile, the parameter is kept in tt0, + which correspondence in tt2 has the minimal value. \~ + \param[out] tt0 - \ru Исходный массив 1 параметров, который требуется отсортировать. + \en Source array of first parameters to sort. \~ + \param[out] tt2 - \ru Исходный массив 2 параметров, который требуется отсортировать синхронно с tt0. + \en Source array of second parameters to sort synchronously with tt0. \~ + \param[in] eps - \ru Точность сравнения параметров. + \en Parameters comparison tolerance. \~ + \param[in] checkCoincidentParams - \ru Флаг проверки на наличие совпадающих параметров. + \en Flag for checking of duplicate parameters. \~ + \ingroup Base_Algorithms +*/ +//--- +template +MATH_FUNC (bool) SortSynchroArrays( DoubleParamsVector & tt0, DoubleParamsVector & tt2, + double eps, bool checkCoincidentParams ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отсортировать массив. + \en Sort the array. \~ + \details \ru Множество сортируется по возрастанию параметра. Если установлен соответствующий флаг, + то проводится проверка на наличие совпадающих параметров. Если они есть, + то оставляется только один из них. + \en Sort the array in ascending order. If the corresponding flag is set, + then the check for duplicate parameters is to be performed. If they exist, + then only one of them is kept. \~ + \param[out] tt0 - \ru Исходный массив параметров, который требуется отсортировать. + \en Source array of parameters to sort. \~ + \param[in] eps - \ru Точность сравнения параметров. + \en Parameters comparison tolerance. \~ + \param[in] checkCoincidentParams - \ru Флаг проверки на наличие совпадающих параметров. + \en Flag for checking of duplicate parameters. \~ + \ingroup Base_Algorithms +*/ +//--- +template +MATH_FUNC (void) SortArray( DoubleParamsVector & tt0, double eps, bool checkCoincidentParams ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Уточнить параметр. + \en Refine the parameter. \~ + \details \ru Если параметр замкнутый или должен находится не на расширении параметрической области, + то он в случае необходимости загоняется внутрь интервала [pmin, pmax]. + \en If parameter is closed or must not be in the extension of parametric region, + then it drawn inside region [pmin, pmax] if necessary. \~ + \param[in] pext - \ru Используется ли расширение параметрической области. + \en Whether extension of parametric region is used. \~ + \param[in] pc - \ru Замкнутость области определения параметра. + \en Closedness of parameter domain. \~ + \param[in] pmin - \ru Минимальное значение параметра. + \en The minimal value of parameter. \~ + \param[in] pmax - \ru Максимальное значение параметра. + \en The maximal value of parameter. \~ + \param[out] p - \ru Уточняемый параметр. + \en The parameter to refine. \~ + \param[in] eps - \ru Точность вычислений. + \en Computational tolerance. \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (void) CorrectParameter( bool pext, bool pc, double pmin, double pmax, + double & p, double eps = Math::paramRegion ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Коррекция параметра с проверкой. + \en Correction of parameter with validation. \~ + \details \ru Если после коррекции параметр выходит за пределы интервала [tmin, tmax], а флаг + использования параметра на расширении параметрической области равен false, то + параметр приравнивается либо к tmin, либо к tmax, в зависимости от того, с какой + стороны он вышел за пределы интервала [tmin, tmax]. + \en If the parameter is not in range [tmin, tmax] after correction, and flag + of use of parameter on extension of parametric region is false, then + parameter equates to tmin or tmax, according to which + bound it get out from range [tmin, tmax]. \~ + \param[in] tmin - \ru Минимальное значение параметра. + \en Minimal value of parameter. \~ + \param[in] tmax - \ru Максимальное значение параметра. + \en Maximal value of parameter. \~ + \param[in] tPeriod - \ru Период. + \en Period. \~ + \param[in] ext - \ru Используется ли расширение параметрической области. + \en Whether extension of parametric region is used. \~ + \param[in] tRegion - \ru Точность задания параметра. + \en Accuracy of parameter. \~ + \param[out] t - \ru Уточняемый параметр. + \en The parameter to refine. \~ + \return \ru true, если не было выхода за пределы интервала [tmin, tmax] после коррекции, \n иначе false. + \en True if there was no parameter out of range [tmin, tmax] after correction, \n otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (bool) CorrectCheckNearParameter( const double & tmin, const double & tmax, + const double & tPeriod, const bool & ext, const double & tRegion, double & t ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить матрицу инвертирования значка. + \en Determine the inversion matrix of roughness symbol. \~ + \details \ru Рассчитывается матрица инвертирования в трехмерных размерах. + \en Calculating the inversion matrix in three-dimensional space. \~ + \param[in] place3D - \ru Локальная система координат. + \en Local coordinate system. \~ + \param[in] pDir - \ru Направление. + \en Direction. \~ + \param[in] seeY - \ru Ось Y экрана. + \en Screen Y-axis. \~ + \param[in] seeZ - \ru Ось Z экрана. + \en Screen Z-axis. \~ + \param[out] matrix - \ru Матрица инвертирования. + \en Inversion matrix. \~ + \return \ru true, если матрица найдена, \n иначе false + \en True if the matrix was found, \n otherwise false \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (bool) MatrixRoughInverse( const MbPlacement3D & place3D, const MbDirection * pDir, const MbVector3D & seeY, + const MbVector3D & seeZ, MbMatrix & matrix ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить матрицу инвертирования текста. + \en Determine the inversion matrix of text. \~ + \details \ru Рассчитывается матрица инвертирования в трехмерных размерах. + \en Calculating the inversion matrix in three-dimensional space. \~ + \param[in] place3D - \ru Локальная система координат. + \en Local coordinate system. \~ + \param[in] pDir - \ru Направление. + \en Direction. \~ + \param[in] seeY - \ru Ось Y экрана. + \en Screen Y-axis. \~ + \param[in] seeZ - \ru Ось Z экрана. + \en Screen Z-axis. \~ + \param[out] matrix - \ru Матрица инвертирования. + \en Inversion matrix. \~ + \return \ru true, если матрица найдена, \n иначе false + \en True if the matrix was found, \n otherwise false \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (bool) MatrixTextInverse ( const MbPlacement3D & place3D, const MbDirection * pDir, const MbVector3D & seeY, + const MbVector3D & seeZ, MbMatrix & matrix ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Округлить значение до n значащих цифр. + \en The value is rounded to n significant digits. \~ + \details \ru Округлить значение до n значащих цифр. \n + \en The value is rounded to n significant digits. \n \~ + \param[in,out] value - \ru Округляемое число. + \en The value. \~ + \param[in] n - \ru Число значащих цифр. + \en Number of significant digits. \~ + \return \ru true, если округление выполнено, иначе false. + \en true, if value is rounded, otherwise false. \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (bool) RoundedValue( double & value, uint8 n ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Решить квадратное уравнение вида a * x^2 + b * x + c = 0 без внешнего управления погрешностью. + \en Solve a quadratic equation of the form a * x ^ 2 + b * x + c = 0 without external tolerance control. \~ + \details \ru Решить квадратное уравнение вида a * x^2 + b * x + c = 0 без внешнего управления погрешностью. \n + \en Solve a quadratic equation of the form a * x ^ 2 + b * x + c = 0 without external tolerance control. \n \~ + \param[in] a - \ru Коэффициент при квадрате неизвестной. + \en The second-degree term coefficient. \~ + \param[in] b - \ru Коэффициент при неизвестной. + \en The first-degree term coefficient. \~ + \param[in] c - \ru Коэффициент - константный член уравнения. + \en The constant term coefficient. \~ + \param[out] d - \ru Дискриминант уравнения. + \en The discriminant of equation. \~ + \param[out] res - \ru Корни уравнения. + \en Roots of equation. \~ + \return \ru Количество действительных решений и дискриминант уравнения. + \en Number of real roots and discriminant of equation. \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (int) QuadraticEquation( double a, double b, double c, + double & d, std::pair & res ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Решить квадратное уравнение вида a * x^2 + b * x + c = 0. + \en Solve a quadratic equation of the form a * x ^ 2 + b * x + c = 0. \~ + \details \ru Решить квадратное уравнение вида a * x^2 + b * x + c = 0. \n + \en Solve a quadratic equation of the form a * x ^ 2 + b * x + c = 0. \n \~ + \param[in] a - \ru Коэффициент при квадрате неизвестной. + \en The second-degree term coefficient. \~ + \param[in] b - \ru Коэффициент при неизвестной. + \en The first-degree term coefficient. \~ + \param[in] c - \ru Коэффициент - константный член уравнения. + \en The constant term coefficient. \~ + \param[out] x1 - \ru Первый корень уравнения. + \en The first root of equation. \~ + \param[out] x2 - \ru Второй корень уравнения. + \en The second root of equation. \~ + \param[in] epsilon - \ru Погрешность нахождения решения. + \en Solution tolerance. \~ + \return \ru Количество действительных решений. + \en Number of real roots. \~ +\ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (int) QuadraticEquation( double a, double b, double c, + double & x1, double & x2, double epsilon = Math::paramEpsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Решить кубическое уравнение вида a * x^3 + b * x^2 + c * x + d = 0. + \en Solve a cubic equation of the form a * x^3 + b * x^2 + c * x + d = 0. \~ + \details \ru Решить кубическое уравнение вида a * x^3 + b * x^2 + c * x + d = 0. \n + \en Solve a cubic equation of the form a * x^3 + b * x^2 + c * x + d = 0. \n \~ + \param[in] a - \ru Коэффициент при кубе неизвестной. + \en The third-degree term coefficient. \~ + \param[in] b - \ru Коэффициент при квадрате неизвестной. + \en The second-degree term coefficient. \~ + \param[in] c - \ru Коэффициент при неизвестной. + \en The first-degree term coefficient. \~ + \param[in] d - \ru Коэффициент - константный член уравнения. + \en The constant term coefficient. \~ + \param[out] x - \ru Корни уравнения. + \en Roots of equation. \~ + \param[in] epsilon - \ru Погрешность нахождения решения. + \en Solution tolerance. \~ + \return \ru Количество действительных решений. +\en Number of real roots. \~ +\ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (int) QubicEquation( double a, double b, double c, double d, double * x, double epsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Решить кубическое уравнение вида x^3 - i1 * x^2 + i2 * x - i3 = 0. + \en Solve a cubic equation of the form x^3 - i1 * x^2 + i2 * x - i3 = 0. \~ + \details \ru Решить кубическое уравнение вида x^3 - i1 * x^2 + i2 * x - i3 = 0. \n + \en Solve a cubic equation of the form x^3 - i1 * x^2 + i2 * x - i3 = 0. \n \~ + \param[in] i1 - \ru Коэффициент при квадрате неизвестной. + \en The second-degree term coefficient. \~ + \param[in] i2 - \ru Коэффициент при неизвестной. + \en The first-degree term coefficient. \~ + \param[in] i3 - \ru Коэффициент - константный член уравнения. + \en The constant term coefficient. \~ + \param[out] x - \ru Корни уравнения. + \en Roots of equation. \~ + \param[in] epsilon - \ru Погрешность нахождения решения. + \en Solution tolerance. \~ + \return \ru Количество действительных решений. + \en Number of real roots. \~ +\ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (int) CubicEquation( double i1, double i2, double i3, double * x, double epsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Решить уравнение четвертой степени вида a * x^4 + b * x^3 + с * x^2 + d * x + e = 0. + \en Solve a quartic equation of the form a * x^4 + b * x^3 + с * x^2 + d * x + e = 0. \~ + \details \ru Решить уравнение четвертой степени вида a * x^4 + b * x^3 + с * x^2 + d * x + e = 0. \n + \en Solve a cubic equation of the form a * x^4 + b * x^3 + с * x^2 + d * x + e = 0. \n \~ + \param[in] a - \ru Коэффициент при четвертой степени неизвестной. + \en The fourth-degree term coefficient. \~ + \param[in] b - \ru Коэффициент при кубе неизвестной. + \en The third-degree term coefficient. \~ + \param[in] c - \ru Коэффициент при квадрате неизвестной. + \en The second-degree term coefficient. \~ + \param[in] d - \ru Коэффициент при неизвестной. + \en The first-degree term coefficient. \~ + \param[in] e - \ru Коэффициент - константный член уравнения. + \en The constant term coefficient. \~ + \param[out] x - \ru Корни уравнения. + \en Roots of equation. \~ + \param[in] epsilon - \ru Погрешность нахождения решения. + \en Solution tolerance. \~ + \return \ru Количество действительных решений. + \en Number of real roots. \~ +\ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (int) Degree4Equation( double a, double b, double c, double d, double e, double * x, double epsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить собственный вектор матрицы 3 x 3. + \en Determine the eigenvector of 3 x 3 matrix. \~ + \details \ru Определить собственный вектор матрицы 3 x 3. \n + \en Determine the eigenvector of 3 x 3 matrix. \n \~ + \param[in] a - \ru Матрица 3 x 3. + \en 3 x 3 matrix. \~ + \param[out] vect - \ru Собственный вектор матрицы. + \en The eigenvector of matrix. \~ +\ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (void) EigenVector( double a[c3d::SPACE_DIM][c3d::SPACE_DIM], MbVector3D & vect ); + + +#endif // __ALG_BASE_H diff --git a/C3d/Include/alg_circle_curve.h b/C3d/Include/alg_circle_curve.h new file mode 100644 index 0000000..8769b69 --- /dev/null +++ b/C3d/Include/alg_circle_curve.h @@ -0,0 +1,582 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение окружности, вычисление центра окружности. + \en Circle construction, center of circle calculation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CIRCLE_CURVE_H +#define __ALG_CIRCLE_CURVE_H + +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbLine; +class MATH_CLASS MbArc; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вспомогательная окружность. + \en Auxiliary circle. \~ + \details \ru Вспомогательная окружность, заданная центром и радиусом. \n + \en Auxiliary circle, defined by center and radius. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbTempCircle { +private: + MbCartPoint centre; ///< \ru Центр. \en Center. + double radius; ///< \ru Радиус. \en Radius. + +public : + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор окружности нулевого радиуса с центром в начале координат.\n + \en Constructor of a circle with zero radius, centered at the origin of coordinate system.\n \~ + */ + MbTempCircle() + : centre() + , radius( 0 ) + {}; + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор окружности с центром в начале координат.\n + \en Constructor of a circle, centered at the origin of coordinate system.\n \~ + \param[in] rad - \ru Радиус окружности. + \en Radius of circle. \~ + */ + MbTempCircle( double rad ) + : centre() + , radius( rad ) + {}; + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по центру и радиусу.\n + \en Constructor by center and radius.\n \~ + \param[in] p - \ru Центр окружности. + \en Center of circle. \~ + \param[in] rad - \ru Радиус окружности. + \en Radius of circle. \~ + */ + MbTempCircle( const MbCartPoint & p, double rad ) + : centre( p ) + , radius( rad ) + {}; + + /// \ru Копирующий конструктор. \en Copy-constructor. + MbTempCircle( const MbTempCircle & other ) + : centre( other.centre) + , radius( other.radius ) + {}; + +public : + ~MbTempCircle() {} + + /**\ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация по окружности.\n + \en Initialization by circle.\n \~ + \param[in] other - \ru Окружность. + \en Circle. \~ + */ + void Init( const MbTempCircle & other ) { centre = other.centre; radius = other.radius; } + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация по центру и радиусу.\n + \en Initialization by center and radius.\n \~ + \param[in] p - \ru Центр. + \en Center. \~ + \param[in] rad - \ru радиус. + \en radius. \~ + */ + void Init( const MbCartPoint & p, double rad ) { centre = p; radius = rad; } + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + const MbCartPoint & GetCentre() const { return centre; } ///< \ru Центр окружности. \en Center of circle. + const double & GetR()const { return radius; } ///< \ru Радиус окружности. \en Radius of circle. + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + MbCartPoint & SetCentre() { return centre; } ///< \ru Выдать центр окружности для изменения. \en Get center of circle for editing. + void SetCentre( const MbCartPoint & c ) { centre = c; } ///< \ru Изменить центр окружности. \en Set center of circle. + + double & SetRadius() { return radius; } ///< \ru Выдать радиус окружности для изменения. \en Get radius of circle for editing. + void SetRadius( double r ) { radius = r; } ///< \ru Изменить радиус окружности. \en Set radius of circle. + + /** \} */ + /**\ru \name Функции расчета данных. + \en \name Functions for calculating data. + \{ */ + + /** \brief \ru Точка на окружности. + \en Point on circle. \~ + \details \ru Точка на окружности по параметру.\n + \en Point on circle by parameter.\n \~ + \param[in] t - \ru Параметр на окружности. + \en Parameter on circle. \~ + \param[out] p - \ru Точка на окружности. + \en Point on circle. \~ + */ + void PointOn( double t, MbCartPoint & p ) const { + p.x = ( centre.x + radius * ::cos(t) ); + p.y = ( centre.y + radius * ::sin(t) ); + } + + /** \brief \ru Первая производная. + \en First derivative. \~ + \details \ru Первая производная по параметру.\n + \en First derivative by parameter.\n \~ + \param[in] t - \ru Параметр на окружности. + \en Parameter on circle. \~ + \param[out] v - \ru Вектор первой производной. + \en First derivative vector. \~ + */ + void FirstDer( double t, MbVector & v ) const { + v.x = -( radius * ::sin(t) ); + v.y = ( radius * ::cos(t) ); + } + + /** \brief \ru Вычислить расстояние до точки. + \en Calculate distance to point. \~ + \details \ru Расстояние от окружности до точки.\n + \en Distance from circle to point.\n \~ + \param[in] p - \ru Точка. + \en Point. \~ + \return \ru Вычислить расстояние до точки. + \en Calculate distance to point. \~ + */ + double DistanceToPoint( const MbCartPoint & p ) const { + return ::fabs( centre.DistanceToPoint(p) - radius ); + } + + /** \brief \ru Проекция точки. + \en Point projection. \~ + \details \ru Проекция точки на окружность.\n + \en Point projection on circle.\n \~ + \param[in] p - \ru Точка. + \en Point. \~ + \return \ru Параметр проекции точки на окружности. + \en Parameter of point projection on circle. \~ + */ + double PointProjection( const MbCartPoint & p ) const { + return c3d::CalcAngle0X( centre, p ); + } + + /** \brief \ru Лежит ли точка на окружности? + \en Is point on circle? \~ + \details \ru Проверка, лежит ли точка на окружности.\n + \en Check if the point is on circle.\n \~ + \param[in] p - \ru Точка. + \en Point. \~ + \param[in] eps - \ru Погрешность. + \en Tolerance. \~ + \return \ru true, если точка лежит на окружности. + \en true if the point on circle. \~ + */ + bool IsPointOn( const MbCartPoint & p, double eps = Math::LengthEps ) const { + return ( DistanceToPoint(p) < eps ); + } + + /** \brief \ru Проверить на вырожденность. + \en Check for degeneracy. \~ + \details \ru Проверить окружность на вырожденность.\n + \en Check circle for degeneracy. \~ + \return \ru true, если окружность вырождена. + \en true if the circle is degenerate. \~ + */ + bool IsDegenerate() const { // \ru проверка вырожденности окружности \en check for circle degeneracy + return ( radius < Math::minRadius || radius > Math::maxRadius ); + } + /** \} */ +private: + void operator = ( const MbTempCircle & other ) { centre = other.centre; radius = other.radius; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить центры окружностей. + \en Calculate centers of circles. \~ + \details \ru Вычислить центры окружностей заданного радиуса rad, касающихся + двух данных прямых pl1 и pl2. + \en Calculate centers of circles with fixed radius rad, that touches + two given lines pl1 and pl2. \~ + \param[in] pl1 - \ru Первая прямая. + \en First line. \~ + \param[in] pl2 - \ru Вторая прямая. + \en Second line \~ + \param[in] rad - \ru Радиус окружности. + \en Radius of circle. \~ + \param[out] pc - \ru Результат - массив окружностей с искомым центром. + \en Result - set of circles with required center. \~ + \return \ru Количество окружностей в массиве. + \en The number of circles in array. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CircleTanLineLineRad( MbLine & pl1, MbLine & pl2, double rad, MbTempCircle * pc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить центры окружностей. + \en Calculate centers of circles. \~ + \details \ru Вычислить центры окружностей заданного радиуса rad, касающихся + данных прямой pl1 и окружности pc1. + \en Calculate centers of circles with fixed radius rad, that touches + given line pl1 and circle pc1. \~ + \param[in] pl1 - \ru Прямая. + \en Line. \~ + \param[in] pc1 - \ru Окружность. + \en Circle. \~ + \param[in] rad - \ru Радиус окружностей с искомым центром. + \en Result - set of circles with the required center. \~ + \param[out] pc - \ru Результат - массив окружностей с искомым центром. + \en Result - set of circles with the required center. \~ + \return \ru Количество окружностей в массиве. + \en The number of circles in array. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CircleTanLineCircleRadius( const MbLine & pl1, const MbArc & pc1, double rad, + MbTempCircle * pc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить центры окружностей. + \en Calculate centers of circles. \~ + \details \ru Вычислить центры окружностей заданного радиуса rad, касающихся + двух окружностей pc1 и pc2. + \en Calculate centers of circles with fixed radius rad, that touches + given circles pc1 and pc2. \~ + \param[in] pc1 - \ru Первая окружность. + \en First circle. \~ + \param[in] pc2 - \ru Вторая окружность. + \en Second circle. \~ + \param[in] rad - \ru Радиус окружностей с искомым центром. + \en Radius of circles with the required center. \~ + \param[out] pc - \ru Результат - массив окружностей с искомым центром. + \en Result - set of circles with the required center. \~ + \return \ru Количество окружностей в массиве. + \en Count of circles in set. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) CircleTanCircleCircleRad( MbArc & pc1, MbArc & pc2, double rad, + MbTempCircle * pc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности с заданным центром, + касающиеся заданной кривой. + \en Create circles with given center, + that touches given curve. \~ + \param[in] pCurve - \ru Кривая, касающаяся окружности. + \en Curve, that touches circle. \~ + \param[in] pnt - \ru Центр окружности. + \en Center of circle. \~ + \param[out] pCircle - \ru Набор окружностей. + \en Set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTanCurveCentre( const MbCurve & pCurve, MbCartPoint & pnt, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности, касающиеся заданной кривой, + проходящие через две заданные точки. + \en Create circles that touch given curve + and pass through given two points. \~ + \param[in] pCurve - \ru Кривая, касающаяся окружности. + \en Curve, that touches circle. \~ + \param[in] on1 - \ru Точка на окружности. + \en Point on circle. \~ + \param[in] on2 - \ru Точка на окружности. + \en Point on circle. \~ + \param[out] pCircle - \ru Набор окружностей. + \en Set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTangentCurveTwoPoints( const MbCurve & pCurve, + MbCartPoint & on1, MbCartPoint & on2, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности, касающиеся заданной кривой, + с заданным радиусом, проходящие через заданную точку. + \en Create circles that touch given curve + and with a given radius, passing through a given point. \~ + \param[in] pCurve - \ru Кривая, касающаяся окружности. + \en Curve that touches circle. \~ + \param[in] radius - \ru Радиус. + \en Radius. \~ + \param[in] on - \ru Точка на окружности. + \en Point on circle. \~ + \param[out] pCircle - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTangentCurveRPointOn( const MbCurve & pCurve, double radius, MbCartPoint & on, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности с заданным радиусом, + касающиеся двух кривых. + \en Create circles with a given radius + that touch two curves. \~ + \param[in] pCurve1 - \ru Первая кривая, касающаяся окружности. + \en The first curve that touches circle. \~ + \param[in] pCurve2 - \ru Вторая кривая, касающаяся окружности. + \en The second curve, that touches circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[out] pCircle - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTanTwoCurvesRadius( const MbCurve & pCurve1, const MbCurve & pCurve2, double rad, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности, проходящие через заданную точку, + касающиеся двух кривых. + \en Create circles that pass through given point + and touch two curves. \~ + \param[in] pCurve1 - \ru Первая кривая, касающаяся окружности. + \en The first curve, that touches circle. \~ + \param[in] pCurve2 - \ru Вторая кривая, касающаяся окружности. + \en The second curve that touches circle. \~ + \param[in] pOn - \ru Точка на окружности. + \en Point on circle. \~ + \param[out] pCircle - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTanTwoCurvesPointOn( const MbCurve & pCurve1, const MbCurve & pCurve2, const MbCartPoint & pOn, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности с центром на первой кривой, + касательные ко второй кривой, проходящие через заданную точку. + \en Create circles with center on the first curve + that touches second curve and passes through the given point. \~ + \param[in] pCurve1 - \ru Первая кривая, содержащая центр окружности. + \en The first curve which contains center of circle. \~ + \param[in] pCurve2 - \ru Вторая кривая, касающаяся окружности. + \en The second curve that touches circle. \~ + \param[in] pp - \ru Точка на окружности. + \en Point on circle. \~ + \param[out] pCircle - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleOriginOneTangentTwo( const MbCurve & pCurve1, const MbCurve & pCurve2, const MbCartPoint & pp, + RPArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности, касательные заданной кривой, + проходящие через заданную точку, составляющие в точке касания угол(p1, centre, ptan), + равный данному. + \en Create circles that touch given curve + and pass through given point, with angle(p1, centre, ptan) at tangent point + that equal to the given one. \~ + \param[in] curve - \ru Кривая, касающаяся окружности. + \en Curve that touches the circle. \~ + \param[in] p1 - \ru Точка на окружности. + \en Point on circle. \~ + \param[in] angle - \ru Угол, образованный тремя точками:\n + заданной точкой на окружности p1,\n + центром окружности,\n + точкой касания. + \en Angle formed by three points:\n + given point on circle p1,\n + center of circle,\n + tangent point. \~ + \param[out] circles - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTanCurvePointOnAngle( MbCurve & curve, MbCartPoint & p1, double angle, + PArray & circles ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить дуги окружностей. + \en Create arcs of circles. \~ + \details \ru Построить дуги окружностей по двум точкам, + касающиеся заданной кривой. + \en Create arcs of circles by two points + that touches given curve. \~ + \param[in] pCurve - \ru Кривая, касающаяся дуг. + \en Curve that touches arcs. \~ + \param[in] on1 - \ru Первая точка на дуге. + \en First point on arc. \~ + \param[in] on2 - \ru Вторая точка на дуге. + \en Second point on arc. \~ + \param[out] arc - \ru Набор дуг. + \en Set of arcs. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) ArcTangentCurveTwoPoints( const MbCurve & pCurve, + MbCartPoint & on1, MbCartPoint & on2, + PArray & arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить дуги окружностей. + \en Create arcs of circles. \~ + \details \ru Построить дуги окружностей по радиусу и точке, + касающиеся заданной кривой. + \en Create arcs of circles by radius and point + that touch given curve. \~ + \param[in] pCurve - \ru Кривая, касающаяся дуг. + \en Curve that touches arcs. \~ + \param[in] radius - \ru Радиус. + \en Radius. \~ + \param[in] on - \ru Точка на дуге. + \en Point on arc. \~ + \param[out] arc - \ru Набор дуг. + \en Set of arcs. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) ArcTangentCurveRPointOn( const MbCurve & pCurve, double radius, MbCartPoint & on, + PArray & arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить дугу окружности. + \en Create a circle arc. \~ + \details \ru Построить дугу окружности, сопряженную с указанной ограниченной кривой + в начальной или конечной точке. Дуга всегда выходит из кривой. + \en Create arc of circle conjugated with the given bounded curve + at the start point or at the end point. An arc always starts at curve. \~ + \param[in] line - \ru Кривая для сопряжения. + \en Curve to conjugate with. \~ + \param[in] p2 - \ru Точка на дуге. + \en Point on arc. \~ + \param[out] arc - \ru Множество с дугой окружности. + \en A set that contains the arc of circle. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) ArcTangentCurveContinue( MbLine & line, MbCartPoint & p2, + PArray & arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить дугу окружности. + \en Create a circle arc. \~ + \details \ru Построить дугу окружности заданного радиуса, + сопряженной с указанной ограниченной кривой + в начальной или конечной точке. Дуга всегда выходит из кривой. + \en Create an arc of circle with the given radius + conjugated with the given bounded curve + at the start point or at the end point. An arc always starts at curve. \~ + \param[in] line - \ru Кривая для сопряжения. + \en Curve to conjugate with. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] p2 - \ru Точка на дуге. + \en Point on arc. \~ + \param[out] arc - \ru Множество с дугой окружности. + \en A set that contains the arc of circle. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) ArcTangentCurveRadContinue( MbLine & line, double rad, MbCartPoint & p2, + PArray & arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружности. + \en Create circles. \~ + \details \ru Построить окружности, касающиеся трех кривых. + \en Create circles that touch three curves. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] curve3 - \ru Третья кривая. + \en The third curve. \~ + \param[in] pnt - \ru Точка на перпендикуляре к точке касания кривой.\n + Используется для тех кривых их трех перечисленных, + которые не являются отрезком, прямой или полилинией. + \en A point on perpendicular to curve at the tangent point.\n + Used for those of the given three curves + which are not segment, line or polyline. \~ + \param[out] circle - \ru Набор окружностей. + \en A set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleTanThreeCurves( const MbCurve * curve1, const MbCurve * curve2, const MbCurve * curve3, + MbCartPoint & pnt, + PArray & circle ); + + +//----------------------------------------------------------------------------- +/** \brief \ru Копировать временные окружности + \en Copy temporary circles \~ + \details \ru Копировать временные окружности.\n + Очищает временный массив cTmp. + \en Copy temporary circles.\n + Clear temporary array cTmp. \~ + \param[in, out] cTmp - \ru Набор временных окружностей. Множество очищается. + \en Set of temporary circles. Array will be cleared. \~ + \param[out] pCircle - \ru Набор дуг окружностей, созданных соответственно временным окружностям. + \en Set of arcs of circles, created by temporary circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CreateNewCircles( PArray & cTmp, + PArray & pCircle ); + + +#endif // __ALG_CIRCLE_CURVE_H diff --git a/C3d/Include/alg_curve_delete_part.h b/C3d/Include/alg_curve_delete_part.h new file mode 100644 index 0000000..7721781 --- /dev/null +++ b/C3d/Include/alg_curve_delete_part.h @@ -0,0 +1,316 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Операции с кривой в двумерном пространстве. Удаление части кривой. + \en Operations with a curve in two-dimensional space. Deletion of a curve piece. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_DELETE_PART_H +#define __ALG_CURVE_DELETE_PART_H + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить часть кривой. + \en Delete the piece of a curve. \~ + \details \ru Удалить часть кривой по отношению к точке.\n + У кривой удаляется часть, + ограниченная двумя последовательными параметрами пересечения ее с кривыми из заданного списка, + ближайшая к проекции заданной точки. + \en Delete a piece of a curve by the point.\n + Delete the piece + bounded by two successive parameters of intersection of the curve with the curves from the given list + and the nearest to the projection of the given point. \~ + \param[in] curveList - \ru Список кривых для пересечения. + \en The list of curves for intersection. \~ + \param[in] pnt - \ru Точка, показывающая удаляемую часть кривой. + \en The point indicating the piece of a curve to be deleted. \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The curve to be modified. \~ + \param[out] part2 - \ru Конечный участок измененной кривой, если кривая распалась на две части. + \en The finite piece of the modified curve if the curve is split into two pieces. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) DeleteCurvePart( List & curveList, + const MbCartPoint & pnt, + MbCurve * curve, MbCurve *& part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить часть кривой. + \en Delete the piece of a curve. \~ + \details \ru Удалить часть кривой по двум точкам.\n + Для замкнутых кривых дополнительно задается третья точка, + которая показывает удаляемую часть. + \en Delete the piece of a curve by two points.\n + The third point is additionally specified for closed curves, + it indicates the piece of a curve to be deleted. \~ + \param[in] p1 - \ru Точка, показывающая первую границу удаляемого участка. + \en The point indicating the first boundary of the piece to be deleted. \~ + \param[in] p2 - \ru Точка, показывающая вторую границу удаляемого участка. + \en The point indicating the second boundary of the piece to be deleted. \~ + \param[in] p3 - \ru Точка, показывающая удаляемую часть замкнутой кривой. + \en The point indicating the piece of a closed curve to be deleted. \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The curve to be modified. \~ + \param[out] part2 - \ru Конечный участок измененной кривой, если кривая распалась на две части. + \en The finite piece of the modified curve if the curve is split into two pieces. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) DeleteCurvePart( const MbCartPoint & p1, + const MbCartPoint & p2, + const MbCartPoint & p3, + MbCurve * curve, MbCurve *& part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Оставить часть кривой. + \en Keep the piece of a curve. \~ + \details \ru Оставить часть кривой по отношению к точке. + У кривой оставляется часть, + ограниченная двумя последовательными параметрами пересечения ее с кривыми из заданного списка, + ближайшая к проекции заданной точки. + \en Keep the piece of a curve by the point. + Keep the curve piece + bounded by two successive parameters of intersection of the initial curve with the curves from the given list + and the nearest to the projection of the given point. \~ + \param[in] curveList - \ru Список кривых для пересечения. + \en The list of curves for intersection. \~ + \param[in] pnt - \ru Точка, показывающая оставляемую часть кривой. + \en The point indicating the piece of a curve to be kept. \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The curve to be modified. \~ + \param[in, out] part2 - \ru Всегда NULL. + \en This value is always NULL. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after its modification. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) TrimmCurvePart( List & curveList, + const MbCartPoint & pnt, + MbCurve * curve, MbCurve *& part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Оставить часть кривой. + \en Keep the piece of a curve. \~ + \details \ru Оставить часть кривой по двум точкам.\n + Для замкнутых кривых дополнительно задается третья точка, + которая показывает оставляемую часть. + \en Keep the piece of a curve by two points.\n + The third point is additionally specified for closed curves, + it indicates the piece of a curve to be kept. \~ + \param[in] p1 - \ru Точка, показывающая первую границу удаляемого участка. + \en The point indicating the first boundary of the piece to be deleted. \~ + \param[in] p2 - \ru Точка, показывающая вторую границу удаляемого участка. + \en The point indicating the second boundary of the piece to be deleted. \~ + \param[in] p3 - \ru Точка, показывающая оставляемую часть замкнутой кривой. + \en The point indicating the piece of a closed curve to be kept \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The curve to be modified. \~ + \param[in, out] part2 - \ru Всегда NULL. + \en This value is always NULL. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after its modification. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) TrimmCurvePart( const MbCartPoint & p1, + const MbCartPoint & p2, + const MbCartPoint & p3, + MbCurve * curve, MbCurve *& part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выровнить кривую. + \en Justify the curve. \~ + \details \ru Выровнить кривую по отношению к заданной кривой и точке на кривой.\n + Кривая усекается точкой пересечения ее с граничной кривой, ближайшей к заданной + точке. Остается часть кривой со стороны указанной точки. + \en Justify the curve relative to the given curve and a point on the curve.\n + The curve is truncated by the point of its intersection with the boundary curve, which is the nearest to the given + point. Only the piece of a curve at the side of the given point is kept. \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] limitCurve - \ru Граничная кривая для выравнивания. + \en Boundary curve for justification. \~ + \param[in] pnt - \ru Точка для выбора нужной части кривой. + \en The point for selecting the piece of a curve. \~ + \param[in, out] part2 - \ru Всегда NULL. + \en This value is always NULL. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) JustifyCurve( MbCurve * curve, MbCurve * limitCurve, + const MbCartPoint & pnt, MbCurve *& part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Положение точки. + \en The position of the point. \~ + \details \ru Положение точки относительно замкнутых границ. + \en The position of the point relative to closed borders. \~ + \param[in] limits - \ru Набор кривых, задающий границы. + В совокупности должен представлять собой замкнутые границы. + \en The set of curves that defines boundaries. + These curves should be closed boundaries in the aggregate. \~ + \param[in] pnt - \ru Точка для определения положения. + \en The point for the position definition. \~ + \return \ru Положение точки относительно кривой. + \en The point position relative to the curve. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeLocation) PointLocation( const RPArray & limits, + const MbCartPoint & pnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выкинуть части кривой. + \en Exclude the piece of a curve. \~ + \details \ru Выкинуть части кривой, попадающие в замкнутые границы. + \en Exclude curve pieces from closed boundaries. \~ + \param[in] curve - \ru Кривая, на которую накладываются границы. + \en The bounded curve. \~ + \param[in] limits - \ru Множество замкнутых кривых-границ. + \en The array of closed curves-boundaries. \~ + \param[in] inside - \ru Признак удаления внутри границ. + \en The attribute of deletion inside boundaries. \~ + \param[out] part2 - \ru Множество оставшихся участков кривой. + \en The array of remaining curve pieces. \~ + \param[out] cross - \ru Точки пересечения кривой с границами. + \en The curve and boundaries intersection point. \~ + \param[out] isEqualCurve - \ru Признак совпадения разбиваемой кривой с какой-то из + присланного массива границ. Имеет смысл при результате dp_NoChanged. + \en The attribute of coincidence between the broken curve with one of + the given array of boundaries. It is worthwhile if the result is dp_NoChanged. \~ + \param[in] cutOnCurve - \ru Если false, не удаляются части кривой, + совпадающие с участками границы. + \en If it equals to false, then the pieces of a curve + coincident with pieces of the boundary are not to be deleted. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) BreakByClosedCurves( MbCurve & curve, + const RPArray & limits, + bool inside, + PArray & part2, + SArray * cross = NULL, + bool * isEqualCurve = NULL, + bool cutOnCurve = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Выкинуть части кривой. + \en Exclude the piece of a curve. \~ + \details \ru Выкинуть части кривой, совпадающие с набором кривых. + \en Exclude pieces of a curve by coincidence with curves from a set. \~ + \param[in] curve - \ru Кривая, на которую накладываются границы. + \en The bounded curve. \~ + \param[in] limits - \ru Множество кривых для тестирования попадания. + \en The array of curves for the hit testing. \~ + \param[out] part2 - \ru Множество оставшихся кусков кривой. + \en The array of remaining curve pieces. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) BreakByCurvesArr( MbCurve & curve, + const RPArray & limits, + PArray & part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разбить кривую. + \en Split the curve. \~ + \details \ru Разбить кривую на две части.\n + В результате кривая разбивается на части, первая часть которой остается в curve, + остальные части складываются в массив part2. + \en Split the curve into two pieces. + In result the curve is split into pieces. The first piece remains, + the other pieces are added to the array part2. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \param[in, out] curve - \ru Разбиваемая кривая. + \en The curve for splitting. \~ + \param[in] p1 - \ru Первая точка разбиения. + \en The first point of splitting. \~ + \param[in] p2 - \ru Вторая точка разбиения. + \en The second point of splitting. \~ + \param[out] part2 - \ru Множество частей кривой. + \en The array of curve pieces. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) BreakCurve( MbCurve & curve, + const MbCartPoint & p1, const MbCartPoint & p2, + PArray & part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разбить кривую.. + \en Split the curve. \~ + \details \ru Разбить кривую на ресколько равных частей. + \en Split the curve by several equal pieces. \~ + \param[in, out] curve - \ru Разбиваемая кривая. + \en The curve for splitting. \~ + \param[in] partsCount - \ru Количество частей. + \en The count of pieces. \~ + \param[in] p1 - \ru Одна из точек разбиения. + \en One of splitting points. \~ + \param[out] part2 - \ru Множество частей кривой. + \en The array of curve pieces. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) BreakCurveNParts( MbCurve & curve, ptrdiff_t partsCount, const MbCartPoint & p1, + PArray & part2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удлиннить кривую. + \en Extend the curve. \~ + \details \ru Удлиннить кривую curve до кривой-границы limitCurve с конца ближайшего к точке pnt + \en Extend the curve to the given curve-boundary limitCurve from the end nearest to the given point pnt. \~ + \param[in, out] curve - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] limitCurve - \ru Кривая-граница. + \en The curve-boundary \~ + \param[in] pnt - \ru Точка, показывающая удлинняемый конец кривой. + \en The point indicating the extended end of a curve. \~ + \return \ru Состояние кривой после ее модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) ExtendCurveToCurve( MbCurve * curve, const MbCurve * limitCurve, + const MbCartPoint & pnt ); + + +#endif // __ALG_CURVE_DELETE_PART_H diff --git a/C3d/Include/alg_curve_distance.h b/C3d/Include/alg_curve_distance.h new file mode 100644 index 0000000..853aae7 --- /dev/null +++ b/C3d/Include/alg_curve_distance.h @@ -0,0 +1,426 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение кривых в двумерном пространстве. + \en Construction of curves in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_DISTANCE_H +#define __ALG_CURVE_DISTANCE_H + + +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbArc; +class MATH_CLASS MbLine; +class MATH_CLASS MbTempCircle; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую, параллельную заданной. + \en Construct a line parallel to a given line. \~ + \details \ru Построить прямую, параллельную заданной через точку. + \en Construct a line parallel to a given line and passing through a given point. \~ + \param[in] p - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] pl - \ru Параллельная прямая. + \en The parallel line. \~ + \param[out] pl_par - \ru Результат - прямая, параллельная pl, через точку p. + \en The result - the line parallel to the line pl and passing through the point p. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LineParallelPoint( const MbCartPoint & p, const MbLine & pl, MbLine & pl_par ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую, параллельную заданной. + \en Construct a line parallel to a given line. \~ + \details \ru Построить прямую, параллельную заданной, на расстоянии. + \en Construct a line parallel to a given line at a given distance from it. \~ + \param[in] delta - \ru Расстояние до параллельной прямой. + \en The distance to the parallel line. \~ + \param[in] pl - \ru Параллельная прямая. + \en The parallel line. \~ + \param[out] pl_par - \ru Результат - прямая, параллельная pl, на расстоянии delta. + \en The result - the line parallel to the line pl at a given distance delta. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LineParallelDistance( double delta, const MbLine & pl, MbLine & pl_par ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую через точку. + \en Construct a line passing through a given point. \~ + \details \ru Построить прямую, проходящую через точку, + являющуюся биссектриссой угла между прямыми. + \en Construct a line passing through a given point + and being a bisector of angle between two given lines. \~ + \param[in] p - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] pl1 - \ru Прямая, задающая сторону угла. + \en The line defining the angle side. \~ + \param[in] pl2 - \ru Прямая, задающая сторону угла. + \en The line defining the angle side. \~ + \param[out] pl3 - \ru Результат. + \en The result. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (int) LineBisector( const MbCartPoint & p, const MbLine & pl1, const MbLine & pl2, MbLine & pl3 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую под углом. + \en Construct a line passing at angle. \~ + \details \ru Построить прямую под углом angle к заданной pl через точку p + \en Construct a line at an angle to a given line and passing through a given point. \~ + \param[in] angle - \ru Угол. + \en The angle. \~ + \param[in] p - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] pl - \ru Прямая под углом angle к построенной. + \en The line at the given angle to the created line. \~ + \param[out] pl_new - \ru Результат - построенная прямая. + \en The result - the created line. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LinePointAngle( double angle, const MbCartPoint & p, const MbLine & pl, MbLine & pl_new ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить центр окружности. + \en Calculate a circle center. \~ + \details \ru Вычислить центр окружности по двум точкам и радиусу. + \en Calculate a circle center by two points and radius. \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point. \~ + \param[in] radius - \ru Радиус + \en Radius. \~ + \param[out] circle - \ru Результат - массив временных окружностей. + \en The result - the array of temporary circles. \~ + \return \ru Количество элементов в массиве circle. + \en The count of elements in the array "circle". \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (int) Circle2PointsRadius( const MbCartPoint & p1, const MbCartPoint & p2, + double radius, MbTempCircle * circle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить центр и радиус окружности. + \en Calculate center and radius of a circle. \~ + \details \ru Вычислить центр и радиус окружности по трем точкам. + \en Calculate center and radius of a circle by three points. \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point. \~ + \param[in] p3 - \ru Третья точка. + \en The third point. \~ + \param[out] centre - \ru Результат - центр окружности. + \en The result - the circle center. \~ + \return \ru true в случае возможности построения. + \en true if the construction is possible. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) CircleCentre3Points( const MbCartPoint & p1, + const MbCartPoint & p2, + const MbCartPoint & p3, MbCartPoint & centre ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить эллипс + \en Construct an ellipse. \~ + \details \ru Построить эллипс.\n + Зафиксирована конечная точка и длина первой полуоси. + Вводится конечная точка второй полуоси. + Вычислить длину второй полуоси, центр эллипса и угол наклона первой полуоси. + \en Construct an ellipse.\n + The finite point and the length of the first semi-axis are fixed. + The end point of the second semi-axis is put in. + Calculate the length of the second semi-axis, ellipse center and inclination angle of the first semi-axis. \~ + \param[in] p1 - \ru Конечная точка первой полуоси. + \en The end point of the first semi-axis. \~ + \param[in] l1 - \ru Длина первой полуоси. + \en The length of the first semi-axis. \~ + \param[in] p2 - \ru Конечная точка второй полуоси. + \en The end point of the second semi-axis. \~ + \param[out] l2 - \ru Длина второй полуоси. + \en The length of the second semi-axis. \~ + \param[out] pc - \ru Центр эллипса. + \en The ellipse center. \~ + \param[out] angle - \ru Угол наклона первой полуоси. + \en The inclination angle of the first semi-axis. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (bool) EllipsePntPntDist( const MbCartPoint & p1, const double & l1, + const MbCartPoint & p2, double & l2, + MbCartPoint & pc, double & angle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую через точку. + \en Construct a line passing through a given point. \~ + \details \ru Построить прямую через точку, перпендикулярную данной кривой.\n + Базовая точка прямой сопадает с точкой пересечения. + \en Construct a line passing through a point and perpendicular to a given curve.\n + A line origin is coincident with intersection point. \~ + \param[in] pnt - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] pCurve - \ru Перпендикулярная прямая. + \en The perpendicular line. \~ + \param[out] pLine - \ru Результат - массив прямых. + \en The result - the array of lines. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LinePointPerpCurve( const MbCartPoint & pnt, const MbCurve & pCurve, + PArray & pLine ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямую через точку. + \en Construct a line passing through a given point. \~ + \details \ru Построить прямую, проходящую через точку и касательную заданной окружности, + заданной центром и радиусом.\n + \en Construct a line passing through a point and tangent to a given circle + with given center and radius.\n \~ + \param[in] p - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] centre - \ru Центр окружности. + \en The circle center. \~ + \param[in] radius - \ru Радиус окружности. + \en The circle radius. \~ + \param[out] pl - \ru Результат - массив прямых. + \en The result - the array of lines. \~ + \return \ru Количество прямых. + \en The number of lines. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (int) LinePointTangentCircle( const MbCartPoint & p, const MbCartPoint & centre, double radius, + MbLine * pl ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружность. + \en Construct a circle. \~ + \details \ru Построить окружность по радиусу и точке на ней, + центр окружности лежит на заданной кривой. + \en Construct a circle by radius and coincident point, + a circle center lies on a given curve. \~ + \param[in] pCurve - \ru Кривая, содержащая центр окружности. + \en The curve containing the circle center. \~ + \param[in] radius - \ru Радиус окружности. + \en The circle radius. \~ + \param[in] on - \ru Точка на окружности. + \en The point on the circle. \~ + \param[out] pCircle - \ru Результат - набор окружностей. + \en The result - the set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleCentreOnCurveRadPointOn( const MbCurve & pCurve, double radius, const MbCartPoint & on, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить окружность. + \en Construct a circle. \~ + \details \ru Построить окружность по двум точкам, + центр которой лежит на заданной кривой. + \en Construct a circle by two points, + with a center lying on a given curve. \~ + \param[in] pCurve - \ru Кривая, содержащая центр окружности. + \en The curve containing the circle center. \~ + \param[in] on1 - \ru Точка на окружности. + \en The point on the circle. \~ + \param[in] on2 - \ru Точка на окружности. + \en The point on the circle. \~ + \param[out] pCircle - \ru Результат - набор окружностей. + \en The result - the set of circles. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CircleCentreOnCurveTwoPoints( const MbCurve & pCurve, const MbCartPoint & on1, const MbCartPoint & on2, + PArray & pCircle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расстояние между объектами. + \en Distance between objects. \~ + \details \ru Расстояние между двумя объектами.\n + \en The distance between two objects.\n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MbDistance { +public : + double u; ///< \ru Параметр на первой кривой. \en Parameter on the first curve. + double v; ///< \ru Параметр на второй кривой. \en Parameter on the second curve. + double d; ///< \ru Минимальное расстояние. \en Minimal distance. +}; // MbDistance + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить расстояние. + \en Calculate distance. \~ + \details \ru Вычислить расстояние между двумя кривыми. + \en Calculate distance between two curves. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] dmin - \ru Результат - расстояние между кривыми. + \en The result - the distance between curves. \~ + \return \ru true - кривые не пересекаются; + false - кривые пересекаются. + \en true if curves do not intersect. + false if curves intersect. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) DistanceCurveCurve( const MbCurve & curve1, const MbCurve & curve2, + MbDistance & dmin ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить дугу окружности. + \en Construct a circle arc. \~ + \details \ru Построить дугу окружности по двум точкам, радиусу и направлению. + \en Construct a circle arc by two points, radius and direction. \~ + \param[in] p1 - \ru Точка на окружности. + \en The point on the circle. \~ + \param[in] p2 - \ru Точка на окружности. + \en The point on the circle. \~ + \param[in] rad - \ru Радиус окружности. + \en The circle radius. \~ + \param[in] clockwise - \ru Признак направления против часовой стенки. + \en The attribute of counterclockwise direction. \~ + \param[out] arc - \ru Результат - массив окружностей. + \en The result - the array of circles. \~ + \return \ru Количество окружностей в массиве. + \en The count of circles in array. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (int) Arc2PointsRadius( const MbCartPoint & p1, + const MbCartPoint & p2, + double rad, bool clockwise, + MbArc * arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать параметры кривых. + \en Calculate parameters of curves. \~ + \details \ru Рассчитать параметры кривых для минимального расстояния. + \en Calculate curves parameters for the minimal distance. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] u - \ru Параметр на первой кривой. + \en Parameter on the first curve. \~ + \param[out] v - \ru Параметр на второй кривой. + \en Parameter on the second curve. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) CalculateUV( const MbCurve & curve1, const MbCurve & curve2, double & u, double & v ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расставить точки на кривой. + \en Put points on a curve. \~ + \details \ru Расставить заданное количество точек на кривой.\n + Точки можно расставить только на ограниченную кривую. + \en Put a given number of points on curve.\n + Points may be put only on a bounded curve. \~ + \param[in] count - \ru Количество точек. + \en The number of points. \~ + \param[in] on - \ru Точка, проекция которой будет добавлена в результат + в случае замкнутой кривой. + \en Projection of this point will be added in the result + in a case of closed curve. \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[out] points - \ru Точки на кривой. + \en Points on the curve. \~ + \param[out] pars - \ru Параметры на кривой. + \en Parameters on the curve. \~ + \return \ru true, если точки были насчитаны. + \en true if points were calculated. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) PointsOnCurve( ptrdiff_t count, const MbCartPoint & on, const MbCurve & curve, + SArray & points, + SArray & pars ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить кривые. + \en Construct curves. \~ + \details \ru Построить кривые по коэффициентам конического сечения. + \en Construct curves by conic section coefficients. \~ + \param[in] A, B, C, D, E, F - \ru Коэффициенты уравнения конического сечения + A*x^2 + B*x*y + C*y^2 + D*x + E*y + F = 0. + \en The coefficients of the conic section equation + A*x^2 + B*x*y + C*y^2 + D*x + E*y + F = 0. \~ + \param[in] X1, Y1 - \ru Координаты первой граничной точки. + \en The first boundary point coordinates. \~ + \param[in] X2, Y2 - \ru Координаты второй граничной точки. + \en The second boundary point coordinates. \~ + \return \ru Результаты построения: + - дуга окружности -> дуга окружности; + - дуга эллипса -> дуга эллипса; + - дуга параболы -> NURBS-кривая; + - дуга гиперболы -> NURBS-кривая. + \en The construction results: + - circle arc -> circle arc; + - ellipse arc -> ellipse arc; + - parabola arc -> NURBS-curve; + - hyperbola arc -> NURBS-curve. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbCurve *) CanonicToParametricConic( double A, double B, double C, double D, double E, double F, + double X1, double Y1, double X2, double Y2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Аппроксимация кривой дугами и отрезками. + \en Approximation of a curve by arcs and segments. \~ + \details \ru Аппроксимация кривой дугами и отрезками. + \en Approximation of a curve by arcs and segments. \~ + \param[in] curve - \ru Кривая для аппроксимации. + \en The curve for approximation. \~ + \param[in] eps - \ru Метрическая погрешность. + \en The metric tolerance. \~ + \param[in] maxRadius - \ru Максимальный радиус аппроксимации. + \en The minimal approximation radius. \~ + \param[in] mate - \ru Флаг аппроксимации с учетом сопряжений. + \en The approximation flag with consideration of conjugations. \~ + \param[in] version - \ru Версия построения. + \en The version of construction. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbCurve *) FatArcContour( const MbCurve & curve, double eps, double maxRadius, bool mate, + VERSION version = Math::DefaultMathVersion() ); + + +#endif // __ALG_CURVE_DISTANCE_H diff --git a/C3d/Include/alg_curve_envelope.h b/C3d/Include/alg_curve_envelope.h new file mode 100644 index 0000000..f545999 --- /dev/null +++ b/C3d/Include/alg_curve_envelope.h @@ -0,0 +1,130 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Операции с кривыми в двумерном пространстве. + \en Operations with curves in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_ENVELOPE_H +#define __ALG_CURVE_ENVELOPE_H + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти первый сегмент контура. + \en Find the first segment of a contour. \~ + \details \ru Найти первый сегмент контура.\n + В контур добавляется часть кривой selectCurve между параметрами пересечение, + ближайшими к проекции точки insidePoint. + \en Find the first segment of a contour.\n + A piece of the curve "selectCurve" between intersection parameters is added in contour, + the parameters are the nearest to the projection of the point "insidePoint". \~ + \param[in] insidePnt - \ru Точка, вокруг которой надо построить контур. + \en The point around which to create the contour. \~ + \param[in] selectCurve - \ru Ближайшая кривая. + \en The nearest curve. \~ + \param[in] cross - \ru Множество точек пересечения ближайшей кривой. + \en The array of points of intersection with the nearest curve. \~ + \param[out] contour - \ru Контур для добавления сегмента. + \en The contour for adding the segment to. \~ + \param[out] crossRight - \ru Узел - массив точек пересечения кривой в сторону продолжения конутра. + \en The node - the array of intersection points in the side of contour extension. \~ + \return \ru true, если сегмент добавлен. + \en true if a segment has been added. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) BeginEnvelopeContour( MbCartPoint & insidePnt, const MbCurve * selectCurve, + SArray & cross, + MbContour & contour, + SArray & crossRight ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти ближайшую кривую. + \en Find the nearest curve. \~ + \details \ru Найти ближайшую к точке кривую. + \en Find the curve nearest to a point. \~ + \param[in] curveList - \ru Список кривых. + \en The list of curves. \~ + \param[in] pnt - \ru Точка. + \en The point. \~ + \return \ru Ближайшую кривую. + \en The nearest curve. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbCurve *) FindNearestCurve( List & curveList, MbCartPoint & pnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти точки пересечения. + \en Find intersection points. \~ + \details \ru Найти точки пересечения выбранной кривой с + остальными кривыми списка от кривой включительно. + \en Find intersection points of the chosen curve with + the other curves from the list. \~ + \param[in] selectCurve - \ru Кривая. + \en The curve. \~ + \param[in] fromCurve - \ru Итератор списка кривых. + \en The iterator of the curves list. \~ + \param[out] cross - \ru Точки пересечения. + \en Intersection points. \~ + \param[in] self - \ru Флаг поиска самопересечений. + \en Flag of self-intersections search. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) IntersectWithAll( const MbCurve * selectCurve, + LIterator & fromCurve, + SArray & cross, bool self ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сортировать точки пересечения. + \en Sort intersection points. \~ + \details \ru Сортировать точки пересечения по отношению к точки проекции + выбранной кривой. + \en Sort intersection points relative to the projection point + of the chosen curve. \~ + \param[in] tProj - \ru Параметр проекции на кривую. + \en Parameter of the projection on the curve. \~ + \param[in] selectCurve - \ru Кривая. + \en The curve. \~ + \param[in, out] cross - \ru Множество точек пересечения для сортировки. + \en The array of intersection points for sorting. \~ + \param[out] crossLeft - \ru Узел точек пересечения слева от проекции. + \en The node of intersection points on the left of the projection. \~ + \param[out] crossRight - \ru Узел точек пересечения справа от проекции. + \en The node of intersection points on the right of the projection. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) SortCrossPoints( double tProj, const MbCurve * selectCurve, + SArray & cross, + SArray & crossLeft, + SArray & crossRight ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить совпадающие точки. + \en Delete coincident points. \~ + \details \ru Удалить из массива точки совпадающие с точкой проекции, заданной параметром.\n + Если все точки совпадают с точкой проекции, то они не будут удалены. + \en Delete points from the array which are coincident with the projection point specified by the parameter.\n + If all the points are coincident with the projection point, then they will not be deleted. \~ + \param[in] tProj - \ru Параметр проекции. + \en The projection parameter. \~ + \param[in, out] cross - \ru Множество точек пересечения. + \en The array of intersection points. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) RemoveEquPoints( double tProj, SArray & cross ); + + +#endif // __ALG_CURVE_ENVELOPE_H diff --git a/C3d/Include/alg_curve_equid.h b/C3d/Include/alg_curve_equid.h new file mode 100644 index 0000000..35c5abe --- /dev/null +++ b/C3d/Include/alg_curve_equid.h @@ -0,0 +1,79 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение эквидистанты. Построение штриховки. + \en Construction of equidistance. Construction of hatching. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_EQUID_H +#define __ALG_CURVE_EQUID_H + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение эквидистантных кривых к кривой. + \en Construction of offset curves to a curve. \~ + \details \ru Построение эквидистантных кривых к произвольной кривой справа и слева. + Имя каждого эквидистантного контура совпадает с именем исходного. + \en Construction of equidistant curves to arbitrary curve on the right and on the left. + A name of every offset contour matches with the name of the initial one. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve \~ + \param[in] radLeft - \ru Радиус эквидистанты слева по направлению. + \en The equidistance radius on the left by direction. \~ + \param[in] radRight - \ru Радиус эквидистанты справа по направлению. + \en The equidistance radius on the right by direction. \~ + \param[in] side - \ru Признак, с какой стороны строить:\n + 0 - слева по направлению,\n + 1 - справа по направлению,\n + 2 - с двух сторон. + \en Attribute defining the side to construct:\n + 0 - on the left by derection,\n + 1 - on the right by derection,\n + 2 - on the both sides. \~ + \param[in] arcMode - \ru Cпособ обхода углов:\n + true - дугой, + false - срезом. + \en The way of traverse of angles:\n + true - by arc, + false - by section. \~ + \param[in] degState - \ru Признак разрешения вырожденных сегментов:\n + 0 - вырожденные сегменты запрещены,\n + 1 - вырожденные сегменты разрешены. + \en Attribute of degenerate segments allowance:\n + 0 - degenerate segments are forbidden,\n + 1 - degenerate segments are allowed. \~ + \param[out] equLeft - \ru Множество контуров слева. + \en The array of contours on the left side. \~ + \param[out] equRight - \ru Множество контуров справа. + \en The array of contours on the right side. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) Equid( const MbCurve *curve, double radLeft, double radRight, + int side, bool arcMode, bool degState, + PArray &equLeft, PArray &equRight ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение области штриховки кривых. + \en Construction of curves hatching region. \~ + \details \ru Построение штриховки заданной ширины внутри или около кривых. + \en Construction of hatching with a given width inside or near curves. \~ + \param[in] contour - \ru Исходная кривые. + \en Initial curves \~ + \param[in] witdh - \ru Ширина штриховки. + \en The hatching width. \~ + \param[out] borders - \ru Множество линий штриховки и границ штриховки. + \en The array of hatching lines and hatching boundaries. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) MakeHatchingArea( const PArray & contour, double witdh, + PArray & borders ); + + +#endif // __ALG_CURVE_EQUID_H diff --git a/C3d/Include/alg_curve_fillet.h b/C3d/Include/alg_curve_fillet.h new file mode 100644 index 0000000..21d3c9f --- /dev/null +++ b/C3d/Include/alg_curve_fillet.h @@ -0,0 +1,190 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение скругления, фаски между двумя кривыми в двумерном пространстве. + \en Construction of fillet or chamfer between two curves in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_FILLET_H +#define __ALG_CURVE_FILLET_H + +#include + + +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbArc; +class MATH_CLASS MbContour; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить скругление между кривыми. + \en Construct fillet between curves. \~ + \details \ru Построить скругление постоянным радиусом между двумя кривыми. + \en Construct fillet with a constant radius between two curves. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] pnt1 - \ru Точка вблизи первой кривой. + \en The point near the first curve. \~ + \param[in] trim1 - \ru Признак усечения первой кривой. + \en The attribute of trimming of the first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] pnt2 - \ru Точка вблизи второй кривой. + \en The point near the second curve. \~ + \param[in] trim2 - \ru Признак усечения второй кривой. + \en The attribute of trimming of the second curve. \~ + \param[in] rad - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[out] state1 - \ru Состояние первой кривой. + \en The state of the first curve. \~ + \param[out] state2 - \ru Состояние второй кривой. + \en The state of the second curve. \~ + \param[out] arc - \ru Дуга скругления. + \en The arc of fillet. \~ + \return \ru true в случае успешной операции. + \en true in case of successful operation. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) Fillet( MbCurve * curve1, const MbCartPoint & pnt1, bool trim1, + MbCurve * curve2, const MbCartPoint & pnt2, bool trim2, + double rad, + MbeState & state1, + MbeState & state2, + MbArc *& arc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фаску. + \en Construct a chamfer. \~ + \details \ru Построить фаску между двумя кривыми. + \en Construct a chamfer between two curves. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] pnt1 - \ru Точка вблизи первой кривой. + \en The point near the first curve. \~ + \param[in] trim1 - \ru Признак усечения первой кривой. + \en The attribute of trimming of the first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] pnt2 - \ru Точка вблизи второй кривой. + \en The point near the second curve. \~ + \param[in] trim2 - \ru Признак усечения второй кривой. + \en The attribute of trimming of the second curve. \~ + \param[in] len - \ru Размер фаски на первой кривой. + \en The size of the chamfer on the first curve. \~ + \param[in] angle - \ru Угол фаски или размер фаски на второй кривой в зависимости от типа построения. + \en The angle of the chamfer or the size of the chamfer on the second curve according to the type of construction. \~ + \param[in] type - \ru Тип построения фаски:\n + true - размер + угол,\n + false - размер + размер. + \en The type of chamfer construction:\n + true - size + angle,\n + false - size + size. \~ + \param[out] state1 - \ru Состояние первой кривой. + \en The state of the first curve. \~ + \param[out] state2 - \ru Состояние второй кривой. + \en The state of the second curve. \~ + \param[out] lineseg - \ru Отрезок фаски. + \en The segment of the chamfer. \~ + \return \ru true в случае успешной операции. + \en is true in case of successful operation. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) Chamfer( MbCurve * curve1, const MbCartPoint & pnt1, bool trim1, + MbCurve * curve2, const MbCartPoint & pnt2, bool trim2, + double len, double angle, bool type, + MbeState & state1, + MbeState & state2, + MbLineSegment *& lineseg ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить скругление. + \en Construct a fillet. \~ + \details \ru Построить скругление полилинии или контура.\n + Изменяемая кривая mc должна быть полилинией или контуром. + \en Construct a fillet of polyline or contour.\n + The curve "mc" being modified should be a polyline or a contour. \~ + \param[in] mc - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] rad - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] nodeFlag - \ru Флаг выбора узлов скругления:\n + true - скругление во всех узлах,\n + false - скругление ближайшего узла. + \en The flag of selection of fillet nodes.\n + true - fillet at all nodes,\n + false - fillet of the nearest node. \~ + \param[in] pnt - \ru Точка для выбора ближайшего узла. + \en The point of choosing of the nearest node. \~ + \param[out] contour - \ru Контур, построенный по полилинии. + \en Contour constructed by a polyline. \~ + \return \ru Состояние кривой после её модификации. + \en The state of a curve after modification. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeState) FilletPolyContour( MbCurve * mc, double rad, bool nodeFlag, + const MbCartPoint & pnt, MbContour *& contour ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить фаску. + \en Construct a chamfer. \~ + \details \ru Построить фаску полилинии или контура.\n + Изменяемая кривая mc должна быть полилинией или контуром. + \en Construct a chamfer of polyline or contour.\n + The curve "mc" being modified should be a polyline or a contour. \~ + \param[in] mc - \ru Изменяемая кривая. + \en The modified curve. \~ + \param[in] l1 - \ru Размер фаски. + \en The size of a chamfer. \~ + \param[in] par - \ru Угол фаски или размер фаски в зависимости от типа построения. + \en The angle of a chamfer or the size of a chamfer on the second curve according to the type of construction. \~ + \param[in] chamferTypeFlag - \ru Тип построения фаски:\n + true - размер + угол,\n + false - размер + размер. + \en The type of chamfer construction:\n + true - size + angle,\n + false - size + size. \~ + \param[in] nodeFlag - \ru Флаг выбора узлов скругления:\n + true - скругление во всех узлах,\n + false - скругление ближайшего узла. + \en The flag of selection of fillet nodes.\n + true - fillet at all nodes,\n + false - fillet of the nearest node. \~ + \param[in] pnt - \ru Точка для выбора ближайшего узла. + \en The point of choosing of the nearest node. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) ChamferPolyContour( MbCurve * mc, double l1, double par, + bool chamferTypeFlag, bool nodeFlag, + const MbCartPoint & pnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Продлить кривые. + \en Extend curves. \~ + \details \ru Продлить две кривые до точки пересечения. + \en Extend two curves to the point of intersection. \~ + \param[in, out] crv1 - \ru Первая кривая + \en The first curve. \~ + \param[in, out] crv2 - \ru Вторая кривая. + \en The second curve. \~ + \param[in] p1 - \ru Точка для выбора места пересечения. + \en The point for selection of intersection location. \~ + \param[in] p2 - \ru Точка для выбора места пересечения. + \en The point for selection of intersection location. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) Corner( MbCurve * crv1, MbCurve * crv2, + const MbCartPoint & p1, const MbCartPoint & p2 ); + + +#endif // __ALG_CURVE_FILLET_H diff --git a/C3d/Include/alg_curve_hatch.h b/C3d/Include/alg_curve_hatch.h new file mode 100644 index 0000000..f315c35 --- /dev/null +++ b/C3d/Include/alg_curve_hatch.h @@ -0,0 +1,54 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пересечение кривых в двумерном пространстве для штриховки. + \en Intersection of curves in two-dimensional space for hatching. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_HATCH_H +#define __ALG_CURVE_HATCH_H + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти пересечение с горизонтальной прямой. + \en Find intersection with horizontal line. \~ + \details \ru Найти пересечение кривой с горизонтальной прямой. + Для штриховки. + \en Find intersection of a curve with horizontal line. + For hatching. \~ + \param[in] y - \ru Координата у горизонтальной прямой. + \en The coordinate of a horizontal line. \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[out] crossPnt - \ru Точки пересечения. + \en Intersection points. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) HatchIntersectLine( double y, MbCurve * curve, SArray & crossPnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти пересечение с окружностью. + \en Find intersection with a circle. \~ + \details \ru Найти пересечение с окружностью.\n + Для штриховки. + \en Find intersection with a circle.\n + For hatching. \~ + \param[in] circle - \ru Окружность. + \en The circle. \~ + \param[in] curve - \ru Кривая. + \en The curve. \~ + \param[out] crossPnt - \ru Точки пересечения. + \en Intersection points. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) HatchIntersectCircle( MbCurve * circle, MbCurve * curve, SArray & crossPnt ); + + +#endif // __ALG_CURVE_HATCH_H diff --git a/C3d/Include/alg_curve_tangent.h b/C3d/Include/alg_curve_tangent.h new file mode 100644 index 0000000..d16da71 --- /dev/null +++ b/C3d/Include/alg_curve_tangent.h @@ -0,0 +1,163 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение прямой. + \en Construction of line. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_CURVE_TANGENT_H +#define __ALG_CURVE_TANGENT_H + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить касательные прямые. + \en Construct a line. \~ + \details \ru Построить все возможные прямые через точку касательно данной кривой.\n + Базовая точка прямой сопадает с точкой касания. + \en Construct a line passing throgh a point and tangent to a given curve.\n + A line origin is coincident with a tangency point. \~ + \param[in] pnt - \ru Точка, через которую проходит прямая. + \en The point which the line passing through. \~ + \param[in] pCurve - \ru Кривая, которой должна касаться построенная прямая. + \en The curve which the constructed line should be tangent to. \~ + \param[out] pLine - \ru Набор прямых. + \en The set of lines. \~ + \param[in] lineAsCurve - \ru Обрабатывать прямую, ломаную и отрезок как кривую в общеи мслучае. + \en Work with MbLline, MbPolyline, MbLineSegment as with MbCurve. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LinePointTangentCurve( MbCartPoint & pnt, const MbCurve & pCurve, + PArray & pLine, bool lineAsCurve = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямые под углом. + \en Construct lines passing at angle. \~ + \details \ru Построить прямые, проходящие под углом angle к оси 0X и касательные к кривой.\n + Базовая точка прямой сопадает с точкой касания. + \en Construct lines at angle "angle" to the axis OX and tangent to the curve.\n + A line origin is coincident with a tangency point. \~ + \param[in] angle - \ru Угол к оси абсцисс. + \en The angle to the abscissa axis. \~ + \param[in] pCurve - \ru Кривая, которой должна касаться построенная прямая. + \en The curve which the constructed line should be tangent to. \~ + \param[out] pLine - \ru Набор прямых. + \en The set of lines. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LineAngleTangentCurve( double angle, const MbCurve & pCurve, + PArray & pLine ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямые, касательные к окружностям. + \en Construct lines tangent to circles. \~ + \details \ru Построить прямые, касательные к двум окружностям, + заданным центрами и радиусами.\n + Базовая точка прямой сопадает с точкой касания первой окружности. + Функция строит от 0 до 4 прямых. + \en Construct lines tangent to two circles. + with given centers and radii.\n + A line origin is coincident with a point of tangency with the first circle. + Function constructs from 0 to 4 variables. \~ + \param[in] centre1 - \ru Центр первой окружности. + \en The center of the first circle. \~ + \param[in] radius1 - \ru Радиус первой окружности. + \en The radius of the first circle. \~ + \param[in] centre2 - \ru Центр второй окружности. + \en The center of the second circle. \~ + \param[in] radius2 - \ru Радиус второй окружности. + \en The radius of the second circle. \~ + \param[out] pl - \ru Результат - массив прямых. + \en The result - the array of lines. \~ + \param[out] sp - \ru Множество точек касания на второй кривой. + \en The array of tangency points on the second curve. \~ + \return \ru Количество прямых в массиве pl, + равное количеству базовых точек в массиве sp. + \en The number of lines in array "pl" + that is equal to the number of the base points in array "sp". \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) LineTan2Circles( const MbCartPoint & centre1, double radius1, + const MbCartPoint & centre2, double radius2, + MbLine * pl, MbCartPoint * sp ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить касательную прямую. + \en Construct a tangent line. \~ + \details \ru Построить прямую, касательную двум кривым.\n + Базовая точка прямой сопадает с точкой касания первой кривой. + \en Construct a line tangent to two curves.\n + A line origin is coincident with a point of tangency on the first curve. \~ + \param[in] pCurve1 - \ru Первая кривая, которой должна касаться построенная прямая. + \en The first curve which the constructed line should be tangent to. \~ + \param[in] pCurve2 - \ru Вторая кривая, которой должна касаться построенная прямая. + \en The second curve the constructed line should be tangent to. \~ + \param[out] pLine - \ru Результат - массив прямых. + \en The result - the array of lines. \~ + \param[out] secodnPnt - \ru Множество точек касания на второй кривой. + \en The array of tangency points on the second curve. \~ + \return \ru Количество прямых в массиве pLine, + равное количеству точек в массиве secodnPnt. + \en The number of lines in array "pline" + that is equal to the number of points in array "secondPnt". \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) LineTangentTwoCurves( const MbCurve * pCurve1, const MbCurve * pCurve2, + PArray * pLine, + SArray * secodnPnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить прямые под углом. + \en Construct lines passing at angle. \~ + \details \ru Построить прямые, проходящие под углом angle к оси 0X, + касательные к окружности, заданной центром и радиусом. + \en Construct lines at angle "angle" to the axis OX, + tangent to a circle with the given center and radius. \~ + \param[in] angle - \ru Угол. + \en The angle. \~ + \param[in] centre - \ru Центр окружности. + \en The circle center. \~ + \param[in] radius - \ru Радиус окружности. + \en The circle radius. \~ + \param[out] pLine - \ru Результат - массив прямых. + \en The result - the array of lines. \~ + \return \ru Количество прямых в массиве pLine. + \en The number of lines in array "pLine", \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (ptrdiff_t) LineAngleTanCircle( double angle, const MbCartPoint & centre, double radius, MbLine * pLine ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Перестывить прямые. + \en Swap lines. \~ + \details \ru Перестывить прямые местами. + \en Swap lines. \~ + \param[in] l1 - \ru Первая прямая. + \en The first line. \~ + \param[in] l2 - \ru Вторая прямая. + \en The second line. \~ + \ingroup Curve_Modeling +*/ +// --- +inline +void SwapLines( MbLine & l1, MbLine & l2 ) +{ + std::swap( l1.SetOrigin(), l2.SetOrigin() ); + std::swap( l1.SetDirection(), l2.SetDirection() ); +} + + +#endif // __ALG_CURVE_TANGENT_H diff --git a/C3d/Include/alg_dimension.h b/C3d/Include/alg_dimension.h new file mode 100644 index 0000000..d80d839 --- /dev/null +++ b/C3d/Include/alg_dimension.h @@ -0,0 +1,446 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \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 + + +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbPlaneCurve; +class MATH_CLASS MbSurface; +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 surface. \~ + \details \ru Класс содержит данные о расстоянии между точками и координатами этих точек + на поверхностях. + \en The class contains data about the distance between points and their coordinates + on surfaces. \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS MbSurfDist { + friend class MbMinMaxSurfDists; +private: + double d; ///< \ru Расстояние. \en Distance. + MbCartPoint uv1; ///< \ru Параметр на первой поверхности. \en Parameter on the first surface. + MbCartPoint uv2; ///< \ru Параметр на второй поверхности. \en Parameter on the second surface. + uint8 sign; ///< \ru Знак расстояния. \en Sign of direction. + +public: + /// \ru Конструктор. \en Constructor. + MbSurfDist() : d( UNDEFINED_DBL ), uv1(), uv2(), sign( 1 ) {} + /// \ru Конструктор по данным. \en The constructor by data. + MbSurfDist( double _d, const MbCartPoint & _uv1, const MbCartPoint & _uv2, bool plus ) { Init( _d, _uv1, _uv2, plus ); } + /// \ru Конструктор копирования. \en Copy constructor. + MbSurfDist( const MbSurfDist & other ) { Init( other ); } + /// \ru Деструктор. \en The destructor. + virtual ~MbSurfDist() {} +public: + /// \ru Функция копирования. \en Copy function. + void Init( const MbSurfDist & obj ) { d = obj.d; uv1 = obj.uv1; uv2 = obj.uv2; sign = obj.sign; } + /// \ru Получить расстояние. \en Get distance. + double GetDistance() const { return d; } + /// \ru Получить точку на первой поверхности. \en Get the point on the first surface. + const MbCartPoint & GetPointOne() const { return uv1; } + /// \ru Получить точку на второй поверхности. \en Get the point on the second surface. + const MbCartPoint & GetPointTwo() const { return uv2; } + /// \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 MbSurfDist & operator = ( const MbSurfDist & other ) { Init( other ); return (*this); } + +private: + void Init( double _d, const MbCartPoint & _uv1, const MbCartPoint & _uv2, bool plus ); +}; + + +//------------------------------------------------------------------------------ +// \ru инициализатор \en Initializer +// --- +inline void MbSurfDist::Init( double _d, const MbCartPoint & _uv1, const MbCartPoint & _uv2, bool plus ) +{ + d = _d; + uv1 = _uv1; + uv2 = _uv2; + sign = plus ? 1 : 0; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Расстояния с точками между поверхностями. + \en Distances between surfaces with points. \~ + \details \ru Расстояния с точками между поверхностями. + \en Distances between surfaces with points. \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS MbMinMaxSurfDists { +private : + SArray surfDistances; ///< \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: + MbMinMaxSurfDists( size_t nReserve = 0 ); ///< \ru Конструктор. \en Constructor. + virtual ~MbMinMaxSurfDists(); ///< \ru Деструктор. \en Destructor. + +public: + bool IsEmpty() const { return (surfDistances.Count() < 1); } ///< \ru Есть ли замеры? \en Are there any measurements? + size_t GetCount() const { return surfDistances.Count(); } ///< \ru Количество замеров. \en The number of measurements. + ptrdiff_t GetMaxIndex() const { return surfDistances.MaxIndex(); } ///< \ru Индекс последнего замера. \en Index of the last measurement + void Reserve( size_t nReserve ); ///< \ru Зарезервировать память под nReserve элементов. \en Reserve memory for 'nReserve' elements. + void RemoveAll( bool bAdjustMemory ); ///< \ru Удалить все элементы \en Delete all elements. + void AdjustMemory(); ///< \ru Освободить лишнюю память \en Free the unnecessary memory. + + /// \ru Получить расстояние по индексу. \en Get the distance by the index. + bool GetDistance( size_t k, double & d ) const; + /// \ru Получить расстояние со знаком, по индексу. \en Get the signed distance by the index. + bool GetSignedDistance( size_t k, double & d ) const; + /// \ru Считаем ли вы расстояние отрицательным. \en Whether the distance is negative. + bool IsNegativeDistance( size_t k ) const { return ((k < surfDistances.Count()) ? surfDistances[k].IsNegative() : false); } + /// \ru Получить минимальное расстояние. \en Get minimal distance. + bool GetMinDistance( double & d ) const; + /// \ru Получить максимальное расстояние. \en Get maximal distance. + bool GetMaxDistance( double & d ) const; + /// \ru Получить среднее расстояние. \en Get average distance. + bool GetMidDistance( double & d ) const; + /// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface. + bool GetSurfDistance( size_t k, double & d, MbCartPoint & uv1, MbCartPoint & uv2 ) const; + /// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface. + bool GetSurfDistance( size_t k, double & d, bool & plus, MbCartPoint & uv1, MbCartPoint & uv2 ) const; + /// \ru Добавить расстояние и точки на поверхностях. \en Add distance and points on surface. + bool AddSurfDistance( double distance, bool plus, const MbCartPoint & uv1, const MbCartPoint & uv2, + bool bAddEqual, double eps = LENGTH_EPSILON ); + /// \ru Сортировать по возрастанию расстояния. \en Sort by distance in the ascending order. + void Sort(); + /// \ru Убрать объекты с одинаковыми расстояниями. \en Remove objects with similar distances. + void RemoveEqualDistances( double eps = LENGTH_EPSILON ); + + void operator = ( const MbMinMaxSurfDists & ); ///< \ru Оператор присваивания. \en Assignment operator. + +private: + MbMinMaxSurfDists( const MbMinMaxSurfDists & ); +}; + + +//------------------------------------------------------------------------------ +// \ru выдать расстояние \en get the distance +// --- +inline bool MbMinMaxSurfDists::GetDistance( size_t k, double & d ) const +{ + if ( k < surfDistances.Count() ) { + d = surfDistances[k].GetDistance(); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru выдать расстояние со знаком \en get signed distance +// --- +inline bool MbMinMaxSurfDists::GetSignedDistance( size_t k, double & d ) const +{ + if ( k < surfDistances.Count() ) { + d = surfDistances[k].GetDistance(); + if ( surfDistances[k].IsNegative() ) + d = -d; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/** \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 Direction of search. \~ + \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 registrated minimums. \~ + \param[in,out] nMax - \ru Кол-во регистрируемых максимумов. + \en The number of registrated 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 +*/ +// --- +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, + MbMinMaxSurfDists & allResults, + MbMinMaxSurfDists & minResults, + MbMinMaxSurfDists & maxResults, + IProgressIndicator * indicator = NULL ); + + +#endif // __ALG_DIMENSION_H diff --git a/C3d/Include/alg_diskrete_length_data.h b/C3d/Include/alg_diskrete_length_data.h new file mode 100644 index 0000000..72434a7 --- /dev/null +++ b/C3d/Include/alg_diskrete_length_data.h @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Данные для обеспечения дискретной длины/радиуса/расстояния в процессах пользовательского ввода кривых + \en Data for support of discrete length/radius/distance in processes of input of curves by user. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_DISKRETE_LENGTH_DATA_H +#define __ALG_DISKRETE_LENGTH_DATA_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для обеспечения дискретной длины/радиуса/расстояния. + \en Data for support of discrete length/radius/distance. \~ + \details \ru Данные для обеспечения дискретной длины/радиуса/расстояния в процессах + пользовательского ввода кривых.\n + Для округления до числа, кратного значению шага курсора:\n + Стандартное округление - значение округляется в меньшую сторону, если + разница между текущим значением и ближайшим кратным меньше половины шага курсора, + в противном случае округление выполняется в большую сторону. + \en Data for support of discrete length/radius/distance in processes + of input of curves by user.\n + For rounding to the multiple of value of the cursor step:\n + Standard round-off - the value is rounded down if + the difference between the current value and the nearest multiple of the initial value is less than a half of cursor step, + the value is rounded up otherwise. \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS DiskreteLengthData { +private: + double factor; ///< \ru Число, которому должна быть кратна корректируемая величина. \en Number, which should be a multiple of the value to be corrected. + +public: + /// \ru Конструктор. \en Constructor. + DiskreteLengthData( double fact ); + + /// \ru Установить число, которому должна быть кратна корректируемая величина. \en Set the number, which should be a multiple of the value to be corrected. + void SetFactor( double fact ); + /// \ru Скорректировать присланную величину. \en Correct the given value. + bool CorrectLength( double & len ) const; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры построения синусоиды. + \en Parameters of a sinusoid creation. \~ + \details \ru Параметры построения синусоиды для объекта "Волнистая линия". \n + \en Parameters of sinusoid construction for object "Wavy line". \n \~ + \ingroup Data_Structures + */ +// --- +class MATH_CLASS CosinusoidPar { +public : + static const double maxAmpl; ///< \ru Максимальное значение амплитуды. \en Maximal value of amplitude. + static const double minAmpl; ///< \ru Минимальное значение амплитуды. \en Minimal value of amplitude. + + Param m_WaveLineAmpl; ///< \ru Величина амплитуды. \en Amplitude value. + Param m_WaveLineAmplByPercent; ///< \ru Амплитуда задается в процентах от длины волны. \en The amplitude is defined as a percentage of the wave length. + double m_WaveLineLen; ///< \ru Величина длины волны. \en Wave length value. + size_t m_WaveLineCount; ///< \ru Величина количество полуволн. \en Value of half-waves number. + bool m_WaveLineByCount; ///< \ru Построение волнистой линии по количеству волн. \en Construction of wavy line by the number of waves. + bool m_WaveLineDir; ///< \ru Направление первой полуволны вверх или вниз. \en Up or down direction of the first half-wave. + + public : + CosinusoidPar(); + CosinusoidPar( const CosinusoidPar & ); + virtual ~CosinusoidPar(); + + void Assign( const CosinusoidPar & ); + void Read ( reader & ); + void Write ( writer & ) const; +}; + + +#endif // __ALG_DISKRETE_LENGTH_DATA_H diff --git a/C3d/Include/alg_draw.h b/C3d/Include/alg_draw.h new file mode 100644 index 0000000..48f85a9 --- /dev/null +++ b/C3d/Include/alg_draw.h @@ -0,0 +1,1050 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Отрисовка объектов. + \en Objects drawing. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_DRAW_H +#define __ALG_DRAW_H + + +#include +#include +#include +#include + + +#define TRGB_BLACK 0, 0, 0 ///< \ru Черный цвет. \en Black color. \~ \ingroup Drawing +#define TRGB_BLUE 0, 0, 192 ///< \ru Синий цвет. \en Blue color. \~ \ingroup Drawing +#define TRGB_GREEN 0, 128, 0 ///< \ru Зеленый цвет. \en Green color. \~ \ingroup Drawing +#define TRGB_CYAN 0, 128, 128 ///< \ru Голубой цвет. \en Cyan color. \~ \ingroup Drawing +#define TRGB_RED 192, 0, 0 ///< \ru Красный цвет. \en Red color. \~ \ingroup Drawing +#define TRGB_MAGENTA 96, 0, 192 ///< \ru Пурпурный цвет. \en Magenta color. \~ \ingroup Drawing +#define TRGB_BROWN 192, 128, 0 ///< \ru Коричневый цвет. \en Brown color. \~ \ingroup Drawing +#define TRGB_LIGHTGRAY 192, 192, 192 ///< \ru Светло-серый цвет. \en Light gray color \~ \ingroup Drawing +#define TRGB_DARKGRAY 128, 128, 128 ///< \ru Темно-серый цвет. \en Dark gray color \~ \ingroup Drawing +#define TRGB_LIGHTBLUE 0, 0, 255 ///< \ru Ярко-синий цвет. \en Light blue color. \~ \ingroup Drawing +#define TRGB_LIGHTGREEN 0, 255, 0 ///< \ru Ярко-зеленый цвет. \en Light green color. \~ \ingroup Drawing +#define TRGB_LIGHTCYAN 0, 96, 255 ///< \ru Светло-голубой цвет. \en Light cyan color \~ \ingroup Drawing +#define TRGB_LIGHTRED 255, 0, 0 ///< \ru Ярко-красный цвет. \en Light red color. \~ \ingroup Drawing +#define TRGB_LIGHTMAGENTA 96, 0, 255 ///< \ru Светло-пурпурный цвет. \en Light magenta color \~ \ingroup Drawing +#define TRGB_ORANGE 255, 128, 0 ///< \ru Оранжевый цвет. \en Orange color. \~ \ingroup Drawing +#define TRGB_YELLOW 255, 255, 0 ///< \ru Желтый цвет. \en Yellow color. \~ \ingroup Drawing +#define TRGB_WHITE 255, 255, 255 ///< \ru Белый цвет. \en White color. \~ \ingroup Drawing + +#define TRGB_PURPLE 255, 0, 255 ///< \ru Светло-фиолетовый цвет. \en Purple color \~ \ingroup Drawing +#define TRGB_AZURE 0, 125, 255 ///< \ru Лазурный цвет. \en Azure color. \~ \ingroup Drawing +#define TRGB_TANGERINE 255, 136, 0 ///< \ru Мандариновый цвет. \en Tangerine color. \~ \ingroup Drawing +#define TRGB_CERISE 255, 0, 125 ///< \ru Светло-вишневый цвет. \en Cerise color. \~ \ingroup Drawing +#define TRGB_OLIVE 128, 128, 0 ///< \ru Оливковый цвет. \en Olive color. \~ \ingroup Drawing +#define TRGB_SPRINGGREEN 0, 255, 127 ///< \ru Весенне-зеленый цвет. \en Spring green color. \~ \ingroup Drawing + +#define TRGB_DELETE TRGB_GREEN // \ru цвет удаляемых объектов \en A color of deleted objects +#define TRGB_NEW TRGB_RED // \ru цвет вновь создаваемых объектов \en A color of new objects +#define TRGB_CLEAR TRGB_LIGHTGRAY // \ru Закрасить \en Clear +#define TRGB_SHOW TRGB_BLACK // \ru Показать \en Show + + +class MATH_CLASS MbSpaceItem; +class MATH_CLASS MbPlaneItem; +class MATH_CLASS MbTopItem; +class MATH_CLASS MbVertex; +class MATH_CLASS MbEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbPlaneItem; +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbParamCurvePatch; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbFloatPoint3D; +class MATH_CLASS MbMesh; +class MATH_CLASS MbCube; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbPolygon3D; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbVector; +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbContourOnSurface; +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbCurveBoundedSurface; +class MATH_CLASS MbGrid; +class MATH_CLASS MbPlanarGrid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс отладочной отрисовки приложения. + \en Interface of debug drawing of application. \~ + \details \ru Интерфейс отладочной отрисовки для CallBack связи с вызывающим приложением. + \en Interface of debug drawing for connection with the calling application using callbacks. \~ + \ingroup Drawing +*/ +// --- +class IfDrawGI { +public: + IfDrawGI() {} + virtual ~IfDrawGI() {} + +public: + /// \ru Отрисовать объект. \en Draw an any object. + virtual void DrawItem( const MbRefItem * ri, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать трехмерный геометрический объект. \en Draw a three-dimensional geometric object. + virtual void DrawItem( const MbSpaceItem * gi, int R, int G, int B, int width = 1 ) = 0; + // Отрисовать трехмерный геометрический объект с размещением по матрице. + virtual void DrawItem( const MbSpaceItem * gi, int R, int G, int B, const MbMatrix3D & from, int width = 1 ) = 0; + /// \ru Отрисовать полигональный геометрический объект. \en Draw a polygonal geometric object. + virtual void DrawMesh( const MbMesh * ms, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать полигон. \en Draw a polygon. + virtual void DrawPolygon( const MbPolygon3D * polygon, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать трехмерную точку. \en Draw a three-dimensional point. + virtual void DrawPoint( const MbCartPoint3D * gi, int R, int G, int B, int width = 2 ) = 0; + /// \ru Отрисовать трехмерный отрезок. \en Draw a three-dimensional segment. + virtual void DrawLine( const MbCartPoint3D & q1, const MbCartPoint3D & q2, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать полилинию. \en Draw a polyline. + virtual void DrawPolyline( SArray & points, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать трехмерный отрезок. \en Draw a three-dimensional segment. + virtual void DrawLine( const MbCartPoint3D & p, const MbVector3D & v, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать трехмерный отрезок. \en Draw a three-dimensional segment. + virtual void DrawLine( const MbFloatPoint3D & q1, const MbFloatPoint3D & q2, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать участок трехмерной кривой. \en Draw a piece of a three-dimensional curve. + virtual void DrawCurve( const MbCurve3D & curve, double t1, double t2, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать часть двумерной кривой на плоскости. \en Draw a piece of a two-dimensional curve on a plane. + virtual void DrawCurve( const MbCurve & curve, const MbPlacement3D & place, double t1, double t2, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать двумерный геометрический объект. \en Draw a two-dimensional geometric object. + virtual void DrawItem( const MbPlaneItem * gi, int R, int G, int B, const MbMatrix3D & from, int width = 1 ) = 0; + /// \ru Отрисовать двумерный геометрический объект. \en Draw a two-dimensional geometric object. + virtual void DrawItem( const MbPlaneItem * gi, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать двумерную точку. \en Draw a two-dimensional point. + virtual void DrawPoint( const MbCartPoint * gi, int R, int G, int B, const MbMatrix3D & from, int width = 1 ) = 0; + /// \ru Отрисовать двумерную точку. \en Draw a two-dimensional point. + virtual void DrawPoint( const MbCartPoint * gi, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать двумерный отрезок. \en Draw a two-dimensional segment. + virtual void DrawLine( const MbCartPoint & q1, const MbCartPoint & q2, int R, int G, int B, const MbMatrix3D & from, int width = 1 ) = 0; + /// \ru Отрисовать двумерный отрезок. \en Draw a two-dimensional segment. + virtual void DrawLine( const MbCartPoint & q1, const MbCartPoint & q2, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать топологический объект. \en Draw a topological object. + virtual void DrawItem( const MbTopItem * ti, int R, int G, int B, const MbMatrix3D & from = MbMatrix3D::identity, int width = 1 ) = 0; + /// \ru Отрисовать ребро. \en Draw an edge. + virtual void DrawEdge( const MbEdge * edge, int r, int g, int b, bool drawVerts, int width = 1 ) = 0; + /// \ru Отрисовать патч двумерной кривой. \en Draw a patch of a two-dimensional curve. + virtual void PutPatch( const MbCartPoint & pnt, const MbVector & dir, double a, double b, int R, int G, int B, const MbMatrix3D & mapInto ) = 0; + /// \ru Отрисовать габаритный куб. \en Draw a bounding box. + virtual void PutCube( const MbCube & gab, int width = 1, bool bDrawRed = true ) = 0; + /// \ru Отрисовать систему координат. \en Draw a coordinate system. + virtual void DrawPlacement3D( const MbPlacement3D & place, double lenAxes, int width = 1 ) = 0; + /// \ru Очистить текущее окно. \en Clear the active window. + virtual void DrawClearMap() = 0; + /// \ru Отрисовать двумерную кривую на поверхности. \en Draw a two-dimensional curve on a surface. + virtual void DrawItem( const MbCurve * curve, const MbSurface * surface, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать карту кривой на поверхности. \en Draw a map of a curve on a surface. + virtual void DrawCurveMap( const MbCurve * curve, const MbSurface * surface, int R, int G, int B ) = 0; + /// \ru Отрисовать кривую на поверхности. \en Draw a curve on a surface. + virtual void DrawSurfaceCurveMap( const MbSurfaceCurve * scurve, int R, int G, int B ) = 0; + /// \ru Отрисовать точку на поверхности. \en Draw a point on a surface. + virtual void DrawPointMap( const MbCartPoint * pnt, const MbSurface * surface, int R, int G, int B ) = 0; + /// \ru Отрисовать кривую пересечения на параметрической плоскости. \en Draw an intersection curve on a parametric plane. + virtual void DrawSurfaceIntersectionMap( const MbSurfaceIntersectionCurve * gi, int R1, int G1, int B1, int R2, int G2, int B2 ) = 0; + /// \ru Отрисовать контур на поверхности в параметрической плоскости. \en Draw a contour on a surface in a parametric plane. + virtual void DrawContourOnSurfaceMap( const MbContourOnSurface * gi, int R, int G, int B ) = 0; + /// \ru Отрисовать ограничивающие кривые усеченной поверхности в ее параметрической плоскости. \en Draw bounding curves of a trimmed surface in its parametric plane. + virtual void DrawCurveBoundedSurfaceMap( const MbCurveBoundedSurface * bnds, int R, int G, int B ) = 0; + /// \ru Отрисовать параметрическую плоскость поверхности. \en Draw a parametric plane of a surface. + virtual void DrawSurfaceMap( const MbSurface * surface, int R, int G, int B ) = 0; + /// \ru Отрисовать ограничивающие кривые грани в ее параметрической плоскости. \en Draw bounding curves of a face in its parametric plane. + virtual void DrawFaceMap( const MbFace *, int R, int G, int B ) = 0; + /// \ru Отрисовать параметрическую точку поверхности. \en Draw a parametric point of a surface. + virtual void DrawPoint( const MbSurface & surface, const MbCartPoint & uv, int R, int G, int B, int width = 2 ) = 0; + /// \ru Отрисовать массив 3d-точек по массиву 2d-точек и поверхности. \en Draw an array of 3D-points by an array of 2D-points and a surface. + virtual void DrawPoints( const MbSurface & surface, const SArray & uvArr, int R, int G, int B, int width = 2 ) = 0; + /// \ru Отрисовать массив 3d-точек по массиву параметров и кривой. \en Draw an array of 3D-points by an array of parameters and a curve. + virtual void DrawPoints( const MbCurve3D & curve, const SArray & tArr, int R, int G, int B, int width = 2 ) = 0; + /// \ru Отрисовать массив 3d-точек. \en Draw an array of 3D-points. + virtual void DrawPoints( const SArray & pnts, int R, int G, int B, int width = 2 ) = 0; + /// \ru Отрисовать триангуляцию. \en Draw a triangulation. + virtual void PutGrid( const MbGrid & grid, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать треугольник. \en Draw a triangle. + virtual void PutTriangle( const MbGrid & grid, ptrdiff_t index, int R, int G, int B ) = 0; + /// \ru Отрисовать треугольник. \en Draw a triangle. + virtual void PutTriangle( const MbSurface & surface, + const MbCartPoint & uv0, const MbCartPoint & uv1, const MbCartPoint & uv2, + int R, int G, int B ) = 0; + /// \ru Отрисовать четырёхугольник. \en Draw a quadrangle. + virtual void PutQuadrangle( const MbGrid & grid, ptrdiff_t index, int R, int G, int B ) = 0; + /// \ru Отрисовать двумерную триангуляцию. \en Draw a two-dimensional triangulation. + virtual void PutPlanarGrid( MbPlanarGrid & grid, const MbPlacement3D & place, int R, int G, int B, int width = 1 ) = 0; + /// \ru Отрисовать триангуляционную сетку на поверхности. \en Draw a triangular mesh on a surface. + virtual void DrawGridMap( const MbGrid & grid, const MbSurface & surface, int R, int G, int B ) = 0; + /// \ru Стереть модель. \en Delete model. + virtual void EraseModel() = 0; + /// \ru Перерисовать модель. \en Redraw the model. + virtual void RedrawModel() = 0; + +OBVIOUS_PRIVATE_COPY( IfDrawGI ) +}; + + +#if defined(_DRAWGI) + + +//------------------------------------------------------------------------------ +/** \brief \ru Функции отладочной отрисовки объектов приложения. + \en Functions of debug drawing of application objects. \~ + \details \ru Функции отладочной отрисовки геометрических объектов заданным цветом в текущем окне + используют интерфейс IfDrawGI, полученный через функцию SetDrawGI. + \en Functions of debug drawing of geometric objects by a given color in an active window + use the interface 'IfDrawGI' obtained by the function 'SetDrawGI'. \~ + \ingroup Drawing +*/ +// --- +class MATH_CLASS DrawGI { +public: + +////////////////////// \ru Отрисовка трехмерных объектов. ////////////////////////// +////////////////////// \en Drawing of three-dimensional objects. ////////////////////////// + + /** \brief \ru Отрисовать трехмерный геометрический объект. + \en Draw a three-dimensional geometric object. \~ + \details \ru Функция геометрического объекта заданным цветом в текущем окне. + \en The function of geometric object drawing by a given color in an active window. \~ + \param[in] gi - \ru Пространственный объект. + \en The spatial object. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawItem( const MbSpaceItem * gi, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать полигональный геометрический объект. + \en Draw a polygonal geometric object. \~ + \details \ru Функция отрисовки полигонального геометрического объекта заданным цветом в текущем окне. + \en The function of the polygonal geometric object drawing by a given color in an active window. \~ + \param[in] ms - \ru Фасетный объект. + \en The mesh. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawMesh( const MbMesh * ms, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать полигон. + \en Draw a polygon. \~ + \details \ru Функция отрисовки полигона заданным цветом в текущем окне. + \en The function of polygon drawing by a given color in an active window. \~ + \param[in] polygon - \ru Полигон. + \en The polygon. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPolygon( const MbPolygon3D * polygon, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать трехмерную точку. + \en Draw a three-dimensional point. \~ + \details \ru Функция отрисовки точки заданным цветом в текущем окне. + \en The function of point drawing by a given color in an active window. \~ + \param[in] gi - \ru Исходная точка. + \en The initial point. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoint( const MbCartPoint3D * gi, int R, int G, int B, int width = 2 ); + + /** \brief \ru Отрисовать трехмерный отрезок. + \en Draw a three-dimensional segment. \~ + \details \ru Функция отрисовки отрезка заданным цветом в текущем окне. Отрезок задается + крайними точками. + \en The function of segment drawing by a given color in an active window. A segment is specified + by the end points. \~ + \param[in] q1, q2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawLine( const MbCartPoint3D & q1, const MbCartPoint3D & q2, int R, int G, int B, int width = 1 ); + + + /** \brief \ru Отрисовать полилинию. + \en Draw a polyline. \~ + \details \ru Функция отрисовки полилинии заданным цветом в текущем окне. Полилиния задается + массивом трехмерных точек. + \en The function of polyline drawing by a given color in an active window. Polyline is specified + by an array of three-dimensional points. \~ + \param[in] points - \ru Исходный массив точек. + \en The initial array of points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPolyline( SArray & points, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать трехмерный отрезок. + \en Draw a three-dimensional segment. \~ + \details \ru Функция отрисовки отрезка заданным цветом в текущем окне. Отрезок задается + точкой и вектором. + \en The function of segment drawing by a given color in an active window. A segment is specified + by point and vector. \~ + \param[in] p - \ru Исходная точка. + \en The initial point. \~ + \param[in] v - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawLine( const MbCartPoint3D & p, const MbVector3D & v, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать трехмерный отрезок. + \en Draw a three-dimensional segment. \~ + \details \ru Функция отрисовки отрезка заданным цветом в текущем окне. Отрезок задается + крайними точками. + \en The function of segment drawing by a given color in an active window. A segment is specified + by the end points. \~ + \param[in] q1, q2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawLine( const MbFloatPoint3D & q1, const MbFloatPoint3D & q2, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать участок трехмерной кривой. + \en Draw a piece of a three-dimensional curve. \~ + \details \ru Функция отрисовки участка кривой заданным цветом в текущем окне. Участок + кривой задается параметрами начала и конца участка. + \en The function of curve piece drawing by a given color in an active window. A piece + of a curve is specified by start and end parameters of a piece. \~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] t1, t2 - \ru Начало и конец участка кривой, который требуется отрисовать. + \en The start parameter and the end parameter of a curve piece which is required to draw. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawCurve( const MbCurve3D & curve, double t1, double t2, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать часть двумерной кривой на плоскости. + \en Draw a piece of a two-dimensional curve on a plane. \~ + \details \ru Функция отрисовки участка кривой заданным цветом в текущем окне. Участок + кривой задается параметрами начала и конца участка. + \en The function of curve piece drawing by a given color in an active window. A piece + of a curve is specified by start and end parameters of a piece. \~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] place - \ru Исходный плейсмент. Задает плоскость для отрисовки. + \en The initial placement. It specifies the plane for drawing. \~ + \param[in] t1, t2 - \ru Начало и конец участка кривой, который требуется отрисовать. + \en The start parameter and the end parameter of a curve piece which is required to draw. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawCurve( const MbCurve & curve, const MbPlacement3D & place, double t1, double t2, int R, int G, int B, int width = 1 ); + +////////////////////// \ru Отрисовка двумерных объектов. /////////////////////////// \en Drawing of two-dimensional objects. /////////////////////////// + + /** \brief \ru Отрисовать двумерный геометрический объект. + \en Draw a two-dimensional geometric object. \~ + \details \ru Функция геометрического объекта заданным цветом в текущем окне. + \en The function of geometric object drawing by a given color in an active window. \~ + \param[in] gi - \ru Исходный объект. + \en The initial object. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] from - \ru Матрица перехода из плейсмента объекта в глобальную систему координат. + \en The matrix of transformation from the object placement to the global coordinate system. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawItem( const MbPlaneItem * gi, int R, int G, int B, const MbMatrix3D & from, int width = 1 ); + + /** \brief \ru Отрисовать двумерный геометрический объект. + \en Draw a two-dimensional geometric object. \~ + \details \ru Функция геометрического объекта заданным цветом в текущем окне. + \en The function of geometric object drawing by a given color in an active window. \~ + \param[in] gi - \ru Исходный объект. + \en The initial object. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawItem( const MbPlaneItem * gi, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать двумерную точку. + \en Draw a two-dimensional point. \~ + \details \ru Функция отрисовки точки заданным цветом в текущем окне. + \en The function of point drawing by a given color in an active window. \~ + \param[in] gi - \ru Исходная точка. + \en The initial point. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] from - \ru Матрица перехода из плейсмента объекта в глобальную систему координат. + \en The matrix of transformation from the object placement to the global coordinate system. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoint( const MbCartPoint * gi, int R, int G, int B, const MbMatrix3D & from, int width = 1 ); + + /** \brief \ru Отрисовать двумерную точку. + \en Draw a two-dimensional point. \~ + \details \ru Функция отрисовки точки заданным цветом в текущем окне. + \en The function of point drawing by a given color in an active window. \~ + \param[in] gi - \ru Исходная точка. + \en The initial point. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoint( const MbCartPoint * gi, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать двумерный отрезок. + \en Draw a two-dimensional segment. \~ + \details \ru Функция отрисовки отрезка заданным цветом в текущем окне. Отрезок задается + крайними точками. + \en The function of segment drawing by a given color in an active window. A segment is specified + by the end points. \~ + \param[in] q1, q2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] from - \ru Матрица перехода из плейсмента объекта в глобальную систему координат. + \en The matrix of transformation from the object placement to the global coordinate system. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawLine( const MbCartPoint & q1, const MbCartPoint & q2, int R, int G, int B, const MbMatrix3D & from, int width = 1 ); + + /** \brief \ru Отрисовать трехмерный отрезок. + \en Draw a three-dimensional segment. \~ + \details \ru Функция отрисовки отрезка заданным цветом в текущем окне. Отрезок задается + крайними точками. + \en The function of segment drawing by a given color in an active window. A segment is specified + by the end points. \~ + \param[in] q1, q2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawLine( const MbCartPoint & q1, const MbCartPoint & q2, int R, int G, int B, int width = 1 ); + +////////////////////////// \ru Отрисовка топологических объектов. ////////////////// \en Drawing of topological objects. ////////////////// + + /** \brief \ru Отрисовать топологический объект. + \en Draw a topological object. \~ + \details \ru Топологический объект отрисовывается заданным цветом в текущем окне. + \en A topological object is drawn by a given color in an active window. \~ + \param[in] ti - \ru Исходный топологический объект. + \en The initial topological object. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] from - \ru Матрица перехода из плейсмента объекта в глобальную систему координат. + \en The matrix of transformation from the object placement to the global coordinate system. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawItem( const MbTopItem * ti, int R, int G, int B, const MbMatrix3D & from = MbMatrix3D::identity, int width = 1 ); + + /** \brief \ru Отрисовать ребро. + \en Draw an edge. \~ + \details \ru Ребро отрисовывается заданным цветом в текущем окне. При установке соответствующего + флага отрисовываются вершины. + \en An edge is drawn by a given color in an active window. If the corresponding flag is set, + the vertices are drawn. \~ + \param[in] edge - \ru Исходное ребро. + \en The initial edge. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] drawVerts - \ru Флаг отрисовки вершин ребра. + \en Whether edge vertices are drawn. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawEdge( const MbEdge * edge, int R, int G, int B, bool drawVerts, int width = 1 ); + +////////////////////// \ru Отрисовка вспомогательных объектов. ///////////////////// \en Drawing of assisting items. ///////////////////// + + /** \brief \ru Отрисовать патч двумерной кривой. + \en Draw a patch of a two-dimensional curve. \~ + \details \ru Патч отрисовывается заданным цветом в текущем окне. + \en A patch is drawn by a given color in an active window. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] mapInto - \ru Матрица перехода в локальную систему координат. + \en The matrix of transformation to the local coordinate system. \~ + \ingroup Drawing + */ + static void PutPatch( const MbCartPoint & pnt, const MbVector & dir, double a, double b, int R, int G, int B, const MbMatrix3D & mapInto ); + + /** \brief \ru Отрисовать габаритный куб в текущем окне. + \en Draw a bounding box in an active window. \~ + \details \ru Куб отрисовывается либо красным, либо синим цветом в текущем окне. + \en A bounding box is drawn by the red color or by the blue color in an active window. \~ + \param[in] gab - \ru Исходный габаритный куб. + \en The initial bounding box. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \param[in] bDrawRed - \ru Флаг отрисовки красным цветом. Если false, отрисовывается + синим цветом. + \en Whether the red color is used. If the value is 'false' then to draw by + the blue color. \~ + \ingroup Drawing + */ + static void PutCube( const MbCube & gab, int width = 1, bool bDrawRed = true ); + + /** \brief \ru Отрисовать систему координат. + \en Draw a coordinate system. \~ + \details \ru Система координат отрисовывается с заданными длинами осей. + \en A coordinate system is drawn with given axes lengths. \~ + \param[in] place - \ru Исходная система координат. + \en The initial coordinate system. \~ + \param[in] lenAxes - \ru Длина осей. + \en Axes lengths. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPlacement3D( const MbPlacement3D & place, double lenAxes, int width = 1 ); + +////////// \ru Отрисовка объектов в пространстве параметров поверхности. /////////// \en Drawing of objects in a surface parameter space. /////////// + + /// \ru Очистить текущее окно. \en Clear the active window. + static void DrawClearMap(); + + /** \brief \ru Отрисовать двумерную кривую на поверхности. + \en Draw a two-dimensional curve on a surface. \~ + \details \ru Отрисовка заданной двумерной кривой на заданной поверхности заданным цветом + в текущем окне. + \en Drawing of a given two-dimensional curve on a given surface by a given color + in an active window. \~ + \param[in] curve - \ru Исходная двумерная кривая. + \en An initial two-dimensional curve. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawItem( const MbCurve * curve, const MbSurface * surface, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать карту кривой на поверхности. + \en Draw a map of a curve on a surface. \~ + \details \ru Отрисовка карты заданной кривой на заданной поверхности заданным цветом + в текущем окне. + \en Drawing of a map of a given curve on a given surface by a given color + in an active window. \~ + \param[in] curve - \ru Исходная кривая. + \en An initial curve. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawCurveMap( const MbCurve * curve, const MbSurface * surface, int R, int G, int B ); + + /** \brief \ru Отрисовать кривую на поверхности. + \en Draw a curve on a surface. \~ + \details \ru Отрисовка кривой на поверхности в параметрической плоскости заданным цветом + в текущем окне. + \en Drawing of a curve on a surface in a parametric plane by a given color + in an active window. \~ + \param[in] scurve - \ru Исходная кривая на поверхности. + \en The initial curve on a surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawSurfaceCurveMap( const MbSurfaceCurve * scurve, int R, int G, int B ); + + /** \brief \ru Отрисовать точку на поверхности. + \en Draw a point on a surface. \~ + \details \ru Отрисовка точки на поверхности заданным цветом в текущем окне. + \en Drawing of point on a surface by a given color in an active window. \~ + \param[in] pnt - \ru Исходная точка. + \en The initial point. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawPointMap( const MbCartPoint * pnt, const MbSurface * surface, int R, int G, int B ); + + /** \brief \ru Отрисовать кривую пересечения на параметрической плоскости. + \en Draw an intersection curve on a parametric plane. \~ + \details \ru Отрисовывается кривая 1 цветом 1 на поверхности 1 и кривая 2 цветом 2 на поверхности 2. + \en The curve 1 is drawn by the color 1 on the surface 1 and the curve 2 is drawn by the color 2 on the surface 2. \~ + \param[in] gi - \ru Кривая пересечения. + \en The intersection curve \~ + \param[in] R1, R2 - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G1, G2 - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B1, B2 - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawSurfaceIntersectionMap( const MbSurfaceIntersectionCurve * gi, int R1, int G1, int B1, int R2, int G2, int B2 ); + + /** \brief \ru Отрисовать контур на поверхности в параметрической плоскости. + \en Draw a contour on a surface in a parametric plane. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] gi - \ru Контур на поверхности. + \en The contour on a surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawContourOnSurfaceMap( const MbContourOnSurface * gi, int R, int G, int B ); + + /** \brief \ru Отрисовать ограничивающие кривые усеченной поверхности в ее параметрической плоскости. + \en Draw bounding curves of a trimmed surface in its parametric plane. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] bnds - \ru Ограниченная кривыми поверхность. + \en The surface bounded by curves. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawCurveBoundedSurfaceMap( const MbCurveBoundedSurface * bnds, int R, int G, int B ); + + /** \brief \ru Отрисовать параметрическую плоскость поверхности. + \en Draw a parametric plane of a surface. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawSurfaceMap( const MbSurface * surface, int R, int G, int B ); + + /** \brief \ru Отрисовать параметрическую точку поверхности. + \en Draw a parametric point of a surface. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] uv - \ru Исходная точка. + \en The initial point. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoint( const MbSurface & surface, const MbCartPoint & uv, int R, int G, int B, int width = 2 ); + + /** \brief \ru Отрисовать массив 3d-точек по массиву 2d-точек и поверхности. + \en Draw an array of 3D-points by an array of 2D-points and a surface. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] uvArr - \ru Исходный массив двумерных точек. + \en The initial array of two-dimensional points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoints( const MbSurface & surface, const SArray & uvArr, int R, int G, int B, int width = 2 ); + + /** \brief \ru Отрисовать массив 3d-точек по массиву параметров и кривой. + \en Draw an array of 3D-points by an array of parameters and a curve. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] tArr - \ru Исходный массив точек на кривой. + \en The initial array of points on a curve. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoints( const MbCurve3D & curve, const SArray & tArr, int R, int G, int B, int width = 2 ); + + /** \brief \ru Отрисовать массив 3d-точек. + \en Draw an array of 3D-points. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] pnts - \ru Исходный массив трехмерных точек. + \en The initial array of three-dimensional points. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void DrawPoints( const SArray & pnts, int R, int G, int B, int width = 2 ); + +///////////////////////// \ru Отрисовка триангуляции. ////////////////////////////// \en Drawing of a triangulation. ////////////////////////////// + + /** \brief \ru Отрисовать триангуляцию. + \en Draw a triangulation. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en The triangular mesh. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void PutGrid( const MbGrid & grid, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать треугольник. + \en Draw a triangle. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. Нужный треугольник из триангуляции + задается индексом. + \en Drawing by a given color in an active window. A necessary triangle from triangulation + is specified by an index. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en The triangular mesh. \~ + \param[in] index - \ru Индекс треугольника. + \en The index of triangle. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void PutTriangle( const MbGrid & grid, ptrdiff_t index, int R, int G, int B ); + + /** \brief \ru Отрисовать треугольник. + \en Draw a triangle. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] uv0, uv1, uv2 - \ru Точки в параметрах поверхности. + \en Points in surface parameters. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void PutTriangle( const MbSurface & surface, + const MbCartPoint & uv0, const MbCartPoint & uv1, const MbCartPoint & uv2, + int R, int G, int B ); + + /** \brief \ru Отрисовать четырёхугольник. + \en Draw a quadrangle. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. Нужный четырёхугольник из триангуляции + задается индексом. + \en Drawing by a given color in an active window. A necessary quadrangle from triangulation + is specified by an index. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en The triangular mesh. \~ + \param[in] index - \ru Индекс четырёхугольник. + \en The index of quadrangle. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void PutQuadrangle( const MbGrid & grid, ptrdiff_t index, int R, int G, int B ); + + /** \brief \ru Отрисовать двумерную триангуляцию. + \en Draw a two-dimensional triangulation. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en The triangular mesh. \~ + \param[in] place - \ru Исходная плоскость. + \en The initial plane. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \param[in] width - \ru Ширина линий рисования. + \en The width of the draw lines. \~ + \ingroup Drawing + */ + static void PutPlanarGrid( MbPlanarGrid & grid, const MbPlacement3D & place, int R, int G, int B, int width = 1 ); + + /** \brief \ru Отрисовать триангуляционную сетку на поверхности. + \en Draw a triangular mesh on a surface. \~ + \details \ru Отрисовывается заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en The triangular mesh. \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] R - \ru Красный цвет [0,255]. + \en Red color [0,255]. \~ + \param[in] G - \ru Зеленый цвет [0,255]. + \en Green color [0,255]. \~ + \param[in] B - \ru Синий цвет [0,255]. + \en Blue color [0,255]. \~ + \ingroup Drawing + */ + static void DrawGridMap( const MbGrid & grid, const MbSurface & surface, int R, int G, int B ); + + /** \brief Стереть модель. + \ingroup Drawing + */ + static void EraseModel(); + + /** \brief Перерисовать модель. + \ingroup Drawing + */ + static void RedrawModel(); + +}; // class DrawGI + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрисовать объект. + \en Draw an object. \~ + \details \ru Отрисовать объект заданным цветом в текущем окне. + \en Drawing by a given color in an active window. \~ + \ingroup Drawing +*/ +// --- +template +void DrawItem( SPtr & item, int R, int G, int B ) { + DrawGI::DrawItem( item.get(), R, G, B ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрисовать множество объектов. + \en Draw a set of objects. \~ + \details \ru Отрисовать множество объектов заданным цветом в текущем окне. + \en Draw a set of objects by a given color in an active window. \~ + \ingroup Drawing +*/ +// --- +template +void DrawItems( const PtrArray & items, int R, int G, int B ) +{ + for ( size_t k = 0, cnt = items.Count(); k < cnt; k++ ) + DrawGI::DrawItem( items[k], R, G, B ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрисовать вершину с прилегающими ребрами. + \en Draw a vertex with adjacent edges. \~ + \details \ru Отрисовать вершину с прилегающими ребрами заданным цветом в текущем окне. + \en Draw a vertex with adjacent edges by a given color in an active window. \~ + \ingroup Drawing +*/ +// --- +template +void DrawVertexEdges( const Vertex * vertex, int vR, int vG, int vB, + const Edges & edges, int eR, int eG, int eB ) +{ + DrawGI::DrawItem( vertex, vR, vG, vB ); + MbMesh edgeMesh; + MbStepData stepData( ist_SpaceStep, Math::visualSag ); + MbFormNote note(true, false); + for ( size_t k = 0, cnt = edges.Count(); k < cnt; k++ ) { + if ( edges[k] != NULL ) { + edges[k]->GetCurve().CalculateMesh( stepData, note, edgeMesh ); + DrawGI::DrawMesh( &edgeMesh, TRGB_WHITE ); + DrawGI::DrawMesh( &edgeMesh, eR, eG, eB ); + edgeMesh.Flush(); + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция имплементации интерфейса IfDrawGI. + \en The function of 'IfDrawGI' interface implementarion. \~ + \details \ru Функция установки указателя на имплементацию интерфейса IfDrawGI. + \en The function of setting a pointer to the 'IfDrawGI' interface implementarion. \~ + \ingroup Drawing +*/ +// --- +MATH_FUNC (void) SetDrawGI( const IfDrawGI * iDrawGIImpl ); + + +#endif // defined(_DRAWGI) + + +#endif // __ALG_DRAW_H diff --git a/C3d/Include/alg_indicator.h b/C3d/Include/alg_indicator.h new file mode 100644 index 0000000..a6f46ad --- /dev/null +++ b/C3d/Include/alg_indicator.h @@ -0,0 +1,399 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Индикатор прогресса. + \en A progress indicator. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ALG_INDICATOR_H +#define __ALG_INDICATOR_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные о строке. + \en Data of a string \~ + \details \ru Данные о строке (абстракция с возможностью посещения). + \en Data of a string (an abstraction with a possibility of visit). \~ + \ingroup Base_Items +*/ +//--- +class MATH_CLASS IStrData { +public: + IStrData() {} ///< \ru Конструктор по умолчанию. \en Default constructor. + virtual ~IStrData() {} ///< \ru Деструктор. \en Destructor. +public: + virtual bool Accept( Visitor & ) = 0; ///< \ru Прием посетителя. \en Acceptance of a visitor. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Конкретные данные о строке. + \en Specific data of a string \~ + \details \ru Конкретные данные о строке. \n + \en Specific data of a string \n \~ + \ingroup Base_Items +*/ +//--- +template +class StrData : public IStrData { +private: + T m_msg; ///< \ru Данные. \en Data. + +public: + /// \ru Конструктор по данным. \en Constructor by data. + StrData( T msg ) : m_msg( msg ) {} + /// \ru Деструктор. \en Destructor. + virtual ~StrData() {} + + /// \ru Прием посетителя. \en Acceptance of a visitor. + virtual bool Accept( Visitor & visitor ) + { + VisitorImpl * impl = dynamic_cast *>(&visitor); + if( impl ) + impl->Visit( m_msg ); + else + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не реализована ф-ия посещения этого типа данных! \en the function of visit for this data type is not implemented! + + return !!impl; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый класс для потокобезопасного посетителя, извлекающего строку. + \en Base class for thread-safe visitor extracting a string. \~ + \details \ru Базовый класс для потокобезопасного посетителя, извлекающего строку. + Можно использовать как образец при создании потокобезопасных посетителей, работающих с другими данными. \n + \en Base class for thread-safe visitor extracting a string. + Can be used as a sample when creating thread-safe visitors, working with other data.\n \~ +\ingroup Base_Items +*/ +//--- +//------------------------------------------------------------------------------ +// \ru Базовый класс для потокобезопасного посетителя, извлекающего строку. +// \en Base class for thread-safe visitor extracting a string. +// --- +class BaseStrVisitor : public Visitor, public VisitorImpl { +protected: + /// \ru Данные посетителя. \en Visitor data. + struct BaseAuxiliaryData : public AuxiliaryData + { + c3d::string_t data; + BaseAuxiliaryData() : data() {} + }; + + ///< \ru Менеджер, обеспечивающий потокобезопасный доступ к данным. \en Manager providing thread-safe access to the data. + mutable CacheManager cache; + +public: + /// \ru Конструктор. \en Constructor. + BaseStrVisitor() : cache() {} + /// \ru Деструктор. \en Destructor. + virtual ~BaseStrVisitor() {} + +public: + + ///< \ru Обработка посещения объекта. \en Processing of the object visit. + virtual void Visit( const TCHAR*& str ) { + if ( str ) + cache()->data.assign( str ); + } + + ///< \ru Извлечение строки объекта. \en Extracting a string of the object. + virtual const TCHAR* GetString() const { + return cache()->data.c_str(); + } + + ///< \ru Доступ к данным объекта. \en Access to the object data. + c3d::string_t& Data() { + return cache()->data; + } +}; + + +#define EMPTY_STR StrData( NULL ) ///< \ru Создание пустой строки \en Creation of an empty string + + +//------------------------------------------------------------------------------ +/** \brief \ru Добытчик строки из данных о строке. + \en The getter of a string from string data. \~ + \details \ru Добытчик строки из данных о строке. \n + \en The getter of a string from string data. \n \~ + \ingroup Base_Items +*/ +//--- +class MATH_CLASS IGetMsg { +public: + IGetMsg() {} ///< \ru Конструктор по умолчанию. \en Default constructor. + virtual ~IGetMsg() {} ///< \ru Деструктор. \en Destructor. +public: + /// \ru Данные о строке в строку. \en Convert data of a string to string. + virtual const TCHAR * Msg( IStrData & msg ) const = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс индикатора прогресса выполнения. + \en Interface of the execution progress indicator. \~ + \details \ru Интерфейс индикатора прогресса выполнения. \n + \en Interface of the execution progress indicator. \n \~ + \ingroup Base_Items +*/ +//--- +class MATH_CLASS IProgressIndicator : public IGetMsg { +public: + IProgressIndicator() {} ///< \ru Конструктор по умолчанию. \en Default constructor. + virtual ~IProgressIndicator() {} ///< \ru Деструктор. \en Destructor. +public: + /// \ru Установка диапазона индикации, сброс состояния. \en Setting of an indication range, reset state. + virtual bool Initialize( size_t range, size_t delta, IStrData & msg ) = 0; + /// \ru Обработать прогресс на n у.е., вернет false - пора останавливаться \en Process the progress by 'n' units, if it returns 'false', then it is time to stop. + virtual bool Progress ( size_t n ) = 0; + /// \ru Ликвидация ошибок округления дорастим прогресс бар до 100% \en Rounding errors liquidation, increase of a progress bar to 100% + virtual void Success () = 0; + + /// \ru Проверка, не пора ли остановиться \en Check whether it is time to stop. + virtual bool IsCancel () = 0; + /// \ru Скажем, что пора остановиться. \en It is time to stop. + virtual void SetCancel ( bool c ) = 0; + /// \ru Команда пора остановиться \en Command to stop. + virtual void Stop () = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \details \ru Обертка индикатора прогресса выполнения + (потокобезопасна при условии, если реализация IProgressIndicator также потокобезопасна). \n + \en The wrapper of the execution progress indicator + (thread-safe provided that IProgressIndicator implementation is also thread-safe). \n \~ + \ingroup Base_Items +*/ +// --- +class MATH_CLASS ProgressBarWrapper : public MbRefItem { +private: + /// \ru Данные индикатора прогресса. \en The progress indicator data. + struct ProgressBarWrapperData : public AuxiliaryData + { + c3d::string_t name; ///< \ru Название процесса. \en A name of a process. + size_t range; ///< \ru Диапазон значений. \en A range of values. + size_t delta; ///< \ru Минимальное приращение прогресса. \en A minimal increase of a progress. + size_t value; ///< \ru Текущий прогресс. \en A current index. + bool useParentName; ///< \ru Использовать имя родителя для наследника. \en Whether to use a name of a parent for its successor. + + ProgressBarWrapperData(); + }; + + IProgressIndicator & progBar; ///< \ru Общий индикатор прогресса. \en A common progress indicator. + ProgressBarWrapper * parentProgBar; ///< \ru Родительский индикатор прогресса. \en A parent progress indicator. + mutable CacheManager cache; ///< \ru Менеджер, обеспечивающий потокобезопасный доступ к данным. \en Manager providing thread-safe access to the data. + +public: + /// \ru Конструктор по индикатору прогресса выполнения. \en Constructor by an indicator of execution progress. + ProgressBarWrapper( IProgressIndicator & pBar ); + virtual ~ProgressBarWrapper(); ///< \ru Деструктор. \en Destructor. + +public: + + /// \ru Проверка на остановку процесса. \en Check whether a process stopped. + bool IsCancel() { return progBar.IsCancel(); } + /// \ru Окончание процесса. \en End the process. + void Success() { progBar.Success(); } + /// \ru Остановка процесса. \en Stop the process. + void Stop() { progBar.Stop(); } + /// \ru Восстановление данных процесса. \en Restoring of a process data. + bool Reset(); + /// \ru Установка состояния. \en Set the state. + bool Init( size_t range, size_t delta, size_t value, IStrData & msg ); + /// \ru Установка состояния. \en Set the state. + bool Init( size_t range, size_t delta, size_t value ); + /// \ru Узнать текущее состояние прогресса. \en Get the current state of a progress. + size_t GetValue() const { return cache()->value; } + /// \ru Задать имя процесса. \en Set the name of a process. + bool SetName( IStrData & msg ); + /// \ru Увеличить прогресс выполнения. \en Increase the execution progress. + bool SetProgress( size_t v ); + /// \ru Создать наследника (если msg нулевой, то используется имя родителя). \en Create a successor (if 'msg' is empty, then the name of a parent is used). + ProgressBarWrapper & CreateChildAddRef( IStrData & msg ) const; + /// \ru Создать наследника (если msg нулевой, то используется имя родителя). \en Create a successor (if 'msg' is empty, then the name of a parent is used). + ProgressBarWrapper & CreateChild( IStrData & msg ) const; + /// \ru Использовать базовое имя при создании наследника. \en Use a base name while creating a successor. + void UseParentName( bool s ) { cache()->useParentName = s; } + /// \ru Используется ли базовое имя. \en Whether a base name is used. + bool IsParentNameUsed() const { return cache()->useParentName; } + /// \ru Получить родительский индикатор прогресса. \en Get parent progress indicator. + ProgressBarWrapper * GetParent() { return parentProgBar; } + +OBVIOUS_PRIVATE_COPY( ProgressBarWrapper ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать индикатор прогресса. + \en < Create a progress indicator. \~ + \param[in] progInd - \ru Интерфейс индикатора прогресса выполнения. + \en Interface of the execution progress indicator. \~ + \param[in] msg - \ru Данные о строке. + \en Data of a string \~ + \return \ru Обертку индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \ingroup Base_Items +*/ +// --- +MATH_FUNC (ProgressBarWrapper *) CreateProgressBarAddRef( IProgressIndicator * progInd, IStrData & msg ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать индикатор прогресса. + \en < Create a progress indicator. \~ + \param[in] progInd - \ru Интерфейс индикатора прогресса выполнения. + \en Interface of the execution progress indicator. \~ + \param[in] msg - \ru Данные о строке. + \en Data of a string \~ + \return \ru Обертку индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \ingroup Base_Items +*/ +// --- +MATH_FUNC (ProgressBarWrapper *) CreateProgressBar( IProgressIndicator * progInd, IStrData & msg ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить имя прогресса. + \en Set the progress name. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \param[in] msg - \ru Данные о строке. + \en Data of a string \~ + \return \ru true, если progBar != NULL и удалось задать имя процесса. + \en true if 'progBar' is not null and the process name is successfully set. \~ + \ingroup Base_Items +*/ +// --- +inline bool SetProgressBarName( ProgressBarWrapper * progBar, IStrData & msg ) +{ + if ( progBar != NULL ) + return progBar->SetName( msg ); + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить значение прогресса. + \en Set the value of a progress. \~ + \details \ru Установить значение прогресса. + \en Set the value of a progress. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \param[in] v - \ru Значение прогресса. + \en The value of a progress. \~ + \return \ru true, в случае успешного выполнение операции. + \en true if the operation is successful. \~ + \ingroup Base_Items +*/ +// --- +inline bool SetProgressBarValue( ProgressBarWrapper * progBar, size_t v ) +{ + if ( progBar != NULL && !progBar->IsCancel() ) + return progBar->SetProgress( v ); + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Завершить индикатор прогресса. + \en End the progress indicator. \~ + \details \ru Либо индикатор останавливается, либо, если он уже дошел до 100%, выдается + сообщение об этом. + \en Either the indicator stops or, if it already has reached 100%, then + the corresponding message appears. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \ingroup Base_Items +*/ +// --- +inline void FinishProgressBar( ProgressBarWrapper * progBar ) +{ + if ( progBar != NULL ) { + if ( progBar->IsCancel() ) progBar->Stop(); + else progBar->Success(); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить индикатор прогресса. + \en Delete the progress indicator. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution prorgress indicator. \~ + \return \ru true, в случае успешного выполнение операции. + \en true if the operation is successful. \~ + \ingroup Base_Items +*/ +// --- +inline bool StopProgressBar( ProgressBarWrapper * progBar ) +{ + if ( progBar != NULL && progBar->IsCancel() ) { + progBar->Stop(); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Использовать имя родителя для наследника. + \en Whether to use the name of a parent for its successor. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \param[in] useParentName - \ru Флаг использования имени родителя. + \en The flag of using the parent name. \~ + \return \ru true, если progBar != NULL. + \en true if 'progBar' is not null. \~ + \ingroup Base_Items +*/ +// --- +inline bool UseParentName( ProgressBarWrapper * progBar, bool useParentName ) +{ + if ( progBar != NULL ) { + progBar->UseParentName( useParentName ); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Используется ли имя родителя для наследника. + \en Whether the name of a parent is used for its successor. \~ + \param[in] progBar - \ru Обертка индикатора прогресса выполнения. + \en The wrapper of the execution progress indicator. \~ + \return \ru true, если используется. + \en true if it is used. \~ + \ingroup Base_Items +*/ +// --- +inline bool IsParentNameUsed( const ProgressBarWrapper * progBar ) +{ + if ( progBar != NULL ) + return progBar->IsParentNameUsed(); + + return false; +} + + +#endif // __ALG_INDICATOR_H diff --git a/C3d/Include/alg_max_distance.h b/C3d/Include/alg_max_distance.h new file mode 100644 index 0000000..32b07f8 --- /dev/null +++ b/C3d/Include/alg_max_distance.h @@ -0,0 +1,165 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение расстояния между объектами. + \en Definition of distance between objects. \~ + \details \ru Функции определения максимальных расстояний между различными + трехмерными объектами. + \en Functions for definition of maximal distances between different + three-dimensional objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ALG_MAX_DISTANCE_H +#define __ALG_MAX_DISTANCE_H + + +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние между точкой и кривой. + \en Find the maximal distance between a point and a curve. \~ + \details \ru Максимальное расстояние между точкой и кривой. + \en The maximal distance between a point and a curve. \~ + \param[in] pnt - \ru Исходная точка. + \en The initial point. \~ + \param[in] curv - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] t - \ru Параметр на кривой, при котором достигается искомое расстояние. + \en The parameter on a curve where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbCartPoint3D & pnt, const MbCurve3D & curv, + double & t, + double & distance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние между двумя кривыми. + \en Find the maximal distance between two curves. \~ + \details \ru Найти максимальное расстояние между двумя кривыми. + \en Find the maximal distance between two curves. \~ + \param[in] curv1, curv2 - \ru Исходные кривая. + \en The initial curves. \~ + \param[out] t1, t2 - \ru Параметры на кривых, при которых достигается искомое расстояние. + \en The parameters on curves where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbCurve3D & curv1, const MbCurve3D & curv2, + double & t1, double & t2, + double & distance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние между точкой и поверхностью. + \en Find the maximal distance between a point and a surface. \~ + \details \ru Найти максимальное расстояние между точкой и поверхностью. + \en Find the maximal distance between a point and a surface. \~ + \param[in] pnt - \ru Исходная точка. + \en The initial point. \~ + \param[in] surf - \ru Исходная поверхность. + \en The initial surface. \~ + \param[out] uv - \ru Параметры точки на поверхности, при которой достигается искомое расстояние. + \en The point parameters on a surface where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbCartPoint3D & pnt, const MbSurface & surf, + MbCartPoint & uv, + double & distance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние между кривой и поверхностью. + \en Find the maximal distance between a curve and a surface. \~ + \details \ru Найти максимальное расстояние между кривой и поверхностью. + \en Find the maximal distance between a curve and a surface. \~ + \param[in] curv - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] surf - \ru Исходная поверхность. + \en The initial surface. \~ + \param[out] t - \ru Параметр на кривой, при котором достигается искомое расстояние. + \en The parameter on a curve where the required distance is reached. \~ + \param[out] uv - \ru Параметры точки на поверхности, при которой достигается искомое расстояние. + \en The point parameters on a surface where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbCurve3D & curv, const MbSurface & surf, + double & t, MbCartPoint & uv, + double & distance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние между поверхностями. + \en Find the maximal distance between two surfaces. \~ + \details \ru Найти максимальное расстояние между поверхностями. + \en Find the maximal distance between two surfaces. \~ + \param[in] surf1, surf2 - \ru Исходные поверхности. + \en The initial surfaces. \~ + \param[out] uv1, uv2 - \ru Параметры точек на поверхностях, при которых достигается искомое расстояние. + \en The parameters on surfaces where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbSurface & surf1, const MbSurface & surf2, + MbCartPoint & uv1, MbCartPoint & uv2, + double & distance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти максимальное расстояние от оси до кривой. + \en Find the maximal distance between an axis an a curve. \~ + \details \ru Ищется максимальное расстояние от оси до кривой перпендикулярно оси. + \en Find the maximal distance between an axis and a curve perpendicularly to an axis. \~ + \param[in] axis - \ru Исходная ось. + \en The initial axis. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[out] param - \ru Параметр на кривой, при котором достигается искомое расстояние. + \en The parameter on a curve where the required distance is reached. \~ + \param[out] distance - \ru Искомое расстояние. + \en The required distance. \~ + \return \ru true, если максимальное расстояние было найдено. + \en true if the maximal distance has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) MaxDistance( const MbAxis3D & axis, const MbCurve3D & curve, + double & param, + double & distance ); + + +#endif // __ALG_MAX_DISTANCE_H diff --git a/C3d/Include/alg_mesh_to_brep.h b/C3d/Include/alg_mesh_to_brep.h new file mode 100644 index 0000000..46b28a9 --- /dev/null +++ b/C3d/Include/alg_mesh_to_brep.h @@ -0,0 +1,96 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief Функции преобразования полигональной модели в граничное представление. + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_MESH_TO_BREP_H +#define __ALG_MESH_TO_BREP_H + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbMesh; +class MATH_CLASS MbGrid; +class MATH_CLASS MbCollection; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbTriangle; +class MATH_CLASS IProgressIndicator; +class MATH_CLASS ProgressBarWrapper; +struct MATH_CLASS GridsToShellValues; + + +//------------------------------------------------------------------------------ +// Удалить дублирующие с заданной точностью друг друга точки. +// --- +bool RemoveRedundantPoints( std::vector & points, + std::vector & triangles, + double epsilon, + ProgressBarWrapper * baseProgBar ); + +//------------------------------------------------------------------------------ +// Удалить дублирующие с заданной точностью друг друга точки. +// --- +bool RemoveRedundantPoints( std::vector< std::pair > & pointNormals, + std::vector & triangles, + double epsilon, + ProgressBarWrapper * baseProgBar ); + +//------------------------------------------------------------------------------ +// Удалить дублирующие с заданной точностью друг друга точки. +// --- +bool RemoveRedundantPoints( std::vector & points, + std::vector & indexes, + double epsilon ); + +//------------------------------------------------------------------------------ +// Объединить ребра двух смежных плоских граней с полигональной границей +// (возвращает общее после сшивки ребро) +// --- +MbCurveEdge * StitchAdjacentGridsEdges( MbFace & face1, MbOrientedEdge & edge1, + MbFace & face2, MbLoop & loop2, size_t e2Ind ); + +//------------------------------------------------------------------------------ +// Обеспечить связность треугольных граней +// --- +bool ConnectTriangleFaces( const c3d::FacesSPtrVector & faces, + const std::vector< std::pair > & edgesPairs, + std::vector< std::pair > * combinedPairs, + ProgressBarWrapper * baseProgBar ); + +//------------------------------------------------------------------------------ +// Преобразовать триангуляцию в оболочку. +// --- +MbFaceShell * ConvertGridToShell( const MbGrid & grid, const GridsToShellValues & params, const MbSNameMaker & snMaker, + MbResultType & res, IProgressIndicator * progBar = NULL ); + + +//------------------------------------------------------------------------------ +// Преобразовать полигональную модель в оболочку. +// --- +MbFaceShell * ConvertMeshToShell( const MbMesh & mesh, const GridsToShellValues & params, const MbSNameMaker & snMaker, + MbResultType & res, IProgressIndicator * progBar = NULL ); + + +//------------------------------------------------------------------------------ +// Преобразовать триангуляцию в оболочку. +// --- +MbFaceShell * ConvertCollectionToShell( const MbCollection & grid, + bool mergeFaces, + const MbSNameMaker & snMaker, + MbResultType & res, + IProgressIndicator * progIndicator ); + + +#endif // __ALG_UTILITES_H diff --git a/C3d/Include/alg_nurbs_conic.h b/C3d/Include/alg_nurbs_conic.h new file mode 100644 index 0000000..eb11ebc --- /dev/null +++ b/C3d/Include/alg_nurbs_conic.h @@ -0,0 +1,377 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение конических сечений в виде NURBS-кривой. + \en Construction of conic sections as NURBS curves. \~ + \details \ru Построение конических сечений производится следующими способами: + по двум точкам, вершине и дискриминанту, по трем точкам и вершине, + по трем точкам и двум наклонам, по двум точкам, двум наклонам и дискриминанту, + по четырем точкам и наклону и по пяти точкам. \n + NURBS кривая, описывающая конику, строится по трем точкам: началу и концу коники и + средней точке (вершине угола, в который надо вписать конику). + Принимая весы начальной и конечной точки равными 1 и рассчитывая вес средней точки, + по трем точкам и трем весам строится NURBS 3-го порядка, который будет искомой коникой. + \en Construction of conic sections is performed in the following way: + by two points, a vertex and a discriminant, by three points and a vertex, + by three points and two inclinations, by two points, two inclinations and discriminant, + by four points and inclination and by five points. \n + A NURBS curve describing a conic is constructed by three points: a start and an end of a conic and + an average point (a vertex of angle which should be inscribed into the conic). + Let weights of the start point and the end point be equal to 1. After calculating of the weight of the average point + NURBS of third degree is constructed by these three weights. This NURBS is the required conic. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ALG_NURBS_CONIC_H +#define __ALG_NURBS_CONIC_H + + +#include + + +class MbCurve3D; +class MbNurbs3D; +class MbCartPoint3D; +class MbVector3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по двум точкам вершине и дискриминанту. + \en Construct a conic section by two points, an angle vertex and a discriminant. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + двум точкам, которые задают начало и конец кривой, вершине инженерного + треугольника и дискриминанту, который используется для определения третьей точки кривой. + \en Construction of a conic section as a NURBS curve of the third degree by + two points setting ends of a curve, a vertex of enginer + triangle and a discriminant which is used for the definition of the third point. \~ + \param[in] mbPoint0 - \ru Координаты начала коники. + \en Coordinates of the conic start point. \~ + \param[in] mbPoint1 - \ru Координаты вершины угла, в который надо вписать конику. + \en Coordinates of the vertex of angle which should be inscribed into the conic. \~ + \param[in] mbPoint2 - \ru Координаты конца коники. + \en Coordinates of the conic end point. \~ + \param[in] fDiscr - \ru Дискриминант < 1, если задать дискриминант >= 1, то он + автоматически будет сброшен до значения 0.99999999. + \en The discriminant is less than 1. Otherwise it + will be set to 0.99999999 automatically. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось построить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for a given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_1( const MbCartPoint3D & mbPoint0, const MbCartPoint3D & mbPoint1, + const MbCartPoint3D & mbPoint2, double fDiscr ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по двум точкам вершине и дискриминанту. + \en Construct a conic section by two points, an angle vertex and a discriminant. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + двум точкам, которые задают начало и конец кривой, вершине инженерного + треугольника и дискриминанту, который используется для определения третьей точки кривой. + \en Construction of a conic section as a NURBS curve of the third degree by + two points setting ends of a curve, a vertex of enginer + triangle and a discriminant which is used for the definition of the third point. \~ + \param[in] mbPoint0 - \ru Координаты начала коники. + \en Coordinates of the conic start point. \~ + \param[in] mbPoint1 - \ru Координаты вершины угла, в который надо вписать конику. + \en Coordinates of the vertex of angle which should be inscribed into the conic. \~ + \param[in] mbPoint2 - \ru Координаты конца коники. + \en Coordinates of the conic end point. \~ + \param[in] fDiscr - \ru Дискриминант < 1, если задать дискриминант >= 1, то он + автоматически будет сброшен до значения 0.99999999. + \en The discriminant is less than 1. Otherwise it + will be set to 0.99999999 automatically. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось построить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for a given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_1( const MbCartPoint & mbPoint0, const MbCartPoint & mbPoint1, + const MbCartPoint & mbPoint2, double fDiscr ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по трем точкам и вершине. + \en Construct a conic section by three points, and an angle vertex. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + трем точкам: началу, концу и средней точке кривой, а также вершине угла, в который + должна быть вписана коника. + \en Construction of a conic section as a NURBS curve of the third degree by + three points: ends of a curve, its average point and by a vertex of an angle, + a conic should be inscribed in. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: начало, средняя точка, конец; + точек должно быть 3. + \en The container for points of a conic: start point, average point and end point; + there should be exactly 3 points. \~ + \param[in] mbVertex - \ru Координаты вершины угла, в который надо вписать конику. + \en Coordinates of the vertex of angle which should be inscribed into the conic. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_2( std::vector & vmbConicPoints, const MbCartPoint3D & mbVertex ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по трем точкам и вершине. + \en Construct a conic section by three points, and an angle vertex. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + трем точкам: началу, концу и средней точке кривой, а также вершине угла, в который + должна быть вписана коника. + \en Construction of a conic section as a NURBS curve of the third degree by + three points: ends of a curve, its average point and by a vertex of an angle, + a conic should be inscribed in. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: начало, средняя точка, конец; + точек должно быть 3. + \en The container for points of a conic: start point, average point and end point; + there should be exactly 3 points. \~ + \param[in] mbVertex - \ru Координаты вершины угла, в который надо вписать конику. + \en Coordinates of the vertex of angle which should be inscribed into the conic. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_2( std::vector & vmbConicPoints, const MbCartPoint & mbVertex ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по трем точкам и двум наклонам. + \en Construct a conic section by three points and two inclinations. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 3-ем точкам, которые задают начало, конец и среднюю точку кривой и двум + наклонам, выходящим из начальной и конечной точек. + \en Construction of a conic section as a NURBS curve of the third degree by + 3 points setting begin, end and an average point of a curve and two + inclinations outgoing from the start point and from the end point \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: начало, средняя точка, конец; + точек должно быть 3. + \en The container for points of a conic: start point, average point and end point; + there should be exactly 3 points. \~ + \param[in] mbTangent1 - \ru Наклон в начале кривой. + \en Inclination at start of a curve. \~ + \param[in] mbTangent2 - \ru Наклон в конце кривой. + \en Inclination at end of a curve. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_3( const std::vector & vmbConicPoints, + MbVector3D & mbTangent1, MbVector3D & mbTangent2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по трем точкам и двум наклонам. + \en Construct a conic section by three points and two inclinations. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 3-ем точкам, которые задают начало, конец и среднюю точку кривой и двум + наклонам, выходящим из начальной и конечной точек. + \en Construction of a conic section as a NURBS curve of the third degree by + 3 points setting begin, end and an average point of a curve and two + inclinations outgoing from the start point and from the end point \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: начало, средняя точка, конец; + точек должно быть 3. + \en The container for points of a conic: start point, average point and end point; + there should be exactly 3 points. \~ + \param[in] mbTangent1 - \ru Наклон в начале кривой. + \en Inclination at start of a curve. \~ + \param[in] mbTangent2 - \ru Наклон в конце кривой. + \en Inclination at end of a curve. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_3( const std::vector & vmbConicPoints, MbVector & mbTangent1, MbVector & mbTangent2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по двум точкам, двум наклонам и дискриминанту. + \en Construct a conic section by two points, two inclinations and a discriminant. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 2-ум точкам, которые задают начало и конец кривой, двум наклонам, выходящим из этих точек + и дискриминанту. + \en Construction of a conic section as a NURBS curve of the third degree by + 2 points setting start and end of a curve, two incllinations outgoing from these points + and a discriminant. \~ + \param[in] mbPoint1 - \ru Координаты начала коники. + \en Coordinates of the conic start point. \~ + \param[in] mbPoint2 - \ru Координаты конца коники. + \en Coordinates of the conic end point. \~ + \param[in] mbTangent1 - \ru Наклон в начале коники. + \en Inclination at start of conic. \~ + \param[in] mbTangent2 - \ru Наклон в конце коники. + \en Inclination at end of conic. \~ + \param[in] fDiscr - \ru Дискриминант < 1, если задать дискриминант >= 1, то он + автоматически будет сброшен до значения 0.99999999. + \en The discriminant is less than 1. Otherwise it + will be set to 0.99999999 automatically. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось построить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_4( const MbCartPoint3D & mbPoint1, const MbCartPoint3D & mbPoint2, + const MbVector3D & mbTangent1, const MbVector3D & mbTangent2, double fDiscr ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по двум точкам, двум наклонам и дискриминанту. + \en Construct a conic section by two points, two inclinations and a discriminant. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 2-ум точкам, которые задают начало и конец кривой, двум наклонам, выходящим из этих точек + и дискриминанту. + \en Construction of a conic section as a NURBS curve of the third degree by + 2 points setting start and end of a curve, two incllinations outgoing from these points + and a discriminant. \~ + \param[in] mbPoint1 - \ru Координаты начала коники. + \en Coordinates of the conic start point. \~ + \param[in] mbPoint2 - \ru Координаты конца коники. + \en Coordinates of the conic end point. \~ + \param[in] mbTangent1 - \ru Наклон в начале коники. + \en Inclination at start of conic. \~ + \param[in] mbTangent2 - \ru Наклон в конце коники. + \en Inclination at end of conic. \~ + \param[in] fDiscr - \ru Дискриминант < 1, если задать дискриминант >= 1, то он + автоматически будет сброшен до значения 0.99999999. + \en The discriminant is less than 1. Otherwise it + will be set to 0.99999999 automatically. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось построить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_4( const MbCartPoint & mbPoint1, const MbCartPoint & mbPoint2, + const MbVector & mbTangent1, const MbVector & mbTangent2, double fDiscr ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по четырем точкам и наклону. + \en Construct a conic section by four points, and an inclination. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 4-ем точкам и наклону в первой из них. \n + Путем подставления начальных точек в общее уравнение коники Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 + и касательной к ней в начальной точке (x1, y1): (2Ax1 + By1 + D)(x - x1) + (2Cy1 + Bx1 + E)(y - y1) = 0 + получим СЛАУ. Решив СЛАУ относительно параметров A,B,C,D,E, найдем искомую конику. + \en Construction of a conic section as a NURBS curve of the third degree by + 4 points and inclination in the first of them. \n + By substituting of start points in the common equation of the conic Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 + and its tangent at the start point (x1, y1): (2Ax1 + By1 + D)(x - x1) + (2Cy1 + Bx1 + E)(y - y1) = 0 + we get the SLAE. Having SLAE solved relative to parameters A,B,C,D,E we find the required conic. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: первая точка начальная, последняя - конечная; + точек должно быть 4. + \en The container for points of a conic: the first point is start point, the last point is end point. + there should be exactly 4 points. \~ + \param[in] mbTangent1 - \ru Наклон в точке коники. + \en Inclination at point of conic. \~ + \param[in] tanPntNb - \ru Номер точке, в которой задан наклон. + \en Point number at which the inclination is specified. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_5( const std::vector & vmbConicPoints, MbVector3D & mbTangent1, size_t tanPntNb = 1 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по четырем точкам и наклону. + \en Construct a conic section by four points, and an inclination. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по + 4-ем точкам и наклону в первой из них. \n + Путем подставления начальных точек в общее уравнение коники Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 + и касательной к ней в начальной точке (x1, y1): (2Ax1 + By1 + D)(x - x1) + (2Cy1 + Bx1 + E)(y - y1) = 0 + получим СЛАУ. Решив СЛАУ относительно параметров A,B,C,D,E, найдем искомую конику. + \en Construction of a conic section as a NURBS curve of the third degree by + 4 points and inclination in the first of them. \n + By substituting of start points in the common equation of the conic Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 + and its tangent at the start point (x1, y1): (2Ax1 + By1 + D)(x - x1) + (2Cy1 + Bx1 + E)(y - y1) = 0 + we get the SLAE. Having SLAE solved relative to parameters A,B,C,D,E we find the required conic. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: первая точка начальная, последняя - конечная; + точек должно быть 4. + \en The container for points of a conic: the first point is start point, the last point is end point. + there should be exactly 4 points. \~ + \param[in] mbTangent1 - \ru Наклон в точке коники. + \en Inclination at point of conic. \~ + \param[in] tanPntNb - \ru Номер точке, в которой задан наклон. + \en Point number at which the inclination is specified. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_5( const std::vector & vmbConicPoints, MbVector & mbTangent1, size_t tanPntNb = 1 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по пяти точкам. + \en Construct a conic section by five points. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по 5-ти точкам.\n + Путем подставления начальных точек в общее уравнение коники Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 получим СЛАУ. + Решив СЛАУ относительно параметров A,B,C,D,E, найдем искомую конику. + \en Construction of a conic section as a NURBS curve of the third degree by 5 points.\n + By substituting of start points in the common equation of the conic Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 we get the SLAE. + Having SLAE solved relative to parameters A,B,C,D,E we find the required conic. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: первая точка начальная, последняя - конечная; + точек должно быть 5. + \en The container for points of a conic: the first point is start point, the last point is end point. + there should be exactly 5 points. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC ( MbCurve3D * ) NurbsConic_6( const std::vector & vmbConicPoints ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить коническое сечение по пяти точкам. + \en Construct a conic section by five points. \~ + \details \ru Построение конического сечения в виде NURBS-кривой 3-го порядка по 5-ти точкам.\n + Путем подставления начальных точек в общее уравнение коники Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 получим СЛАУ. + Решив СЛАУ относительно параметров A,B,C,D,E, найдем искомую конику. + \en Construction of a conic section as a NURBS curve of the third degree by 5 points.\n + By substituting of start points in the common equation of the conic Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 we get the SLAE. + Having SLAE solved relative to parameters A,B,C,D,E we find the required conic. \~ + \param[in] vmbConicPoints - \ru Контейнер точек коники: первая точка начальная, последняя - конечная; + точек должно быть 5. + \en The container for points of a conic: the first point is start point, the last point is end point. + there should be exactly 5 points. \~ + \return \ru Указатель на построенную кривую \n + NULL, если не удалось постороить конику для заданных параметров. + \en The pointer to the constructed curve \n + is NULL if a try to construct a conic for given parameters has failed. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC ( MbCurve * ) NurbsConic_6( const std::vector & vmbConicPoints ); + + +#endif // __ALG_NURBS_CONIC_H diff --git a/C3d/Include/alg_polyline.h b/C3d/Include/alg_polyline.h new file mode 100644 index 0000000..2fd6656 --- /dev/null +++ b/C3d/Include/alg_polyline.h @@ -0,0 +1,361 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции создания кривых для внешнего использования. + \en Functions to create curves for external use. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __ALG_POLYLINE_H +#define __ALG_POLYLINE_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbVector; +class MATH_CLASS MbCurve; +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbBezier; +class MATH_CLASS MbNurbs; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbNurbs3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbContour3D; +class MATH_CLASS MbCubicSpline3D; + + +//------------------------------------------------------------------------------- +/** \brief \ru Параметры точки для создания полилинии. + \en Point parameters for creation of a polyline. \~ + \details \ru Часть точек может быть удалена при построении, поэтому вводится старый индекс, + который заполняется и используется в модели. Параметрами точки являются координаты точки и + радиус скругления в этой точке. При создании заполняются поля m_lineSeg и m_arcSeg. + m_lineSeg - это прямолинейный сегмент из этой точки в следующую. Для последней точки + и замкнутой ломаной - из последней в первую. m_arcSeg - дуга скругления в данной точке. + Если какой-то сегмент был полностью удален или не создан, то его указатель должен быть NULL. + Объектами m_lineSeg и m_arcSeg не владеет, поэтому и не удаляет их. Объекты из полилинии. + \en Some points may be deleted while the construction, therefore the old index is entered, + it is filled and used in a model. Parameters of a point are its coordinates and + fillet radius in this point. In a time of creation the fields 'm_lineSeg' and 'm_lineSeg' are being filled. + 'm_lineSeg' is the straight-line segment from this point to the next point. For the last point + and a closed polyline - from the last point to the first point. 'm_arcSeg'is the arc of a fillet in the given point. + If a segment has been fully deleted or it was not created then the pointer should be NULL. + Object 'm_lineSeg' and 'm_arcSeg' are not owned, therefore they are not deleted. Objects from a polyline. \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS Polyline3DPoint { +public: + size_t m_oldIndex; ///< \ru Исходный индекс в модели. \en The initial index of a model. + MbCartPoint3D m_point; ///< \ru Координаты вершины ломаной. \en The coordinates of a polyline vertex. + double m_radius; ///< \ru Радиус скругления в вершине. \en The fillet radius in a vertex. + const MbCurve3D * m_lineSeg; ///< \ru Прямолинейный сегмент из этой вершины в следующую. \en The straight-line segment from this vertex to the next. + const MbCurve3D * m_arcSeg; ///< \ru Дуга скругления в этой вершине (если m_radius > 0). \en the arc of a fillet in this vertex (if 'm_radius' > 0) + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + Polyline3DPoint() + : m_oldIndex( SYS_MAX_T ) + , m_point () + , m_radius ( 0.0 ) + , m_lineSeg ( NULL ) + , m_arcSeg ( NULL ) + {} + /// \ru Конструктор копирования. \en Copy constructor. + Polyline3DPoint( const Polyline3DPoint & other ) + : m_oldIndex( other.m_oldIndex ) + , m_point ( other.m_point ) + , m_radius ( other.m_radius ) + , m_lineSeg ( other.m_lineSeg ) + , m_arcSeg ( other.m_arcSeg ) + {} + /// \ru Деструктор. \en Destructor. + ~Polyline3DPoint() + {} +public: + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const Polyline3DPoint & other ) { + m_oldIndex = other.m_oldIndex; + m_point = other.m_point; + m_radius = other.m_radius; + m_lineSeg = other.m_lineSeg; + m_arcSeg = other.m_arcSeg; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить контур из отрезков по заданным точкам. + \en Construct a contour from segments by given points. \~ + \details \ru Вершины сочленения скругляются. Каждой вершине соответствует радиус скругления. \n + Eсли две вершины совпадают, то одна из них и соответствующий ей радиус удаляются. + \en Vertices of joint are rounded. Some fillet radius corresponds to every vertex. \n + If two vertices are coincident then one of them and the corresponding radius are deleted. \~ + \param[out] contour - \ru Контур. + \en The countour. \~ + \param[in] closed - \ru Флаг замкнутости контура. + \en Whether the contour is closed. \~ + \param[in] initList - \ru Множество точек полилинии. + \en The array of points of a polyline. \~ + \param[out] errorIndexes - \ru Множество индексов сегментов, сочленение которых со следующим прошло с ошибками. + \en The array of segments indices, each of which has been jointed with the next one with errors. \~ + \param[in] lengthEpsilon - \ru Погрешность построения элементов полилинии. + \en The tolerance of polyline elements construction. \~ + \return \ru true, если сегментов больше нуля. + \en true if the number of segments is greater than zero. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (bool) InitContour3D( MbContour3D & contour, bool closed, + SArray & initList, + SArray & errorIndexes, + double lengthEpsilon = Math::lengthEpsilon ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить погрешность точки на кривой. + \en Calculate the tolerance of a point on a curve. \~ + \details \ru Погрешностью считается ограничивающая сфера точки. + \en The tolerance is a sphere bounding a point. \~ + \param[in] crv - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] t - \ru Координата точки на кривой. + \en A coordinate of a point on a curve. \~ + \param[out] pnt - \ru Трехмерная координата точки на кривой. + \en A three-dimensional coordinate of a point on a curve. \~ + \param[out] eps - \ru Погрешность точки. + \en The tolerance of a point. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (void) GetEpsilonBound( const MbCurve3D & crv, double t, + MbCartPoint3D & pnt, double & eps, + VERSION version /*= Math::DefaultMathVersion()*/ ); // \ru KVA K13+ 6.5.2011 Версия нужна обязательно \en KVA K13+ 6.5.2011 A version is absolutely necessary. + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить инцидентность двух вершин. + \en Check the coincidence of two vertices. \~ + \details \ru Кривые рассматриваются как ребра). + \en Curves are considered as edges. \~ + \param[in] crv1 - \ru Кривая 1. + \en The curve 1. \~ + \param[in] t1 - \ru Если t1 == 1, рассматривается конец кривой, иначе начало. + \en If 't1' equals 1 then the end of a curve is considered, the start of a curve is considered otherwise. \~ + \param[in] crv2 - \ru Кривая 2. + \en The curve 2. \~ + \param[in] t2 - \ru Если t2 == 1, рассматривается конец кривой, иначе начало. + \en If 't2' equals 1 then the end of a curve is considered, the start of a curve is considered otherwise. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \return \ru true, если вершины инцидентны. + \en true if vertices are coincident. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) IsIncidence( const MbCurve3D & crv1, int t1, + const MbCurve3D & crv2, int t2, + VERSION version /*= Math::DefaultMathVersion()*/ ); // \ru KVA K13+ 6.5.2011 Версия нужна обязательно \en KVA K13+ 6.5.2011 A version is absolutely necessary. + + +//------------------------------------------------------------------------------ +/** \brief \ru Дать ближайший к лучу параметр кривой. + \en Get the curve parameter which is nearest to the ray. \~ + \details \ru Луч проходит через точку point в направлении вектора direct + \en The ray is passed through the point 'point' in the direction of the vector 'direct' \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] point - \ru Точка луча. + \en The point of a ray. \~ + \param[in] direct - \ru Вектор направления луча. + \en The vector of ray direction. \~ + \return \ru Ближайший к лучу параметр кривой. + \en The nearest curve parameter to the ray. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (double) GetNearCurveParam( const MbCurve3D & curve, + const MbCartPoint3D & point, const MbVector3D & direct ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Дать ближайший к лучу параметр кривой. + \en Get the curve parameter which is nearest to the ray. \~ + \details \ru Луч проходит через точку point в направлении вектора direct. \n + setOnSide == true принуждает установить параметр кривой к ближайшему концу и + вычислить флаг isBegin, определяющий близость к началу (true) или концу (false) кривой. + \en The ray is passed through the point 'point' in the direction of the vector 'direct'. \n + if 'setOnSide' equals true then the parameter of curve should be set for the nearest end and + the flag 'isBegin' determines the proximity to the curve start (true) or to the curve end (false). \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] point - \ru Точка луча. + \en The point of a ray. \~ + \param[in] direct - \ru Вектор направления луча. + \en The vector of a ray direction. \~ + \param[in] setOnSide - \ru Надо ли приравнять параметр к ближайшему концу кривой. + \en Whether the parameter should be equated to the nearest end of a curve. \~ + \param[out] isBegin - \ru если true, то параметр находится ближе к началу кривой. \n + Если false, то параметр находится ближе к концу кривой. + \en if true than the parameter is located closer to the start of a curve. \n + if false than the parameter is located closer to the end of a curve. \~ + \return \ru Ближайший к лучу параметр кривой. + \en The nearest curve parameter to the ray. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (double) GetNearCurveParam( const MbCurve3D & curve, + const MbCartPoint3D & point, const MbVector3D & direct, + bool setOnSide, bool & isBegin ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать гладкую кривую из кривой Безье. + \en Create a smooth curve from a Bezier curve. \~ + \details \ru По исходной кривой Безье создается NURBS 4-го порядка. После NURBS разбивается + в трижды кратных внутренних узлах, если они существуют. \n + Если bline принимает значение true, то проверяется вырожденность в линию. Если рассматриваемый + сегмент или кривая целиком - линия, то выполняется преобразование в линию. + \en A NURBS of the fourth degree is created by an initial Bezier curve . Thereafter the NURBS is splitted + in internal knots of triple multiplicity if they exist \n + If 'bline' is true then the degeneration into a line is checked. If the considered + segment or the entire curve is a line then it is trandformed into a line. \~ + \param[in] bez - \ru Кривая Безье. + \en Bezier curve \~ + \param[out] arCurve - \ru Множество созданных кривых. + \en The array of created curves. \~ + \param[in] bline - \ru Флаг проверки вырожденности в линию. + \en The flag for the check of degeneration into a line. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CreateSmoothFromBezier( const MbBezier & bez, RPArray & arCurve, + bool bline ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую заданного типа базе NURBS-кривой. + \en Create a curve of a given type as NURBS-curve. \~ + \details \ru Работает для двух типов: pt_LineSegment и pt_Arc. Если не удалось + аппроксимировать с заданной точностью функция вернет NULL. + \en It works for the two types: 'pt_LineSegment' and 'pt_Arc'. If approximation with the given tolerance has failed + then the function returns NULL. \~ + \param[in] nurbs - \ru Исходная NURBS-кривая. + \en The initial NURBS-curve. \~ + \param[in] type - \ru Тип кривой, которую требуется создать. + \en The type of a curve which is required to create. \~ + \param[in] eps - \ru Точность аппроксимации. + \en The tolerance of approximation. \~ + \return \ru Указатель на кривую, если она была создана. + \en The pointer to the curve if it has been created. \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (MbCurve *) ConvertNurbsToCurveOfType( const MbNurbs & nurbs, MbePlaneType type, double eps ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить плоскую проекцию кривой. + \en Construct a planar projection of a curve. \~ + \details \ru Построить двумерную кривую - проекцию кривой на плоскость XY локальной системы координат, заданной матрицей преобразования. + Двумерные кубические сплайны Эрмита (MbHermit) и кубические сплайны (MbCubicSpline) заменяются на NURBS (MbNurbs). + \en Construct a two-dimensional curve - projection of a curve to the plane XY of a coordinate system which is set by the matrix of transformation. + Two-dimensional cubic splines of Hermite ('MbHermit') and cubic splines ('MbCubicSpline') are replaced by NURBS ('MbNurbs'). \~ + \param[in] curve3D - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] into - \ru Матрица преобразования из глобальной системы координат в видовую плоскость. + \en The transformation matrix from the global coordinate system into a plane of view. \~ + \param[in] pRgn - \ru Параметрическая область кривой для создания проекции. + \en The parametric region of a curve for the creation of a projection. \~ + \param[in] version - \ru Версия построения. + \en The version of construction. \~ + \return \ru Указатель на полученную кривую. + \en The pointer to the obtained curve. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbCurve *) GetFlatCurve( const MbCurve3D & curve3D, const MbMatrix3D & into, + MbRect1D * pRgn = NULL, VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить плоскую проекцию кривой. + \en Get a planar projection of a curve. \~ + \details \ru Кривая проецируется на заданную плоскость. + \en A curve is projected onto a given plane. \~ + \param[in] curve3D - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] place - \ru Плоскость, на которую требуется спроецировать кривую. + \en The plane the curve should be projected on. \~ + \return \ru Указатель на полученную проекционную кривую. + \en The pointer to the obtained projection curve. \~ + + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbCurve *) GetFlatProjection( const MbCurve3D & curve3D, + const MbPlacement3D & place, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Положение кривой относительно точек оси. + \en The location of a curve relative to axis points. \~ + \details \ru Для определения направления оси вращения. + \en For the definition of the rotation axis direction. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] p1 - \ru Первая точка оси. + \en The first point of an axis. \~ + \param[in] p2 - \ru Вторая точка оси. + \en The second point of an axis. \~ + \return \ru 0 в случае сбоя при работе программы, \n + иначе возвращается векторное произведение нормализованного вектора оси (p1, p2) и + вектора (p1, w), где w - координаты центра тяжести кривой. + \en 0 in a case of failure, \n + otherwise the vector product of the normalized axis vector ('p1', 'p2') and + the vector ('p1', 'w') is returned. ('w' is the coordinates of the curve's center of gravity). \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (double) CurveRelative( const MbCurve & curve, const MbCartPoint & p1, const MbCartPoint & p2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Знак площади тени кривой на отрезок. + \en A sign of area of a curve's shadow on a segment. \~ + \details \ru Требуется для определения направления контура заметания. + Если кривая не замкнута, то она замыкается через ось. + \en This is required for the definition of the sweep contour direction. + If a curve is not closed then it becomes closed through an axis. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] p1 - \ru Первая точка отрезка. + \en The first point of a segment. \~ + \param[in] p2 - \ru Вторая точка отрезка. + \en The second point of a segment. \~ + \param[in] sag - \ru Угол отклонения. Используется для расчета шага по кривой. + \en The deviation angle. Used for calculation of the step by a curve. \~ + \return \ru Площадь тени со знаком. + \en The area of the shadow with a sign. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (double) ContourRelative( const MbCurve & curve, const MbCartPoint & p1, const MbCartPoint & p2, double sag ); + + +#endif // __ALG_POLYLINE_H + diff --git a/C3d/Include/alg_silhouette_hide.h b/C3d/Include/alg_silhouette_hide.h new file mode 100644 index 0000000..a795e3f --- /dev/null +++ b/C3d/Include/alg_silhouette_hide.h @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Получение линий очерка. + \en Obtaining the isocline curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ALG_SILHOUETTE_HIDE_H +#define __ALG_SILHOUETTE_HIDE_H + + +#include +#include +#include + + +class MATH_CLASS MbVector3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbMesh; + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить массив кривых плоской проекции очерка поверхности. + \en Get the array of surface silhouette curves of planar projection. \~ + \details \ru Получить массив кривых плоской проекции очерка поверхности. \n + \en Get the array of surface silhouette curves of planar projection. \n \~ + \ingroup Curve_Modeling +*/ +// --- +MATH_FUNC (void) CreateSurfaceHide( const MbSurface & surf, const MbPlacement3D & eyePlace, double sag, + RPArray & hideCurves, VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать сетку. + \en Calculate mesh. \~ + \details \ru Рассчитать сетку массива кривых очерка поверхности. \n + \en Calculate mesh of array of surface silhouette curves. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (void) CalculateHideMesh( const MbSurface & surf, const MbVector3D & eyeDir, double sag, + MbMesh *& mesh, VERSION version = Math::DefaultMathVersion() ); + + +#endif // __ALG_SILHOUETTE_HIDE_H diff --git a/C3d/Include/assembly.h b/C3d/Include/assembly.h new file mode 100644 index 0000000..85ee33a --- /dev/null +++ b/C3d/Include/assembly.h @@ -0,0 +1,392 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сборочная единица. + \en Assembly unit. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __ASSEMBLY_H +#define __ASSEMBLY_H + +#include +#include +#include +#include +#include + + +class MbConstraintSystem; +class MATH_CLASS MtGeomArgument; +class MATH_CLASS MtGeomConstraint; +class MATH_CLASS MtConstraintIter; +struct ItAssemblyReactor; +struct ItAssemblyImportData; +struct ItModelVisitor; +class MbModelTreeReader; +class MATH_CLASS MbAssembly; + +namespace c3d // namespace C3D +{ +typedef SPtr AssemblySPtr; +typedef SPtr ConstAssemblySPtr; + +typedef std::vector AssembliesVector; +typedef std::vector ConstAssembliesVector; + +typedef std::vector AssembliesSPtrVector; +typedef std::vector ConstAssembliesSPtrVector; +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Сборочная единица. + \en Assembly unit. \~ + \details \ru Сборка состоит из множества объектов геометрической модели MbItem. + Сборка может содержать объекты любого подкласса MbItem, в том числе и сборочные + единицы (тип MbAssembly). + \en The assembly consists of a set of objects of geometric model MbItem. + The assembly may contain objects of any sub-class of MbItem, including + assembly units (of type MbAssembly). + \par \ru Отношение "часть-целое". + \en Relationship "is a part of". + \ru Сборочная единица - это объект модели объединяющий в себе набор других объектов. + Такое объединение рассматривается как агрегация, устанавливающая отношение + владения между сборкой и её собственными суб-объектами. Это предполагает что любой + объект модели типа MbItem может принадлежать только одной сборке. + \en Assembly unit is object of model aggregating a collection of other objects. + Such an association is regarded as an aggregation establishing an ownership + between the assembly and its proper sub-objects. This implies that any + model object of type MbItem can belong to only assembly. + \~ + \ingroup Model_Items +*/ +//--- +class MATH_CLASS MbAssembly : public MbItem +{ +private: + typedef sorting_array ItemContainer; + typedef ItemContainer::iterator item_iterator; + +private: + ItemContainer assemblyItems; ///< \ru Множество объектов сборки. \en A set of assembly objects. + MbConstraintSystem * constraintSystem; ///< \ru Система ограничений сборки. \en Constraint system of assembly unit. + mutable ItAssemblyReactor * m_reactor; ///< \ru Обработчик события, связанные с решением сборки. \en The event handles related to solving the assembly. + +protected: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbAssembly( const MbAssembly & init, MbRegDuplicate * iReg ); + +public: + /// \ru Конструктор пустой сборки. \en Construct an empty assembly. + MbAssembly(); + /// \ru Конструктор по объекту. \en The constructor by an object. + explicit MbAssembly( MbItem & ); + /// \ru Конструктор по объектам в локальной системе координат. \en The constructor by objects in a local coordinate system. + template + MbAssembly( const ItemsVector & items ); + // \ru Деструктор. \en Destructor. + virtual ~MbAssembly(); + +public: + VISITING_CLASS( MbAssembly ); + + // \ru Общие функции геометрического объекта \en Common functions of a geometric object + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en An object type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * iReg = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move( const MbVector3D &, MbRegTransform * iReg = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * iReg = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными? \en Are the objects similar? + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать объекты равным \en Make the objects equal + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add own bounding box to the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate the bounding box in a local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create own property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Выдать локальную систему координат объектов сборки. \en Get the local coordinate system of assembly items. + virtual bool GetPlacement( MbPlacement3D & ) const; + // \ru Установить локальную систему координат объектов сборки. \en Set coordinate system of assembly items. + virtual bool SetPlacement( const MbPlacement3D & ); + // \ru Перестроить объект по журналу построения. \en Rebuild object according to the history tree. + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + // \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Добавить полигональную сетку объекта. \en Add a polygonal mesh of the object. + virtual bool AddYourMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + // \ru Разрезать полигональный объект одной или двумя параллельными плоскостями. \en Cut the polygonal object by one or two parallel planes. + virtual MbItem * CutMesh( const MbPlacement3D & cutPlace, double distance ) const; + // \ru Найти ближайший объект или имя ближайшего объекта. \en Find the closest object or its name. + virtual bool NearestMesh( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType, + const MbAxis3D & axis, double maxDistance, bool gridPriority, double & t, double & dMin, + MbItem *& find, SimpleName & findName, + MbRefItem *& element, SimpleName & elementName, + MbPath & path, MbMatrix3D & from ) const; + // \ru Дать все объекты указанного типа. \en Get all objects by type. \~ + virtual bool GetItems( MbeSpaceType type, const MbMatrix3D & from, + RPArray & items, SArray & matrs ); + // \ru Дать все полигональные объекты, отображающие геометрические элементы, участвующие в геометрических огриничениях.\en Get all polygonal objects for drawing the elements participated in geometric constraints. \~ + bool GetConstraintMesh( std::vector & meshes ) const; + // \ru Дать все уникальные объекты указанного типа. \en Get all unique objects by type . \~ + virtual bool GetUniqItems( MbeSpaceType type, CSSArray & items ) const; + // \ru Дать объект по его пути положения в модели и матрицу преобразования объекта в глобальную систему координат. \en Get the object by its path in the model and get the matrix of transformation of the object to the global coordinate system. + virtual const MbItem * GetItemByPath( const MbPath & path, size_t ind, MbMatrix3D & from, size_t currInd = 0 ) const; + // \ru Найти объект по геометрическому объекту (MbSpaceItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbSpaceItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Найти объект по геометрическому объекту (MbPlaneItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbPlaneItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Найти объект и матрицу его преобразования в глобальную систему координат. \en Find the object and the matrix of its transformation to the global coordinate system. + virtual const MbItem * FindItem( const MbItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Дать объект с заданным именем и матрицу его преобразования в глобальную систему координат. \en Get the object with the specified name and the matrix of its transformation to the global coordinate system. + virtual const MbItem * GetItemByName( SimpleName n, MbPath & path, MbMatrix3D & from ) const; + + // \ru Преобразовать согласно матрице c использованием регистратора селектированные содержимые объекты. \en Transform selected objects according to the matrix using the registrator. + virtual void TransformSelected( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Сдвинуть вдоль вектора с использованием регистратора селектированные содержимые объекты. \en Move selected objects along the vector using the registrator. + virtual void MoveSelected( const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Повернуть вокруг оси на заданный угол с использованием регистратора селектированные содержимые объекты. \en Rotate selected objects about the axis by the given angle using the registrator. + virtual void RotateSelected( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + /// \ru Отдать селектированные содержимые объекты. \en Get selected objects. + bool DetachSelected( RPArray & items, SArray & matrs, bool selected = true ); + /// \ru Отцепить все видимые или невидимые объекты. \en Detach all visible or invisible objects. \~ + bool DetachInvisible( RPArray & items, SArray & matrs, bool invisible = true ); + /// \ru Отцепить все объекты с указанным свойством. \en Detach all objects with pointed attribute. \~ + bool DetachByAttribute( RPArray & items, SArray & matrs, int attribute ); + /** \brief \ru Алгоритм общего назначения для обхода дерева модели в глубину. + \en General-purpose algorithm traversing the model graph in depth. */ + void Traverse( ItModelVisitor & ) const; + +public: + /** \ru \name Функции сборочной единицы. + \en \name The assembly unit functions. + \{ */ + /// \ru Выдать непосредственный объект сборки по идентификатору. \en Get the immediate item of assembly by identifier. + const MbItem * SubItem( SimpleName n ) const { return _ItemByName(n); } + /// \ru Добавить объект в сборку. \en Add an item to the assembly. + MbItem * AddItem( MbItem & item ); + /** + \brief \ru Добавить вставку геометрического объекта. + \en Add an instance of the geometric object. \~ + \param item - \ru Источник, на котором основан экземпляр вставки. + \en A source item on which the instance is based. + \param lcs - \ru Локальная система координат экземпляра вставляемого объекта. + \en Local coordinate system of the instanced object. \~ + \return \ru Экземпляр класса MbInstance, размещающего объект в пространстве сборки. + \en An Instance of class MbInstance placing the item in the space of the assembly. + */ + MbItem * AddInstance( MbItem & item, const MbPlacement3D & lcs ); + /** \brief \ru Заменить объект. + \en Replace an item. \~ + \details \ru Заменить объект новым. + \en Replace an item by a new one. \~ + \param[in] item - \ru Заменяемый объект. + \en An item to be replaced. \~ + \param[in] newItem - \ru Новый объект. + \en A new item. \~ + \return \ru Возвращает true, если замена была выполнена. + \en Returns true if the replacement has been performed. \~ + */ + bool ReplaceItem( const MbItem & item, MbItem & newItem, bool saveName = false ); + + /// \ru Выдать все объекты. \en Get all the items. + void GetItems( RPArray & items ) const; + /// \ru Выдать все объекты. \en Get all the items. + void GetItems( RPArray & items ); + + /// \ru Отцепить объект по индексу. \en Detach the item by index. + MbItem* DetachItem ( size_t ind ); + /// \ru Отцепить объект, если такой есть в сборке. \en Detach the item if it belongs to the assembly. + bool DetachItem ( MbItem * obj ); + /// \ru Удалить объект, если такой есть в сборке или в подсборках. \en Delete the item if it belongs to the assembly or its sub-assemblies. + bool DeleteItem ( MbItem * obj ); + /// \ru Удалить все объекты сборки. \en Delete all the assembly items. + void DeleteItems(); + /// \ru Выдать количество объектов сборки. \en Get the assembly item count. + size_t ItemsCount() const { return assemblyItems.size(); } + /// \ru Вернуть true, если сборка не содержит геометрических объекты. \en Return true, if the assembly has no geometric objects. + bool IsEmpty() const { return assemblyItems.empty(); } + /// \ru Выдать объект по индексу. \en Get the item by index. + const MbItem * GetItem( size_t i ) const; + /// \ru Выдать объект по индексу для модификации. \en Get the item by index for modification. + MbItem * SetItem( size_t i ); + /// \ru Содержит ли сборка присланный объект? \en Does the assembly contain the given item? + bool ContainsItem( const MbItem * obj ) const; + /// \ru Вычислить габарит сборки. \en Calculate the bounding box of the assembly. + void CalculateGabarit( MbCube & cube ) const; + /// \ru Выдать количество граней. \en Get the number of faces. + size_t GetFacesCount() const; + /// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. + template + void GetFacesSet( FacesVector & faces ) const; +public: + /** \} + \ru \name Функции системы ограничений. + \en \name The constraint system functions. + \{ */ + /// \ru Добавить ограничение для пары геометрических объектов. \en Add geometric constraint. + MtGeomConstraint AddConstraint( MtMateType, const MtGeomArgument &, const MtGeomArgument &, MtParVariant = MtParVariant::undef ); + /// \ru Изменить значение управляющего размера. \en Change the value of driving dimension. + MtResultCode3D ChangeDimension( MtGeomConstraint & dimCon, double newVal ); + /// \ru Решить ограничения сборки. \en Evaluate constraints. + MtResultCode3D EvaluateConstraints(); + /// \ru Выдать диапазон итераторов для обхода всех ограничений сборки. \en Get a range of iterators to traverse all assembly constraints. + void GetConstraints( MtConstraintIter & begIter, MtConstraintIter & endIter ) const; + /// \ru Задать или сбросить обработчик событий решателя. \en Set or reset an handler of constraint solving events. + void SetReactor( ItAssemblyReactor * ) const; + /// \ru Импортировать систему ограничений из приложения САПР. \ru Import the constraint system from CAD application. + bool Import( ItAssemblyImportData & ); + +public: + /** \} */ + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbAssembly ); + + static const MbPlacement3D & GetPlacement() { return MbPlacement3D::global; } // This function is deprecated. Use MbInstanse to give the assembly its own placement. + + friend class MbModelTreeReader; + +private: + // \ru Инициализатор по массиву составляющих объектов. // \en Initializer to aggregate items in the assembly. + template + void _Init( const ItemsVector & ); + // Найти объект по геометрическому объекту + template + const MbItem * _FindItem( const ItemType * s, MbPath & path, MbMatrix3D & from ) const; + // Поиск в глубину среди подчиненных + template + const MbItem * _FindRecursively( const ItemType * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Выдать объект по идентификатору. \en Get the item by identifier. + const MbItem * _ItemByName( SimpleName ) const; + // \ru Генерация имени для нового элемента сборки. \en Generate identifier for new assembly item. + SimpleName _NewItemName() const; + /// \ru Добавить в сборку объекты сборки без трансформации. \en Add assembly items to the assembly without transformation. + bool _AddAssemblyItems( MbAssembly & ); + + OBVIOUS_PRIVATE_COPY( MbAssembly ); +}; // MbAssembly + +IMPL_PERSISTENT_OPS( MbAssembly ) + + +//---------------------------------------------------------------------------------------- +// Экспериментальный посетитель дерева модели +/* + Возможные применения: + - Сбор любых данных об/из иерархии модели; + - Загрузка подсборок и вставок в утилиту поиска соударений (MbCollisionDetectionUtility); + - Геометрический поиск с выдачей маршрута(MbPath) и матрицу отображения МСК вставок и подсборок; + - Восстановление текущей матрицы и маршрута MbPath по hash-коду ссылок в системе + геометрических ограничений; +*/ +//--- +struct ItModelVisitor +{ +public: + virtual void VisitItem( const MbItem * ) = 0; + virtual void FinishItem( const MbItem * ) = 0; + virtual bool ExamineSubItem( const MbItem * owner, const MbItem * subItem ) = 0; + virtual void ExamineInstance( const MbInstance * inst, const MbItem * srcItem ) = 0; +}; + + +//---------------------------------------------------------------------------------------- +// \ru Конструктор по объектам. \en The constructor by objects. +//--- +template +MbAssembly::MbAssembly( const ItemsVector & items ) + : MbItem() + , assemblyItems() + , constraintSystem( NULL ) + , m_reactor( NULL ) +{ +#ifdef C3D_DEBUG + // Check a condition of the single owner. + for ( size_t i = 0, iCount = items.size(); i < iCount; ++i ) + { + if ( items[i]->GetItemName() != UNDEFINED_SNAME ) + { + C3D_ASSERT_UNCONDITIONAL( false ); // The item has already a name. It's probably means that the item is owned another assembly. + break; + } + } +#endif // C3D_DEBUG + + _Init( items ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Инициализатор по массиву составляющих объектов. +// \en Initializer to aggregate items in the assembly. +//--- +template +void MbAssembly::_Init( const ItemsVector & items ) +{ + C3D_ASSERT( assemblyItems.empty() && (constraintSystem == NULL) ); + SimpleName idCounter = 0; + + for ( size_t i = 0, iCount = items.size(); i < iCount; ++i ) + { + if ( MbItem * item = items[i] ) { + if ( item->GetItemName() == UNDEFINED_SNAME ) { + item->SetItemName( idCounter ); + } + else { + C3D_ASSERT( idCounter <= item->GetItemName() ); + idCounter = max_of( idCounter, item->GetItemName() ); + } + ++idCounter; + item->AddRef(); + assemblyItems.push_back( item ); + } + } +} + + +//---------------------------------------------------------------------------------------- +// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. +//--- +template +void MbAssembly::GetFacesSet( FacesVector & faces ) const +{ + for ( size_t i = assemblyItems.size(); i--; ) + { + if ( const MbItem * assemblyItem = assemblyItems[i] ) + { + if ( assemblyItem->IsA() == st_Solid ) + static_cast(*assemblyItem).GetFacesSet( faces ); + else if ( assemblyItem->IsA() == st_Instance ) + static_cast(*assemblyItem).GetFacesSet( faces ); + else if ( assemblyItem->IsA() == st_Assembly ) + static_cast(*assemblyItem).GetFacesSet( faces ); + } + } +} + +//---------------------------------------------------------------------------------------- +// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. +//--- +template +void MbInstance::GetFacesSet( FacesVector & faces ) const +{ + if ( item != NULL ) { + if ( item->IsA() == st_Solid ) + static_cast( *item ).GetFacesSet( faces ); + else if ( item->IsA() == st_Assembly ) + static_cast( *item ).GetFacesSet( faces ); + else if ( item->IsA() == st_Instance ) + static_cast( *item ).GetFacesSet( faces ); + } +} + + +#endif // __ASSEMBLY_H diff --git a/C3d/Include/assisting_item.h b/C3d/Include/assisting_item.h new file mode 100644 index 0000000..34f3a39 --- /dev/null +++ b/C3d/Include/assisting_item.h @@ -0,0 +1,100 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вспомогательный объект геометрической модели. + \en Assisting item of the geometric model. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ASSISTING_ITEM_H +#define __ASSISTING_ITEM_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbCube; +class MATH_CLASS MbProperties; +class MATH_CLASS MbMesh; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вспомогательный объект геометрической модели. + \en Assisting item of the geometric model. \~ + \details \ru Вспомогательный объект позволяет использовать в геометрической модели такие объекты, + как локальная система координат, ось, матрица преобразования для позиционирования других объектов.\n + \en The assisting item allows to use such an objects in a geometric model + as a local coordinate system, axis, transformation matrix for the other objects location.\n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbAssistingItem : public MbItem { +protected : + MbPlacement3D place; ///< \ru Локальная система координат. \en Local coordinate system. + +protected : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbAssistingItem( const MbAssistingItem &, MbRegDuplicate * ); +public : + /// \ru Конструктор по локальной системе координат. \en Constructor by a local coordinate system. + MbAssistingItem( const MbPlacement3D & ); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbAssistingItem(); + +public : + VISITING_CLASS( MbAssistingItem ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en An object type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Whether the objects are equal? + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными? \en Whether the objects are similar? + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равным. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add own bounding box to the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate the bounding box in a local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create own property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /// \ru Получить систему координат объекта. \en Get the coordinate system of an item. + virtual bool GetPlacement( MbPlacement3D & ) const; + /// \ru Установить систему координат объекта. \en Set the coordinate system of an item. + virtual bool SetPlacement( const MbPlacement3D & p ); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + + /// \ru Дать матрицу преобразования из локальной системы объекта. \en Get transform matrix from local coordinate system of object. + virtual bool GetMatrixFrom( MbMatrix3D & from ) const; + /// \ru Дать матрицу преобразования в локальную систему объекта. \en Get transform matrix into local coordinate system of object. + virtual bool GetMatrixInto( MbMatrix3D & into ) const; + + /** \ru \name Функции вспомогательного объекта. + \en \name Functions of assisting item. + \{ */ + /// \ru Выдать систему координат объекта. \en Get the coordinate system of an item. + const MbPlacement3D & GetPlacement() const { return place; } + /// \ru Выдать систему координат объекта для редактирования. \en Get the coordinate system of an item for editing. + MbPlacement3D & SetPlacement() { return place; } + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbAssistingItem ) +OBVIOUS_PRIVATE_COPY( MbAssistingItem ) +}; + +IMPL_PERSISTENT_OPS( MbAssistingItem ) + +#endif // __ASSISTING_ITEM_H diff --git a/C3d/Include/ats_check.h b/C3d/Include/ats_check.h new file mode 100644 index 0000000..e3a58fa --- /dev/null +++ b/C3d/Include/ats_check.h @@ -0,0 +1,320 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции сравнения и тестирования тел. + \en Functions for solids comparison and testing. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// +#ifndef __ATS_CHECK_H +#define __ATS_CHECK_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbSolid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Различия примитивов. + \en Differences of primitives. \~ + \details \ru Различия примитивов.\n + \en Differences of primitives.\n \~ + \ingroup Algorithms_3D +*/ +// --- +struct PrimitiveDifference { +public: + /// \ru Типы различий в именовании \en Types of naming differences + enum DifferenceType + { + dt_Geometry = 0, ///< \ru Изменения в геометрии. \en Changes in geometry. + dt_NameChanged, ///< \ru Изменилось наименование. \en Name has changed. + dt_NameNotFound, ///< \ru Не найдено соответствие имени. \en A correspondence for the name was not found. + dt_NameMultiple, ///< \ru Найдено более одного соответствия имени. \en There are more than one correspodences for the name. + }; +private: + MbeTopologyType objType; ///< \ru Тип объекта с различиями. \en The type of an object with differences. +public: + PrimitiveDifference( MbeTopologyType type ) : objType( type ) {} ///< \ru Коннструктор по типу топологического объекта. \en Constructor by a type of topological object. + virtual ~PrimitiveDifference() {} +public: + MbeTopologyType GetObjType() const { return objType; } ///< \ru Тип топологического объекта. \en The type of topological object + virtual void Accept( Visitor & visitor ) = 0; ///< \ru Прием посетителя. \en Acceptance of a visitor. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Различие в именовании двух примитивов. + \en Naming difference between two primitives. \~ + \details \ru Различие в именовании двух примитивов или ненайденный примитив.\n + \en Naming difference between two primitives or not found primitive.\n \~ + \ingroup Algorithms_3D +*/ +// --- +struct MATH_CLASS NameDifference : public PrimitiveDifference { +public: + MbName name1; ///< \ru Имя некоего примитива в первом объекте. \en The name of a primitive in the first object. + MbName name2; ///< \ru Имя того же примитива во втором объекте. \en The name of a primitive in the first object. + DifferenceType diffType; ///< \ru Тип различия. \en A type of difference. +public: + /// \ru Различие в именовании двух примитивов. \en Naming difference between two primitives. + NameDifference( const MbName & n1, const MbName & n2, DifferenceType dType, MbeTopologyType oType ); + /// \ru Ненайденный примитив. \en The found primitive. + NameDifference( const MbName & n, DifferenceType dType, MbeTopologyType oTType ); +public: + /** \brief \ru Это различие в именовании? + \en Is this a naming difference? \~ + \details \ru Это различие в именовании?\n + \en Is this a naming difference?\n \~ + \return \ru true, если это различие в именовании,\n + иначе это ненайденный примитив или геометрическое различие.\n + \en true if this is a naming difference,\n + otherwise this is a unfound primitive or geometric difference.\n \~ + */ + bool IsNamesDifference() const; + +VISITING_CLASS( NameDifference ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Различие в количестве. + \en Difference in count. \~ + \details \ru Различие в количестве.\n + \en Difference in count.\n \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS CountDifference : public PrimitiveDifference { +public: + size_t cnt1; ///< \ru Количество компонентов данного типа в первом объекте. \en The number of components of the given type in the first object. + size_t cnt2; ///< \ru Количество компонентов данного типа во втором объекте. \en The number of components of the given type in the second object. + bool valid; ///< \ru Подсчитаны корректные объекты. \en Calculated objects are correct. +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] n1 - \ru Количество компонентов данного типа в первом объекте. + \en The number of components of the given type in the first object. \~ + \param[in] n2 - \ru Количество компонентов данного типа во втором объекте. + \en The number of components of the given type in the second object. \~ + \param[in] good - \ru Подсчитаны корректные объекты. + \en Calculated objects are correct. \~ + \param[in] oType - \ru Тип объекта с различиями. + \en Type of an object with differences. \~ + */ + CountDifference( size_t n1, size_t n2, bool good, MbeTopologyType oType ) + : PrimitiveDifference( oType ) + , cnt1( n1 ) + , cnt2( n2 ) + , valid( good ) + {} + +VISITING_CLASS( CountDifference ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Различие точек. + \en Difference of points. \~ + \details \ru Различие точек.\n + \en Difference of points.\n \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS PointDifference : public PrimitiveDifference { +public: + MbCartPoint3D pnt1; ///< \ru Первая точка. \en The first point. + MbCartPoint3D pnt2; ///< \ru Вторая точка. \en The second point. +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point. \~ + \param[in] objType - \ru Тип объекта с различиями. + \en Type of an object with differences. \~ + */ + PointDifference( const MbCartPoint3D & p1, const MbCartPoint3D & p2, MbeTopologyType objType ); + +VISITING_CLASS( PointDifference ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Различие нормалей. + \en Difference of normals. \~ + \details \ru Различие нормалей.\n + \en Difference of normals.\n \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS VectorDifference : public PrimitiveDifference { +public: + MbVector3D vect1; ///< \ru Первый вектор. \en The first vector. + MbVector3D vect2; ///< \ru Второй вектор. \en The second vector. +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] v1 - \ru Первый вектор. + \en The first vector. \~ + \param[in] v2 - \ru Второй вектор. + \en The second vector. \~ + \param[in] objType - \ru Тип объекта с различиями. + \en Type of an object with differences. \~ + */ + VectorDifference( const MbVector3D & v1, const MbVector3D & v2, MbeTopologyType objType ); + +VISITING_CLASS( VectorDifference ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Результат сравнения двух объектов. + \en The result of comparison between two objects. \~ + \details \ru Результат сравнения двух объектов.\n + \en The result of comparison between two objects.\n \~ + \ingroup Algorithms_3D +*/ +// --- +class MATH_CLASS CompareItemsResult { +protected: + bool areItemsEqual; ///< \ru Признак отсутствия различий в моделях и в именованиях. \en Attribute of absence of differences in models and names. + PArray differences; ///< \ru Различия в именовании примитивов и ненайденные примитивы. \en Differences in primitives names and unfound primitives. +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор результата сравнения одинаковых моделей.\n + \en Constructor of result of comparison between equal models.\n \~ + */ + CompareItemsResult(); + /// \ru Деструктор. \en Destructor. + virtual ~CompareItemsResult(); +public: + + void Reset(); ///< \ru Сбросить различия. \en Reset differences. + void Add( PrimitiveDifference & diff ); ///< \ru Добавить различие. \en Add a difference. + + void SetItemsEqual( bool set ); ///< \ru Установить флаг отсутствия различий. \en Set the flag when differences are absence. + + /** \brief \ru Тела одинаковые? + \en Are solids equal? \~ + \details \ru Тела одинаковые?\n + \en Are solids equal?\n \~ + \return \ru true, если нет ни различий в именовании, ни геометрических отличий. + \en true if there are no naming differences and there are no geometric differences. \~ + */ + bool AreItemsEqual() const; + + size_t NamesDifferencesCount() const; ///< \ru Число различий в именовании. \en The number of naming differences. + bool HaveGeometricDifferences() const; ///< \ru Есть геометрические различия? \en Is there any geometric difference? + + const PArray & GetPrimitiveDifferences() const; ///< \ru Дать результаты сравнения. \en Get comparison results. +}; + + +/////////////////////////////////////////////////////////////////////////// +// +// \ru Функции \en Functions +// +/////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Способы "перемешивания". + \en Ways of "mixing". \~ + \details \ru Способы "перемешивания" составляющих оболочки. + \en Ways of shell components "mixing". \~ + \ingroup Algorithms_3D +*/ +// --- +enum SolidMixUpMode { + /// \ru Изменение порядка следования граней в массиве. \en A change of faces order in array. + smm_FacesReorder = 1, + + /// \ru Изменение порядок следования циклов на грянях (толко внутренних). \en A change of loops order in faces (internal only). + smm_LoopsReorder = 2, + + /// \ru Изменение начального ребра в циклах граней. \en A change of first edge in loops of faces. + smm_LoopsBegReset = 4, //-V112 + + /// \ru Изменение направления ребер в циклах граней. \en A change of edges directions in loops of faces. + smm_EdgesRedirection = 8, + + /// \ru Разбивка ребер вставкой вершины. \en Splitting of edges by vertex insertion. + smm_EdgesSection = 16, +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Стрессовый тест тела. + \en A stress test for solid. \~ + \details \ru Стрессовый тест тела, перемешивание составляющих оболочки.\n + \en A stress test for solid, shell components mixing.\n \~ + \param[in] solid - \ru Тестируемое тело. + \en The tested solid. \~ + \param[in] mixUpModes - \ru Флаги из SolidMixUpMode. + \en Flags from SolidMixUpMode. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC ( void ) SolidMixUp( MbSolid & solid, uint mixUpModes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сравнение двух тел. + \en Two solids comparison. \~ + \details \ru Сравнение двух тел.\n + \en Two solids comparison.\n \~ + \param[in] solid1 - \ru Первое тело. + \en The first solid. \~ + \param[in] solid2 - \ru Второе тело. + \en The second solid. \~ + \param[in] compareMassInertia - \ru Проверять сначала МЦХ тел. + \en Check mass-inertial properties at first. \~ + \param[in] checkSense - \ru Проверять совпадение ориентаций рёбер и граней. + \en Check orientations coincidence of edges and faces. \~ + \param[out] compareResult - \ru Результат сравнения двух тел. + \en The result of comparison between two solids. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) CompareSolids( const MbSolid & solid1, + const MbSolid & solid2, + CompareItemsResult & compareResult, + bool compareMassInertia, + bool checkSense ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Сравнение двух тел по именам. + \en Comparison of two solids by name. \~ + \details \ru Сравнение двух тел по именам.\n + \en Comparison of two solids by name.\n \~ + \param[in] before - \ru Тело до перестроения. + \en The solid before construction. \~ + \param[in] after - \ru Тело после перестроения. + \en The solid after construction. \~ + \param[out] compareResult - \ru Результат сравнения двух тел. + \en The result of comparison between two solids. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) CompareSolidsByNames( const MbSolid & before, + const MbSolid & after, + CompareItemsResult & compareResult ); + + +#endif // __ATS_CHECK_H diff --git a/C3d/Include/attr_color.h b/C3d/Include/attr_color.h new file mode 100644 index 0000000..0b57bab --- /dev/null +++ b/C3d/Include/attr_color.h @@ -0,0 +1,343 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибуты. Цвет. Толщина линий отрисовки. Стиль линий отрисовки. Свойства для OpenGL. + \en Attributes. Color. Thickness of drawing lines. Style of drawing lines. Properties for OpenGL. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_COLOR_H +#define __ATTR_COLOR_H + + +#include +#include + + +#define __RGB__ 3 + + +//------------------------------------------------------------------------------ +/** \brief \ru Преобразовать цвет по трём компонентам в uint32. + \en Convert a color by 3 components in uint32. \~ + \details + \warning \ru Значения компонент цвета должны лежать в диапазоне [ 0; 1 ]. + \en Values of color components should belong to the range [ 0; 1 ]. \~ + \ingroup Model_Attributes +*/ +// --- +inline uint32 RGB2uint32( double r, double g, double b ) +{ + const double f1 = 255.0 / 256.0; + uint32 uinturgb[3]; + const uint32 bt = 256; + uinturgb[0] = uint32 ( 256.0 * r * f1 ); + uinturgb[1] = uint32 ( 256.0 * g * f1 ); + uinturgb[2] = uint32 ( 256.0 * b * f1 ); + for ( int n = 0; n < 3; n++ ) + if ( uinturgb[n] >= bt ) { + uinturgb[n] = bt - 1; + C3D_ASSERT_UNCONDITIONAL( false ); + } + return uinturgb[0] + bt * ( uinturgb[1] + bt * uinturgb[2] ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Преобразовать unit32 в три компоненты цвета. + \en Convert unit32 to 3 components of color. \~ + \details + \warning \ru Компоненты цветов лежат в диапазоне [ 0; 1 ]. + \en Color components belong to the range [ 0; 1 ]. \~ + \ingroup Model_Attributes +*/ +// --- +template +void uint322RGB( uint32 color, float_t& r, float_t& g, float_t& b ) { + const float_t r255 = float_t(1.0 / 255.0); + const uint32 u256 = (uint32)SYS_MAX_UINT8 + 1; + r = float_t ( color % u256); + g = float_t ( (color / 256) % u256); + b = float_t ( (color / 65536) % u256); + r *= r255; g *= r255; b *= r255; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Цвет. + \en Color. \~ + \details \ru Цвет. \n + \en Color. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbColor : public MbElementaryAttribute { +protected : + uint32 color; ///< \ru Цвет. \en Color. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbColor( const MbColor & init ); +public : + /// \ru Конструктор. \en Constructor. + MbColor( uint32 init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbColor(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить цвет. \en Set a color. + void Init( uint32 init ) { color = init; } + /// \ru Дать цвет. \en Get a color. + uint32 Color() const { return color; } +//int R() const { return red; } // \ru Красный цвет \en Red color +//int G() const { return green; } // \ru Зеленый цвет \en Green color +//int B() const { return blue; } // \ru Синий цвет \en Blue color + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbColor & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbColor ) +}; // MbColor + +IMPL_PERSISTENT_OPS( MbColor ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Толщина линий отрисовки. + \en Thickness of drawing lines. \~ + \details \ru Толщина линий отрисовки. \n + \en Thickness of drawing lines. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbWidth : public MbElementaryAttribute { +protected : + int width; ///< \ru Толщина линий отрисовки. \enThickness of drawing lines. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbWidth( const MbWidth & init ); +public : + /// \ru Конструктор. \en Constructor. + MbWidth( int init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbWidth(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить толщину. \en Set a thickness. + void Init( int init ) { width = init; } + /// \ru Дать толщину. \en Get a thickness. + int Width() const { return width; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbWidth & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbWidth ) +}; // MbWidth + +IMPL_PERSISTENT_OPS( MbWidth ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Стиль линий отрисовки. + \en Style of drawing lines. \~ + \details \ru Стиль линий отрисовки. \n + \en Style of drawing lines. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbStyle : public MbElementaryAttribute { +protected : + int style; ///< \ru Стиль линий отрисовки. \en Style of drawing lines. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbStyle( const MbStyle & init ); +public : + /// \ru Конструктор. \en Constructor. + MbStyle( int init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbStyle(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить стиль линий отрисовки. \en Set style of drawing lines. + void Init( int init ) { style = init; } + /// \ru Дать стиль линий отрисовки. \en Get style of drawing lines. + int Style() const { return style; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbStyle & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStyle ) +}; // MbStyle + +IMPL_PERSISTENT_OPS( MbStyle ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойства для OpenGL. + \en Properties for OpenGL. \~ + \details \ru Свойства для OpenGL для трех цветов: RED, GREEN, BLUE. \n + \en Properties for OpenGL for colors: RED, GREEN, BLUE. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbVisual : public MbElementaryAttribute { +protected : + float ambient[__RGB__]; ///< \ru Коэффициент общего фона для трех цветов: RED, GREEN, BLUE. \en Coefficient of ambient background for colors: RED, GREEN, BLUE, range 0.0 - 1.0. + float diffuse[__RGB__]; ///< \ru Коэффициент диффузного отражения для трех цветов: RED, GREEN, BLUE. \en Coefficient of diffuse reflection for colors: RED, GREEN, BLUE, range 0.0 - 1.0. + float specularity[__RGB__]; ///< \ru Коэффициент зеркального отражения света трех цветов: RED, GREEN, BLUE. \en Coefficient of specular reflection for light colors: RED, GREEN, BLUE, range 0.0 - 1.0. + float shininess; ///< \ru Блеск (показатель степени в законе зеркального отражения). \en Shininess (index according to the law of specular reflection), range 0 - 128. + float opacity; ///< \ru Коэффициент непрозрачности (коэффициент суммарного отражения). \en Opacity coefficient (coefficient of total reflection), range 0.0 (transparent) - 1.0(opaque). + float emission; ///< \ru Коэффициент излучения. \en Emissivity coefficient, range 0.0 - 1.0. + float chrom; ///< \ru Коэффициент зеркального отражения объектов. \en Coefficient of specular reflection for objects, range 0.0 - 1.0. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbVisual( const MbVisual & init ); +public : + /// \ru Конструктор. \en Constructor. + MbVisual( float a = MB_AMBIENT, float d = MB_DIFFUSE, float s = MB_SPECULARITY, + float h = MB_SHININESS, float t = MB_OPACITY, float e = MB_EMISSION ); + /// \ru Деструктор. \en Destructor. + virtual ~MbVisual(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить свойства для OpenGL. \en Set properties for OpenGL. + void Init( float a = MB_AMBIENT, float d = MB_DIFFUSE, float s = MB_SPECULARITY, + float h = MB_SHININESS, float t = MB_OPACITY, float e = MB_EMISSION, uint rgb = 0 ) { + ambient[rgb%__RGB__] = a; // \ru Коэффициент общего фона. \en Coefficient of ambient background. + diffuse[rgb%__RGB__] = d; // \ru Коэффициент диффузного отражения. \en Coefficient of diffuse reflection. + specularity[rgb%__RGB__] = s; // \ru Коэффициент зеркального отражения света. \en Coefficient of specular reflection for light. + shininess = h; // \ru Блеск (показатель степени. в законе зеркального отражения). \en Shininess (index according to the law of specular reflection). + opacity = t; // \ru Коэффициент непрозрачности. \en Opacity coefficient. + emission = e; // \ru Коэффициент излучения. \en Emissivity coefficient. + chrom = s; // \ru Коэффициент зеркального отражения объектов. \en Coefficient of specular reflection for objects. + } + /// \ru Дать свойства для OpenGL. \en Get properties for OpenGL. + void Get( float & a, float & d, float & s, float & h, float & t, float & e, uint rgb = 0 ) const { + a = ambient[rgb%__RGB__]; // \ru Коэффициент общего фона. \en Coefficient of ambient background. + d = diffuse[rgb%__RGB__]; // \ru Коэффициент диффузного отражения. \en Coefficient of diffuse reflection. + s = specularity[rgb%__RGB__]; // \ru Коэффициент зеркального отражения света. \en Coefficient of Specular reflection for light. + h = shininess; // \ru Блеск (показатель степени в законе зеркального отражения). \en Shininess (index according to the law of specular reflection). + t = opacity; // \ru Коэффициент непрозрачности. \en Opacity coefficient. + e = emission; // \ru Коэффициент излучения. \en Emissivity coefficient. + } + float Ambient ( uint rgb = 0 ) const { return ambient[rgb%__RGB__]; } // \ru Дать коэффициент общего фона. \en Get a coefficient of ambient background. + float Diffuse ( uint rgb = 0 ) const { return diffuse[rgb%__RGB__]; } // \ru Дать коэффициент диффузного отражения. \en Get a coefficient of diffuse reflection. + float Specularity ( uint rgb = 0 ) const { return specularity[rgb%__RGB__]; } // \ru Дать коэффициент зеркального отражения света. \en Get a coefficient of specular reflection for light. + float Shininess () const { return shininess; } // \ru Дать блеск (показатель степени в законе зеркального отражения). \en Get shininess (index according to the law of specular reflection). + float Opacity () const { return opacity; } // \ru Дать коэффициент непрозрачности. \en Get an opacity coefficient. + float Emission () const { return emission; } // \ru Дать коэффициент излучения. \en Get a coefficient of emissivity. + float Chrom () const { return chrom; } // \ru Дать коэффициент зеркального отражения объектов. \en Get a coefficient of specular reflection for objects. + const float * Ambients () const { return ambient; } // \ru Дать коэффициенты общего фона. \en Get all coefficients of ambient background. + const float * Diffuses () const { return diffuse; } // \ru Дать коэффициенты диффузного отражения. \en Get all coefficients of diffuse reflection. + const float * Specularitys() const { return specularity; } // \ru Дать коэффициенты зеркального отражения света. \en Get all coefficients of specular reflection for light. + + void SetAmbient ( float v, uint rgb = 0 ) { ambient[rgb%__RGB__] = v; } // \ru Установить коэффициент общего фона. \en Set a coefficient of ambient background. + void SetDiffuse ( float v, uint rgb = 0 ) { diffuse[rgb%__RGB__] = v ; } // \ru Установить коэффициент диффузного отражения. \en Set a coefficient of diffuse reflection. + void SetSpecularity ( float v, uint rgb = 0 ) { specularity[rgb%__RGB__] = v; } // \ru Установить коэффициент зеркального отражения света. \en Set a coefficient of specular reflection for light. + void SetShininess ( float v ) { shininess = v; } // \ru Установить блеск (показатель степени в законе зеркального отражения). \en Set shininess (index according to the law of specular reflection). + void SetOpacity ( float v ) { opacity = v; } // \ru Установить коэффициент непрозрачности. \en Set an opacity coefficient. + void SetEmission ( float v ) { emission = v; } // \ru Установить коэффициент излучения. \en Set a coefficient of emissivity. + void SetChrom ( float v ) { chrom = v; } // \ru Установить коэффициент зеркального отражения объектов. \en Set a coefficient of specular reflection for objects. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbVisual & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbVisual ) +}; // MbVisual + +IMPL_PERSISTENT_OPS( MbVisual ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Количество u-линий и v-линий отрисовочной сетки. + \en The number of u-mesh and v-mesh drawing lines. \~ + \details \ru Количество u-линий и v-линий отрисовочной сетки. \n + \en The number of u-mesh and v-mesh drawing lines. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbWireCount : public MbElementaryAttribute { +protected : + size_t uMeshCount; ///< \ru Количество u-линий отрисовочной сетки. \en The number of u-mesh lines. + size_t vMeshCount; ///< \ru Количество v-линий отрисовочной сетки. \en The number of v-mesh lines. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbWireCount( const MbWireCount & init ); +public : + /// \ru Конструктор. \en Constructor. + MbWireCount( size_t uCount, size_t vCount ); + /// \ru Деструктор. \en Destructor. + virtual ~MbWireCount(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить количество линий отрисовки. \en Set count of drawing lines. + void Init( size_t uCount, size_t vCount ) { uMeshCount = uCount, vMeshCount = vCount; } + /// \ru Выдать количество разбиений по u и v. \en The the number of splittings in u-direction and v-direction. + void Get( size_t & uCount, size_t & vCount ) const { uCount = uMeshCount; vCount = vMeshCount; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbWireCount & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbWireCount ) +}; // MbWireCount + +IMPL_PERSISTENT_OPS( MbWireCount ) + + +#endif // __ATTR_COLOR_H diff --git a/C3d/Include/attr_common_attribut.h b/C3d/Include/attr_common_attribut.h new file mode 100644 index 0000000..8596bed --- /dev/null +++ b/C3d/Include/attr_common_attribut.h @@ -0,0 +1,302 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Подтип обобщенные атрибуты. + \en Common attributes subtype. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_COMMON_ATTRIBUE_H +#define __ATTR_COMMON_ATTRIBUE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Обобщенный атрибут - базовый класс. + \en Common attribute - the base class. \~ + \details \ru Обобщенный атрибут - базовый класс. \n + \en Common attribute - the base class. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbCommonAttribute : public MbAttribute { +protected : + c3d::string_t prompt_; ///< \ru Строка описания. \en String of description. + bool changeable; ///< \ru Признак редактируемости. \en Attribute of editability. + +protected : + /// \ru Конструктор. \en Constructor. + MbCommonAttribute( const c3d::string_t & prompt, bool change ); + /// \ru Конструктор. \en Constructor. + explicit MbCommonAttribute( bool change ); + /// \ru Деструктор. \en Destructor. + virtual ~MbCommonAttribute(); + +public : + virtual MbeAttributeType AttributeFamily() const; // \ru Выдать тип атрибута. \en Get attribute type. + virtual MbeAttributeType AttributeType() const = 0; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ) = 0; // \ru Инициализировать данные по присланным. \en Initialize data. + + // \ru Выполнить действия при изменении владельца, не связанное с другими действиями. \en Perform actions which are not associated with other actions when changing the owner. + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + // \ru Выполнить действия при конвертации владельца. \en Perform actions when converting the owner. + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ); + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging he owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + + virtual void GetCharValue( TCHAR * v ) const = 0; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ) = 0; // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + /** \brief \ru Выдать подсказку атрибута. \en Get a prompt of attribute. + \details \ru Строковое значение, которое может быть использовано, как совего рода тэг, имя или пометка атрибута. + \en String value which can be used as some kind of tag, name or label of an attribute. + */ + const c3d::string_t & GetPrompt() const; + /// \ru Выдать признак изменяемости. \en Get an attribute of changeability. + bool IsChangeable() const; + +DECLARE_PERSISTENT_CLASS( MbCommonAttribute ) +OBVIOUS_PRIVATE_COPY( MbCommonAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbCommonAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru bool атрибут. + \en Bool attribute. \~ + \details \ru bool атрибут. \n + \en Bool attribute. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbBoolAttribute : public MbCommonAttribute { +private: + bool value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbBoolAttribute( const c3d::string_t & prompt, bool change, bool initValue ); + /// \ru Деструктор. \en Destructor. + virtual ~MbBoolAttribute(); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + bool GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( bool val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBoolAttribute ) +OBVIOUS_PRIVATE_COPY( MbBoolAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbBoolAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru int атрибут. + \en Int attribute. \~ + \details \ru int атрибут. \n + \en Int attribute. \n \~ + \ingroup Model_Attributes +*/ +class MATH_CLASS MbIntAttribute : public MbCommonAttribute { +private: + int value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbIntAttribute( const c3d::string_t & prompt, bool change, int initValue ); + /// \ru Деструктор. \en Destructor. + virtual ~MbIntAttribute(); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + int GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( int val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbIntAttribute ) +OBVIOUS_PRIVATE_COPY( MbIntAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbIntAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru int64 атрибут. + \en Int64 attribute. \~ + \details \ru int64 атрибут. \n + \en Int64 attribute. \n \~ + \ingroup Model_Attributes +*/ +class MATH_CLASS MbInt64Attribute : public MbCommonAttribute { +private: + int64 value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbInt64Attribute( const c3d::string_t & prompt, bool change, int64 initValue ); + /// \ru Деструктор. \en Destructor. + virtual ~MbInt64Attribute(); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + int64 GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( int64 val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbInt64Attribute ) +OBVIOUS_PRIVATE_COPY( MbInt64Attribute ) +}; + +IMPL_PERSISTENT_OPS( MbInt64Attribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru double атрибут. + \en Double attribute. \~ + \details \ru double атрибут. \n + \en Double attribute. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbDoubleAttribute : public MbCommonAttribute { +private: + double value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbDoubleAttribute( const c3d::string_t & prompt, bool change, double initValue ); + /// \ru Деструктор. \en Destructor. + virtual ~MbDoubleAttribute(); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + double GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( double val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbDoubleAttribute ) +OBVIOUS_PRIVATE_COPY( MbDoubleAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbDoubleAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru String атрибут. + \en String attribute. \~ + \details \ru String атрибут. \n + \en String attribute. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbStringAttribute : public MbCommonAttribute { +private: + c3d::string_t value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbStringAttribute( const c3d::string_t & prompt, bool change, const c3d::string_t & string ); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + c3d::string_t GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( c3d::string_t & val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +protected: + virtual ~MbStringAttribute(); // Use AddRef/Release or smart pointer SPtr to destruct it correctly. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStringAttribute ) +OBVIOUS_PRIVATE_COPY( MbStringAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbStringAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru Бинарный атрибут. + \en Binary attribute. \~ + \details \ru Бинарный атрибут. \n + \en Binary attribute. \n \~ + \ingroup Model_Attributes +*/ +class MATH_CLASS MbBinaryAttribute : public MbCommonAttribute { +private: + std::vector value_; ///< \ru Значение. \en The value. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbBinaryAttribute( const c3d::string_t & prompt, bool change, const std::vector & value ); + +public: + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + std::vector GetValue() const; // \ru Выдать значение свойства. \en Get a value of the property. + bool SetValue( std::vector & val ); // \ru Установить новое значение свойства. \en Set new value of the property. + +protected: + virtual ~MbBinaryAttribute(); // Use AddRef/Release or smart pointer SPtr to destruct it correctly. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBinaryAttribute ) +OBVIOUS_PRIVATE_COPY( MbBinaryAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbBinaryAttribute ) + +#endif // __ATTR_COMMON_ATTRIBUE_H diff --git a/C3d/Include/attr_dencity.h b/C3d/Include/attr_dencity.h new file mode 100644 index 0000000..e4738af --- /dev/null +++ b/C3d/Include/attr_dencity.h @@ -0,0 +1,163 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибуты. Плотность. + \en Attributes. Density. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_DENCITY_H +#define __ATTR_DENCITY_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Плотность. + \en Density. \~ + \details \ru Плотность. \n + \en Density. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbDencity : public MbElementaryAttribute { +protected : + double dencity; ///< \ru Плотность. \en Density. + +protected : + /// \ru Конструктор. \en Constructor. + MbDencity( const MbDencity & init ); +public : + /// \ru Конструктор. \en Constructor. + MbDencity( double init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbDencity(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить плотность. \en Set a density. + void Init( double init ) { dencity = init; } + /// \ru Дать плотность. \en Get a density. + double Dencity() const { return dencity; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbDencity & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbDencity ) + +}; // MbDencity + +IMPL_PERSISTENT_OPS( MbDencity ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Жесткость. + \en The stiffness. \~ + \details \ru Механические характеристики материала: модуль Юнга и коэффициент Пуассана. \n + \en Mechanical properties of the material: Young's modulus and Poisson's ratio. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbElasticity : public MbElementaryAttribute { +protected : + double young; ///< \ru Модуль Юнга. \en The Young's modulus of material. + double poisson; ///< \ru Коэффициент Пуассона. \en The Poisson's ratio of material. + +protected : + /// \ru Конструктор. \en Constructor. + MbElasticity( const MbElasticity & init ); +public : + /// \ru Конструктор. \en Constructor. + MbElasticity( double e, double v ); + /// \ru Деструктор. \en Destructor. + virtual ~MbElasticity(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить свойства. \en Set a density. + void Init( double e_, double v_ ) { young = e_; poisson = v_; } + /// \ru Дать Модуль Юнга. \en Get an Young's modulus. + double YoungModulus() const { return young; } + /// \ru Дать Коэффициент Пуассона. \en Get a Poisson's ratio. + double PoissonRatio() const { return poisson; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbElasticity & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbElasticity ) + +}; // MbElasticity + +IMPL_PERSISTENT_OPS( MbElasticity ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Деформации / Напряжения. + \en The strains / The tensions. \~ + \details \ru Напряжённо деформированное состояние объекта - три деформации или три напряжения. \n + \en Tension strain state of an object. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbStrains : public MbElementaryAttribute { +protected : + double strain1; ///< \ru Деформация 1 / Напряжение 1. \en The strain 1 / The tension 1. + double strain2; ///< \ru Деформация 2 / Напряжение 2. \en The strain 2 / The tension 2. + double strain3; ///< \ru Деформация 3 / Напряжение 3. \en The strain 3 / The tension 3. + +protected : + /// \ru Конструктор. \en Constructor. + MbStrains( const MbStrains & init ); +public : + /// \ru Конструктор. \en Constructor. + MbStrains( double e1, double e2, double e3 ); + /// \ru Деструктор. \en Destructor. + virtual ~MbStrains(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Установить свойства. \en Set a density. + void Init( double e1, double e2, double e3 ) { strain1 = e1; strain2 = e2; strain3 = e3; } + /// \ru Дать деформированное состояние объекта. \en Get a deformed state. + double Strain( size_t i ) const { if ( i <= 1 ) return strain1; else if ( i == 2 ) return strain1; else return strain3; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbStrains & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStrains ) + +}; // MbStrains + +IMPL_PERSISTENT_OPS( MbStrains ) + + +#endif // __ATTR_DENCITY_H diff --git a/C3d/Include/attr_elementary_attribut.h b/C3d/Include/attr_elementary_attribut.h new file mode 100644 index 0000000..f97ff5e --- /dev/null +++ b/C3d/Include/attr_elementary_attribut.h @@ -0,0 +1,68 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Подтип элементарные атрибуты. + \en Elementary attributes subtype. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_ELEMENTARY_ATTRIBUTE_H +#define __ATTR_ELEMENTARY_ATTRIBUTE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Элементарный атрибут - базовый класс. + \en Elementary attribute - the base class. \~ + \details \ru Элементарный атрибут - базовый класс. \n + \en Elementary attribute - the base class. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbElementaryAttribute : public MbAttribute { +protected: + MbElementaryAttribute(); +public: + virtual ~MbElementaryAttribute(); + +public : + virtual MbeAttributeType AttributeFamily() const; // \ru Тип атрибута \en Type of an attribute + virtual MbeAttributeType AttributeType() const = 0; // \ru Выдать подтип атрибута \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const = 0; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ) = 0; // \ru Инициализировать данные по присланным \en Initialize data. + + // \ru Действия при изменении владельца, не связанное с другими действиями. \en Actions which are not associated with other actions when changing the owner. + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + // \ru Действия при конвертации владельца. \en Actions when converting the owner. + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + /// \ru Действия при трансформировании владельца. \en Actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Действия при перемещении владельца. \en Actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Действия при вращении владельца. \en Actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Действия при копировании владельца. \en Actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ); + // \ru Действия при объединении владельца. \en Actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Действия при замене владельца. \en Actions when replacing the owner. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Действия при разделении владельца. \en Actions when splitting the owner. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + // \ru Действия при удалении владельца. \en Actions when merging the owner. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual size_t SetProperties( const MbProperties & ) = 0; // \ru Установить свойства объекта \en Set properties of object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + +DECLARE_PERSISTENT_CLASS( MbElementaryAttribute ) +OBVIOUS_PRIVATE_COPY( MbElementaryAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbElementaryAttribute ) + +#endif // __ATTR_ELEMENTARY_ATTRIBUTE_H diff --git a/C3d/Include/attr_geometric_attribut.h b/C3d/Include/attr_geometric_attribut.h new file mode 100644 index 0000000..1181a73 --- /dev/null +++ b/C3d/Include/attr_geometric_attribut.h @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Геометрический атрибут. + \en Geometric attribute. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_GEOMETRIC_ATTRIBUTE_H +#define __ATTR_GEOMETRIC_ATTRIBUTE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSpaceItem; +class MATH_CLASS MbProperty; +class MATH_CLASS MbProperties; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Геометрический атрибут. + \en Geometric attribute. \~ + \details \ru Геометрический атрибут. \n + \en Geometric attribute. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbGeomAttribute : public MbCommonAttribute { +protected : + MbSpaceItem * spaceItem; ///< \ru Геометрический объект. \en A geometric object. + MbeCreatorType type; ///< \ru Тип операции. \en Operation type. + bool keepItem; ///< \ru Сохранять исходный объект при копировании. \en Save the initial object when copying. + +private: + // \ru Конструктор копирования. \en Copy constructor. + MbGeomAttribute( const MbGeomAttribute & init, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор. \en Constructor. + MbGeomAttribute( const MbSpaceItem & item, MbeCreatorType t, bool keepItem ); + /// \ru Конструктор. \en Constructor. + MbGeomAttribute( const MbSpaceItem & item, MbeCreatorType t, bool keepItem, const c3d::string_t & itemPrompt ); + /// \ru Деструктор. \en Destructor. + virtual ~MbGeomAttribute(); + +public: + // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual MbeAttributeType AttributeType() const; + // \ru Сделать копию элемента. \en Create a copy of the element. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; + // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; + // \ru Инициализировать данные по присланным. \en Initialize data. + virtual bool Init( const MbAttribute & ); + // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg ); + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg ); + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + /// \ru Дать геометрический объект. \en Get geometric object. + const MbSpaceItem * GetSpaceItem() const { return spaceItem; } + MbSpaceItem * SetSpaceItem() { return spaceItem; } + /// \ru Заменить геометрический объект. \en Replace geometric object. + void ChangeSpaceItem( MbSpaceItem & init ); + /// \ru Дать тип операции. \en Get operation type. + MbeCreatorType GetOperationType() const { return type; } + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbGeomAttribute ) +OBVIOUS_PRIVATE_COPY( MbGeomAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbGeomAttribute ) + +#endif // __ATTR_GEOMETRIC_ATTRIBUTE_H diff --git a/C3d/Include/attr_identifier.h b/C3d/Include/attr_identifier.h new file mode 100644 index 0000000..16bff54 --- /dev/null +++ b/C3d/Include/attr_identifier.h @@ -0,0 +1,322 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Идентификатор объекта. + \en Object identifier. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_IDENTIFIER_H +#define __ATTR_IDENTIFIER_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификатор объекта. + \en Object identifier. \~ + \details \ru Идентификатор объекта. \n + \en Object identifier. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbIdentifier : public MbElementaryAttribute { +protected : + int32 identifier; ///< \ru Идентификатор объекта. \en Object identifier. + +protected : + /// \ru Конструктор. \en Constructor. + MbIdentifier( const MbIdentifier & ); +public : + /// \ru Конструктор. \en Constructor. + MbIdentifier( int32 init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbIdentifier(); + + // \ru Общие функции объекта. \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + // \ru Специфические свойства объекта. \en Specific functions of object. + + /// \ru Установить идентификатор. \en Set identifier. + void Init( int32 init ) { identifier = init; } + /// \ru Дать идентификатор объекта. \en Get identifier of object. + int32 Identifier() const { return identifier; } + +private: + MbIdentifier & operator = ( const MbIdentifier & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbIdentifier ) +}; // MbIdentifier + +IMPL_PERSISTENT_OPS( MbIdentifier ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Топологическое имя. + \en Topological name. \~ + \details \ru Топологическое имя. \n + \en Topological name. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbNameAttribute : public MbElementaryAttribute { + typedef std::vector NameAttributesVector; +protected : + MbName tName; ///< \ru Топологическое имя объекта. \en A name of a topological object +private: + NameAttributesVector parentNames; ///< \ru Топологические имена родителей объекта. \en Topological names of object parents. + mutable bool isTemporal; ///< \ru Атрибут временный, на время операции (Этот признак не пишется и не читается). \en Attribute is temporary, for the duration of the operation only (This tag is not read or written). + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbNameAttribute( const MbNameAttribute & ); +public : + /// \ru Конструктор. \en Constructor. + MbNameAttribute( bool isTemporal = false ); + /// \ru Конструктор. \en Constructor. + MbNameAttribute( const MbName &, bool isTemporal = false ); + /// \ru Деструктор. \en Destructor. + virtual ~MbNameAttribute(); + + // \ru Общие функции объекта \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + /// \ru Выдать имя. \en Get name. + const MbName & GetName() const { return tName; } + /// \ru Выдать имя. \en Get name. + MbName & SetName() { return tName; } + /// \ru Установить имя. \en Set name. + void SetName( const MbName &, bool deleteParentNames = true ); + + /// \ru Определить, есть ли хоть одно имя родительского объекта. \en Determine whether at least one name of parent object exists. + bool IsAnyParentName() const { return (parentNames.size() > 0); } + /// \ru Выдать количество родительских имен первого уровня. \en Get the number of parent names of the first level. + size_t GetParentNamesCount() const { return parentNames.size(); } + /// \ru Удалить имена родительских объектов. \en Delete names of parent objects. + void DeleteParentNames(); + /// \ru Добавить имя родительского объекта. \en Add a name of parent object. + bool AddParentName( const MbName &, bool isTemporal = false ); + /// \ru Добавить имена родительских объектов. \en Add names of parent objects. + bool AddParentNames( const MbNameAttribute &, double accuracy ); + /// \ru Получить имена родительских объектов. \en Get names of parent objects. + void GetParentNames( std::vector & ) const; + ///< \ru Является ли атрибут временным. \en Whether this attribute is temporary. + bool IsTemporal() const { return isTemporal; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + MbNameAttribute & operator = ( const MbNameAttribute & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNameAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbNameAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru Метка времени обновления. + \en Stamp of update time. \~ + \details \ru Метка времени обновления. \n + \en Stamp of update time. \n \~ + \ingroup Model_Attributes +*/ +class MATH_CLASS MbUpdateStamp : public MbElementaryAttribute +{ +protected : + uint32 updStamp; ///< \ru Значение метки. \en The value of stamp. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbUpdateStamp( const MbUpdateStamp & ); +public : + /// \ru Конструктор. \en Constructor. + MbUpdateStamp(); + /// \ru Конструктор. \en Constructor. + MbUpdateStamp( uint32 stampVal ); + /// \ru Деструктор. \en Destructor. + virtual ~MbUpdateStamp(); + + // \ru Общие функции объекта \en Common functions of object + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Сбросить значение метки времени обновления. \en Reset a value of a stamp of update time. + void ResetStamp() { updStamp = 0; } + /// \ru Проверить, равно ли значение метки нулю. \en Check whether the value of a stamp is null. + bool IsNull () const { return updStamp == 0; } + /// \ru Дать значение метки времени обновления. \en Get the value of a stamp of update time. + uint32 GetStamp () const { return updStamp; } + + /// \ru Увеличить значение метки на единицу. \en Increase the value of stamp by one. + void Increment () { updStamp++; } + /// \ru Установить значение метки максимальным из присланного и действующего. \en Set the value of stamp to the maximum from the given value and the current value. + void Maximize ( uint32 val ) { if (val > updStamp) updStamp = val; } + + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + MbUpdateStamp & operator = ( const MbUpdateStamp & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbUpdateStamp ) +}; + +IMPL_PERSISTENT_OPS( MbUpdateStamp ) + +//------------------------------------------------------------------------------ +/** \brief \ru Атрибут "якорь". + \en Attribute "anchor". \~ + \details \ru Атрибут "якорь". \n + \en Attribute "anchor". \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbAnchorAttribute : public MbAttribute { +public: + enum AnchorType { + ant_Undefined = 0, ///< \ru Неопределенный тип. \en An undefined type. + ant_TopoName, ///< \ru Для топологического имени. \en For a topological name. + }; + +protected : + uint8 aType; ///< \ru Тип якорного атрибута. \en Type of an anchor attribute. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbAnchorAttribute( const MbAnchorAttribute & ); +public : + /// \ru Конструктор. \en Constructor. + MbAnchorAttribute(); + /// \ru Конструктор. \en Constructor. + MbAnchorAttribute( AnchorType type ); + /// \ru Деструктор. \en Destructor. + virtual ~MbAnchorAttribute(); + + // \ru Общие функции объекта. \en Common functions of object. + + virtual MbeAttributeType AttributeFamily() const; // \ru Дать тип атрибута. \en Get type of an attribute. + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data. + + /// \ru Дать тип якорного атрибута. \en Get type of an anchor attribute. + AnchorType GetAnchorType() { return static_cast(aType); } + + // \ru Выполнить действия при изменении владельца, не связанное с другими действиями. \en Perform actions which are not associated with other actions when changing the owner. + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + // \ru Выполнить действия при конвертации владельца \en Perform actions when converting the owner. + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ); + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + MbAnchorAttribute & operator = ( const MbAnchorAttribute & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbAnchorAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbAnchorAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru Признак исполнения (варианта реализации модели). + \en Indication of embodiment (variant of model implementation). \~ + \details \ru Признак исполнения (варианта реализации модели). \n + \en Indication of embodiment (variant of model implementation). \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbEmbodimentAttribute : public MbElementaryAttribute { +protected: + SimpleName m_name; ///< \ru Имя исполнения. \en Name of embodiment. + SimpleName m_parent; ///< \ru Имя родительского исполнения. \en Name of parent embodiment. + bool m_current; ///< \ru Признак, является ли исполнение текущим. \en Flag, whether the embodiment is current. + +protected: + // \ru Конструктор. \en Constructor. + MbEmbodimentAttribute( const MbEmbodimentAttribute & ); +public: + // \ru Конструктор. \en Constructor. + MbEmbodimentAttribute(); + // \ru Конструктор. \en Constructor. + MbEmbodimentAttribute( const SimpleName & name1, const SimpleName & name2, bool curr = false ); + // \ru Деструктор. \en Destructor. + virtual ~MbEmbodimentAttribute(); + + // \ru Общие функции объекта. \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по атрибуту. \en Initialize by attribute. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + // \ru Специфические функции объекта. \en Specific functions of object. + + // \ru Установить родительское исполнение. \en Set a parent embodiment. + void Init( const SimpleName & name1, const SimpleName & name2, bool curr = false ) { + m_name = name1; m_parent = name2; m_current = curr; + } + // \ru Выдать имя исполнения. \en Get a name of embodiment. + SimpleName Name() const { return m_name; } + // \ru Выдать имя родительского исполнения. \en Get a name of parent embodiment. + SimpleName ParentName() const { return m_parent; } + // \ru Является ли исполнение текущим. \en Whether the embodiment is current. + bool IsCurrent() const { return m_current; } + +private: + void operator = ( const MbEmbodimentAttribute & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbEmbodimentAttribute ) + +}; // MbEmbodimentAttribute + +IMPL_PERSISTENT_OPS( MbEmbodimentAttribute ) + + +#endif // __ATTR_IDENTIFIER_H diff --git a/C3d/Include/attr_product.h b/C3d/Include/attr_product.h new file mode 100644 index 0000000..d5a83b5 --- /dev/null +++ b/C3d/Include/attr_product.h @@ -0,0 +1,432 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибуты изделий. + \en Product attributes. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef __ATTR_PRODUCT_H +#define __ATTR_PRODUCT_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Родительский класс атрибутов изделий. + \en Base calss of product attributes. +*/ +// --- +class MATH_CLASS MbProductAttribute : public MbAttribute { +protected : + MbProductAttribute(); // \ru Конструктор. \en Constructor. +public : + // \ru Деструктор. \en Destructor. + virtual ~MbProductAttribute(); + +public : + virtual MbeAttributeType AttributeFamily() const; + // Выдать подтип атрибута (временно). + virtual MbeAttributeType AttributeType() const = 0; + // Сделать копию элемента. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const = 0; + virtual bool IsSame( const MbAttribute &, double accuracy ) const = 0; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + // Инициализировать данные по присланным. + virtual bool Init( const MbAttribute & ) = 0; + + virtual MbePrompt GetPropertyName() = 0; + + // Действия при изменении владельца, не связанное с другими действиями. + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + // Действия при конвертации владельца. + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // Действия при трансформировании владельца. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // Действия при перемещении владельца. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // Действия при вращении владельца. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // Действия при копировании владельца. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ); + // Действия при объединении владельца. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // Действия при замене владельца. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // Действия при разделении владельца. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + // Действия при удалении владельца. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + +DECLARE_PERSISTENT_CLASS( MbProductAttribute ) +OBVIOUS_PRIVATE_COPY( MbProductAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbProductAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru Сведения о лице в организации. + \en Information related to a person and the organization he/she in. +*/ +// --- +class MATH_CLASS MbPersonOrganizationInfo : public MbProductAttribute { + c3d::string_t personId; ///< \ru Идентификатор лица. \en Identifier of the person. + c3d::string_t lastName; ///< \ru Фамилия. \en Last name. + c3d::string_t firstName; ///< \ru Имя. \en First name. + std::list middleNames; ///< \ru Отчество/средние имена. \en Middle names. + std::list prefixTitles; ///< \ru Титулы предшествующие. \en Prefix titles. + std::list suffixTitles; ///< \ru Титулы завершающие. \en Suffix titles. + c3d::string_t orgId; ///< \ru Идентификатор организации. \en Identifier of the organization. + c3d::string_t orgLabel; ///< \ru Название организации. \en Label of the organization. + c3d::string_t orgDescription; ///< \ru Описание организации. \en Description of the organization. + std::set roles; ///< \ru Роли лица по отношению к изделию. \en The person's roles concerning a product. +protected : + // Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. + MbPersonOrganizationInfo( const MbPersonOrganizationInfo & ); +public : + // Конструктор без параметров для наследников. + MbPersonOrganizationInfo(); + // Деструктор. + virtual ~MbPersonOrganizationInfo(); + +public : + // Выдать подтип атрибута (временно). + virtual MbeAttributeType AttributeType() const; + // Сделать копию элемента. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // Определить, являются ли объекты равными. + // Инициализировать данные по присланным. + virtual bool Init( const MbAttribute & ) ; + virtual void GetProperties( MbProperties & ); // выдать свойства объекта + + virtual MbePrompt GetPropertyName() ; + + /** + \brief \ru Получить данные. \en Get data. \~ + \param[out] oPersonId - \ru Идентификатор лица. \en Identifier of the person. \~ + \param[out] oLast - \ru Фамилия. \en Last name. \~ + \param[out] oFirst - \ru Имя. \en First name. \~ + \param[out] oMid - \ru Итератор для вставки всех строк, соответствующих отчеству/средним именам. \en Insert iterator for middle names. \~ + \param[out] oPre - \ru Итератор для вставки всех строк, соответствующих титулов предшествующих. \en Insert iterator for prefix titles. \~ + \param[out] oSuf - \ru Итератор для вставки всех строк, соответствующих титулов завершающих. \en Insert iterator for suffix titles. \~ + \param[out] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[out] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[out] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + template< typename OutMid, typename OutPre, typename OutSuf > + void GetData( c3d::string_t& oPersonId, c3d::string_t& oLast, c3d::string_t& oFirst, + OutMid oMid, OutPre oPre, OutSuf oSuf, + c3d::string_t& oOrgId, c3d::string_t& oOrgLabel, c3d::string_t& oOrgDesc ) const; + + + /** + \brief \ru Получить данные. \en Get data. \~ + \param[out] oPersonId - \ru Идентификатор лица. \en Identifier of the person. \~ + \param[out] oLast - \ru Фамилия. \en Last name. \~ + \param[out] oFirst - \ru Имя. \en First name. \~ + \param[out] oMid - \ru Итератор для вставки всех строк, соответствующих отчеству/средним именам. \en Insert iterator for middle names. \~ + \param[out] oPre - \ru Итератор для вставки всех строк, соответствующих титулов предшествующих. \en Insert iterator for prefix titles. \~ + \param[out] oSuf - \ru Итератор для вставки всех строк, соответствующих титулов завершающих. \en Insert iterator for suffix titles. \~ + \param[out] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[out] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[out] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + template< typename OutMid, typename OutPre, typename OutSuf > + void GetPOData( std::string& oPersonId, std::string& oLast, std::string& oFirst, + OutMid oMid, OutPre oPre, OutSuf oSuf, + std::string& oOrgId, std::string& oOrgLabel, std::string& oOrgDesc ) const; + + /** + \brief \ru Получить полное имя с префиксами и суффиксами. \en full name with prefixes and suffixes. \~ + */ + c3d::string_t NameOneLine() const; + + /** + \brief \ru Получить данные организации. \en Get organization data. \~ + \param[out] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[out] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[out] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + void GetOrganization( c3d::string_t& oOrgId, c3d::string_t& oOrgLabel, c3d::string_t& oOrgDesc ) const; + + + /** + \brief \ru Получить данные организации. \en Get organization data. \~ + \param[out] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[out] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[out] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + void GetOrganizationInfo( std::string& oOrgId, std::string& oOrgLabel, std::string& oOrgDesc ) const; + + /** + \brief \ru Задать данные лица. \en Set person's data. \~ + \param[in] oPersonId - \ru Идентификатор лица. \en Identifier of the person. \~ + \param[in] oLast - \ru Фамилия. \en Last name. \~ + \param[in] oFirst - \ru Имя. \en First name. \~ + \param[in] firstMid - \ru Итератор первой строки, соответствующей отчеству/средним именам. \en First iterator for middle names. \~ + \param[in] lastMid - \ru Итератор за последней строкой, соответствующей отчеству/средним именам. \en Next after last iterator for middle names. \~ + \param[in] firstPre - \ru Итератор первой строки, соответствующей титулам предшествующих. \en First iterator for prefix titles. \~ + \param[in] lastPre - \ru Итератор первой строки, соответствующей титулам предшествующих. \en Next after last iterator for prefix titles. \~ + \param[in] firstSuf - \ru Итератор первой строки, соответствующей титулам завершающих. \en First iterator for suffix titles. \~ + \param[in] lastSuf - \ru Итератор первой строки, соответствующей титулам завершающих. \en Next after last iterator for suffix titles. \~ + */ + template< typename InMid, typename InPre, typename InSuf > + void SetPerson( const c3d::string_t& oPersonId, const c3d::string_t& oLast, const c3d::string_t& oFirst, + InMid firstMid, InMid lastMid, + InPre firstPre, InPre lastPre, + InSuf firstSuf, InSuf lastSuf ); + + /** + \brief \ru Задать данные лица. \en Set person's data. \~ + \param[in] oPersonId - \ru Идентификатор лица. \en Identifier of the person. \~ + \param[in] oLast - \ru Фамилия. \en Last name. \~ + \param[in] oFirst - \ru Имя. \en First name. \~ + \param[in] firstMid - \ru Итератор первой строки, соответствующей отчеству/средним именам. \en First iterator for middle names. \~ + \param[in] lastMid - \ru Итератор за последней строкой, соответствующей отчеству/средним именам. \en Next after last iterator for middle names. \~ + \param[in] firstPre - \ru Итератор первой строки, соответствующей титулам предшествующих. \en First iterator for prefix titles. \~ + \param[in] lastPre - \ru Итератор первой строки, соответствующей титулам предшествующих. \en Next after last iterator for prefix titles. \~ + \param[in] firstSuf - \ru Итератор первой строки, соответствующей титулам завершающих. \en First iterator for suffix titles. \~ + \param[in] lastSuf - \ru Итератор первой строки, соответствующей титулам завершающих. \en Next after last iterator for suffix titles. \~ + */ + template< typename InMid, typename InPre, typename InSuf > + void SetPersonInfo( const std::string& oPersonId, const std::string& oLast, const std::string& oFirst, + InMid firstMid, InMid lastMid, + InPre firstPre, InPre lastPre, + InSuf firstSuf, InSuf lastSuf ); + + /** + \brief \ru Задать данные организации. \en Set organization's data. \~ + \param[in] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[in] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[in] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + void SetOrganization( const c3d::string_t& initOrgId, const c3d::string_t& initOrgLabel, const c3d::string_t& initOrgDesc ); + + /** + \brief \ru Задать данные организации. \en Set organization's data. \~ + \param[in] oOrgId - \ru Идентификатор организации. \en Identifier of the organization. \~ + \param[in] oOrgLabel - \ru Название организации. \en Label of the organization. \~ + \param[in] oOrgDesc - \ru Описание организации. \en Description of the organization. \~ + */ + void SetOrganizationInfo( const std::string& initOrgId, const std::string& initOrgLabel, const std::string& initOrgDesc ); + + /** + \brief \ru Задать данные лица и организации в упрощенной форме. \en Set person's and organization's simplified data. \~ + \param[in] person - \ru Фамилия автора. \en Author's second name. \~ + \param[in] organization - \ru Название организации. \en Label of the organization. \~ + */ + void SetPersonOrganization( const c3d::string_t& person, const c3d::string_t& organization ); + + /** + \brief \ru Задать данные лица и организации в упрощенной форме. \en Set person's and organization's simplified data. \~ + \param[in] person - \ru Фамилия автора. \en Author's second name. \~ + \param[in] organization - \ru Название организации. \en Label of the organization. \~ + */ + void SetPersonOrganizationInfo( const std::string& person, const std::string& organization ); + + /// \ru Добавить роль автора. \en Add person's role. + inline void AddRole( const c3d::string_t& role ) { roles.insert( role ); } + + /// \ru Добавить роль автора. \en Add person's role. + inline void AddToRoles( const std::string& role ) { roles.insert( c3d::ToC3Dstring( role ) ); } + + /// \ru Получить роли автора. \en Get person's roles. + template< typename T > void GetRoles( T dest ) const { std::copy( roles.begin(), roles.end(), dest ); } + + /// \ru Добавить роли к приёмнику. \en Add person's roles to destination. + template< typename T > void AddRolesTo( T dest ) const; + +private: + MbPersonOrganizationInfo & operator = ( const MbPersonOrganizationInfo & ); // forbidden + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPersonOrganizationInfo ) // Атрибуты писать ни к чему, они создаются только для конвертирования +}; + +IMPL_PERSISTENT_OPS( MbPersonOrganizationInfo ) + +//------------------------------------------------------------------------------ +/** \brief \ru Данные об изделии. \en Product data. +*/ +// --- +class MATH_CLASS MbProductInfo : public MbProductAttribute +{ + c3d::string_t id; ///< \ru Идентификатор. \en Identifier. + c3d::string_t name; ///< \ru Название. \en Name. + c3d::string_t description; ///< \ru Описание. \en Description. + bool isAssembly; ///< \ru Является ли сборочной единицей. \en If the product is an assembly. + +protected : + // Объявление (перегрузка) конструктора копирования без реализации, чтобы не было копирования по умолчанию. + MbProductInfo( const MbProductInfo & ); +public : + MbProductInfo( c3d::StringTCRef initId, c3d::StringTCRef initName, c3d::StringTCRef initDesc, bool isAssm ); + + MbProductInfo( const TCHAR* initId, const TCHAR* initName, TCHAR* initDesc, bool isAssm ); + + MbProductInfo( bool isAssm, const std::string & initId, const std::string & initName, const std::string & initDesc ); + // Деструктор. + virtual ~MbProductInfo(); + +public : + // Выдать подтип атрибута (временно). + virtual MbeAttributeType AttributeType() const; + // Сделать копию элемента. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const ; + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // Определить, являются ли объекты равными. + // Инициализировать данные по присланным. + virtual bool Init( const MbAttribute & ) ; + virtual void GetProperties( MbProperties & ); // выдать свойства объекта + virtual size_t SetProperties( const MbProperties & ); // Установить свойства объекта. + + virtual MbePrompt GetPropertyName() ; + + const c3d::string_t& GetId() const; ///< \ru Получить идентификатор. \en Get id. + + const c3d::string_t& GetName() const; ///< \ru Получить наименование. \en Get name. + + const c3d::string_t& GetDescription() const; ///< \ru Получить описание. \en Get description. + + /// \ru Получить данные. \en Get data. + void GetData( c3d::string_t & oId, c3d::string_t & oName, c3d::string_t & oDesc ) const; + + /// \ru Получить данные. \en Get data. + void GetDataStd( std::string & oId, std::string & oName, std::string & oDesc ) const; + + /// \ru Задать название. \en Set the name of the product. + void SetNameC3D( const c3d::string_t& oName ); + + /// \ru Задать наименование. \en Set the designation of the product. + void SetId( const std::string& oId ); + /// \ru Задать название. \en Set the name of the product. + void SetName( const std::string& iName ); + /// \ru Задать описание. \en Set the description of the product. + void SetDescription( const std::string& oDesc ); + + /// \ru Является ли изделие сборочной единицей. \en If the product is an assembly. + bool IsAssembly() const; + +private: + MbProductInfo & operator = ( const MbProductInfo & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbProductInfo ) // Атрибуты писать ни к чему, они создаются только для конвертирования +}; + +IMPL_PERSISTENT_OPS( MbProductInfo ) + +//////////////////////////////////////////////////////////////////////////////// +// +// Класс Лицо и организация. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// Получить данные +// --- +template< typename OutMid, typename OutPre, typename OutSuf > +void MbPersonOrganizationInfo::GetData( c3d::string_t& oPersonId, c3d::string_t& oLast, c3d::string_t& oFirst, + OutMid oMid, OutPre oPre, OutSuf oSuf, + c3d::string_t& oOrgId, c3d::string_t& oOrgLabel, c3d::string_t& oOrgDesc ) const { + oPersonId = personId; + oLast = lastName; + oFirst = firstName; + std::copy( middleNames.begin(), middleNames.end(), oMid ); + std::copy( prefixTitles.begin(), prefixTitles.end(), oPre ); + std::copy( suffixTitles.begin(), suffixTitles.end(), oSuf ); + oOrgId = orgId; + oOrgLabel = orgLabel; + oOrgDesc = orgDescription; +} + + +//------------------------------------------------------------------------------ +// Получить данные +// --- +template< typename OutMid, typename OutPre, typename OutSuf > +void MbPersonOrganizationInfo::GetPOData( std::string& oPersonId, std::string& oLast, std::string& oFirst, + OutMid oMid, OutPre oPre, OutSuf oSuf, + std::string& oOrgId, std::string& oOrgLabel, std::string& oOrgDesc ) const { + oPersonId = c3d::ToSTDstring( personId ); + oLast = c3d::ToSTDstring( lastName ); + oFirst = c3d::ToSTDstring( firstName ); + std::list< std::string > tmp; + for( std::list::const_iterator itr = middleNames.begin(); itr != middleNames.end(); ++itr ) + tmp.push_back( c3d::ToSTDstring( *itr ) ); + std::copy( tmp.begin(), tmp.end(), oMid ); + tmp.clear(); + for( std::list::const_iterator itr = prefixTitles.begin(); itr != prefixTitles.end(); ++itr ) + tmp.push_back( c3d::ToSTDstring( *itr ) ); + std::copy( tmp.begin(), tmp.end(), oPre ); + tmp.clear(); + for( std::list::const_iterator itr = suffixTitles.begin(); itr != suffixTitles.end(); ++itr ) + tmp.push_back( c3d::ToSTDstring( *itr ) ); + std::copy( tmp.begin(), tmp.end(), oSuf ); + oOrgId = c3d::ToSTDstring( orgId ); + oOrgLabel = c3d::ToSTDstring( orgLabel ); + oOrgDesc = c3d::ToSTDstring( orgDescription ); +} + + +//------------------------------------------------------------------------------ +// Задать данные лица +// --- +template< typename InMid, typename InPre, typename InSuf > +void MbPersonOrganizationInfo::SetPerson( const c3d::string_t& oPersonId, const c3d::string_t& oLast, const c3d::string_t& oFirst, + InMid firstMid, InMid lastMid, + InPre firstPre, InPre lastPre, + InSuf firstSuf, InSuf lastSuf ) { + personId = oPersonId; + lastName = oLast; + firstName = oFirst; + middleNames.assign( firstMid, lastMid ); + prefixTitles.assign( firstPre, lastPre ); + suffixTitles.assign( firstSuf, lastSuf ); +} + + +//------------------------------------------------------------------------------ +// Задать данные лица +// --- +template< typename InMid, typename InPre, typename InSuf > +void MbPersonOrganizationInfo::SetPersonInfo( const std::string& oPersonId, const std::string& oLast, const std::string& oFirst, + InMid firstMid, InMid lastMid, + InPre firstPre, InPre lastPre, + InSuf firstSuf, InSuf lastSuf ) { + personId = c3d::ToC3Dstring( oPersonId ); + lastName = c3d::ToC3Dstring( oLast ); + firstName = c3d::ToC3Dstring( oFirst ); + std::list< c3d::string_t > tmp; + for( InMid itr = firstMid; itr != lastMid; ++itr ) + tmp.push_back( c3d::ToC3Dstring( *itr ) ); + middleNames.swap( tmp ); + tmp.clear(); + for( InPre itr = firstPre; itr != lastPre; ++itr ) + tmp.push_back( c3d::ToC3Dstring( *itr ) ); + prefixTitles.swap(tmp); + tmp.clear(); + for( InSuf itr = firstSuf; itr != lastSuf; ++itr ) + tmp.push_back( c3d::ToC3Dstring( *itr ) ); + suffixTitles.swap(tmp); +} + + +//------------------------------------------------------------------------------ +// Добавить роли к приёмнику. +// --- +template< typename T > +void MbPersonOrganizationInfo::AddRolesTo( T dest ) const { + std::list tmp; + for( std::set::const_iterator itr = roles.begin(); itr != roles.end(); ++itr ) + tmp.push_back( c3d::ToSTDstring( *itr ) ); + std::copy( tmp.begin(), tmp.end(), dest ); +} + + +#endif // __ATTR_PRODUCT_H \ No newline at end of file diff --git a/C3d/Include/attr_registry.h b/C3d/Include/attr_registry.h new file mode 100644 index 0000000..c593e39 --- /dev/null +++ b/C3d/Include/attr_registry.h @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Инстанс определения атрибута. + \en Attribute definition instance. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_REGISTRY_H +#define __ATTR_REGISTRY_H + + +#include +#include +#include +#include + + +class IAttrDefinition; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификатор пользовательского атрибута. + \en Identifier of external attribute. \~ + \details \ru Идентификатор пользовательского атрибута. + \en Identifier of external attribute. \~ + \ingroup Model_Attributes + */ +// KVT class MbUserAttribType +// KVT { +// KVT public: +// KVT uint subtype1; +// KVT uint subtype2; +// KVT uint subtype3; +// KVT +// KVT public: +// KVT MbUserAttribType() +// KVT : subtype1( 0 ), subtype2( 0 ), subtype3( 0 ) {} +// KVT MbUserAttribType( uint type1, uint type2, uint type3 ) +// KVT : subtype1( type1 ), subtype2( type2 ), subtype3( type3 ) {} +// KVT MbUserAttribType( const MbUserAttribType & other ) +// KVT : subtype1( other.subtype1 ), subtype2( other.subtype2 ), subtype3( other.subtype3 ) {} +// KVT +// KVT bool operator == ( const MbUserAttribType & other ) const +// KVT { return subtype1 == other.subtype1 && subtype2 == other.subtype2 && subtype3 == other.subtype3; } +// KVT bool operator < ( const MbUserAttribType & other ) const +// KVT { +// KVT if (subtype1 != other.subtype1) +// KVT return subtype1 < other.subtype1; +// KVT else if (subtype2 != other.subtype2) +// KVT return subtype2 < other.subtype2; +// KVT else if (subtype3 != other.subtype3) +// KVT return subtype3 < other.subtype3; +// KVT +// KVT return false; +// KVT } +// KVT +// KVT private: +// KVT void operator = ( const MbUserAttribType & ); // \ru Не реализовано \en Not implemented +// KVT }; + +typedef MbUuid MbUserAttribType; + +//------------------------------------------------------------------------------ +/** \brief \ru Инстанс определения атрибута. + \en Attribute definition instance. \~ + \ingroup Model_Attributes + */ +class MATH_CLASS AttrDefInstance +{ +private: + MbUserAttribType id_; +public: + AttrDefInstance( const MbUserAttribType & id ); + virtual ~AttrDefInstance(); + +public: + virtual IAttrDefinition * GetAttrDefinition() = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти определение пользовательского атрибута. + \en Find an external attribute definition. \~ + \ingroup Model_Attributes +*/ +MATH_FUNC (IAttrDefinition *) GetUserAttrDefinition( const MbUserAttribType & id ); + + +#endif // __ATTR_REGISTRY_H diff --git a/C3d/Include/attr_selected.h b/C3d/Include/attr_selected.h new file mode 100644 index 0000000..2ae80b1 --- /dev/null +++ b/C3d/Include/attr_selected.h @@ -0,0 +1,154 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибуты. Селектированность. Видимость. Изменённость. + \en Attributes. Selection. Visibility. Modification. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_SELECTED_H +#define __ATTR_SELECTED_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Селектированность. + \en Selection. \~ + \details \ru Селектированность. \n + \en Selection. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbSelected : public MbElementaryAttribute { +protected : + bool selected; ///< \ru Селектированность. \en Selection. + +protected : + /// \ru Конструктор копирования. \en Copy-constructor. + MbSelected( const MbSelected & init ); +public : + /// \ru Конструктор. \en Constructor. + MbSelected( bool init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbSelected(); + + // \ru Общие функции объекта. \en Common functions of object. + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data by given attribute. + + /// \ru Установить селектированность. \en Set selection. + void Init( bool init ) { selected = init; } + /// \ru Дать селектированность. \en Get selection. + bool Selected() const { return selected; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbSelected & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSelected ) + +}; // MbSelected + +IMPL_PERSISTENT_OPS( MbSelected ) + +//------------------------------------------------------------------------------ +/** \brief \ru Видимость. + \en Visibility. \~ + \details \ru Видимость. \n + \en Visibility. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbVisible : public MbElementaryAttribute { +protected : + bool visible; ///< \ru Видимость. \en Visibility. + +protected : + /// \ru Конструктор копирования. \en Copy-constructor. + MbVisible( const MbVisible & init ); +public : + /// \ru Конструктор. \en Constructor. + MbVisible( bool init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbVisible(); + + // \ru Общие функции объекта. \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data by given attribute. + + /// \ru Установить видимость. \en Set visibility. + void Init( bool init ) { visible = init; } + /// \ru Дать видимость. \en Get visibility. + bool Visible() const { return visible; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbVisible & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbVisible ) + +}; // MbVisible + +IMPL_PERSISTENT_OPS( MbVisible ) + +//------------------------------------------------------------------------------ +/** \brief \ru Изменённость. + \en Modification. \~ + \details \ru Изменённость. \n + \en Modification. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbChanged : public MbElementaryAttribute { +protected : + bool changed; ///< \ru Изменённость. \en Modification. + +protected : + /// \ru Конструктор копирования. \en Copy-constructor. + MbChanged( const MbChanged & init ); +public : + /// \ru Конструктор. \en Constructor. + MbChanged( bool init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbChanged(); + + // \ru Общие функции объекта. \en Common functions of object. + + virtual MbeAttributeType AttributeType() const; // \ru Дать подтип атрибута. \en Get subtype of an attribute. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data by given attribute. + + /// \ru Установить изменённость. \en Set modification. + void Init( bool init ) { changed = init; } + /// \ru Дать изменённость. \en Get modification. + bool Changed() const { return changed; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +private: + void operator = ( const MbChanged & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbChanged ) + +}; // MbChanged + +IMPL_PERSISTENT_OPS( MbChanged ) + +#endif // __ATTR_SELECTED_H diff --git a/C3d/Include/attr_stamprib_attribut.h b/C3d/Include/attr_stamprib_attribut.h new file mode 100644 index 0000000..16752b1 --- /dev/null +++ b/C3d/Include/attr_stamprib_attribut.h @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибут ребра жесткости листового тела. + \en Attribute of reinforsed rib of sheet solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_STAMPRIB_ATTRIBUTE_H +#define __ATTR_STAMPRIB_ATTRIBUTE_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Атрибут ребра жесткости листового тела. + \en Attribute of reinforsed rib of sheet solid. \~ + \details \ru Атрибут ребра жесткости листового тела. Двумерный контур ребра + жесткости и локальная система координат, в плоскости XY которой + расположен двумерный контур содержатся в MbGeomAttribute. + \en Attribute of reinforsed rib of sheet solid. Two-dimensional contour + of a rib and a local coordinate system the two-dimensional contour + is located in XY plane of are stored in MbGeomAttribute \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbStampRibAttribute : public MbGeomAttribute +{ +protected : + size_t index; ///< \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. \en Index of a segment in the contour at which the inclination direction will be set. + SheetRibValues pars; ///< \ru Параметры операции. \en The operation parameters. + MbSNameMaker names; ///< \ru Именователь операции. \en An object defining names generation in the operation. + MbVector3D bendNorm; ///< \ru Нормаль поверхности сгиба (только для внутреннего использования). \en A normal to bend surface (for internal usage only). + MbCartPoint3D bendPoint; ///< \ru Точка на оси сгиба сгиба (только для внутреннего использования). \en A point on bend axis (for internal usage only). +private: + // \ru Конструктор копирования. \en Copy constructor. + MbStampRibAttribute( const MbStampRibAttribute & init, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор. \en Constructor. + MbStampRibAttribute( const MbSpaceItem & item, MbeCreatorType t, size_t index, const SheetRibValues & pars, const MbSNameMaker & n, bool keepItem); + /// \ru Конструктор. \en Constructor. + MbStampRibAttribute( const MbSpaceItem & item, MbeCreatorType t, size_t index, const SheetRibValues & pars, const MbSNameMaker & n, bool keepItem, const c3d::string_t & itemPrompt ); + /// \ru Деструктор. \en Destructor. + virtual ~MbStampRibAttribute(); + +public: + // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual MbeAttributeType AttributeType() const; + // \ru Сделать копию элемента. \en Create a copy of the element. + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; + // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; + // \ru Инициализировать данные по присланным. \en Initialize data. + virtual bool Init( const MbAttribute & ); + + // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg ); + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg ); + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get a string value of the property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + /// \ru Дать индекс сегмента в контуре. \en Get index of a segment in the contour. + const size_t & GetIndex() const { return index; } + /// \ru Дать параметры операции. \en Get operation parameters. + const SheetRibValues & GetRibValues() const { return pars; } + /// \ru Дать именователь операции. \en Get an object defining a name of the operation. + const MbSNameMaker & GetNameMaker() const { return names; } + /// \ru Дать нормаль к поверхности сгиба. \en Get normal to bend surface. + const MbVector3D & GetBendNormal() const { return bendNorm; } + /// \ru Установить нормаль к поверхности сгиба. \en Set normal to bend surface. + void SetBendNormal( const MbVector3D & n ) { bendNorm = n; } + /// \ru Дать точку на оси сгиба. \en Get point on bend axis. + const MbCartPoint3D & GetBendPoint() const { return bendPoint; } + /// \ru Установить точку на оси сгиба. \en Set point on bend axis. + void SetBendPoint( const MbCartPoint3D & p ) { bendPoint = p; } +DECLARE_PERSISTENT_CLASS( MbStampRibAttribute ) +OBVIOUS_PRIVATE_COPY( MbStampRibAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbStampRibAttribute ) + +#endif // __ATTR_STAMPRIB_ATTRIBUTE_H diff --git a/C3d/Include/attr_user_attribut.h b/C3d/Include/attr_user_attribut.h new file mode 100644 index 0000000..8e24113 --- /dev/null +++ b/C3d/Include/attr_user_attribut.h @@ -0,0 +1,426 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пользовательские атрибуты. + \en User attributes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTR_USER_ATTRIBUT_H +#define __ATTR_USER_ATTRIBUT_H + + +#include +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbExternalAttribute; +class MATH_CLASS MbUserAttribute; +class MATH_CLASS MbFixAttrSet; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс определения атрибута. + \en Attribute definition interface. \~ + \details \ru Интерфейс определения атрибута. Определение атрибута - объект используемый + для преобразования пользовательских внесистемных атрибутов в пользовательские системные, + а так же для разборки пользовательских системных атрибутов + на составные части - другие атрибуты системные атрибуты, и обратной сборки. + \en Attribute definition interface. Attribute definition - the object used + for converting user external attributes to user system attributes + and for a disassembly of user system attributes + to their components - other system attributes, and for reassembly. \~ + \ingroup Model_Attributes + */ +class IAttrDefinition +{ +public: + /// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. + virtual MbUserAttribute * ReduceUserAttrib ( const MbExternalAttribute & source ) = 0; + + /// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. + virtual MbExternalAttribute * AdvanceUserAttrib( const MbUserAttribute & source ) = 0; + + /// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. + virtual MbFixAttrSet * DisassembleUsetAttrib( const MbExternalAttribute & source ) = 0; + + /// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. + virtual bool ReassembleUsetAttrib ( const MbFixAttrSet & source, MbExternalAttribute & targer ) = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Шаблон "определения" пользовательского атрибута. + \en A template of user attribute definition. \~ + \details \ru Шаблонный класс "Определения" пользовательского атрибута - используется для создания + стандартных определений, с предопределенным функционалом. + \en Template class "Definition" of user attribute - used for creation + of standard definitions with predefined functionality. \~ + \ingroup Model_Attributes + */ +template +class UserAttrDefinition : public IAttrDefinition +{ +public: + /// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. + virtual MbUserAttribute * ReduceUserAttrib ( const MbExternalAttribute & source ); + + /// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. + virtual MbExternalAttribute * AdvanceUserAttrib( const MbUserAttribute & source ); + + /// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. + virtual MbFixAttrSet * DisassembleUsetAttrib( const MbExternalAttribute & source ); + + /// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. + virtual bool ReassembleUsetAttrib( const MbFixAttrSet & source, MbExternalAttribute & targer ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Пользовательский системный атрибут. + \en User system attribute. \~ + \details \ru Пользовательский системный атрибут. \n + \en User system attribute. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbUserAttribute : public MbAttribute, public MbSyncItem { + typedef std_unique_ptr UniqueMembufPtr; +protected : + MbUserAttribType userType_; ///< \ru Тип пользовательского атрибута. \en Type of user attribute. + c3d::string_t prompt_; ///< \ru Строка описания. \en String of description. +private: + SPtr extAttr; + mutable UniqueMembufPtr userBuf; + +private: // public: // You must inherit from MbExternalAttribute only!!! + /// \ru Конструктор. \en Constructor. + MbUserAttribute( const TCHAR * prompt, const MbUserAttribType & id ); + +public: + virtual MbeAttributeType AttributeFamily() const; // \ru Дать тип атрибута. \en Get type of an attribute. + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + + /// \ru Выдать подтип пользовательского атрибута по пользовательскому типу. \en Get subtype of an user attribute by user-defined type. + static MbeAttributeType AttributeType( const MbUserAttribType & userType ); + + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & ); // \ru Инициализировать данные по присланным. \en Initialize data by given attribute. + + // \ru Выполнить действия при изменении владельца не связанное с другими действиями \en Perform actions which are not associated with other actions when changing the owner + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + + // \ru Выполнить действия при конвертации владельца \en Perform actions when converting the owner + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + // \ru Выполнить действия при трансформировании владельца \en Perform actions when transforming the owner + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg ); + + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + + // \ru Выполнить действия при копировании владельца \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg ); + + // \ru Выполнить действия при объединении владельца \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + + // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + + // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + + /// \ru Выдать подсказку. \en Get a hint. + const TCHAR * GetPrompt() const; + /// \ru Выдать идентификатор хранимого атрибута. \en Get identifier of stored attribute. + void GetUserAttribId( MbUserAttribType & attrId ) const; + + /// \ru Установить пользовательские данные. \en Set user data. + void SetUserData( const char * extAttrMemory ); + /// \ru Установить пользовательские данные. \en Set user data. + void SetUserData( const std::vector & extAttrData ); + /// \ru Получить пользовательские данные. \en Get user data. + bool GetUserData( membuf & memBuf ) const; + /// \ru Создать пользовательский внесистемный атрибут по пользовательским данным. \en Make a user external attribute using user data. + bool MakeExternalAttribute( bool keepExisting ); + /// \ru Обновить пользовательские данные по внесистемному атрибуту пользователя. \en Update user data using the user external attribute. + bool UpdateByExternalAttribute() const; + + /// \ru Выдать пользовательский внесистемный атрибут. \en Get a user external attribute. + const MbExternalAttribute * GetExternalAttribute() const { return extAttr; } + /// \ru Установить пользовательский внесистемный атрибут. \en Set a user external attribute. + bool SetExternalAttribute( MbExternalAttribute * ); + /// \ru Установить пользовательский внесистемный атрибут (его копию). \en Set a user external attribute (сopy). + void SetExternalAttribute( const MbExternalAttribute & ); + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + template + friend MbUserAttribute * UserAttrDefinition::ReduceUserAttrib( const MbExternalAttribute & ); + +protected: + virtual ~MbUserAttribute(); // Use AddRef/Release or smart pointer SPtr to destruct it correctly. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbUserAttribute ) +OBVIOUS_PRIVATE_COPY( MbUserAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbUserAttribute ) + +class MATH_CLASS MbFixAttrSet; + + +//------------------------------------------------------------------------------ +/** \brief \ru Пользовательский внесистемный атрибут - базовый класс. + \en User external attribute - the base class. \~ + \details \ru Пользовательский внесистемный атрибут - базовый класс. \n + \en User external attribute - the base class. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbExternalAttribute : public MbAttribute +{ +public : + /// \ru Конструктор. \en Constructor. + MbExternalAttribute(); + /// \ru Деструктор. \en Destructor. + virtual ~MbExternalAttribute(); + + virtual MbeAttributeType AttributeFamily() const; // \ru Дать тип атрибута. \en Get type of an attribute. + virtual MbeAttributeType AttributeType() const; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. + /// \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual MbUserAttribType AttrTypeEx() const = 0; + + virtual MbAttribute & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame( const MbAttribute &, double accuracy ) const = 0; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. + virtual bool Init( const MbAttribute & attr ) = 0; // \ru Инициализировать данные по присланным. \en Initialize data. + + // \ru Выполнить действия при изменении владельца, не связанное с другими действиями. \en Perform actions which are not associated with other actions when changing the owner. + virtual void OnChangeOwner( const MbAttributeContainer & owner ); + // \ru Выполнить действия при конвертации владельца. \en Perform actions when converting the owner. + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ); + // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ); + // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ); + // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. + virtual void OnDeleteOwner( const MbAttributeContainer & owner ); + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual size_t SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + +protected: + static MbFixAttrSet * CreateFixAttrSet( const MbUserAttribType &, c3d::AttrVector & ); + +OBVIOUS_PRIVATE_COPY( MbExternalAttribute ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Фиксированный набор атрибутов + \en Fixed set of attributes. \~ + \details \ru Набор атрибутов, состав которого нельзя изменить, но никто не запрещает + менять значение самих атрибутов. + \en A set of attributes the structure of which cannot be changed, but it is possible + to change values of the attributes. \~ + \ingroup Model_Attributes +*/ +class MATH_CLASS MbFixAttrSet +{ +private: + MbUserAttribType userAttrId; ///< \ru Идентификатор соответствующего пользовательского атрибута. \en Identifier of the corresponding external attribute. + c3d::AttrVector attributes; ///< \ru Атрибуты. \en Attributes. + +private: + /// \ru Конструктор. \en Constructor. + MbFixAttrSet( c3d::AttrVector & attrs ); +public: + /// \ru Деструктор. \en Destructor. + ~MbFixAttrSet() { std::for_each( attributes.begin(), attributes.end(), ReleaseItem ); } + +public: + /// \ru Выдать идентификатор атрибута. \en Get attribute identifier. + const MbUserAttribType & GetUserAttrId() const; + + /// \ru Установить атрибуты. \en Set attributes. + void SetAttribute ( size_t index, const MbAttribute & attrib ); + /// \ru Выдать атрибуты. \en Get attributes. + const MbAttribute & GetAttribute ( size_t index, const MbAttribute & attrib ) const; + + // \ru Выдать количество атрибутов. \en Get the number of attributes. + size_t AttributesCount() const { return attributes.size(); } + + // \ru Доступ хотелось бы ограничить только функцией. \en Access should be constrained only by a function. + // static MbFixAttrSet * MbExternalAttribute::CreateFixAttrSet( const MbUserAttribType & attrId, std::vector & attrs ); + friend class MbExternalAttribute; + +OBVIOUS_PRIVATE_COPY( MbFixAttrSet ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Шаблон явления "Определения" пользовательского атрибута. + \en A template of "Definition" phenomenon of user attribute. \~ + \ingroup Model_Attributes + */ +template +class UserAttrDefinitionInstance : public AttrDefInstance +{ +private: + AttrDefClass * attrDef; ///< \ru "Определение" пользовательского атрибута. \en "Definition" of user attribute. + +public: + /// \ru Конструктор. \en Constructor. + UserAttrDefinitionInstance( const MbUserAttribType & type ); + /// \ru Деструктор. \en Destructor. + virtual ~UserAttrDefinitionInstance(); + +public: + // \ru Дать "определение" пользовательского атрибута. \en Get a "definition" of user attribute. + virtual IAttrDefinition * GetAttrDefinition(); +}; + + +//------------------------------------------------------------------------------ +/// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. +// --- +template +MbUserAttribute * UserAttrDefinition::ReduceUserAttrib( const MbExternalAttribute & source ) +{ + MbUserAttribType attrId( source.AttrTypeEx() ); + + MbUserAttribute * resAttr = new MbUserAttribute( _T("AttrClass"), attrId ); + resAttr->InitActions( source ); + { + const char * charBuf = NULL; + size_t memLen = 0; + { + membuf memBuf; + { + const AttrClass * attrPtr = static_cast(&source); + writer out( memBuf, io::out ); + if ( out.good() ) + out << attrPtr; + } + memBuf.closeBuff(); // before memBuf.getMemLen!!! + + memLen = memBuf.getMemLen(); + charBuf = new char[memLen]; + memBuf.toMemory( charBuf, memLen ); + } + resAttr->SetUserData( charBuf ); + delete [] charBuf; + } + + return resAttr; +} + + +//------------------------------------------------------------------------------ +/// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. +// --- +template +MbExternalAttribute * UserAttrDefinition::AdvanceUserAttrib( const MbUserAttribute & source ) +{ + AttrClass * resAttr = NULL; + MbUserAttribType attrId; + source.GetUserAttribId( attrId ); + { + membuf memBuf; + { + bool canRead = true; + if ( !source.GetUserData( memBuf ) ) { + canRead = false; + if ( source.UpdateByExternalAttribute() ) { + canRead = source.GetUserData( memBuf ); + } + } + if ( canRead ) { + reader in( memBuf, io::in ); + if ( in.good() ) + in >> resAttr; + } + } + memBuf.closeBuff(); + } + return resAttr; +} + + +//------------------------------------------------------------------------------ +/// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. +// --- +template +MbFixAttrSet * UserAttrDefinition::DisassembleUsetAttrib( const MbExternalAttribute & /*source*/ ) { + return NULL; +} + + +//------------------------------------------------------------------------------ +/// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. +// --- +template +bool UserAttrDefinition::ReassembleUsetAttrib( const MbFixAttrSet & /*source*/, MbExternalAttribute & /*targer*/ ) { + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +template +UserAttrDefinitionInstance::UserAttrDefinitionInstance(const MbUserAttribType & type) + : AttrDefInstance( type ) + , attrDef( NULL ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru Деструктор. \en Destructor. +// --- +template +UserAttrDefinitionInstance::~UserAttrDefinitionInstance() +{ + if ( attrDef != NULL ) + delete attrDef; +} + + +//------------------------------------------------------------------------------ +// \ru Дать "определение" пользовательского атрибута. \en Get a "definition" of user attribute. +// --- +template +IAttrDefinition * UserAttrDefinitionInstance::GetAttrDefinition() +{ + if ( attrDef == NULL ) + attrDef = new AttrDefClass(); + return attrDef; +} + + +#endif // __ATTR_USER_ATTRIBUT_H diff --git a/C3d/Include/attribute.h b/C3d/Include/attribute.h new file mode 100644 index 0000000..463a095 --- /dev/null +++ b/C3d/Include/attribute.h @@ -0,0 +1,540 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Атрибуты объекта. + \en Object attributes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTRIBUTE_H +#define __ATTRIBUTE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbVector3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbProperties; +class MATH_CLASS MbAttributeContainer; +class MbRegDuplicate; +class MbRegTransform; + + +class MATH_CLASS MbAttribute; +namespace c3d // namespace C3D +{ +typedef SPtr AttrSPtr; +typedef SPtr ConstAttrSPtr; + +typedef std::vector AttrVector; +typedef std::vector ConstAttrVector; + +typedef std::vector AttrSPtrVector; +typedef std::vector ConstAttrSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы атрибутов. + \en Types of attributes. \~ + \details \ru Типы атрибутов объектов геометрической модели. + Атрибуты объектов группируются по семействам. + \en Types of geometric model objects attributes. + Objects attributes are grouped by families. \~ + \ingroup Model_Attributes + */ +enum MbeAttributeType +{ + at_Undefined = 0, ///< \ru Неопределенный - используется при поиске как "любой". \en Undefined - used as "any" in search. \n + + // \ru Типы простых атрибутов. \en Types of elementary attributes. + at_ElementaryAttribute = 101, ///< \ru Простой атрибут. \en Elementary attribute. + at_Identifier = 102, ///< \ru Идентификатор. \en Identifier. + at_Color = 103, ///< \ru Цвет. \en Color. + at_Width = 104, ///< \ru Ширина линий. \en Lines width. + at_Style = 105, ///< \ru Стиль линий. \en Lines style. + at_Visual = 106, ///< \ru Свойства для OpenGL. \en Properties for OpenGL. + at_Selected = 107, ///< \ru Селектированность. \en Selection. + at_Visible = 108, ///< \ru Видимость. \en Visibility. + at_WireCount = 109, ///< \ru Количество u-линий и v-линий отрисовочной сетки. \en The number of u-mesh and v-mesh drawing lines. \~ + at_Changed = 110, ///< \ru Изменённость. \en Modification. + at_Dencity = 111, ///< \ru Плотность. \en Density. + at_NameAttribute = 112, ///< \ru Топологическое имя. \en Topological name. + at_UpdateStamp = 113, ///< \ru Метка времени обновления. \en Stamp of update time. + at_Embodiment = 114, ///< \ru Признак исполнения (варианта реализации модели). \en Indication of embodiment (variant of model implementation). + at_Elasticity = 115, ///< \ru Механические характеристики: модуль Юнга и коэффициент Пуассана. \en Mechanical properties: Young's modulus and Poisson's ratio. + at_Strains = 116, ///< \ru Деформации. \en The strains. + at_ElementaryLast = 200, /// \ru Простые атрибуты вставлять перед этим значением. \en Elementary attributes should be inserted before this value. \n + + // \ru Типы обобщенных атрибутов. \en Types of common attributes. + at_CommonAttribute = 201, ///< \ru Обобщенный атрибут. \en Common attribute. + at_BoolAttribute = 202, ///< \ru Булев атрибут. \en Boolean attribute. + at_IntAttribute = 203, ///< \ru Целочисленный атрибут. \en Integer attribute. + at_DoubleAttribute = 204, ///< \ru Действительный атрибут. \en Double attribute. + at_StringAttribute = 205, ///< \ru Строковый атрибут. \en String attribute. + at_GeomAttribute = 206, ///< \ru Геометрический атрибут. \en Geometric attribute. \n + at_StampRibAttribute = 207, ///< \ru Атрибут ребра жесткости листового тела. \en Attribute of reinforcement rib of sheet solid. \n + at_Int64Attribute = 208, ///< \ru Атрибут int64. \en Int64 attribute. + at_BinaryAttribute = 209, ///< \ru Бинарный атрибут. \en Binary attribute. + + // \ru Типы связующих атрибутов. \en Types of linking attributes. + at_LinkingAttribute = 301, ///< \ru Связующий атрибут. \en Linking attribute. + at_AnchorAttribute = 302, ///< \ru Якорь. \en Anchor. \n + + // \ru Типы директивных атрибутов. \en Types of directive attributes. + at_DirectiveAttribute = 401, ///< \ru Директивный атрибут. \en Directive attribute. + at_KeepUniqueKey = 402, ///< \ru Поддерживать уникальность ключей. \en Support unique keys. \n + + // \ru Типы изделия. \en Types of product attributes. + at_ProductAttribute = 501, ///< \ru Атрибут конвертеров \en Converters attribute + at_ModelInfo = 502, ///< \ru Сведения о модели в целом. \en Information about model itself. + at_PersonOrganizationInfo = 503, ///< \ru Лицо и организация. \en Person and organization information. + at_ProductInfo = 504, ///< \ru Сведения об изделии. \en Product info. + at_STEPTextDescription = 505, ///< \ru Описание STEP. \en STEP description. + at_STEPReferenceHolder = 506, ///< \ru Обратная ссылка. \en Back reference. \n + + // \ru Типы пользовательских атрибутов. \en Types of user attributes. + at_UserAttribute = 601, ///< \ru Пользовательский атрибут. \en User attribute. + at_UserFirst = 602, ///< \ru Первый пользовательский атрибут. \en First user attribute. + at_UserLast = 900, ///< \ru Последний пользовательский атрибут. \en Last user attribute. \n + + // \ru Типы внешних (внесистемных) атрибутов. \en Types of external (off-system) attributes. + at_ExternalAttribute = 901, ///< \ru Внешний атрибут. \en External attribute. + at_ExternalAttributeImp = 902, ///< \ru Подтип - внешний атрибут \en Subtype - external attribute. + + at_FreeItem = 1000, ///< \ru Тип для прочих объектов. \en Type for the other objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы контейнеров атрибутов. + \en Types of attribute containers. \~ + \details \ru Типы контейнеров атрибутов наследников контейнера атрибутов. + Каждый отдельный атрибут может содержать свой контейнер атрибутов. + \en Types of attribute containers which are inheritors of attribute container. + Each separate attribute may have its attribute container. \~ + \ingroup Model_Attributes + */ +enum MbeImplicationType +{ + ace_Attribute, ///< \ru Контейнер атрибутов, содержащий другие атрибуты. \en Attribute container which contains other attributes. + ace_ModelItem, ///< \ru Контейнер атрибутов объектов геометрической модели. \en Container of geometric model objects attributes. + ace_TopItem, ///< \ru Контейнер атрибутов именованных топологических объектов. \en Container of named topological objects attributes. + ace_MeshItem, ///< \ru Контейнер атрибутов сеточных примитивов. \en Container of mesh primitives attributes. + ace_Model, ///< \ru Контейнер атрибутов геометрической модели. \en Container of geometric model attributes. + ace_AttribContainer, ///< \ru Контейнер атрибутов. \en Attribute container. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Атрибуты объекта. + \en Object attributes. \~ + \details \ru Атрибуты содержат информацию, дополняющую описание геометрической формы объекта. + Атрибут не является неотъемлемой частью объекта, а является элементом данных, которыми может быть наделен объект.\n + Атрибуты являются агентами передачи данных геометрического ядра от одного приложения другому приложению.\n + Атрибуты могут быть следующих типов.\n + Простой атрибут - атрибут несущий простую, однозначно интерпретируемую, информацию, например, цвет, признак выбора.\n + Обобщенный атрибут - атрибут стандартного типа со строковым наименованием, + например, имя, целое число, вещественное число, строка, точка, вектор, указатель.\n + С помощью таких атрибутов приложения могут обмениваться какой либо специфичной информацией + без необходимости разработки дополнительных комплексных атрибутов.\n + Комплексный атрибут - атрибут состоящий из предопределенного набора данных, + описывающих природу атрибута и его смысловую нагрузку, а так же способ его интерпретации. + Такими атрибутами могут описываться некоторые ограничения или простые зависимости а так же аннотационные объекты.\n + Директивный атрибут - атрибут определяющий предназначения объекта или действия которые необходимо с ним произвести, + например атрибут "вычитание" подразумевает что некое тело предназначено для вычитания из другого тела, + и не важно из какого. + Связующий атрибут - атрибут предназначенный для связи объекта геометрического ядра с абстрактным контейнером данных, + то есть набором данных, формат и смысловая нагрузка которых не может быть описана в рамках других атрибутов.\n + \en Attributes contain information supplementing description of object geometric shape. + Attribute is not an intrinsic part of the object, but it is an element of data which the object may contain. \n + Attributes are geometric kernel agents for transferring data from one application to another. \n + The possible types of attributes are the following. \n + Elementary attribute - an attribute which reflects simple and clearly interpreted information, for example, color or selection attribute.\n + Common attribute - attribute of standard type with string naming, + for example: name, integer value, double value, string, point, vector, pointer. \n + Applications may communicate any specific information using such attributes + without necessity of additional complex attributes developing. \n + Complex attribute - an attribute which consists of predefined data set, + which describe a nature of attribute, its semantic meaning and a way of its interpretation. + Such attributes can describe some of constraints or simple dependences and annotation objects.\n + Directive attribute - an attribute defining the purpose of object or actions which should be performed with it, + for example, an attribute "subtraction" implies that one solid is purposed for subtraction from another, + no matter from what exactly. + Linking attribute - an attribute designed for linking of geometric kernel object with abstract container of data, + i.e. a set of data, which format and semantic meaning can not be described by other attributes. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbAttribute : public MbRefItem, + public TapeBase +{ +public: + /**\ru Поведение атрибута при изменении владельца, не связанном с другими описанными действия. + \en Behavior of attribute which is not associated with other described actions when changing the owner. \~ */ + enum OnChangeOwnerAction { + chn_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnChangeOwner. \en Behavior defined by the virtual function OnChangeOwner. + chn_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + chn_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + chn_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при перерождении объекта в другой объект. + \en Behavior of attribute when an object regenerates in other object. \~ */ + enum OnConvertOwnerAction { + cnv_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnConvertOwner. \en Behavior defined by the virtual function OnConvertOwner. + cnv_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + cnv_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + cnv_Copy, ///< \ru Скопировать атрибут и прицепить его копию к копии владельца. \en Copy an attribute and attach its copy to an owner copy. + cnv_Convert, ///< \ru Конвертировать атрибут и прицепить результат к копии владельца. \en Copy an attribute and attach the result to an owner copy. + cnv_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при преобразовании владельца (по матрице). + \en Behaviour of attribute when transforming the owner (by the matrix). \~ */ + enum OnTransformOwnerAction { + trn_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnTransformOwner. \en Behavior defined by the virtual function OnTransformOwner. + trn_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + trn_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + trn_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при копировании владельца. + \en Behaviour of attribute when copying the owner. \~ */ + enum OnCopyOwnerAction { + cpy_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnCopyOwner. \en Behavior defined by the virtual function OnCopyOwner. + cpy_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + cpy_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + cpy_Copy, ///< \ru Скопировать атрибут и прицепить его копию к копии владельца. \en Copy an attribute and attach its copy to an owner copy. + cpy_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при объединении владельца с другим объектом. + \en Behaviour of attribute when merging of the owner with another object. \~ */ + enum OnMergeOwnerAction { + mrg_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnMergeOwner. \en Behavior is defined by the virtual function OnMergeOwner. + mrg_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + mrg_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + mrg_KeepAll, ///< \ru Передать атрибут от поглощаемого объекта поглощающему объекту без замещения. \en Transmit attribute from absorbed object to absorbing object without replacing. + mrg_KeepRep, ///< \ru Передать атрибут от поглощаемого объекта поглощающему объекту с замещением. \en Transmit attribute from absorbed object to absorbing object with replacing. + mrg_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при замещении владельца с другим объектом. + \en Behavior of attribute when replacing the owner by another object. \~ */ + enum OnReplaceOwnerAction { + rep_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnReplaceOwner. \en Behavior is defined by the virtual function OnReplaceOwner. + rep_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + rep_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + rep_KeepAll, ///< \ru Передать атрибут от замещаемого объекта замещающему объекту без замещения. \en Transmit attribute from replaced object to substitutional object without replacing. + rep_KeepRep, ///< \ru Передать атрибут от замещаемого объекта замещающему объекту с замещением. \en Transmit attribute from replaced object to substitutional object with replacing. + rep_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при разделении владельца. + \en Behavior of attribute when splitting the owner. \~ */ + enum OnSplitOwnerAction { + spl_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnSplitOwner. \en Behavior is defined by the virtual function OnSplitOwner. + spl_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + spl_Keep, ///< \ru Сохранить атрибут, т.е. ничего с ним не делать. \en Save attribute, i.e. do not do anything with it. + spl_Copy, ///< \ru Размножить(скопировать) атрибут для каждого результата разбиения. \en Duplicate (copy) attribute for each result of splitting. + spl_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + + /**\ru Поведение атрибута при удалении владельца. + \en Behavior of attribute when deleting the owner. \~ */ + enum OnDeleteOwnerAction { + del_Self = 0, ///< \ru Поведение, определяемое виртуальной функцией OnDeleteOwner. \en Behavior defined by the virtual function OnDeleteOwner. + del_Free, ///< \ru Освободить атрибут, если это возможно, в противном случае удалить. \en Free attribute if it is possible, otherwise delete it. + del_ActCount, ///< \ru Количество элементов в перечислении (добавлять перед данным значением). \en The number of elements in enumeration (add before the given value). + }; + +private : + uint8 forChange; ///< \ru Поведение атрибута при изменении владельца. \en Behavior of attribute when changing the owner. + uint8 forConvert; ///< \ru Поведение атрибута при конвертации владельца. \en Behavior of attribute when converting the owner. + uint8 forTransform; ///< \ru Поведение атрибута при трансформировании владельца. \en Behavior of attribute when transforming the owner. + uint8 forCopy; ///< \ru Поведение атрибута при копировании владельца. \en Behavior of attribute when copying the owner. + uint8 forMerge; ///< \ru Поведение атрибута при объединении владельца. \en Behavior of attribute when merging the owner. + uint8 forReplace; ///< \ru Поведение атрибута при замене владельца. \en Behavior of attribute when replacing the owner. + uint8 forSplit; ///< \ru Поведение атрибута при разделении владельца. \en Behavior of attribute when splitting the owner. + uint8 forDelete; ///< \ru Поведение атрибута при удалении владельца. \en Behavior of attribute when deleting the owner. + bool freeable; ///< \ru Свободность атрибута. \en Attribute freeness + bool copyable; ///< \ru Разрешение копировать атрибут. \en Permission to copy attribute. + +protected : + /// \ru Конструктор без параметров для наследников. \en Constructor without parameters for inheritors. + MbAttribute(); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbAttribute(); + +public : + /** \ru \name Общие функции атрибутов + \en \name Common functions of attributes + \{ */ + /// \ru Выдать регистрационный тип (для копирования, дублирования). \en Get registrational type (for copying, duplication) + virtual MbeRefType RefType() const; + /// \ru Выдать тип контейнера атрибутов. \en Get attribute container type. + virtual MbeImplicationType ImplicationType() const; + /// \ru Выдать тип атрибута. \en Get attribute type. + virtual MbeAttributeType AttributeFamily() const = 0; + /// \ru Выдать подтип атрибута. \en Get subtype of an attribute. + virtual MbeAttributeType AttributeType() const = 0; + /// \ru Сделать копию элемента. \en Create a copy of the element. + virtual MbAttribute & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; + /** \brief \ru Определить, являются ли объекты равными. + \en Determine whether objects are equal. \~ + \details \ru Равными считаются однотипные объекты, все данные которых одинаковы (равны). + \en Objects of the same types with similar (equal) data are considered to be equal. \~ + \param[in] item - \ru Объект для сравнения. + \en Objects for comparison. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether objects are equal. \~ + */ + virtual bool IsSame( const MbAttribute & item, double accuracy ) const = 0; + /// \ru Инициализировать данные по присланным. \en Initialize data. + virtual bool Init( const MbAttribute & ) = 0; + + /// \ru Проверить тип атрибута. \en Check an attribute type. + bool IsA( MbeAttributeType t ) const { return t == AttributeFamily(); } + /** \} */ + + /** \ru \name Действия над объектами геометрического ядра, влияющие на состояние атрибутов + \en \name Actions with objects of geometric kernel influencing on states of attributes. + \{ */ + /** \brief \ru Выполнить действия при изменении владельца, не связанное с другими действиями. + \en Perform actions which are not associated with other actions when changing the owner. \~ + \details \ru Действия при изменении владельца, не связанное с другими действиями. \n + Вызывается после изменения владеющего объекта при условии GetActionForChange() == chn_Self. + \en Actions which are not associated with other actions when changing the owner. \n + This function is called after changing the owning object in a case when GetActionForChange() == chn_Self. \~ */ + virtual void OnChangeOwner( const MbAttributeContainer & owner ) = 0; + + /**\ru Выполнить действия при конвертации владельца, \n + Вызывается после конвертирования владеющего объекта при условии GetActionForConvert() == cnv_Self. \n + В качестве входного параметра передается результат конвертирования объекта. + \en Perform actions when converting the owner, \n + This function is called after converting the owning object in a case when GetActionForConvert() == cnv_Self. \n + The result of object converting is passed as input parameter. \~ */ + virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) = 0; + + /**\ru Выполнить действия при трансформировании владельца, \n + Вызывается после трансформирования владеющего объекта при условии GetActionForTransform() == trn_Self. + В качестве входного параметра может передаваться регистратор трансформированных объектов. + \en Perform actions when transforming the owner, \n + This function is called after transforming the owning object in a case when GetActionForTransform() == trn_Self. + The registrator of transformed objects may be passed as input parameter. \~ */ + virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D & matr, MbRegTransform * iReg = NULL ) = 0; + + /**\ru Выполнить действия при перемещении владельца. \n + Вызывается после перемещения владеющего объекта при условии GetActionForTransform() == trn_Self. + В качестве входного параметра может передаваться регистратор трансформированных объектов. + \en Perform actions when moving the owner. \n + This function is called after moving the owning object in a case when GetActionForTransform() == trn_Self. + The registrator of transformed objects may be passed as input parameter. \~ */ + virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D & to, MbRegTransform * iReg = NULL ) = 0; + + /**\ru Выполнить действия при вращении владельца. \n + Вызывается после вращения владеющего объекта при условии GetActionForTransform() == trn_Self. + В качестве входного параметра может передаваться регистратор трансформированных объектов. + \en Perform actions when rotating the owner. \n + This function is called after rotating the owning object in a case when GetActionForTransform() == trn_Self. + The registrator of transformed objects may be passed as input parameter. \~ */ + virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ) = 0; + + /**\ru Выполнить действия при копировании владельца. \n + Вызывается после копирования владеющего объекта при условии GetActionForCopy() == cpy_Self. \n + В качестве входных параметров передаются: копия владеющего объекта и регистратор скопированных объектов. + \en Perform actions when copying the owner. \n + This function is called after copying the owning object in a case when GetActionForCopy() == cpy_Self. \n + The following objects are passed as input parameters: the owning object copy and registrator of copied objects. \~ */ + virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * iReg = NULL ) = 0; + + /**\ru Выполнить действия при объединении владельца. \n + Вызывается перед слиянием владельца при условии GetActionForMerge() == mrg_Self. \n + В качестве входного параметра передается объект который будет поглощен. + \en Perform actions when merging the owner. \n + This function is called before merging the owner in a case when GetActionForMerge() == mrg_Self. \n + The object which will be absorbed is passed as input parameter. \~ */ + virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) = 0; + + /**\ru Выполнить действия при замене владельца. \n + Вызывается перед выполнением замены владельца при условии GetActionForReplace() == rep_Self. \n + В качестве входного параметра передается объект - заместитель. + \en Perform actions when replacing the owner. \n + This function is called before replacing the owner in a case when GetActionForReplace() == rep_Self. \n + The substitutional object is passed as input parameter. \~ */ + virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) = 0; + + /**\ru Выполнить действия при разделении владельца. \n + Вызывается после разбиения владеющего объекта при условии GetActionForSplit() == spl_Self. \n + В качестве входного параметра передается контейнер результатов разбиения. + \en Perform actions when splitting the owner. \n + This function is called after splitting the owning object in a case when GetActionForSplit() == spl_Self. \n + The container of splitting results is passed as input parameter. \~ */ + virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ) = 0; + + /**\ru Выполнить действия при удалении владельца. \n + Вызывается перед удалением объекта при условии GetActionForDelete() == spl_Self. + \en Perform actions when deleting the owner. \n + This function is called before deleting the owner in a case when GetActionForDelete() == spl_Self. \~ */ + virtual void OnDeleteOwner( const MbAttributeContainer & owner ) = 0; + /** \} */ + + /// \ru Выдать поведение атрибута при изменении владельца. \en Get behavior of attribute when changing the owner. + OnChangeOwnerAction GetActionForChange () const { return static_cast(forChange); } + /// \ru Выдать поведение атрибута при конвертации владельца. \en Get behavior of attribute when converting the owner. + OnConvertOwnerAction GetActionForConvert () const { return static_cast(forConvert); } + /// \ru Выдать поведение атрибута при трансформировании владельца. \en Get behavior of attribute when transforming the owner. + OnTransformOwnerAction GetActionForTransform() const { return static_cast(forTransform); } + /// \ru Выдать поведение атрибута при копировании владельца. \en Get behavior of attribute when copying the owner. + OnCopyOwnerAction GetActionForCopy () const { return static_cast(forCopy); } + /// \ru Выдать поведение атрибута при объединении владельца. \en Get behavior of attribute when merging the owner. + OnMergeOwnerAction GetActionForMerge () const { return static_cast(forMerge); } + /// \ru Выдать поведение атрибута при замене владельца. \en Get behavior of attribute when replacing the owner. + OnReplaceOwnerAction GetActionForReplace () const { return static_cast(forReplace); } + /// \ru Выдать поведение атрибута при разделении владельца. \en Get behavior of attribute when splitting the owner. + OnSplitOwnerAction GetActionForSplit () const { return static_cast(forSplit); } + /// \ru Выдать поведение атрибута при удалении владельца. \en Get behavior of attribute when deleting the owner. + OnDeleteOwnerAction GetActionForDelete () const { return static_cast(forDelete); } + + /// \ru Задать поведение атрибута при изменении владельца. \en Set behavior of attribute when changing the owner. + void SetActionForChange ( OnChangeOwnerAction a ) { forChange = (uint8)a; } + /// \ru Задать поведение атрибута при конвертации владельца. \en Set behavior of attribute when converting the owner. + void SetActionForConvert ( OnConvertOwnerAction a ) { forConvert = (uint8)a; } + /// \ru Задать поведение атрибута при трансформировании владельца. \en Set behavior of attribute when transforming the owner. + void SetActionForTransform( OnTransformOwnerAction a ) { forTransform = (uint8)a; } + /// \ru Задать поведение атрибута при копировании владельца. \en Set behavior of attribute when copying the owner. + void SetActionForCopy ( OnCopyOwnerAction a ) { forCopy = (uint8)a; } + /// \ru Задать поведение атрибута при объедении владельца. \en Set behavior of attribute when merging the owner. + void SetActionForMerge ( OnMergeOwnerAction a ) { forMerge = (uint8)a; } + /// \ru Задать поведение атрибута при замене владельца. \en Set behavior of attribute when replacing the owner. + void SetActionForReplace ( OnReplaceOwnerAction a ) { forReplace = (uint8)a; } + /// \ru Задать поведение атрибута при разбиении владельца. \en Set behavior of attribute when splitting the owner. + void SetActionForSplit ( OnSplitOwnerAction a ) { forSplit = (uint8)a; } + /// \ru Задать поведение атрибута при удалении владельца. \en Set behavior of attribute when deleting the owner. + void SetActionForDelete ( OnDeleteOwnerAction a ) { forDelete = (uint8)a; } + + /// \ru Определить поведение атрибута по другому атрибуту. \en Define behavior of an attribute by another attribute. + void InitActions ( const MbAttribute & ); + + bool CanBeFree () const { return freeable; } + bool CanBeCopied() const { return copyable; } + + void SetCanBeFree ( bool b ) { freeable = b; } + void SetCanBeCopied( bool b ) { copyable = b; } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + virtual void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of object. + virtual size_t SetProperties( const MbProperties & ); + /// \ru Выдать заголовок свойства объекта. \en Get a name of object property. + virtual MbePrompt GetPropertyName() = 0; + + virtual bool IsFamilyRegistrable() const; + +DECLARE_PERSISTENT_CLASS( MbAttribute ) +OBVIOUS_PRIVATE_COPY( MbAttribute ) +}; + +IMPL_PERSISTENT_OPS( MbAttribute ) + +//------------------------------------------------------------------------------ +/** \brief \ru Объект для свойств. + \en Object for properties. \~ + \details \ru Объект для свойств. \n + \en Object for properties. \n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbAttributeAction : public MbRefItem { +private : + uint8 & forChange; ///< \ru Поведение атрибута при изменении владельца. \en Behavior of attribute when changing the owner. + uint8 & forConvert; ///< \ru Поведение атрибута при конвертации владельца. \en Behavior of attribute when converting the owner. + uint8 & forTransform; ///< \ru Поведение атрибута при трансформировании владельца. \en Behavior of attribute when transforming the owner. + uint8 & forCopy; ///< \ru Поведение атрибута при копировании владельца. \en Behavior of attribute when copying the owner. + uint8 & forMerge; ///< \ru Поведение атрибута при объединении владельца. \en Behavior of attribute when merging the owner. + uint8 & forReplace; ///< \ru Поведение атрибута при замене владельца. \en Behavior of attribute when replacing the owner. + uint8 & forSplit; ///< \ru Поведение атрибута при разделении владельца. \en Behavior of attribute when splitting the owner. + uint8 & forDelete; ///< \ru Поведение атрибута при удалении владельца. \en Behavior of attribute when deleting the owner. + bool & freeable; ///< \ru Свободность атрибута. \en Attribute freeness + bool & copyable; ///< \ru Разрешение копировать атрибут. \en Permission to copy attribute. + +public: + /// \ru Конструктор с параметрами. \en Constructor with parameters. + MbAttributeAction( uint8 & cha, uint8 & con, uint8 & tra, uint8 & cop, uint8 & mer, uint8 & rep, uint8 & spl, uint8 & del, + bool & fre, bool & cob ) + : MbRefItem() + , forChange( cha ) + , forConvert( con ) + , forTransform( tra ) + , forCopy( cop ) + , forMerge( mer ) + , forReplace( rep ) + , forSplit( spl ) + , forDelete( del ) + , freeable( fre ) + , copyable( cob ) {} + /// \ru Деструктор. \en Destructor. + ~MbAttributeAction() {} + +public: + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of object. + void SetProperties( const MbProperties & ); + +OBVIOUS_PRIVATE_COPY( MbAttributeAction ) +}; + + +//------------------------------------------------------------------------------ +// \ru Системные строки атрибутов. \en System strings of attributes. +// --- +namespace c3d // namespace C3D +{ + /// \ru Подсказка для эквидистантной грани c нулевым значением эквидистанты. \en Hint for an offset face with the null value of offset. + const c3d::string_t str_ShellFace ( _T( "c3d_ShellFace" ) ); + /// \ru Подсказка для эквидистантной грани. \en Hint for an offset face. + const c3d::string_t str_OffsetFace ( _T( "c3d_OffsetFace" ) ); + /// \ru Подсказка для вскрываемой грани. \en Hint for an open face. + const c3d::string_t str_OpenFace ( _T( "c3d_OpenFace" ) ); + /// \ru Подсказка для доп.эквидистантного смещения слипшейся грани. \en Hint for an offset of a stuck face. + const c3d::string_t str_StuckOffset ( _T( "c3d_StuckOffset" ) ); + /// \ru Подсказка для удаляемой слипшейся грани. \en Hint for a deleted stuck face. + const c3d::string_t str_StuckDelete ( _T( "c3d_StuckDelete" ) ); + + /// \ru Подсказка для расшивки граней по ребру. \en Hint for separation neighbour faces by an edge. + const c3d::string_t str_UnstitchByEdge( _T( "c3d_UnstitchByEdge" ) ); + + /// \ru Подсказка для проверки идентификатора боковой грани. \en Hint for checking flank's identifier. + const c3d::string_t str_CheckFlankId ( _T( "c3d_CheckFlankId" ) ); + /// \ru Подсказка для порядкового номера оболочки. \en Hint for shell sequence number. + const c3d::string_t str_ShellSequenceNumber( _T( "c3d_ShellSequenceNumber" ) ); + + /// \ru Подсказка для сохраняемого объекта. \en Hint for kept object. + const c3d::string_t str_KeptObject ( _T( "c3d_KeptObject" ) ); + /// \ru Подсказка для удаляемого объекта. \en Hint for deleting object. + const c3d::string_t str_DeletingObject( _T( "c3d_DeletingObject" ) ); + /// \ru Подсказка для временного объекта. \en Hint for temporal object. + const c3d::string_t str_TemporalObject( _T( "c3d_TemporalObject" ) ); + + /**\ru Для плоской грани, сгибаемой в цилиндр - параметр u, который меньше соответствующего параметра любой точки грани, + сгибаемой в конус - угловой параметр луча, выходящего из начала координат плоскости параметров и не пересекающего контуры грани. + \en For a planar face bended in cylinder - u-parameter which is less than corresponding parameter of any point on the face, + bended in cone - angular parameter of the ray which goes out from the parameters plane origin and does not intersect contours of the face. \~*/ + const c3d::string_t str_BendMinAnlge ( _T( "BendMinAnlge" ) ); + /// \ru Для цилиндрической и конической грани параметр u, который меньше соответствующего параметра любой точки грани. \en For a cylindrical and conical face - parameter u which is less than corresponding parameter of any point on the face. + const c3d::string_t str_UnbendMinAngle( _T( "UnbendMinAngle" ) ); +} // namespace C3D + +#endif // __ATTRIBUTE_H diff --git a/C3d/Include/attribute_container.h b/C3d/Include/attribute_container.h new file mode 100644 index 0000000..ffbd83f --- /dev/null +++ b/C3d/Include/attribute_container.h @@ -0,0 +1,338 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контейнер атрибутов. + \en An attribute container. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTRIBUTE_CONTAINER_H +#define __ATTRIBUTE_CONTAINER_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS reader; +class MATH_CLASS writer; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbAttribute; +class MATH_CLASS MbUserAttribute; +class MATH_CLASS MbExternalAttribute; +class MATH_CLASS MbProperties; +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Контейнер атрибутов. + \en An attribute container. \~ + \details \ru Контейнер атрибутов. \n + От данного класса наследуются объекты модели геометрического ядра MbItem + и топологические объекты с именем MbTopologyItem .\n + Наследники данного класса содержат атрибуты.\n + Методами данного класса выполняются действия над атрибутами объектов геометрического ядра.\n + Атрибут может влиять на состояние атрибута через его владельца, + тo есть геометрическое ядро предусматривает возможность передачи атрибутам информации об изменениях + их владельцев посредством вызовов предопределенных функций у самого атрибута.\n + Кроме передачи самой информации об изменениях происходящих с владельцем, + предусмотрена возможность определять поведение атрибута при этих изменениях путем выбора + одного из предопределенных типов поведения на каждое изменения владельца.\n + Типы действий, влияющих на состояние атрибутов.\n + Копирование, например, при создании копии тела. Действие над атрибутом производится после копирования владеющего объекта.\n + Разделение, например, разделение грани на две части при вырезании. + Действие над атрибутом производится после разбиения владеющего объекта.\n + Слияние, например, слияние граней при булевых операциях. + Действие над атрибутом производится перед выполнением слияния объектов. + Обрабатываются атрибуты всех объектов, участвующих в слиянии.\n + Изменение, не связанное с разделением или слиянием. + Действие над атрибутом производится после изменения владеющего объекта.\n + Преобразование, например, поворот или параллельный перенос. + Действие над атрибутом производится после преобразования владеющего объекта.\n + Подмена, например замена одной грани тела на другую. Действие над атрибутом производится перед выполнением замены объектов. + Обрабатываются атрибуты всех объектов, участвующих в замене.\n + Удаление объекта. Действие над атрибутом производится перед удалением объекта.\n + \en An attribute container. \n + The inheritors of this class are: objects of geometric kernel model of type MbItem + and topological objects of type MbTopologyItem.\n + Inheritors of this class contain attributes.\n + Operations with attributes of geometric kernel objects are performed by methods of this class.\n + Attribute can affect attribute state using its owner, + i.e. geometric kernel provides an opportunity for transmission to attributes the information about changes + of their owners by calling the predefined functions of the attribute.\n + In addition to transfer of information about changes occurring with owner + provided a possibility to determine the behavior of attribute with these changes by selecting of + one of the predefined types of behavior for each changing of the owner.\n + Types of actions that affect the states of attributes.\n + Copying, for example, when creating a copy of solid. Action on attribute is performed after copying of owning object.\n + Splitting. For example, splitting of a face into two parts in cutting. + Action on attribute is performed after splitting of owning object.\n + Merging. For example, merging of faces in boolean operations. + Action on attribute is performed after merging of owning object.\n + Attributes of all objects involved in merging are processed.\n + Changing which is not associated with splitting or merging. + Action on attribute is performed after changing of owning object.\n + Transformation. For example, rotation or parallel translation. + Action on attribute is performed after transformation of owning object.\n + Replacement. For example, replacement of one face of a solid to another. Action on attribute is performed after replacement of objects. + Attributes of all objects involved in replacement are processed.\n + Deletion of an object. Action on attribute is performed after deletion of an object.\n \~ + \ingroup Model_Attributes +*/ +// --- +class MATH_CLASS MbAttributeContainer +{ +typedef MultiMap AttrMap_t; + +private: + AttrMap_t attributes; ///< \ru Множество атрибутов. \en Set of attributes. + +protected: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbAttributeContainer( const MbAttributeContainer &, MbRegDuplicate * ); +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbAttributeContainer(); + /// \ru Конструктор по атрибуту. \en Constructor by attribute. + MbAttributeContainer( MbAttribute & ); + /// \ru Деструктор. \en Destructor. + virtual ~MbAttributeContainer(); + +public: + + /// \ru Выдать тип контейнера атрибутов. \en Get attribute container type. + virtual MbeImplicationType ImplicationType() const { return ace_AttribContainer; } + + /** \ru \name Общие функции над атрибутами + \en \name Common functions of attributes + \{ */ + /// \ru Cдублировать атрибуты присланного объекта, свои отпустить. \en Duplicate attributes of a given object, release existing attributes. + void AttributesAssign( const MbAttributeContainer & ); + /// \ru Выдать количество объектов. \en Get the number of objects. + size_t AttributesCount() const { return attributes.Count(); } + /// \ru Удалить все атрибуты из контейнера. \en Delete all attributes from container. + void RemoveAttributes(); + + /// \ru Добавить атрибут в контейнер. \en Add attribute in container. + MbAttribute * AddAttribute( MbAttribute *, bool checkSame = true ); + /// \ru Добавить атрибут в контейнер (всегда копирует атрибут). \en Add attribute in container (always copies the attribute). + MbAttribute * AddAttribute( const MbAttribute &, bool checkSame = true ); + /// \ru Выдать атрибуты заданного семейства. \en Get attributes of a given family. + void GetAttributes( c3d::AttrVector &, MbeAttributeType aFamily, MbeAttributeType subType ) const; + /// \ru Выдать атрибуты заданного типа. \en Get attributes of a given type. + void GetAttributes( c3d::AttrVector &, MbeAttributeType aType ) const; + /// \ru Выдать атрибуты по строке описания. \en Get attributes using sample of description string. + void GetCommonAttributes( c3d::AttrVector &, const c3d::string_t & samplePrompt, MbeAttributeType subType = at_Undefined ) const; + /// \ru Выдать строковые атрибуты по строке содержания. \en Get string attributes using sample of contents of the string. + void GetStringAttributes( c3d::AttrVector &, const c3d::string_t & sampleContent ) const; + + /// \ru Выдать атрибут заданного типа, если их несколько - то первый попавшийся. \en Get an attribute of a given type, the first one is returned if there are many. + //const MbAttribute * GetAttribute( MbeAttributeType subType ) const; + /// \ru Удалить атрибут из контейнера. \en Delete an attribute from container. + bool RemoveAttribute( const MbAttribute *, bool checkAccuracySame = false, double accuracy = LENGTH_EPSILON ); + /// \ru Удалить атрибуты заданного типа. \en Delete attributes of a given type. + bool RemoveAttributes( MbeAttributeType type, MbeAttributeType subType ); + + /// \ru Выдать простой атрибут данного подтипа. \en Get a simple attribute of a given subtype. + const MbAttribute * GetSimpleAttribute( MbeAttributeType ) const; + /// \ru Выдать простой атрибут данного подтипа. \en Get a simple attribute of a given subtype. + MbAttribute * SetSimpleAttribute( MbeAttributeType ); + /// \ru Установить простой атрибут данного подтипа. \en Set a simple attribute of a given subtype. + MbAttribute * SetSimpleAttribute( MbAttribute * simpAttr ); + /// \ru Установить простой атрибут данного подтипа (всегда копирует атрибут). \en Set a simple attribute of a given subtype (always copies the attribute). + MbAttribute * SetSimpleAttribute( const MbAttribute & simpAttr ); + /// \ru Удалить простой атрибут(один и более) данного подтипа. \en Delete simple attributes (one or more) of a given subtype. + void RemoveSimpleAttribute( MbeAttributeType ); + /// \ru Отдать простой атрибут данного подтипа. \en Detach a simple attribute of a given subtype. + MbAttribute * DetachSimpleAttribute( MbeAttributeType ); + + /// \ru Выдать пользовательский атрибут данного подтипа. \en Get a user attribute of a given subtype. + void GetUserAttributes( std::vector & attrs, const MbUserAttribType & type ) const; + /// \ru Удалить пользовательский атрибут (один и более) данного подтипа. \en Delete user attributes (one or more) of a given subtype. + void RemoveUserAttributes( const MbUserAttribType & type ); + /// \ru Отдать пользовательский атрибут данного подтипа. \en Detach a user attribute of a given subtype. + void DetachUserAttributes( std::vector & attrs, const MbUserAttribType & type ); + + /// \ru Преобразовать из пользовательского в "системный" \en Convert user attribute to "system" one + static MbUserAttribute * ReduceUserAttrib ( const MbExternalAttribute & ); + /// \ru Преобразовать из "системного" в пользовательский \en Convert "system" attribute to user one + static MbExternalAttribute * AdvanceUserAttrib( const MbUserAttribute & ); + + /// \ru Выполнить действия при изменении атрибутов. \en Perform actions when changing the attributes. + void AttributesChange (); + /// \ru Выполнить действия при конвертации атрибутов. \en Perform actions when converting the attributes. + void AttributesConvert( MbAttributeContainer & other ) const; + /// \ru Выполнить действия при трансформировании атрибутов. \en Perform actions when transforming the attributes. + void AttributesTransform( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Выполнить действия при перемещении атрибутов. \en Perform actions when moving the attributes. + void AttributesMove ( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Выполнить действия при вращении атрибутов. \en Perform actions when rotating the attributes. + void AttributesRotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + /// \ru Выполнить действия при копировании атрибутов. \en Perform actions when copying the attributes. + void AttributesCopy ( MbAttributeContainer & other, MbRegDuplicate * = NULL ) const; + /// \ru Выполнить действия при объединении атрибутов. \en Perform actions when merging the attributes. + void AttributesMerge ( MbAttributeContainer & other ); + /// \ru Выполнить действия при замене атрибутов. \en Perform actions when replacing the attributes. + void AttributesReplace( MbAttributeContainer & other ); + /// \ru Выполнить действия при разделении атрибутов. \en Perform actions when splitting the attributes. + void AttributesSplit ( const std::vector & others ); + /// \ru Выполнить действия при удалении атрибутов. \en Perform actions when deleting the attributes. + void AttributesDelete (); + /** \} */ + + /** \ru \name Функции простых атрибутов объекта. + \en \name Functions of object's simple attributes. + \{ */ + /// \ru Установить плотность объекта. \en Set density of an object. + void SetDensity( double ); + /// \ru Выдать плотность объекта. \en Get density of an object. + double GetDensity() const; + + /// \ru Установить визуальные свойства объекта. \en Set visual properties of the object. + void SetVisual( float a, float d, float sp, float sh, float t, float e ); + /** \brief \ru Выдать визуальные свойства объекта. + \en Get visual properties of the object. \~ + \details \ru Выдать визуальные свойства объекта. + \en Get visual properties of the object. \~ + \param[out] a - \ru Коэффициент общего фона (рассеянного освещения) + \en Coefficient of backlighting \~ + \param[out] d - \ru Коэффициент диффузного отражения + \en Coefficient of diffuse reflection \~ + \param[out] s - \ru Коэффициент зеркального отражения + \en Coefficient of specular reflection \~ + \param[out] h - \ru Блеск (показатель степени в законе зеркального отражения) + \en Shininess (index according to the law of specular reflection) \~ + \param[out] t - \ru Коэффициент непрозрачности + \en Coefficient of total reflection (opacity coefficient) \~ + \param[out] e - \ru Коэффициент излучения + \en Emissivity coefficient \~ + \return \ru true если есть такой атрибут \n false в противном случае + \en True if there is the attribute MbVisual \n otherwise false. \~ + */ + bool GetVisual( float & a, float & d, float & sp, float & sh, float & t, float & e ) const; + + /// \ru Есть ли у объекта свой цвет. \en . + + /** \brief \ru Есть ли у объекта свой цвет. + \en Whether the object is colored. \~ + \details \ru Есть ли у объекта свой цвет. + \en Whether the object is colored. \~ + \return \ru true если есть такой атрибут \n false в противном случае + \en True if there is the attribute MbColor \n otherwise false. \~ + */ + bool IsColored() const { return (GetSimpleAttribute( at_Color ) != NULL); } + /// \ru Изменить цвет объекта. \en Change color of the object. + void SetColor( uint32 ); + /// \ru Выдать цвет объекта. \en Get color of an object. + uint32 GetColor() const; + + /// \ru Установить толщину линий для отображения объекта. \en Set thickness of lines for object's representation. + void SetWidth( int ); + /// \ru Выдать толщину линий для отображения объекта. \en Get thickness of lines for object's representation. + int GetWidth() const; + + /// \ru Установить стиль линий для отображения объекта. \en Set style of lines for object's representation. + void SetStyle( int ); + /// \ru Выдать стиль линий для отображения объекта. \en Get style of lines for object's representation. + int GetStyle() const; + + /// \ru Выделить или не выделить объект. \en To allocate or not to allocate an object. + void SetSelected( bool s = true ); + /// \ru Выделен ли объект? \en Is the object selected. + bool IsSelected() const; + /// \ru Инвертировать выделение объекта. \en Invert object selection. + bool ReverseSelected(); + + /// \ru Задать: объект изменен или не изменён. \en Set: the object is changed or isn't changed. + void SetChanged( bool c = true ); + /// \ru Изменен ли объект? \en Is the object changed? + bool IsChanged() const; + + /// \ru Установить видимость. \en Set visibility. + void SetVisible( bool ); + /// \ru Видимый ли объект? \en Is the object visible? + bool IsVisible() const; + /// \ru Не видимый ли элемент? \en Is the object invisible? + bool IsInvisible() const; + /** \} */ + + /// \ru Прочитать атрибуты из потока. \en Read attributes from stream. + void AttributesRead ( reader & ); + /// \ru Записать атрибуты в поток. \en Writing attributes to stream. + void AttributesWrite( writer & ) const; + /// \ru Выдать свойства атрибутов. \en Get properties of attributes. + void GetProperties( MbProperties & ); + /// \ru Установить свойства атрибутов. \en Set properties of attributes. + void SetProperties( const MbProperties & ); + +OBVIOUS_PRIVATE_COPY( MbAttributeContainer ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить обобщенные атрибуты. + \en Get common attributes. \~ + \details \ru Получить обобщенные атрибуты. \n + \en Get common attributes. \n \~ + \param[in] attrItem - \ru Объект с атрибутами. + \en Object with attributes. \~ + \param[in] attrPrompt - \ru Подсказка атрибута для поиска. + \en Attribute prompt. \~ + \param[out] resAttrs - \ru Найденные атрибуты. + \en Found attributes. \~ + \result \ru Возвращает true, если что-то добавлено. + \en Returns 'true' if the something was got. \~ + \ingroup Model_Attributes +*/ +// --- +MATH_FUNC (bool) GetCommonAttributes( const MbAttributeContainer & attrItem, const c3d::string_t & attrPrompt, c3d::ConstAttrVector & resAttrs ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить обобщенные атрибуты в целевой объект из объекта-источника. + \en Set common attributes in the destination object from the source object. \~ + \details \ru Установить обобщенные атрибуты в целевой объект из объекта-источника. \n + \en Set common attributes in the destination object from the source object. \n \~ + \param[in] srcItem - \ru Объект-источник. + \en The source object. \~ + \param[in] attrType - \ru Тип атрибута. + \en Attribute type. \~ + \param[in] attrPrompt - \ru Подсказка атрибута для поиска. + \en Attribute prompt. \~ + \param[out] dstItem - \ru Целевой объект. + \en The destination object. \~ + \param[in,out] bufAttrs - \ru Буферный массив атрибутов. + \en Buffer attributes vector. \~ + \result \ru Возвращает true, если что-то добавлено. + \en Returns 'true' if the something was added. \~ + \ingroup Model_Attributes +*/ +// --- +MATH_FUNC (bool) AddCommonAttributes( const MbAttributeContainer & srcItem, MbeAttributeType attrType, const c3d::string_t & attrPrompt, + MbAttributeContainer & dstItem, c3d::AttrVector * bufAttrs = NULL ); + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить обобщенные атрибуты. + \en Delete common attributes. \~ + \details \ru Удалить обобщенные атрибуты. \n + \en Delete common attributes. \n \~ + \param[in] attrItem - \ru Объект с атрибутами. + \en Object with attributes. \~ + \param[in] attrPrompt - \ru Подсказка атрибута для поиска. + \en Attribute prompt. \~ + \result \ru Возвращает true, если что-то добавлено. + \en Returns 'true' if the something was deleted. \~ + \ingroup Model_Attributes +*/ +// --- +MATH_FUNC (bool) RemoveCommonAttributes( MbAttributeContainer & attrItem, const c3d::string_t & attrPrompt ); + + +#endif // __ATTRIBUTE_CONTAINER_H diff --git a/C3d/Include/cdet_bool.h b/C3d/Include/cdet_bool.h new file mode 100644 index 0000000..15fbfbb --- /dev/null +++ b/C3d/Include/cdet_bool.h @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Расчет пересечений тел посредством аппарата булевой операции. + \en Calculation of intersections between solids using the boolean operations. \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __CDET_BOOL_H +#define __CDET_BOOL_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbCurveEdge; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Расчет пересечений тел посредством аппарата булевой операции. + \en Calculation of intersections between solids using the boolean operations. \~ + \details \ru Расчет пересечений тел посредством аппарата булевой операции. + \en Calculation of intersections between solids using the boolean operations. \~ \n + \param[in] solid1 - \ru Первое тело. \en The first solid. \~ + \param[in] solid2 - \ru Второе тело. \en The second solid. \~ + \param[out] edges - \ru Ребра пересечения тел. \en Intersection edges. \~ + \param[out] intersectedFaces - \ru Пары номеров пересекшихся граней. \n + - \en The couples of indeses intersected faces of the solids, \n + \param[out] touchedFaces - \ru Пары номеров касающихся граней с противоположно направленными нормалями. + \en The couples of indeses of contacted faces with oppositely directed normals. \~ + \param[out] similarFaces - \ru Пары номеров касающихся подобных граней, которые могут быть объединены. + \en The couples of indeses of relating to similar faces that can be combined. \~ + \return \ru Код результата операции. \en Operation result code. \~ + + \warning \ru Тела будут изменены операцией! Если требуется сохранить тела без изменений, + передавайте копии, сделанные помощью MbSolid::Duplicate(). + \en The solids will be modified by this operation! To keep the body intact, + give the copies made using MbSolid::Duplicate(). \~ + + \ingroup Collision_Detection +*/ +//--- +MATH_FUNC (MbResultType) InterferenceSolids( MbSolid & solid1, MbSolid & solid2, + std::vector * edges, + c3d::IndicesPairsVector * intersectedFaces, + c3d::IndicesPairsVector * similarFaces, + c3d::IndicesPairsVector * touchedFaces ); + + +#endif // __CDET_BOOL_H + diff --git a/C3d/Include/cdet_data.h b/C3d/Include/cdet_data.h new file mode 100644 index 0000000..dcf6819 --- /dev/null +++ b/C3d/Include/cdet_data.h @@ -0,0 +1,390 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Типы данных утилиты обнаружения столкновений. + \en Data types of collision detection. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __CDET_DATA_H +#define __CDET_DATA_H + +#include +#include +#include +#include +#include + +class MbHRepSolid; + +/** + \addtogroup Collision_Detection + \{ +*/ + +//---------------------------------------------------------------------------------------- +/// \ru Объект набора для контроля столкновений. \en Object of the set for collision detection. +//--- +typedef MbHRepSolid * cdet_item; +typedef MbResultType cdet_result; ///< \ru Код результата контроля столкновений. \en Result code of collision queries. + +//---------------------------------------------------------------------------------------- +// \ru Код результата контроля столкновений. \en Codes of collision detection. +//--- +const cdet_result CDET_RESULT_Intersected = rt_Intersect; +const cdet_result CDET_RESULT_NoIntersection = rt_NoIntersect; +const cdet_result CDET_RESULT_Ok = rt_Success; +const cdet_result CDET_RESULT_None = rt_None; +const cdet_result CDET_RESULT_Error = rt_Error; + +//---------------------------------------------------------------------------------------- +// \ru Геометрический объект пользователя. \en User geometric item. +//--- +typedef const void * cdet_app_item; + +//---------------------------------------------------------------------------------------- +// Constants +//--- +const cdet_item CDET_NULL = NULL; ///< \ru Пустой объект набора для контроля столкновений. \en Empty object of the collision query set. +const cdet_app_item CDET_APP_NULL = NULL; ///< \ru "Нулевой" объект модели приложения. \en "Null object" of the client app. + +//---------------------------------------------------------------------------------------- +// Base class to implement collision query details +//--- +struct cdet_query +{ + enum cback_res ///< Result code of the callback function + { + CBACK_VOID + , CBACK_SUFFICIENT ///< This code means that an app stops collision query for given pair of lamps + , CBACK_SKIP ///< Skip testing a given pair of the lumps + , CBACK_BREAK ///< Break search of all collisions of the set + , CBACK_SEARCH_MORE = CBACK_VOID ///< This code notifies a collision detector to continue working at cases CDET_INTERSECTED, CDET_TOUCHED. + }; + + enum message ///< Code of notification + { + CDET_QUERY_STARTED // The collision query is started for the all solids + , CDET_STARTED // The collision query is started for the given pair + , CDET_FINISHED // Collision detector complete searching a collisions for the given pair of lumps. + , CDET_INTERSECTED // The collided pair of objects founded. + , CDET_TOUCHED // Touched faces has been founded with no penetration of the solids. + }; + + struct geom_element ///< Structure representing a collision detection geometry. + { + cdet_app_item appItem; + const MbRefItem * refItem; + const MbMatrix3D * wMatrix; + geom_element() + : appItem( NULL ) + , refItem( NULL ) + , wMatrix( &MbMatrix3D::identity ) {} + }; + + struct cback_data ///< Data structure that notifies an app about collision detection event. + { + geom_element first, second; ///< Pair of geometric objects + cback_data(): first(), second() {} + }; + + cback_res operator() ( message code, cback_data & cData ) { return func( this, code, cData ); } + +protected: + typedef cback_res (*cback_func)( cdet_query *, message, cback_data & ); + + cdet_query( cback_func _func ) : func(_func) {} + ~cdet_query() {} + + OBVIOUS_PRIVATE_COPY( cdet_query ); + +private: + cback_func func; +}; + +//---------------------------------------------------------------------------------------- +// +//--- +struct cdet_query_result: public cdet_query +{ + cdet_result result; + + cdet_query_result() + : cdet_query( QueryFunc ) + , result( CDET_RESULT_NoIntersection ) + {} + +private: + static cback_res QueryFunc( cdet_query * query, message code, cback_data & ) + { + C3D_ASSERT( NULL != query ); + cdet_query_result * q = static_cast( query ); + switch( code ) + { + case CDET_QUERY_STARTED: // The collision query is started for all solids of the set + { + q->result = CDET_RESULT_NoIntersection; + return CBACK_VOID; + } + case CDET_INTERSECTED: // First intersection is founded. + { + q->result = CDET_RESULT_Intersected; + return CBACK_SUFFICIENT; + } + case CDET_FINISHED: // A pair of solids is finished. + return (q->result == CDET_RESULT_Intersected) ? CBACK_BREAK : CBACK_VOID; + + default: + return CBACK_VOID; + } + } +}; + + +//---------------------------------------------------------------------------------------- +// The structure queries first founded collision faces +//--- +struct cdet_first_collided: public cdet_query +{ + SPtr first, second; // collided faces + + cdet_first_collided() + : cdet_query( QueryFunc ) + , first() + , second() + {} + +private: + static cback_res QueryFunc( cdet_query * query, message code, cback_data & cData ) + { + if ( cdet_first_collided * q = static_cast(query) ) + { + switch( code ) + { + case CDET_QUERY_STARTED: // The collision query is started for all solids of the set + { + q->first = q->second = NULL; + return CBACK_VOID; + } + case CDET_FINISHED: // A pair of solids is finished. + return (q->first && q->second) ? CBACK_BREAK : CBACK_SEARCH_MORE; + + case CDET_INTERSECTED: // First intersection is founded. + { + q->first = cData.first.refItem; + q->second = cData.second.refItem; + return (q->first && q->second) ? CBACK_SUFFICIENT : CBACK_SEARCH_MORE; + } + default: + return CBACK_VOID; + } + } + return CBACK_VOID; + } + OBVIOUS_PRIVATE_COPY( cdet_first_collided ); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Структура запроса для поиска граней столкновения. + \en The structure of the query to find collision faces. +*/ +//--- +struct cdet_collided_faces: public cdet_query +{ + typedef std::pair item_face; // represents a face of app item + typedef std::set collided_faces; + collided_faces faces; + std::map groups; + cdet_app_item excluded; // a member of excluded group + +public: + cdet_collided_faces() + : cdet_query( _QueryFunc ) + , faces() + , groups() + , excluded( CDET_APP_NULL ) + {} + + /** \brief \ru Объединить пару геометрических объектов в группу. + \en Unite a pair of geometric items to the group. + \details \ru Функция объединяет в группу два отдельных объекта или присоединяет + первый объект к группе, которой принадлежит второй. Если оба объекта уже + принадлежат каждый своей группе, то обе группы сливаются в одну общую. + \en The function unites to group two separate objects or the first object + attaches to the group, which owns the second. If both objects already + belong to each of their group, the two groups merged into a single. + */ + void Group( cdet_app_item fst, cdet_app_item snd ) + { + fst = _Parent( fst ); + snd = _Parent( snd ); + if ( fst < snd ) + { + std::swap( fst, snd ); + } + groups[fst] = snd; + } + + /** \brief \ru Исключить из контроля на столкновения тела группы. + \en Exclude from the collision control solids of the group. + \param[in] member - \ru Любой участник группы, элементы которой исключаются. + \en Any member of the group whose elements are excluded. \~ + */ + void ExludeGroup( cdet_app_item member ) + { + if ( excluded == CDET_APP_NULL ) + excluded = _Parent( member ); + else + Group( excluded, member ); + } + /** \brief \ru Отменить результаты работы функций Group() и ExludeGroup(). + \en Cancel the results of the functions Group() and ExludeGroup(). + */ + void Reset() + { + faces.clear(); + groups.clear(); + excluded = CDET_APP_NULL; + } + +private: + static cback_res _QueryFunc( cdet_query * query, message code, cback_data & cData ) + { + if ( cdet_collided_faces * q = static_cast(query) ) + { + switch( code ) + { + case CDET_QUERY_STARTED: + { + q->faces.clear(); + return CBACK_VOID; + } + case CDET_STARTED: + { + if ( q->_SameGroups(cData.first.appItem,cData.second.appItem) ) + { + return CBACK_SKIP; + } + return CBACK_VOID; + } + + case CDET_FINISHED: // a pair of solids was finished. + return CBACK_SEARCH_MORE; + + case CDET_INTERSECTED: + { + if ( cData.first.refItem ) + { + q->faces.insert( item_face(cData.first.appItem,cData.first.refItem) ); + } + if ( cData.second.refItem ) + { + q->faces.insert( item_face(cData.second.appItem,cData.second.refItem) ); + } + return CBACK_SEARCH_MORE; + } + default: + return CBACK_VOID; + } + } + return CBACK_VOID; + } + + cdet_app_item _Parent( cdet_app_item appItem ) const + { + std::map::const_iterator iter = groups.find( appItem ); + if ( iter == groups.end() || (iter->second == iter->first) ) + { + return appItem; + } + C3D_ASSERT( iter->second < iter->first ); + + return _Parent( iter->second ); + } + + bool _SameGroups( cdet_app_item fst, cdet_app_item snd ) const + { + return _Parent( fst ) == _Parent( snd ); + } + + OBVIOUS_PRIVATE_COPY( cdet_collided_faces ); +}; + +/** \} */ // Collision_Detection + +class TapeBase; +class MbFace; + +//---------------------------------------------------------------------------------------- +/* \brief \ru Грань столкновения. \en A face of collision. \~ +*/ +// --- +class MbCollisionFace +{ + const MbFace * mathFace; + TapeBase * partFace; + +public: + MbCollisionFace( const MbFace &_mathFace ) : mathFace( &_mathFace ), partFace( NULL ) {} + + const MbFace & GetMathFace() const { return *mathFace; } + + // \ru Установка объекта модели. \en Setting an object of model. + void SetCollisionFaceObject( TapeBase * _partFace ) { partFace = _partFace; } + // \ru Выдача объекта модели. \en Getting an object of model. + TapeBase * GetCollisionFaceObject() const { return partFace; } + + MbCollisionFace & operator = ( const MbCollisionFace & other ) + { + mathFace = other.mathFace; + partFace = other.partFace; //CppCheck + return *this; + } + bool operator > ( const MbCollisionFace & other ) const { return mathFace > other.mathFace; } + bool operator < ( const MbCollisionFace & other ) const { return mathFace < other.mathFace; } + bool operator == ( const MbCollisionFace & other ) const { return mathFace == other.mathFace; } + bool operator != ( const MbCollisionFace & other ) const { return !(*this == other); } + +private: + MbCollisionFace( const MbCollisionFace & ); // not implemented +}; + +//---------------------------------------------------------------------------------------- +// \ru Параметры (характеристика) близости двух объектов. \en Parameters (characteristic) of proximity of two objects. +// --- +class MATH_CLASS MbProximityParameters +{ + MbCollisionFace * theFace1; + MbCollisionFace * theFace2; + SPtr plane; + +public: + MbCartPoint thePar1, thePar2; // \ru Пара точек близости, заданная в поверхностных координатах граненй. \en The points of the proximity specified in the surface coordinates of the faces. + double theDistance; // \ru Расстояние. \en Distance. + double upperDist; // \ru Верхняя оценка для поиска минимальной дистанции. \en The upper bound of the minimal distance estimation. + +public: + MbProximityParameters(); + ~MbProximityParameters(); + +protected: + MbProximityParameters( const MbFace & topoFace1 + , const MbFace & topoFace2 + , MbCartPoint & par1 + , MbCartPoint & par2 + , double dist ); + +public: + const MbCollisionFace & FaceOne() const { return *theFace1; } + const MbCollisionFace & FaceTwo() const { return *theFace2; } + + void SetFacePair( const MbFace &, const MbFace & ); + +private: + MbProximityParameters( const MbProximityParameters & ); // not implemented + MbProximityParameters & operator = ( const MbProximityParameters & ); // not implemented +}; + +#endif // __CDET_DATA_H + +// eof diff --git a/C3d/Include/cdet_utility.h b/C3d/Include/cdet_utility.h new file mode 100644 index 0000000..fa39a1d --- /dev/null +++ b/C3d/Include/cdet_utility.h @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Утилита оценки столкновений и параметров близости тел. + \en Utility of collision detection and proximity queries. +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __CDET_UTILITY_H +#define __CDET_UTILITY_H + +#include + +class MbItem; +class MbSolid; +class MbAssembly; +struct MbLumpAndFaces; +class MbCollisionDetector; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Утилита расчета параметров пересечения и близости тел. + \en Utility for calculation of intersection and proximity parameters of solids. \~ + \details \ru Предоставляет функциональность Collision Detection для взаимодействия + с приложением САПР. + \en Provides facilities of The Collision Detection to interact with the CAD + application. \~ + \attention \ru Для гарантированно правильной работы детектора необходимо, чтобы объект + типа MbLumpAndFaces, добавляемый в рассмотрение посредством функции AddSolid, имел + правильную матрицу преобразования в мир в настоящем его положении, т.е. с самого начала. + \en For the ensure proper functionality of detector it is necessary that + an object of type MbLumpAndFaces to be added in consideration by function AddSolid will + have a correct matrix of transformation to the world coordinate system in its current + state, i.e. from the beginning. \~ + \ingroup Collision_Detection +*/ +// --- +class MATH_CLASS MbCollisionDetectionUtility +{ + MbCollisionDetector & detector; + +public: + MbCollisionDetectionUtility(); + ~MbCollisionDetectionUtility(); + +public: + /** + \brief \ru Добавить твердое тело с заданным положением в набор для контроля столкновений. + \en Add a solid with given placement to the collision detection set. \~ + \return \ru Дескриптор объекта для контроля столкновений. \en Descriptor of object for collision detection. \~ + */ + cdet_item AddItem( const MbSolid & solid, const MbPlacement3D & place, cdet_app_item appItem = CDET_APP_NULL ); + /** + \brief \ru Удалить геометрический объект из набора для контроля столкновений. + \en Remove a geometric object from the set of collision detection. \~ + */ + void RemoveItem( cdet_item cdItem ); + /** + \brief \ru Поменять текущее положение геометрического объекта в наборе. + \en Change current position of a geometric object. \~ + */ + void Reposition( cdet_item, const MbPlacement3D & ); + /** + \brief \ru Проверить соударения между геометрическими объектами набора. + \en Check collisions between geometric objects of the set. \~ + \return \ru Функция вернет CDET_RESULT_Intersected при обранужении хотя бы одной коллизии. + \en The function will return CDET_RESULT_Intersected if it detects at least one collision. + + */ + cdet_result CheckCollisions( cdet_query & ); + + /** + \brief \ru Проверить соударения между геометрическими объектами набора. + \en Check collisions between geometric objects of the set. \~ + \return \ru Функция вернет CDET_RESULT_Intersected при обранужении хотя бы одной коллизии. + \en The function will return CDET_RESULT_Intersected if it detects at least one collision. + */ + cdet_result CheckCollisions(); + + /** + \brief \ru Выдать дескриптор клиентского приложения по дескриптору контрольного набора столкновений. + \en Get an application pointer by descriptor of the collision detection set. + */ + cdet_app_item AppItem( cdet_item cdItem ) const; + + +public: // the functions below can be deprecated in future version. + /** + \brief \ru Добавить модель тела, как набор граней и решеток. + \en Add a solid data as a set of faces and the grids. \~ + \return \ru Индекс добавленной твердотельной модели. \en Index of added solid data. \~ + */ + size_t AddLump( const MbLumpAndFaces & ); + /** + \brief \ru Добавить модель тела, как набор граней и решеток. + \en Add a solid data as a set of faces and the grids. \~ + \return \ru Внутренняя структура данных представляющая добавленную модель. \en Internal data structure representing added solid data. \~ + */ + cdet_item AddSolid( const MbLumpAndFaces & ); + /// \ru Добавить тело с заданным положением. \en Add a solid with a given placement. + cdet_item AddSolid( const MbSolid &, const MbPlacement3D &, cdet_app_item = CDET_APP_NULL ); + /// \ru Удалить твердотельную модель из детектора столкновений. \en Remove a solid model from a collision detector. + void RemoveSolid( cdet_item ); + /// \ru Выдать количество добавленных твердотельных моделей. \en Get number of added solid models. + size_t Count() const; + // Use AppItem() insead this + cdet_app_item Component( size_t solIdx ) const; + /// \ru Номер твердотельной модели, зарегистрированной в детекторе. \en An index of solid model registered in the detector. + size_t SolidIndex( cdet_item cItem ) const; + /// \ru Вычисление минимального расстояния между объектами (см.функцию SetDistanceComputationObjects(...)) \en Calculation of minimal distance between objects (see the function SetDistanceComputationObjects(...)) + cdet_result DistanceQuery( MbProximityParameters & minDist ) const; + /// \ru Выключить из рассмотрения все модели. \en Exclude all models from consideration. + void FlushSolids(); + /// \ru Выдать иерархическое представление тела (NULL = отсутствие такового в списке). \en Get the hierarchical representation of the solid (NULL means that the solid is not in the list). + cdet_item GetHRepSolid ( const MbLumpAndFaces & ) const; + /// \ru Задать барьер для отличия касания от пересечения. \en Set the barrier for the difference between the touch and the intersection. + void SetTouchTolerance( double lTol ); + /// \ru Вкл./выкл. приближенного вычисления пересечений тел \en On/off approximated calculation of intersections of solids + void SetApproxCollisionQuery( bool ff ); + /// \ru Вкл./выкл. приближенного вычисления параметров близости - по триангуляции \en On/off approximated calculation of proximity parameters - by triangulation + void SetApproxDistanceComputation ( bool ff ); + /// \ru Назначить объекты для отслеживания между ними расстояния. \en Assign the pair to track the distance between them. + void SetDistanceTracking( const MbLumpAndFaces &, const MbLumpAndFaces & ); + /// \ru Обновить текущее положение тела с индексом solIdx. \en Update current placement of solid with index solIdx. + void SetPlacement( size_t solIdx, const MbPlacement3D & ); + + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without implementation of the copy-constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( MbCollisionDetectionUtility ); + +public: + // The func is deprecated. Instead, use CheckCollisions + cdet_result InterferenceDetect( void * formalPar = NULL ) const; + // The func is deprecated. Use SetDistanceTracking instead. + void SetDistanceComputationObjects( const MbLumpAndFaces &, const MbLumpAndFaces & ); + // For testing purposes + bool IsEmpty( cdet_item ) const; + // For testing purposes + cdet_item NewComponent( cdet_app_item ); + // For testing purposes + //cdet_item Component( cdet_item subItem ); + // For testing purposes + cdet_item AddInstance( cdet_item compItem, cdet_item subItem, const MbPlacement3D & ); + + +private: + /* + \brief \ru Добавить объект геометрической модели в набор для контроля столкновений. + \en Add an object of geometric model to the set of collision detection control. \~ + \return \ru Объект в наборе для контроля столкновений. \en Object of the set of collision detection. \~ + */ + cdet_item AddItem( const MbItem & ); + // Set an assembly to detect collisions between its elements + void SetAssembly( const MbAssembly & ); + void UpdateGeometry(); +}; + +//---------------------------------------------------------------------------------------- +// Default implemention of the call CheckCollisions. +//--- +inline cdet_result MbCollisionDetectionUtility::CheckCollisions() +{ + cdet_query_result defaultQuery; + return CheckCollisions( defaultQuery ); +} + +#endif // __CDET_UTILITY_H + +// eof \ No newline at end of file diff --git a/C3d/Include/check_geometry.h b/C3d/Include/check_geometry.h new file mode 100644 index 0000000..65af3ec --- /dev/null +++ b/C3d/Include/check_geometry.h @@ -0,0 +1,805 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Диагностика оболочек и их составляющих. + \en Diagnostics of shells and their components. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CHECK_GEOMETRY_H +#define __CHECK_GEOMETRY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Информация о пересечении двух тел. + \en Information about two solids intersection. \~ + \details \ru Информация о пересечении двух тел при диагностике их оболочек. \n + \en Information about intersection of two solids during diagnostics of their shells. \n \~ + \ingroup Algorithms_3D +*/ +//--- +struct MATH_CLASS MbIntersectionData { +protected: + c3d::EdgesSPtrVector edges; ///< \ru Ребра пересечения (владеет по счетчику ссылок). \en Intersection edges (owns by reference counter). + c3d::IndicesVector faceIndices1; ///< \ru Номера касающихся граней первого тела. \en The numbers concerning faces of the first solid. + c3d::IndicesVector faceIndices2; ///< \ru Номера касающихся граней второго тела. \en The numbers concerning faces of the second solid. + + c3d::SolidSPtr solid; ///< \ru Тело пересечения (владеет по счетчику ссылок). \en Intersection solid (owns by reference counter). + + c3d::PointFrameSPtr pointFrame; ///< \ru Группа точек касания. \en Group of touch points. + + bool isTangentCurve; ///< \ru Пересечения - это линии касания. \en Intersections are tangency lines. + bool isSolid; ///< \ru Пересечения образуют тела. \en Intersections form solids. + +public: + /// \ru Конструктор. \en Constructor. + MbIntersectionData(); + /// \ru Конструктор по ребру. \en Constructor by an edge. + MbIntersectionData( const MbCurveEdge & ); + /// \ru Конструктор по ребрам. \en Constructor by edges. + template + MbIntersectionData( const EdgesVector &, bool isSolidEdges ); + /// \ru Конструктор по ребрам. \en Constructor by edges. + template + MbIntersectionData( const EdgesVector &, const FaceIndicesVector & faceNumbers1, const FaceIndicesVector & faceNumbers2 ); + /// \ru Конструктор по ребрам. \en Constructor by edges. + template + MbIntersectionData( const EdgesVector &, const c3d::IndicesPairsVector & faceNumbersPairs ); + /// \ru Конструктор по телу. \en Constructor by a solid. + explicit MbIntersectionData( const MbSolid & ); + /// \ru Конструктор по точкам. \en Constructor by points. + explicit MbIntersectionData( const std::vector & ); + /// \ru Конструктор по вершинам и флагу использования этих объектов, а не их копий. \en Constructor by vertices and by flag of use of these objects instead of their copies. + explicit MbIntersectionData( const c3d::ConstVerticesVector &, bool same ); + /// \ru Конструктор по вершинам и флагу использования этих объектов, а не их копий. \en Constructor by vertices and by flag of use of these objects instead of their copies. + explicit MbIntersectionData( const c3d::ConstVerticesSPtrVector &, bool same ); + /// \ru Деструктор. \en Destructor. + ~MbIntersectionData(); + +public: + /// \ru Пересечение - есть тело. \en Intersection is a solid. + bool IsSolid() const { return ((solid != NULL) || (isSolid && !edges.empty())); } + /// \ru Пересечение касательной областью поверхности. \en Intersection by a tangent region of a surface. + bool IsSurface() const { return !isTangentCurve && !edges.empty(); } + /// \ru Пересечение вдоль касательной линии. \en Intersection along a tangent line. + bool IsCurve() const { return isTangentCurve && !edges.empty(); } + /// \ru Пересечение точкой (еще не реализовано). \en Intersection is a point (not implemented yet). + bool IsPoint() const { return ((pointFrame != NULL) && (pointFrame->GetVerticesCount() > 0)); } + + /// \ru Установить флаг пересечения вдоль касательной линии. \en Set the flag of intersection along a tangent line. + //void SetTangent( bool b ) { isTangentCurve = b; } + + /// \ru Отдать указатель для просмотра тела. \en Get a pointer for viewing the solid. + const MbSolid * GetSolid() const { return solid; } + /// \ru Отдать указатель для просмотра/модификации тела. \en Get a pointer for viewing/modification of the solid. + MbSolid * SetSolid() { return solid; } + + /// \ru Количество кривых пересечения. \en The number of intersection curves. + size_t GetCurvesCount() const { return edges.size(); } + /// \ru Получить массив кривых пересечения. \en Get the intersection curve array. + template + void GetCurves( EdgesVector & curves ) const; + /// \ru Получить указатель на кривую пересечения по индексу. \en Get a pointer to an intersection curve by the index. + const MbCurveEdge * GetCurve( size_t k ) const { return ((k < edges.size()) ? edges[k].get() : NULL); } + /// \ru Получить номера касающихся граней первого/второго тела. \en Get numbers concerning faces of the first/second solid. + template + void GetFaceNumbers( bool first, OutputIndicesVector & ) const; + /// \ru Получить номера касающихся граней первого и второго тел. \en Get numbers concerning faces of the first and second solids. + template + void GetFaceNumbersPairs( OutputIndicesPairsVector & ) const; + + /// \ru Количество точек касания. \en The number of touch points. + size_t GetPointsCount() const { return ((pointFrame != NULL) ? pointFrame->GetVerticesCount() : 0); } + /// \ru Получить набор точек касания. \en Get a set of touch points. + const MbPointFrame * GetPointFrame() const { return pointFrame; } + +OBVIOUS_PRIVATE_COPY( MbIntersectionData ) // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +// \ru Конструктор по ребрам. \en Constructor by edges. +//--- +template +MbIntersectionData::MbIntersectionData( const EdgesVector & initEdges, bool isSolidEgdes ) + : edges ( ) + , faceIndices1 ( ) + , faceIndices2 ( ) + , solid ( NULL ) + , pointFrame ( NULL ) + , isTangentCurve( false ) + , isSolid ( isSolidEgdes ) +{ + size_t addCnt = initEdges.size(); + if ( addCnt > 0 ) { + c3d::EdgeSPtr edge; + edges.reserve( addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + if ( initEdges[k] != NULL ) { + edge = const_cast( &(*initEdges[k]) ); + edges.push_back( edge ); + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор по ребрам. \en Constructor by edges. +//--- +template +MbIntersectionData::MbIntersectionData( const EdgesVector & initEdges, + const FaceIndicesVector & faceInds1, + const FaceIndicesVector & faceInds2 ) + : edges ( ) + , faceIndices1 ( ) + , faceIndices2 ( ) + , solid ( NULL ) + , pointFrame ( NULL ) + , isTangentCurve( false ) + , isSolid ( false ) +{ + size_t edgesCnt = initEdges.size(); + + if ( edgesCnt > 0 ) { + c3d::EdgeSPtr edge; + edges.reserve( edgesCnt ); + for ( size_t k = 0; k < edgesCnt; ++k ) { + if ( initEdges[k] != NULL ) { + edge = const_cast(&(*initEdges[k])); + edges.push_back( edge ); + } + } + std::copy( faceInds1.begin(), faceInds1.end(), std::back_inserter( faceIndices1 ) ); + std::copy( faceInds2.begin(), faceInds2.end(), std::back_inserter( faceIndices2 ) ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор по ребрам. \en Constructor by edges. +//--- +template +MbIntersectionData::MbIntersectionData( const EdgesVector & initEdges, + const c3d::IndicesPairsVector & faceIndicesPairs ) + : edges ( ) + , faceIndices1 ( ) + , faceIndices2 ( ) + , solid ( NULL ) + , pointFrame ( NULL ) + , isTangentCurve( false ) + , isSolid ( false ) +{ + size_t edgesCnt = initEdges.size(); + + if ( edgesCnt > 0 ) { + c3d::EdgeSPtr edge; + edges.reserve( edgesCnt ); + size_t k; + for ( k = 0; k < edgesCnt; ++k ) { + if ( initEdges[k] != NULL ) { + edge = const_cast(&(*initEdges[k])); + edges.push_back( edge ); + } + } + size_t facePairsCnt = faceIndicesPairs.size(); + faceIndices1.reserve( facePairsCnt ); + faceIndices2.reserve( facePairsCnt ); + for ( k = 0; k < facePairsCnt; ++k ) { + faceIndices1.push_back( faceIndicesPairs[k].first ); + faceIndices2.push_back( faceIndicesPairs[k].second ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Получить массив кривых пересечения. \en Get the intersection curve array. +//--- +template +void MbIntersectionData::GetCurves( EdgesVector & dstEdges ) const +{ + size_t addCnt = edges.size(); + c3d::EdgeSPtr edge; + dstEdges.reserve( dstEdges.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + edge = const_cast( &(*edges[k]) ); + dstEdges.push_back( edge ); + ::DetachItem( edge ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Получить номера касающихся граней первого/второго тела. \en Get numbers concerning faces of the first/second solid. +//--- +template +void MbIntersectionData::GetFaceNumbers( bool first, OutputIndicesVector & outputIndices ) const +{ + const c3d::IndicesVector & faceIndices = first ? faceIndices1 : faceIndices2; + size_t addCnt = faceIndices.size(); + if ( addCnt > 0 ) { + outputIndices.reserve( outputIndices.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + outputIndices.push_back( faceIndices[k] ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Получить номера касающихся граней первого и второго тел. \en Get numbers concerning faces of the first and second solids. +//--- +template +void MbIntersectionData::GetFaceNumbersPairs( OutputIndicesPairsVector & outputIndicesPairs ) const +{ + size_t addCnt = std_min( faceIndices1.size(), faceIndices2.size() ); + if ( addCnt > 0 ) { + outputIndicesPairs.reserve( outputIndicesPairs.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + outputIndicesPairs.push_back( std::make_pair( faceIndices1[k], faceIndices2[k] ) ); + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка вырожденности кривой в трехмерном пространстве. + \en Check for the curve degeneration in three-dimensional space. \~ + \details \ru Проверка вырожденности кривой в трехмерном пространстве. \n + \en Check for the curve degeneration in three-dimensional space. \n \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[in] eps - \ru Неразличимая метрическая область, критерий вырождения кривой. + \en Indistinguishable metric domain, curve degeneration criterion. \~ + \return \ru Возвращает состояние вырожденности кривой. + \en Returns the state of the curve degeneration. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) IsDegeneratedCurve( const MbCurve3D & curve, double eps ); + + +//------------------------------------------------------------------------------ +/// \ru Проверка на полное совпадение двух кривых пересечения поверхностей c метрической точностью lenEps \en Check for complete coincidence of two intersection curves of surfaces with metric tolerance lenEps +//--- +bool IsCoincidentCurves( const MbSurfaceIntersectionCurve & intCurve1, + const MbSurfaceIntersectionCurve & intCurve2, + double lenEps ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка оболочки тела на замкнутость. + \en Check of solid's shell for closedness. \~ + \details \ru Проверка оболочки тела на замкнутость. \n + \en Check of solid's shell for closedness. \n \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] checkChangedOnly - \ru Проверять только измененные грани оболочки. + \en Only modified faces of a shell are to be checked. \~ + \return \ru Возвращает состояние замкнутости оболочки. + \en Returns the state of shell closedness. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckShellClosure( const MbFaceShell & shell, bool checkChangedOnly = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка оболочки тела на замкнутость. + \en Check of solid's shell for closedness. \~ + \details \ru Проверка оболочки тела на замкнутость. \n + \en Check of solid's shell for closedness. \n \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckSolidClosure( const MbSolid & solid ); + + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Функции для проверки элементов оболочки \en Functions for checking shell's elements +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Поиск краевых ребер замкнутой оболочки. + \en Search for the boundary edges of a closed shell. \~ + \details \ru Поиск краевых ребер замкнутой оболочки. \n + Краевое ребер - это ребро у которого нет ссылки на одну из смежных граней. \n + Наличие краевых ребер замкнутой оболочки может приводит к отказу операций над оболочкой, + если операцией будет затронута часть оболочки с краевыми ребрами. \n + Наличие одиночных краевых ребер практически никак не влияет на правильность расчета МЦХ. + Множественные краевые ребра, особенно в виде связных цепочек, являются серьезным дефектом замкнутой оболочки. \n + \en Search for the boundary edges of a closed shell. \n + Boundary edge is an edge that has no reference to one of the adjacent faces. \n + The presence of boundary edges of a closed shell may lead to failure of operations on the shell, + if the operation affects a part of the shell with such edges. \n + The presence of single boundary edges has practically no effect on the correctness of the MIP calculation. \n + Multiple boundary edges, especially in the form of related chains, is a serious defect of the closed shell. \n \~ + \param[in] allEdges - \ru Множество ребер оболочки. + \en Set of edges of a shell. \~ + \param[in] boundaryEdges - \ru Множество найденных краевых ребер. + \en Set of found boundary edges. \~ + \return \ru Возвращает true, если найдено хотя бы одно краевое ребро. + \en Returns true if at least one boundary edges is found. \~ + \ingroup Algorithms_3D +*/ +// --- +template +bool CheckBoundaryEdges( const Edges & allEdges, Edges * boundaryEdges ) +{ + bool isBoundary = false; + C3D_ASSERT( boundaryEdges != &allEdges ); + + if ( boundaryEdges != &allEdges ) { + for ( size_t i = 0, cnt = allEdges.size(); i < cnt; ++i ) { + if ( allEdges[i] != NULL && allEdges[i]->IsBoundaryFace( METRIC_PRECISION ) ) { + isBoundary = true; + if ( boundaryEdges != NULL ) + boundaryEdges->push_back( allEdges[i] ); + else + break; + } + } + } + + return isBoundary; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Поиск некорректных ребер. + \en Search of incorrect edges. \~ + \details \ru Поиск некорректных ребер. Не ищет краевые ребра замкнутой оболочки. \n + Для поиска краевых ребер используйте функцию CheckBoundaryEdges. \n + Функция проверяет следующие варианты некорректности ребер : + 1. Ребро с типом граница (cbt_Boundary) должно указывать только на одну грань \n + 2. Поверхности в кривой пересечения ребра должны быть такие же как и поверхности в смежных гранях ребра \n + 3. Граничные точки поверхностных кривых в кривой пересечения ребра должны совпадать с точностью не хуже 1e-6 или толерантности в вершинах ребра \n + 4. Опорные точки сплайнов поверхностных кривых в уточняемой кривой пересечения (cbt_Specific) должны совпадать в пространстве c точностью не хуже 1e-6 \n + Наличие некорректных ребер является серьезным дефектом оболочки. \n + \en Search of incorrect edges. Does not look for the boundary edges of a closed shell. \n + Use function CheckBoundaryEdges for searching for boundary edges. \n + The function checks the next parameters of an edge as signs of its incorrectness : + 1. An edge with the border type cbt_Boundary must point to only one face. \n + 2. The surfaces of the intersection curve of the edge have to be the same as the surfaces in the adjacent faces of the edge. \n + 3. The boundary points of the surface curves in the curve of intersection of the edge must coincide with an accuracy not worse than 1e-6 or tolerance at the vertices of the edge. \n + 4. The reference points of the splines of the surface curves in the intersection curve with the border type cbt_Specific must coincide in space with an accuracy not worse than 1e-6. \n + The presence of incorrect edges is a serious defect of the shell. \n \~ + \param[in] allEdges - \ru Множество ребер оболочки. + \en Set of edges of a shell. \~ + \param[in] badEdges - \ru Множество найденных некорректных ребер. + \en Set of found incorrect edges. \~ + \return \ru Возвращает true, если найдено хотя бы одно некорректное ребро. + \en Returns true if at least one incorrect edge is found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) CheckBadEdges( const RPArray & allEdges, + RPArray * badEdges ); + +//------------------------------------------------------------------------------ +/** \brief \ru Поиск неточных вершин. + \en Search for inexact vertices. \~ + \details \ru Поиск неточных вершин оболочки. \n + Наличие неточных вершин не является серьезным дефектом оболочки. + В большинстве случаев никак не влияет на работу операций с оболочкой. + Не влияет на расчет МЦХ. \n + \en Search for inexact vertices of a shell. \n + The presence of inaccurate vertices is not a serious shell defect. + In most cases, does not affect on the result of operations with this shell. + Does not affect the calculation of the MIP. \n \~ + \param[in] vertArr - \ru Множество вершин оболочки. + \en Set of shell's vertices. \~ + \param[in] mAcc - \ru Порог отбора неточных вершин. + \en Accuracy of inexact vertices filtration. \~ + \param[in] inexactVerts - \ru Множество для неточных вершин. + \en Set of inexact vertices. \~ + \return \ru Возвращает true, если найдена хотя бы одна неточная вершина. + \en Returns true if at least one inexact vertex is found. \~ + \ingroup Algorithms_3D +*/ +// --- +template +bool CheckInexactVertices( const Vertices & vertArr, double mAcc, Vertices * inexactVerts ) +{ + bool isInexactVertex = false; + C3D_ASSERT( inexactVerts != &vertArr ); + + if ( inexactVerts != &vertArr ) { + for ( size_t i = 0, icnt = vertArr.size(); i < icnt; ++i ) { + MbVertex * v = vertArr[i]; + if ( v != NULL && v->GetTolerance() > mAcc ) { + isInexactVertex = true; + if ( inexactVerts != NULL ) + inexactVerts->push_back( v ); + else + break; + } + } + } + + return isInexactVertex; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Является ли кривая пересечения ребра неточной. + \en Is the curve of intersection edges inaccurate. \~ + \details \ru Является ли кривая пересечения ребра неточной (оценочно). \n + Наличие неточных ребер (кривых пересечения) не является серьезным дефектом оболочки. + В большинстве случаев никак не влияет на работу операций с оболочкой. + Незначительно влияет на расчет МЦХ. \n + \en Is the curve of intersection edges inaccurate (estimated). \n + The presence of inaccurate edges is not a serious shell defect. + In most cases, does not affect on the result of operations with this shell. + Can slightly affect the calculation of the MIP. \n \~ + \param[in] edge - \ru Ребро оболочки. + \en The edge of the shell. \~ + \param[in] mMaxAcc - \ru Порог отбора неточного ребра. + \en Accuracy selection inaccurate ribs. \~ + \return \ru Возвращает true, если ребро неточное. + \en Returns true, if the edge is inaccurate. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) IsInexactEdge( const MbCurveEdge & edge, double mMaxAcc ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Поиск неточных ребер оценочно. + \en Approximate search of inexact edges. \~ + \details \ru Поиск неточных ребер оболочки оценочно. \n + Наличие неточных ребер (кривых пересечения) не является серьезным дефектом оболочки. + В большинстве случаев никак не влияет на работу операций с оболочкой. + Незначительно влияет на расчет МЦХ. \n + \en Approximate search of inexact edges of a shell. \n + The presence of inaccurate edges is not a serious shell defect. + In most cases, does not affect on the result of operations with this shell. + Can slightly affect the calculation of the MIP. \n \~ + \param[in] allEdges - \ru Множество ребер оболочки. + \en Set of edges of a shell. \~ + \param[in] mAcc - \ru Порог отбора неточных ребер. + \en Accuracy of inexact edges filtration. \~ + \param[in] inexactEdges - \ru Множество найденных неточных ребер. + \en Set of found inexact edges. \~ + \return \ru Возвращает true, если найдено хотя бы одно неточное ребро. + \en Returns true if at least one inexact edge is found. \~ + \ingroup Algorithms_3D +*/ +// --- +template +bool CheckInexactEdges( const Edges & allEdges, double mAcc, Edges * inexactEdges ) +{ + bool isInexactEdge = false; + + for ( size_t i = 0, icnt = allEdges.size(); i < icnt; ++i ) { + if ( allEdges[i] != NULL) { + bool isSpaceNear = !::IsInexactEdge( *allEdges[i], mAcc ); + + if ( !isSpaceNear ) { + isInexactEdge = true; + if ( inexactEdges != NULL ) + inexactEdges->push_back( allEdges[i] ); + else + break; + } + else if ( !allEdges[i]->IsClosed() ) { + const MbVertex & v1 = allEdges[i]->GetBegVertex(); + const MbVertex & v2 = allEdges[i]->GetEndVertex(); + if ( &v1 == &v2 ) { + double mTol = v1.GetTolerance(); + double mLen = allEdges[i]->GetLengthEvaluation(); + if ( mLen > METRIC_PRECISION && mLen > mTol + METRIC_PRECISION ) { + isInexactEdge = true; + if ( inexactEdges != NULL ) + inexactEdges->push_back( allEdges[i] ); + else + break; + } + } + } + } + } + + return isInexactEdge; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка подложек и указаний на грани. + \en Check of substrates and pointers to faces. \~ + \details \ru Проверка подложек и указаний на грани оболочки. \n + Наличие общих подложек (базовые поверхности в ограниченных кривыми поверхностях) + и неверных ссылок на грани в ребрах является серьезным дефектом оболочки. \n + \en Check of substrates and pointers to faces of a shell. \n + The presence of common substrates (base surfaces in bounded curved surfaces) + and invalid references to faces in edges is a serious shell defect. \n \~ + \param[in] shell - \ru Проверяемая оболочка. + \en A shell to check. \~ + \param[out] areIdenticalBaseSurfaces - \ru Наличие общих подложек. + \en Whether there are common substrates. \~ + \param[out] areBadFacePointers - \ru Наличие неверных указателей на соседние грани. + \en Whether there are invalid pointers to neighboring faces. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (void) CheckBadFaces( const MbFaceShell & shell, + bool & areIdenticalBaseSurfaces, + bool & areBadFacePointers ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка взаимного расположения циклов грани. + \en Check interposition of face loops. \~ + \details \ru Проверка взаимного расположения циклов грани. + Функция проверять корректность ориентации циклов грани. + Неправильная ориентация циклов граней является серьезным дефектом оболочки. + \en Check interposition of face loops. \n + The function is to check the correctness of the orientation of the face loops (chains of oriented edges). + Incorrect orientation of face's loops is a serious defect in the shell. \n \~ + \param[in] face - \ru Грань. + \en Face. \~ + \return \ru Возвращает true, если расположение и ориентация циклов корректны. + \en Returns true if interposition of loops and their orientations are correct. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckLoopsInterposition( const MbFace & face ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка связности ребер цикла. + \en Check for connectivity of loop edges. \~ + \details \ru Проверка связности ребер цикла грани. + Возвращает максимальные метрическую и параметрическую (опционально) погрешности построения цикла. \n + Наличие неточных стыковок в циклах грани не обязательно является серьезным дефектом оболочки. \n + \en Check for connectivity of loop edges. + Returns the maximal metric and parametric (optionally) tolerances of the loop construction. \n + The presence of inaccurate connection in face loops (chains of oriented edges) is not necessarily a serious shell defect. \n \~ + \param[in] face - \ru Грань, содержащая проверяемый цикл. + \en Face containing the loop under test. \~ + \param[in] loop - \ru Цикл грани. + \en Face loop. \~ + \param[out] lengthTolerance - \ru Максимальное метрическое значение разрыва между ребрами. + \en The maximal metric value of a gap between edges. \~ + \param[out] paramTolerance - \ru Максимальное параметрическое значение разрыва между ребрами. + \en The maximal parametric value of a gap between edges. \~ + \param[out] badLocs - \ru Пары номеров ориентированных ребер с плохой связностью. + \en Edges pairs with bad connectivity. \~ + \return \ru Возвращает true, если связность ребер не нарушена. + \en Returns true if the connectivity is good. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckLoopConnection( const MbFace & face, const MbLoop & loop, + double & lengthTolerance, double & paramTolerance, + c3d::IndicesPairsVector & badLocs ); + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка связности ребер цикла. + \en Check for connectivity of a loop edges. \~ + \details \ru Проверка связности ребер цикла грани. + Возвращает максимальные метрическую и параметрическую (опционально) погрешности построения цикла. \n + Наличие неточных стыковок в циклах грани не обязательно является серьезным дефектом оболочки. \n + \en Check for connectivity of a loop edges. + Returns the maximal metric and parametric (optionally) tolerances of the loop construction. \n + The presence of inaccurate connection in face loops (chains of oriented edges) is not necessarily a serious shell defect. \n \~ + \param[in] face - \ru Грань, содержащая проверяемый цикл. + \en Face containing the loop under test. \~ + \param[in] loop - \ru Цикл грани. + \en Face loop. \~ + \param[out] lengthTolerance - \ru Максимальное метрическое значение разрыва между ребрами. + \en The maximal metric value of a gap between edges. \~ + \param[out] paramTolerance - \ru Максимальное параметрическое значение разрыва между ребрами. + \en The maximal parametric value of a gap between edges. \~ + \param[out] badConnectedEdges - \ru Ребра с плохой связностью. + \en Edges with bad connectivity. \~ + \param[out] badVertexEdges - \ru Ребра с неправильными вершинами. + \en Edges with incorrect vertices. \~ + \return \ru Возвращает true, если связность ребер не нарушена. + \en Returns true if the connectivity is good. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckLoopConnection( const MbFace & face, const MbLoop & loop, + double & lengthTolerance, double * paramTolerance, + RPArray & badConnectedEdges, + RPArray & badVertexEdges ); + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка связности ребер цикла. + \en Check for connectivity of a loop edges. \~ + \details \ru Проверка связности ребер цикла грани. + Возвращает максимальные метрическую и параметрическую (опционально) погрешности построения цикла. \n + Наличие неточных стыковок в циклах грани не обязательно является серьезным дефектом оболочки. \n + \en Check for connectivity of a loop edges. + Returns the maximal metric and parametric (optionally) tolerances of the loop construction. \n + The presence of inaccurate connection in face loops (chains of oriented edges) is not necessarily a serious shell defect. \n \~ + \param[in] face - \ru Грань, содержащая проверяемый цикл. + \en Face containing the loop under test. \~ + \param[in] loop - \ru Цикл грани. + \en Face loop. \~ + \param[out] lengthTolerance - \ru Максимальное метрическое значение разрыва между ребрами. + \en The maximal metric value of a gap between edges. \~ + \param[out] paramTolerance - \ru Максимальное параметрическое значение разрыва между ребрами. + \en The maximal parametric value of a gap between edges. \~ + \param[out] badConnectedEdges - \ru Ребра с плохой связностью. + \en Edges with bad connectivity. \~ + \return \ru Возвращает true, если связность ребер не нарушена. + \en Returns true if the connectivity is good. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckLoopConnection( const MbFace & face, const MbLoop & loop, + double & lengthTolerance, double * paramTolerance, + RPArray & badConnectedEdges ); + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка связности ребер цикла. + \en Check for connectivity of a loop edges. \~ + \details \ru Проверка связности ребер цикла грани. + Возвращает максимальные метрическую и параметрическую (опционально) погрешности построения цикла. \n + Наличие неточных стыковок в циклах грани не обязательно является серьезным дефектом оболочки. \n + \en Check for connectivity of a loop edges. + Returns the maximal metric and parametric (optionally) tolerances of the loop construction. \n + The presence of inaccurate connection in face loops (chains of oriented edges) is not necessarily a serious shell defect. \n \~ + \param[in] face - \ru Грань, содержащая проверяемый цикл. + \en Face containing the loop under test. \~ + \param[in] loop - \ru Цикл грани. + \en Face loop. \~ + \param[out] lengthTolerance - \ru Максимальное метрическое значение разрыва между ребрами. + \en The maximal metric value of a gap between edges. \~ + \param[out] paramTolerance - \ru Максимальное параметрическое значение разрыва между ребрами. + \en The maximal parametric value of a gap between edges. \~ + \return \ru Возвращает true, если связность ребер не нарушена. + \en Returns true if the connectivity is good. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckLoopConnection( const MbFace & face, const MbLoop & loop, + double & lengthTolerance, double * paramTolerance ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти циклы грани с самопересечениями. + \en Find face loops with self-intersections. \~ + \details \ru Найти циклы грани с самопересечениями. + Возвращает найденные циклы с самопересечениям. \n + Наличие самопересечений в циклах граней является серьезным дефектом оболочки. \n + \en Find face loops with self-intersections. + Returns the found loops with self-intersections. \n + The presence of self-intersections in face loops is a serious shell defect. \n \~ + \param[in] face - \ru Грань, содержащая проверяемые циклы. + \en Face containing loops under test. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] checkInsideEdges - \ru Искать самопересечения внутри области определения двумерных кривых ребер. + \en Find edges with self-intersections inside. \~ + \param[out] loopPnts - \ru Точки самопересечения c номерами циклов. + \en Points of self-intersecting loops and the numbers of loops. \~ + \return \ru Возвращает true, если найдены самопересечения циклов. + \en Returns true if the self-intersection has been found. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) FindLoopsSelfIntersections( const MbFace & face, const MbSNameMaker & nameMaker, bool checkInsideEdges, + std::vector< std::pair > * loopPnts ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка связности граней faces. + \en Check for connectivity of faces 'faces'. \~ + \details \ru Проверка топологической связности граней faces. \n + \en Check for topological connectivity of faces 'faces'. \n \~ + \param[in] faces - \ru Проверяемый набор граней. + \en Set of faces under check. \~ + \return \ru Возвращает true, все грани топологически связаны. + \en Returns true if all the faces are topologically connected. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) CheckFacesConnection( const RPArray & faces ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти в исходной оболочке "родительские" грани производной оболочки. + \en Find "parent" faces of a derived shell in the initial shell. \~ + \details \ru Найти в исходной оболочке "родительские" грани производной оболочки геометрическим поиском подобных граней с наложением. \n + Флаг sameNormals установить false, если исходная оболочка участвовала в булевом вычитании тел вторым операндом. \n + \en Find "parent" faces of a derived shell in the initial shell by geometric search of similar faces with overlapping. \n + Flag sameNormals is to be set to false if the initial shell was involved in the boolean subtraction of solids as a second operand. \n \~ + \param[in] srcShell - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] dstShell - \ru Производная оболочка. + \en The derived shell. \~ + \param[in] sameNormals - \ru Искать с одинаковым (true) или противоположным (false) направлением нормалей. + \en Search with the same (true) or the opposite (false) direction of normals. \~ + \param[out] simPairs - \ru Множество соответствий - номеров граней в исходной и производной оболочках. + \en Set of correspondences - indices of faces in the initial and the derived shells. \~ + \return \ru Возвращает true, все найдено хоть одно соответствие. + \en Returns true if at least one correspondence is found. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) FindOverlappingSimilarFaces( const MbFaceShell & srcShell, + const MbFaceShell & dstShell, + bool sameNormals, + c3d::IndicesPairsVector & simPairs ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти на каких гранях исходной оболочки базируются ребра производной оболочки. + \en Find faces edges of the derived shell are based on. \~ + \details \ru Найти на каких гранях исходной оболочки базируются ребра производной оболочки геометрическим поиском. + Поиск соответствия проводится по поверхностям из граней, на которые ссылается ребро, а не по поверхностям в кривой пересечения ребра. + Флаг sameNormals установить false, если исходная оболочка участвовала в булевом вычитании тел вторым операндом. \n + \en Determine on which faces of the initial shell edges of the derived shell are based on by the geometric search. + Search of the correspondence is performed by surfaces from faces the edge refers to, but not by surfaces from the intersection curve of the edge. + Flag sameNormals is to be set to false if the initial shell was involved in the boolean subtraction of solids as a second operand. \n \~ + \param[in] edges - \ru Ребра производной оболочки. + \en Edges of an arbitrary shell. \~ + \param[in] shell - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameNormals - \ru Искать с одинаковым (true) или противоположным (false) направлением нормалей. + \en Search with the same (true) or the opposite (false) direction of normals. \~ + \param[out] efPairs - \ru Множество соответствий - номеров ребер во входном массиве и номеров граней в исходной оболочке. + \en Set of correspondence - indices of edges in the input array and numbers of faces in the input shell. \~ + \return \ru Возвращает true, все найдено хоть одно соответствие. + \en Returns true if at least one correspondence is found. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC (bool) FindFacesEdgesCarriers( const c3d::ConstEdgesVector & edges, + const MbFaceShell & shell, + bool sameNormals, + c3d::IndicesPairsVector & efPairs ); + +//------------------------------------------------------------------------------ +/** \brief \ru Починить некорректное ребро оболочки. + \en Repair incorrect edge of a shell. \~ + \details \ru Починить некорректное ребро оболочки (псевдо-толерантное, псевдо-точное). \n + \en Repair incorrect edge of a shell (pseudo-tolerant, pseudo-exact). \n \~ + \param[in] edge - \ru Ребро оболочки. + \en Shell edge. \~ + \param[in] updateFacesBounds - \ru Обновить границы поверхностей в гранях ребра. + \en Update surface bounds of edge faces. \~ + \return \ru Возвращает true, если была выполнена модификация ребра. + \en Returns true if edge modification was performed. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC( bool ) RepairEdge( MbCurveEdge & edge, bool updateFacesBounds ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Починить некорректные ребра оболочки. + \en Repair incorrect edges of a shell. \~ + \details \ru Починить некорректное ребро оболочки (псевдо-толерантное, псевдо-точное). \n + \en Repair incorrect edge of a shell (pseudo-tolerant, pseudo-exact). \n \~ + \param[in] shell - \ru Оболочка. + \en Shell. \~ + \param[in] updateFacesBounds - \ru Обновить границы поверхностей в гранях ребра. + \en Update surface bounds of edge faces. \~ + \return \ru Возвращает true, если была выполнена модификация ребра. + \en Returns true if edge modification was performed. \~ + \ingroup Algorithms_3D +*/ +//--- +MATH_FUNC( bool ) RepairEdges( MbFaceShell & shell, bool updateFacesBounds = true ); + + +#endif // __CHECK_GEOMETRY_H diff --git a/C3d/Include/collection.h b/C3d/Include/collection.h new file mode 100644 index 0000000..c77d996 --- /dev/null +++ b/C3d/Include/collection.h @@ -0,0 +1,337 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Коллекция элементов. + \en Collection of elements . \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __COLLECTION_H +#define __COLLECTION_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbMesh; +class MATH_CLASS MbGrid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Коллекция элементов. + \en Collection of elements. \~ + \details \ru Коллекция элементов - это объект геометрической модели, наследник MbItem, являющийся + множеством элементов в трехмерном пространстве. \n + \en The collection of 3D elements is an object of geometric model (subclass MbItem) which is + the set of elements in 3D space. \n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbCollection : public MbItem { +public: + /** \brief \ru Типы коллекций 3D объектов. + \en Types of 3D object collection. \~ +*/ +enum CollectionType { + coll_PointCloud = 0, ///< \ru Облако точек. \en The point cloud. + coll_Tessellation = 1, ///< \ru Триангуляция. \en The tessellation. + coll_Elements = 2, ///< \ru Набор элементов. \en Set of elements. + coll_Segmentation = 3, ///< \ru Сегментированная полигональная сетка. \en Segmented polygonal mesh. +}; + +private: + CollectionType type; ///< \ru Тип коллекции 3D объектов. \en Type of 3D object collection. + uint32 xSize; ///< \ru Количество объектов вдоль первой координаты. \en The number of objects along the first coordinate. + uint32 ySize; ///< \ru Количество объектов вдоль второй координаты. \en The number of objects along the second coordinate. + uint32 zSize; ///< \ru Количество объектов вдоль третьей координаты. \en The number of objects along the third coordinate. + std::vector points; ///< \ru Множество точек. \en Set of points. + std::vector normals; ///< \ru Множество нормалей в точках согласовано с множеством точек. \en Set of normals at control points is synchronized with the set of points. + std::vector escorts; ///< \ru Множество значений для дополнительной информации в точках. \en The set of values for additional information of points. + std::vector triangles; ///< \ru Индексное множество треугольных пластин содержит номера элементов множества points и normals. \en Set of triangular plates contains numbers of elements of 'points' and 'normals' sets. + std::vector quadrangles; ///< \ru Индексное множество четырёхугольных пластин содержит номера элементов множества params и/или множеств points и normals. \en Set of quadrangular plates contains numbers of elements of 'params' set and/or of 'points' and 'normals' sets. + std::vector elements; ///< \ru Индексное множество объемных элементов содержит номера элементов множества points. \en Set of volume elements contains numbers of vertices of 'points' sets. + std::vector segments; ///< \ru Множество сегментов полигональной сетки. \en Set of segments of mesh. + + /** \brief \ru Габаритный куб объекта. + \en Bounding box of object. \~ + \details \ru Габаритный куб объекта рассчитывается только при запросе габарита объекта. Габаритный куб в конструкторе объекта и после модификации объекта принимает неопределенное значение. + \en Bounding box of object is calculated only at the request. Bounding box of object is undefined after object constructor and after object modifications \n \~ + */ + mutable MbCube cube; +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbCollection( const MbCollection & init ); + + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbCollection( const MbCollection &, MbRegDuplicate * ); +public: + /// \ru Конструктор. \en Constructor. + MbCollection(); + /// \ru Конструктор. \en Constructor. + MbCollection( const MbMesh & mesh ); + + /// \ru Деструктор. \en Destructor. + virtual ~MbCollection(); + +public: + VISITING_CLASS( MbCollection ); + + // \ru Общие функции геометрического объекта \en Common functions of a geometric object + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbeSpaceType Type() const; // \ru Групповой тип объекта. \en Group type of object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & init, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равным. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + MbGrid * CreateGrid() const; + + // \ru Создать сетки из четырехугольных пластин наружных стенок элементов. \en Create grids by quadrangular plates of the outside walls of elements. + void CreateGridsByElements( RPArray & grids_ ) const; + + // \ru Создать угловые точки и элементы. \en Create corner points and elements. + void CreateCornerPointsAndElements( SArray & points0, SArray & elements0 ) const; + + // \ru Создать сетки из по результатам сегментации. \en Create grids by segmentation results. + void CreateGridsBySegments( RPArray & grids_ ) const; + + /** \ru \name Общие функции коллекции. + \en \name Common functions of a collection. + \{ */ + + /// \ru Выдать количество точек. \en Get count of points. + size_t PointsCount() const { return points.size(); } + /// \ru Выдать количество нормалей. \en Get the number of normals. + size_t NormalsCount() const { return normals.size(); } + /// \ru Выдать количество значений. \en Get count of values. + size_t EscortsCount() const { return escorts.size(); } + /// \ru Выдать количество треугольников. \en Get the number of triangles. + size_t TrianglesCount() const { return triangles.size(); } + /// \ru Выдать количество четырехугольников. \en Get the number of quadrangles. + size_t QuadranglesCount() const { return quadrangles.size(); } + /// \ru Выдать количество объемных элементов. \en Get the number of elements of volume. + size_t ElementsCount() const { return elements.size(); } + /// \ru Выдать количество сегментов. \en Get the number of segments of mesh. + size_t SegmentsCount() const { return segments.size(); } + /// \ru Выдать количество триангуляций. \en Get the number of triangulations. + //size_t GridsCount() const { return grids.size(); } + ptrdiff_t PointsMaxIndex() const { ptrdiff_t c = points.size(); return ( c - 1 ); } + /// \ru Выдать количество нормалей минус 1 (максимальный индекс). \en Get the number of normals minus one (maximal index). + ptrdiff_t NormalsMaxIndex() const { ptrdiff_t c = normals.size(); return ( c - 1 ); } + + /// \ru Добавить в коллекцию точку и нормаль в точке. \en Add a point and normal at the point to collection. + void AddPoint ( const MbCartPoint3D & p3D, const MbVector3D & n3D ) { points.push_back(p3D); normals.push_back(n3D); cube.SetEmpty(); } + /// \ru Добавить в коллекцию точку. \en Add a point to collection. + void AddPoint ( const MbCartPoint3D & p3D ) { points.push_back(p3D); cube.SetEmpty(); } + /// \ru Добавить в коллекцию нормаль. \en Add a normal to collection. + void AddNormal( const MbVector3D & n3D ) { normals.push_back(n3D) ; } + /// \ru Добавить в коллекцию точки. \en Add points to collection. + void AddPoints ( const std::vector & pnts ) { points.insert(points.end(), pnts.begin(), pnts.end()); cube.SetEmpty(); } + /// \ru Добавить в коллекцию нормали. \en Add normals to collection. + void AddNormals( const SArray & nrms ) { normals.insert(normals.end(), nrms.begin(), nrms.end()); cube.SetEmpty(); } + /// \ru Добавить в коллекцию данных. \en Add scores to collection. + void AddEscorts( const std::vector & scores ) { escorts.insert(escorts.end(), scores.begin(), scores.end()); } + + /// \ru Добавить треугольник. \en Add a triangle. + void AddTriangle ( const MbTriangle & triangle ) { triangles.push_back( triangle ); } + /// \ru Добавить треугольник с заданными номерами вершин. \en Add a triangle by the given indices of vertices + void AddTriangle ( uint j0, uint j1, uint j2, bool o ) { MbTriangle t(j0,j1,j2,o); triangles.push_back( t ); } + /// \ru Добавить четырёхугольник. \en Add a quadrangle. + void AddQuadrangle( const MbQuadrangle & quadrangle ) { quadrangles.push_back( quadrangle ); } + /// \ru Добавить четырёхугольник с заданными номерами вершин. \en Add a quadrangle by the given indices of vertices. + void AddQuadrangle( uint j0, uint j1, uint j2, uint j3, bool o ) { MbQuadrangle t(j0,j1,j2,j3,o); quadrangles.push_back( t ); } + /// \ru Добавить объемный элемент. \en Add an element. + void AddElement( const MbElement & element ) { elements.push_back(element); } + /// \ru Добавить объемный элемент. \en Add an element. + void AddElement( uint j0, uint j1, uint j2, uint j3, uint j4, uint j5, uint j6, uint j7 ) { + MbElement t( j0,j1,j2,j3,j4,j5,j6,j7 ); elements.push_back( t ); } + void AddSegment( const MbGridSegment & segment ) { segments.push_back( segment ); } + void AddSegment( const std::vector & initFaces ) { MbGridSegment seg( initFaces ); segments.push_back( seg ); } + /// \ru Добавить полигон. \en Add a polygon. + //void AddGrid( MbExactGrid & grd ) { grids.push_back( &grd ); } + + /// \ru Выдать индексы точек в массиве points для i-го треугольника (связанного или несвязанного). \en Get indices of points in 'points' array for i-th triangle (adjacent or non-adjacent). + bool GetTrianglePointIndex ( size_t i, uint & ind0, uint & ind1, uint & ind2 ) const; + /// \ru Выдать индексы точек в массиве points для i-го четырехугольника (связанного или несвязанного). \en Get indices of points in 'points' array for i-th quadrangle (adjacent or non-adjacent). + bool GetQuadranglePointIndex( size_t i, uint & ind0, uint & ind1, uint & ind2, uint & ind3 ) const; + /// \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + bool GetTrianglePoints ( size_t i, MbCartPoint3D &p0, MbCartPoint3D &p1, MbCartPoint3D &p2 ) const; + /// \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + bool GetTriangleNormals ( size_t i, MbVector3D &n0, MbVector3D &n1, MbVector3D &n2 ) const; + + /// \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + bool GetQuadranglePoints ( size_t i, MbCartPoint3D &p0, MbCartPoint3D &p1, MbCartPoint3D &p2, MbCartPoint3D &p3 ) const; + /// \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + bool GetQuadrangleNormals( size_t i, MbVector3D &n0, MbVector3D &n1, MbVector3D &n2, MbVector3D &n3 ) const; + + /// \ru Удалить точки. \en Delete points. + void PointsRemove() { points.clear(); + #ifdef STANDARD_C11 + points.shrink_to_fit(); + #endif + cube.SetEmpty(); } + /// \ru Удалить точку с заданным номером. \en Delete point by the given index. + void PointRemove ( size_t i ) { if ( i < points.size() ) points.erase( points.begin() + i ); cube.SetEmpty(); } + /// \ru Удалить нормаль с заданным номером. \en Delete normal by the given index. + void NormalRemove( size_t i ) { if ( i < normals.size() ) normals.erase( normals.begin() + i ); } + + /// \ru Установить тип объекта. \en Set type. + void SetType( CollectionType t ) { type = t; } + /// \ru Выдать тип объекта. \en Get type. + CollectionType GetType() const { return type; } + /// \ru Установить количество объектов вдоль первой координаты. \en Set the number of objects along the first coordinate. + void SetXSize( uint32 n ) { xSize = n; } + /// \ru Установить количество объектов вдоль второй координаты. \en Set the number of objects along the cecond coordinate. + void SetYSize( uint32 n ) { ySize = n; } + /// \ru Установить количество объектов вдоль третьей координаты. \en Set the number of objects along the third coordinate. + void SetZSize( uint32 n ) { zSize = n; } + /// \ru Выдать количество объектов вдоль первой координаты. \en Get the number of objects along the first coordinate. + uint32 GetXSize() const { return xSize; } + /// \ru Выдать количество объектов вдоль второй координаты. \en Get the number of objects along the cecond coordinate. + uint32 GetYSize() const { return ySize; } + /// \ru Выдать количество объектов вдоль третьей координаты. \en Get the number of objects along the third coordinate. + uint32 GetZSize() const { return zSize; } + + /// \ru Выдать точку по её номеру. \en Get point by its index. + void GetPoint ( size_t i, MbCartPoint3D & p ) const { p = points[i]; } + /// \ru Выдать множество точек. \en Get set of points. + const std::vector & GetPoints ( ) const { return points; } + /// \ru Выдать нормаль по её номеру. \en Get normal by its index. + void GetNormal( size_t i, MbVector3D & n ) const { n = normals[i]; } + /// \ru Выдать множество нормалей. \en Get set of normals. + const std::vector & GetNormals( ) const { return normals; } + /// \ru Выдать точку по её номеру. \en Get point by its index. + double GetEscort( size_t i ) const { return escorts[i]; } + /// \ru Выдать элемент по его номеру. \en Get element by its index. + void GetElement( size_t i, MbElement & elem ) const { elem = elements[i]; } + /// \ru Выдать индексы точек в массиве points для i-го объемного элемента. \en Get indices of points in 'points' array for i-th element. + bool GetElementIndex( size_t i, uint & ind0, uint & ind1, uint & ind2, uint & ind3, uint & ind4, uint & ind5, uint & ind6, uint & ind7 ) const; + /// \ru Выдать для элемента с номером i точки вершин. \en Get points of vertices for i-th element. + bool GetElementPoints ( size_t i, MbCartPoint3D &p0, MbCartPoint3D &p1, MbCartPoint3D &p2, MbCartPoint3D &p3, + MbCartPoint3D &p4, MbCartPoint3D &p5, MbCartPoint3D &p6, MbCartPoint3D &p7 ) const; + /// \ru Выдать сегмент по его номеру. \en Get segment by its index. + void GetSegment( size_t i, MbGridSegment & seg ) const { seg = segments[i]; } + /// \ru Выдать точку с заданным номером. \en Get point by the given index. + const MbCartPoint3D & GetPoint ( size_t i ) const { return points[i]; } + /// \ru Выдать нормаль с заданным номером. \en Get normal by the given index. + const MbVector3D & GetNormal( size_t i ) const { return ( (normals.size() == 1) ? normals[0] : normals[i] ); } + /// \ru Выдать треугольник с номером i. \en Get i-th triangle. + const MbTriangle & GetTriangle ( size_t i ) const { return triangles[i]; } + /// \ru Выдать четырёхугольник с номером i. \en Get i-th quadrangle. + const MbQuadrangle & GetQuadrangle( size_t i ) const { return quadrangles[i]; } + /// \ru Выдать четырёхугольник с номером i. \en Get i-th quadrangle. + const MbElement & GetElement ( size_t i ) const { return elements[i]; } + /// \ru Выдать сегмент по его номеру. \en Get segment by its index. + const MbGridSegment & GetSegment( size_t i ) const { return segments[i]; } + /// \ru Выдать полигон с номером i. \en Get i-th polygon. + //const MbExactGrid & GetGrid ( size_t i ) const { return *grids[i]; } + + /// \ru Удалить все xтреугольники. \en Delete all triangles. + void TrianglesDelete() { triangles.clear(); } + /// \ru Удалить все четырехугольники. \en Delete all quadrangles. + void QuadranglesDelete() { quadrangles.clear(); } + /// \ru Удалить все объемные элементы. \en Delete all elements. + void ElementsDelete() { elements.clear(); } + /// \ru Удалить все сегменты. \en Delete all segments. + void SegmentsDelete() { segments.clear(); } + /// \ru Удалить все nhbfyuekzwbb. \en Delete all triangulations. + //void GridsDelete(); + + /// \ru Зарезервировать память для контейнеров. \en Reserve memory for some containers. + void ReservePointsNormals( size_t n ) { points.reserve( points.size() + n ); normals.reserve( normals.size() + n ); } + /// \ru Зарезервировать память для контейнера точек. \en Reserve memory for container of points. + void PointsReserve ( size_t n ) { points.reserve( points.size() + n ); } + /// \ru Зарезервировать память для контейнера нормалей. \en Reserve memory for container of normals. + void NormalsReserve ( size_t n ) { normals.reserve( normals.size() + n ); } + /// \ru Зарезервировать память для контейнера параметров. \en Reserve memory for container of elements. + /// \ru Зарезервировать память для контейнера параметров. \en Reserve memory for container of elements. + void EscordsReserve ( size_t n ) { escorts.reserve( escorts.size() + n ); } + /// \ru Зарезервировать память для контейнера треугольников. \en Reserve memory for container of triangles. + void TrianglesReserve ( size_t n ) { triangles.reserve( triangles.size() + n ); } + /// \ru Зарезервировать память для контейнера четырехугольников. \en Reserve memory for container of quadrangles. + void QuadranglesReserve( size_t n ) { quadrangles.reserve( quadrangles.size() + n ); } + /// \ru Зарезервировать память для контейнера элементов. \en Reserve memory for container of elements. + void ElementsReserve ( size_t n ) { elements.reserve( elements.size() + n ); } + /// \ru Зарезервировать память для контейнера сегментов. \en Reserve memory for container of segments. + void SegmentsReserve ( size_t n ) { segments.reserve( segments.size() + n ); } + /// \ru Зарезервировать память для контейнера полигонов. \en Reserve memory for container of grids. + //void GridReserve ( size_t n ) { grids.reserve( grids.size() + n ); } + + /// \ru Удалить всю триангуляцию без освобождения памяти, занятую контейнерами. \en Delete all triangulation without freeing the memory occupied by containers. + void Flush() { points.clear(); normals.clear(); escorts.clear(); + triangles.clear(); quadrangles.clear(); elements.clear(); segments.clear(); //grids.clear(); + cube.SetEmpty(); } + /// \ru Удалить всю триангуляцию и освободить память. \en Delete all triangulation and free the memory. + void HardFlush() { points.clear(); normals.clear(); escorts.clear(); + triangles.clear(); quadrangles.clear(); elements.clear(); segments.clear(); //grids.clear(); + #ifdef STANDARD_C11 + points.shrink_to_fit(); normals.shrink_to_fit(); escorts.shrink_to_fit(); + triangles.shrink_to_fit(); quadrangles.shrink_to_fit(); elements.shrink_to_fit(); segments.shrink_to_fit(); //grids.shrink_to_fit(); + #endif + cube.SetEmpty(); } + /// \ru Освободить лишнюю память. \en Free the unnecessary memory. + void Adjust() { + #ifdef STANDARD_C11 + points.shrink_to_fit(); normals.shrink_to_fit(); escorts.shrink_to_fit(); + triangles.shrink_to_fit(); quadrangles.shrink_to_fit(); elements.shrink_to_fit(); segments.shrink_to_fit(); //grids.shrink_to_fit(); + #endif + } + + /// \ru Инициализировать объект. \en Initialize object. + void Init( const MbCollection & init ); + /// \ru Инициализировать объект. \en Initialize object. + void Init( const MbGrid & init ); + /// \ru Инициализировать объект. \en Initialize object. + void Init( const MbMesh & init ); + + // \ru Выдать контейнер треугольников. \en Get the container of triangles. + template + void GetTriangles( TrianglesVector & tVector ) const { + tVector.reserve( tVector.size() + triangles.size() ); + for ( size_t i = 0, iCount = triangles.size(); i < iCount; i++ ) + tVector.push_back( triangles[i] ); + } + // \ru Выдать контейнер четырёхугольников. \en Get the container of quadrangles. + template + void GetQuadrangles( QuadranglesVector & qVector ) const { + qVector.reserve( qVector.size() + quadrangles.size() ); + for ( size_t i = 0, iCount = quadrangles.size(); i < iCount; i++ ) + qVector.push_back( quadrangles[i] ); + } + + /// \ru Преобразовать четырёхугольники в треугольники. \en Convert quadrangles to triangles. + void ConvertQuadranglesToTriangles(); + /// \ru Преобразовать все объекты в треугольники и уравнять число точек и нормалей. \en Convert all objects to triangles and equalize count of points and count of normals. + void ConvertAllToTriangles(); + /// \ru Удалить дублирующие с заданной точностью друг друга точки. \en Remove redundant points with a given tolerance (duplicates). + bool RemoveRedundantPoints( bool deleteNormals, double epsilon = LENGTH_EPSILON ); + + /** \} */ + private: + /// \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbCollection & operator = ( const MbCollection & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCollection ) +}; + +IMPL_PERSISTENT_OPS( MbCollection ) + +#endif // __COLLECTION_H diff --git a/C3d/Include/comanager.h b/C3d/Include/comanager.h new file mode 100644 index 0000000..f493bf7 --- /dev/null +++ b/C3d/Include/comanager.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль: COMANAGER + \en Module: COMANAGER. \~ + \details \ru Цель: Менеджер геометрических ограничений для MbModel + \en Target: Geometric constraints manager for MbModel \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __COMANAGER_H +#define __COMANAGER_H +// +#include +#include +// constraints +#include "gce_api.h" + + + +class GcFormerImpl; +class MbConstraint; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Менеджер для взаимодействия с решателем \en Manager of interactions with the solver +// +////////////////////////////////////////////////////////////////////////////////////////// + +class MATH_CLASS ConstraintManager2D +{ + GCE_system m_gcSolver; + GcFormerImpl & m_gcFormer; + +public: + ConstraintManager2D(); + ~ConstraintManager2D(); + +public: + /// \ru Добавить ограничение в решатель \en Add a constraint to the solver + bool AddConstraint( const MbConstraint & ); + /// \ru Рассчитать систему ограничений \en Compute a system of constraints + bool Evaluate(); + /// \ru Применить решение \en Apply the solution + void ApplySolution(); + /// \ru Очистить весь контекст решателя \en Clear the whole context of the solver + void Clear(); + +private: + ConstraintManager2D( const ConstraintManager2D & ); + ConstraintManager2D & operator = ( const ConstraintManager2D & ); +}; + +#endif // __COMANAGER_H + + +// eof \ No newline at end of file diff --git a/C3d/Include/constraint.h b/C3d/Include/constraint.h new file mode 100644 index 0000000..d096cee --- /dev/null +++ b/C3d/Include/constraint.h @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Геометрическое ограничение. + \en Geometric constraint. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONSTRAINT_H +#define __CONSTRAINT_H + +#include +#include +#include +#include +#include + +struct CNodeIterator; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Аргумент геометрического ограничения. + \en An argument of geometric constraint. \~ + \details \ru Аргумент ограничений со связанным элементом, указателем на геометрический + объект, содержащий элемент, и указателем на сборку, содержащую объект. + \en An argument of constraints with connected element, the geometric object + containing the element, and the assembly containing the object.\~ + \ingroup Model_Items +*/ +//--- +class MATH_CLASS MtGeomArgument +{ +private: + SPtr propItem; ///< \ru Элемент объекта, непосредственно выбранный для связи. \en The element of geom object which constraints are connected to. + SimpleName propName; ///< \ru Имя связываемого элемента. \en Name of a connected element. + uint32 hash; ///< \ru Имя объекта сборки или подсборки, содержащего объект связи с ограничением. \en Hash code of the path from the root to the item. + SPtr item; ///< \ru Объект сборки или подсборки, содержащий объект связи с ограничением. \en Assembly object that hosts geom entity connected to constraint. + const MbAssembly * root; ///< \ru Сборка, содержащая объект с ограничением. \en The assembly that hosts geom object with entity connected to constraint. + +public: + static const MtGeomArgument null; ///< \ru Пустой аргумент. \en An empty argument. + +public: + MtGeomArgument( const MbRefItem * p, const MbItem * h ); + MtGeomArgument( const MtGeomArgument & ); + MtGeomArgument() : propItem( NULL ), propName( UNDEFINED_SNAME ) + , hash( UNDEFINED_SNAME ), item( NULL ), root( NULL ) {} + +public: + /** \brief \ru Получить непосредственный объект сборки, содержащий ссылочный объект. + \en Get immediate object of the assembly containing the reference object. + \param trans - \ru Матрица ссылочного объекта в системе координат непосредственного объекта сборки. + - \en Matrix from the reference object to the sub-item of the assembly. \~ + */ + const MbItem * SubItemOf( const MbAssembly *, MbMatrix3D & trans ) const; + /// \ru Объект геометрической модели, владеющий аргументом. \en Geometry model object which is a host of an argument. + const MbItem * HostItem() const { return item; } + /// \ru Аргумент ограничения, заданный в ЛСК хозяина. \en Geometric constraint argument given in the host's LCS. + const MbRefItem * PropItem() const { return propItem; } + /// \ru Выдать значение геометрии аргумента, заданное в ЛСК хозяина. \en Get geometric value of argument given in the host LCS. + MtGeomVariant PropGeom() const; + /// \ru Выдать хэш-имя объекта. \en Get a hash name of the object. + SimpleName PropName() const; + /// \ru Равны ли объекты? \en Are objects equal? \~ + bool IsSame( const MtGeomArgument & r ) const { + return ( (propItem == r.propItem) && (propName == r.propName) && (item == r.item) && (hash == r.hash) ); + } + /// \ru Равны ли ссылкпи на объект модели? \en Are the references to the model object equal? \~ + bool IsSameItemReference( const MtGeomArgument & r ) const { // MtItemReference + return ( (hash == r.hash) && (item == r.item) && (root == r.root) ); + } + /// \ru Оператор равенства объектов. \en Objects equality operator. \~ + bool operator == ( const MtGeomArgument & ) const; + /// \ru Оператор копирования. \en Copy operator. \~ + MtGeomArgument & operator = ( const MtGeomArgument & ); + +KNOWN_OBJECTS_RW_REF_OPERATORS( MtGeomArgument ) // Serializing into a file format +}; // MtGeomArgument + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрическое ограничение. + \en Geometric constraint. \~ + \details \ru Этот класс представляет все виды ограничений, включая геометрические и + размерные отношения между объектами модели. + \en This class represents all kinds of constraints of assembly, including + geometrical and dimensional relationships between the model objects. \~ + \ingroup Model_Items +*/ +//--- +class MATH_CLASS MtGeomConstraint +{ +private: + const ItConstraintItem * m_cItem; ///< \ru Указатель на реализацию геометрического ограничения. \en Pointer to geometric constraint implementation. \~ + std::vector m_arguments; ///< \ru Аргументы геометрического ограничения. \en The arguments of geometric constraint. \~ + SPtr m_mesh; ///< \ru Объект для демонстрации геометрического ограничения. \en The draw object of geometric constraint. \~ + +public: + MtGeomConstraint( const MtGeomConstraint & ); + ~MtGeomConstraint(); + +public: + /// \ru Возвращает true, если ограничение не действительно. \en Return true if the constraint is invalid. + bool IsNull() const { return m_cItem == NULL; } + /// \ru Тип сопряжения (геометрического ограничения). \en Type of geometric constraint. + MtMateType ConstraintType() const; + /// \ru Текущее значение размера. \en Current value of the dimension. + double DimValue() const; + /// \ru Создать полигональный объект для отображения геометрических ограничений. \en Create a polygonal object for visualization. + bool CreateMesh( const MbAssembly & assem, const MbStepData & stepData, const MbFormNote & note, double meshUnit, uint32 color ); + /// \ru Выдать указатель на объект для демонстрации геометрического ограничения. \en Get a pointer to draw object of geometric constraint. + const MbItem * GetMesh() const { return m_mesh.get(); } + + // \ru Объявление оператора присваивания. \en Declaration of the assignment operator. + MtGeomConstraint & operator = (const MtGeomConstraint & arg ); + +protected: + friend class MbConstraintSystem; + friend class MtConstraintIter; + /// \ru Выдать указатель на реализацию геометрического ограничения. \en Get a pointer to geometric constraint implementation. \~ + const ItConstraintItem * ConstraintItem() const { return m_cItem; } + + MtGeomConstraint( const ItConstraintItem * cItem, const MtGeomArgument & a1, const MtGeomArgument & a2 ); + MtGeomConstraint( const MbConstraintSystem &, const ItConstraintItem * cItem ); +}; // MtGeomConstraint + + +//---------------------------------------------------------------------------------------- +/// \ru Итератор обходящий ограничения сборки. \en Iterator traversing assembly constraints. +//--- +class MATH_CLASS MtConstraintIter +{ +private: + CNodeIterator * m_cIter; + const MbConstraintSystem * m_gcSystem; + +public: + MtConstraintIter(); + MtConstraintIter( const MtConstraintIter & ); + MtConstraintIter & operator = ( const MtConstraintIter & ); + ~MtConstraintIter(); + +public: + MtGeomConstraint Get() const; + MtConstraintIter & Set( const MbConstraintSystem *, CNodeIterator & ); + const MtConstraintIter & Next(); + bool EqualTo( const MtConstraintIter & ) const; + +public: + //operator CNodeIterator& () { return *impl; } + MtGeomConstraint operator*() const { return Get(); } + // prefix operator + const MtConstraintIter & operator++() { return Next(); } + bool operator ==( const MtConstraintIter & iter ) const { return EqualTo( iter ); } + bool operator !=( const MtConstraintIter & iter ) const { return !EqualTo( iter ); } + +}; // MtConstraintIter + + +//---------------------------------------------------------------------------------------- +/// \ru Обработчик события, связанные с решением сборки. \en The event handles related to solving the assembly. +//--- +struct MATH_CLASS ItAssemblyReactor +{ +public: + /// \ru Захватить сборкой объект для дальнейшей работы. \en Capture the reactor instance by the assembly for further work. + virtual void Capture( const MbAssembly * ) = 0; + /// \ru Отпустить сборкой объект, прекратить работать с ним. \en Release this instance by the assembly, stop working with it. + virtual void Release() = 0; + /// \ru Геометрический решатель не пытался удовлетворить ограничение. \en This called when geometric solver failed to try for constraint satisfaction. + virtual void EvaluationFailed( const MbAssembly * ) const {} + /// \ru Геометрический решатель нашел новую позицию под-объекта сборки. \en The geometric solver found a new position of a constrained sub-object belonging the assembly. + virtual void PositionChanged( const MbAssembly *, const MbItem * /*subItem*/ ) const {} + +protected: + ~ItAssemblyReactor() {} +}; // ItAssemblyReactor + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Интерфейс для системы ограничения импорта сборки из приложения. + \en The user defined interface for import constraint system of an assembly from CAD application. +*/ +//--- +struct MATH_CLASS ItAssemblyImportData +{ +protected: + ~ItAssemblyImportData() {} + +public: + /// \ru Импорт системы ограничений сборки. \en Import a constraint system of the assembly. + virtual bool ImportCSystem( const MbAssembly &, GCM_system & ) const = 0; + /// \ru Получить дескриптор элемента сборки в системе ограничений. \en Get a descriptor of assembly sub-item which used in the constraint system. + virtual MtGeomId GeomId( const MbAssembly &, const MbItem * ) const = 0; + /// \ru Получить объект модели, являющийся аргументом геометрического ограничения. \en Get the model object that is the argument of the geometric constraint. + virtual MtGeomArgument GeomSubItem( const MtArgument & ) const { return MtGeomArgument(); } + /// \ru Получить объект модели, являющийся аргументом геометрического ограничения. \en Get the model object that is the argument of the geometric constraint. + virtual MtGeomArgument GeomSubItem( MtGeomId ) const { return MtGeomArgument(); } +}; //ItAssemblyImportData + +//---------------------------------------------------------------------------------------- +/// \ru Оператор равенства объектов. \en Objects equality operator. \~ +//--- +inline bool MtGeomArgument::operator == ( const MtGeomArgument & r ) const +{ + if ( propItem != r.propItem ) + return false; + if ( propName != r.propName ) + return false; + if ( (item == r.item) && (hash == r.hash) ) + return true; + if ( (hash == r.hash) && (root == r.root) ) + return true; + return false; +} + +//---------------------------------------------------------------------------------------- +/// \ru Оператор копирования. \en Copy operator. \~ +//--- +inline MtGeomArgument & MtGeomArgument::operator = ( const MtGeomArgument & arg ) +{ + propItem = arg.propItem; + propName = arg.propName; + hash = arg.hash; + item = arg.item; + root = arg.root; + return *this; +} + +#endif // __CONSTRAINT_H diff --git a/C3d/Include/constraint_item.h b/C3d/Include/constraint_item.h new file mode 100644 index 0000000..916663d --- /dev/null +++ b/C3d/Include/constraint_item.h @@ -0,0 +1,255 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двухмерные геометрические ограничения для объектов C3D-модели + \en 2D-constraints between geometric objects of C3D-model. + \~ + \attention \ru Данный файл содержит типы данных и вызовы, предназначенные для тестирования + и отладки, поэтому могут быть изменены или удалены из API C3D Kernel без + предупреждения. Для применения функциональности решателя двухмерных ограничений + рекомендуется реализация собственного модуля встраивания в приложение на + основе интерфейсов gce_api.h и gce_types.h. + + \en This file contains data types and calls for testing and debugging, so they + can be modified or removed from the C3D Kernel API without notice. To use + the 2D constraint solver, it is recommended to implement a custom embedding module + based on th interfaces gce_api.h and gce_types.h. + \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONSTRAINT_ITEM_H +#define __CONSTRAINT_ITEM_H + + +#include +#include +#include +#include +#include +#include + + +//---------------------------------------------------------------------------------------- +/// \ru Кодировка геометрического примитива \en Geometric primitive encoding +//--- +struct GeomCode +{ + enum Type + { + // \ru Словарь примитивов плоскости (соответствует словарю решателя; типы геометрических подмножеств плоскости) \en Plane primitive dictionary (corresponds to the solver dictionary; types of geometric subsets of plane) + NULL_GEOM, ///< \ru пустое геометрическое множество \en empty geometric set + POINT, ///< \ru Точка: элемент плоскости \en Point: element of the plane + PROPER_POINT = POINT, ///< \ru Контрольная точка по индексу \en Control point by index + LINE, ///< \ru Прямая \en Line + CIRCLE, + ELLIPSE, + SPLINE, + PARAMETRIC, ///< \ru Неподвижная параметрическая кривая \en Fixed parametric curve + + // \ru Дифференциация подтипов точки \en Differentiation of subtypes of the point + FIRST_END, ///< \ru Начальная точка кривой \en Start point of a curve + SECOND_END, ///< \ru Конечная точка кривой \en End point of a curve + MIDDLE_POINT, ///< \ru Средняя точка кривой \en Middle point of a curve + CENTRE_POINT, ///< \ru Центральная точка эллипса \en Central point of an ellipse + SPLINE_POINT, ///< \ru Контрольная точка сплайна по индексу \en Control point of a spline by index + Q1_POINT, ///< \ru Квадрантная точка на 3 ч \en Quadrant point at 3 o'clock + Q2_POINT, ///< \ru Квадрантная точка на 12 ч \en Quadrant point at 12 o'clock + Q3_POINT, ///< \ru Квадрантная точка на 9 ч \en Quadrant point at 9 o'clock + Q4_POINT, ///< \ru Квадрантная точка на 6 ч \en Quadrant point at 6 o'clock + + // \ru Размеры \en Sizes + /* + LINEAR_DIM, + ANGULAR_DIM, + */ + }; + Type type; ///< \ru Тип геометрии объекта модели (из словаря типов, поддерживаемых решателем) \en Type of geometry of a model object (from dictionary of types supported by the solver) + size_t index; ///< \ru Номер примитива для данного объекта модели (кодируется в индивидуальных адаптерах) \en Number of a primitive for a given object of the model (encoded in individual adapters) + + GeomCode( GeomCode::Type t ) : type(t),index(0) {} + bool operator != ( const GeomCode & g ) const { return type != g.type || index != g.index; } + GeomCode & operator = ( const Type & gType ) { type = gType; index = 0; return *this; } +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Аргумент ограничения (или геометрический примитив решателя) \en Argument of constraint (or geometric primitive of the solver) +/**\ru Этот тип: + 1) Кодирует информацию о геометрии, которая является аргументом для ограничений; + 2) соответствует одному из примитивных типов словаря решателя + + Словарь примитивов решателя: точка, прямая, окружность, эллипс, сплайн. + \en This type: + 1) Encodes the information about the geometry which is the argument for constraints; + 2) Corresponds to one of primitive types of the solver dictionary + + The solver primitives dictionary: point, line, circle, ellipse, spline. \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +class MATH_CLASS GcArgument { +public: + typedef MbRefItem * ParObject; ///< \ru Ассоциированный тип: владелец примитива, которого он содержит, как свою составную часть \en Associated type: primitives owner which contain the primitive as a component + +public: + GeomCode m_geom; ///< \ru Тип геометрии объекта модели (из словаря типов, поддерживаемых решателем) \en Type of geometry of a model object (from dictionary of types supported by the solver) + c3d::RefItemSPtr m_item; ///< \ru Объект модели \en The model object + +public: + GcArgument() : m_geom(GeomCode::NULL_GEOM), m_item() {} + GcArgument( GeomCode type, MbRefItem & item ) : m_geom(type), m_item(&item) {} + GcArgument( const GcArgument & ag ) : m_geom(ag.m_geom), m_item(ag.m_item) {} + GcArgument & operator = ( const GcArgument & g ) { m_geom = g.m_geom; m_item = g.m_item; return *this; } + bool operator != ( const GcArgument & g ) const { return m_item.get() != g.m_item.get() && m_geom != g.m_geom; } +}; + +//---------------------------------------------------------------------------------------- +// +//--- +inline GcArgument::ParObject Owner( GcArgument & g ) { return g.m_item; } +inline GcArgument::ParObject Owner( const GcArgument & g ) { return g.m_item; } + +//---------------------------------------------------------------------------------------- +/// \ru Параметры размерного ограничения \en Parameters of size constraint +//--- +struct DimParameters +{ + double dimValue; + double dirAngle; ///< \ru Угол для направленного размера \en Angle for a directed size +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Элементарное ограничение \en Elementary constraint +/**\ru Элементарное ограничение соответствует типам ограничений из словаря решателя и не более того. + Ограничения более сложных типов описываются набором классов MbConstraint. + \en Elementary constraint corresponds to the types of constraints from the dictionary of the solver and nothing more. + Constraints of more complex types are described by a set of classes MbConstraint. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +class MATH_CLASS MbConstraint +{ +public: + typedef GcArgument Argument; ///< \ru Тип аргумента ограничения \en Type of argument of the constraint + typedef std::vector arg_list; + typedef arg_list::const_iterator arg_iter; + typedef std::pair arg_iter_pair; + static const Argument null_arg; + +private: + constraint_type m_type; ///< \ru Тип ограничения из словаря решателя \en Type of the argument of the solver dictionary + arg_list m_args; ///< \ru Аргументы ограничения (примитивы из словаря решателя) \en Arguments of the constraint (primitives from the solver dictionary) + DimParameters m_pars; ///< \ru Параметры размера (можно считать тоже аргументом, но представлен другим типом) \en Parameters of size (it can be considered as an argument but it is represented by another type) + +public: + MbConstraint( constraint_type, const Argument &, const Argument & ); // \ru Бинарное ограничение \en Binary constraint + MbConstraint( const MbConstraint & ); + +public: + const Argument & GetGeom( size_t nb ) const { --nb; return nb < m_args.size() ? m_args[nb] : null_arg; } + constraint_type Type() const { return m_type; } + arg_iter_pair Arguments() const { return arg_iter_pair( m_args.begin(), m_args.end() ); } + + /* + bool operator < ( const MbConstraint & c ) const; + bool operator == ( const MbConstraint & c ) const; + */ + +public: + MbConstraint & operator = ( const MbConstraint & ); +}; + + +//---------------------------------------------------------------------------------------- +/// \ru Формирователь модели в решателе \en Generator of a model in the solver +//--- +/* struct GcFormer +{ + // \ru Геометрические объекты \en Geometric objects + virtual bool Point( const GcArgument & ) = 0; + virtual bool Line( const GcArgument & ) = 0; + virtual bool LineSeg( const GcArgument &, const GcArgument & ) = 0; + virtual bool Circle( const MbRefItem &, const MbCartPoint &, double ) = 0; + virtual bool Circle( const GcArgument & ) = 0; + + // \ru Геометрические ограничения \en Geometric constraints + virtual bool Coincidence( const GcArgument &, const GcArgument & ) = 0; + virtual bool Incidence( const GcArgument &, const GcArgument & ) = 0; + virtual bool Vertical( const GcArgument &, const GcArgument & ) = 0; + virtual bool Horizontal( const GcArgument &, const GcArgument & ) = 0; + + // \ru Размерные ограничения \en Dimensional constraints + virtual bool LinearDimension( const MbConstraint & ) = 0; +}; +*/ + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Ограничение модели \en Model constraints +// +////////////////////////////////////////////////////////////////////////////////////////// + +class MbConstraintItem: public TapeBase + , public MtRefItem +{ + MbConstraint m_arg; + +public: + MbConstraintItem(); + MbConstraintItem( const MbConstraint & c ) : MtRefItem(), m_arg(c) {} + constraint_type GceType() const { return m_arg.Type(); } + const MbConstraint & GceConstraint() const { return m_arg; } + + virtual ClassDescriptor GetClassDescriptor( const VersionContainer & ) const + { + C3D_ASSERT_UNCONDITIONAL( false ); // Неполная реализация класса + return ClassDescriptor( ::pureName(typeid(*this).name()), Math::MathID() ); + } +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Размерное ограничение \en Dimensional constraint +// +////////////////////////////////////////////////////////////////////////////////////////// + +class MbDimensional: public MbConstraintItem +{ + MbCartPoint legendPos; ///< \ru Положение размерной надписи в ЛСК размера \en Position of a dimension legend in LCS of the dimension + +private: + /// \ru Выдать ЛСК размера \en Get LCS of the dimension + virtual void GetPlacement( MbPlacement & ) const; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Система геометрических ограничений \en Geometric constraints system +// +////////////////////////////////////////////////////////////////////////////////////////// + +class MATH_CLASS MbConstraintSystem2D +{ + typedef SPtr ConstraintPtr; + std::vector myConstraints; + +public: + MbConstraintSystem2D(); + ~MbConstraintSystem2D(); + +public: + void AddConstraint( SPtr ); +}; + + +#endif // __CONSTRAINT_ITEM_H + + +// eof \ No newline at end of file diff --git a/C3d/Include/contour_combine.h b/C3d/Include/contour_combine.h new file mode 100644 index 0000000..8885813 --- /dev/null +++ b/C3d/Include/contour_combine.h @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Нахождение пересечений двух областей. + \en Calculation of intersection of two regions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONTOUR_COMBINE_H +#define __CONTOUR_COMBINE_H + +#include +#include + +class MATH_CLASS MbCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Результат пересечения кривых. + \en The curves intersection result. \~ + \details \ru Результат пересечения двух областей кривых. + \en The result of two curves' regions intersection. \~ + \ingroup Algorithms_2D +*/ +// --- +enum MbeIntLoopsResult { + ilr_error = -1, ///< \ru Ошибка! Кривые не замкнуты или имеют самопересечения. \en Error! Curves are not closed or have self-intersections. + ilr_notIntersect = 0, ///< \ru Области под кривыми не пересекаются (массив кривых пересечения пуст). \en Regions of curves don't have intersections (intersection curve array is empty). + ilr_firstCurve = 1, ///< \ru Пересечением областей является первая кривая (массив кривых пересечения пуст). \en The intersection of regions is the first curve (intersection curve array is empty). + ilr_secondCurve = 2, ///< \ru Пересечением областей является вторая кривая (массив кривых пересечения пуст). \en The intersection of regions is the second curve (intersection curve array is empty). + ilr_success = 3, ///< \ru Произвольное пересечение (одна и более кривых в массиве кривых пересечения). \en An arbitrary intersection (one or more curves in intersection curve array). +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Найти пересечение двух кривых. + \en Calculate two curves intersection. \~ + \details \ru Найти пересечение областей двух замкнутых кривых. + \en Calculate two closed curves' regions intersection. \~ + \param[in] iCheck - \ru Признак проверки кривых на касание вершин. + \en Attribute of check of curves for vertices tangency. \~ + \param[in] loop1 - \ru Первая замкнутая кривая. + \en The first closed curve. \~ + \param[in] bOrient1 - \ru Ориентация первой замкнутой кривой:\n + true - ее областью считаем внутренность,\n + false - внешность. + \en The first closed curve orientation:\n + true - interior is considered to be the curve's region,\n + false - exterior is the curve's region. \~ + \param[in] loop2 - \ru Вторая замкнутая кривая. + \en The second closed curve. \~ + \param[in] bOrient2 - \ru Ориентация второй замкнутой кривой:\n + true - ее областью считаем внутренность,\n + false - внешность. + \en The second closed curve orientation:\n + true - interior is considered to be the curve's region,\n + false - exterior is the curve's region. \~ + \param[out] intLoops - \ru Массив кривых пересечения. + \en Intersection curve array. \~ + \attention \ru Устаревшая функция. + \en An obsolete function. \~ + \return \ru Код результата пересечения. + \en Intersection result code. \~ + \ingroup Algorithms_2D +*/ +// --- +DEPRECATE_DECLARE MATH_FUNC ( MbeIntLoopsResult ) BooleanIntLoops( const MbCurve & loop1, bool bOrient1, + const MbCurve & loop2, bool bOrient2, + RPArray & intLoops ); + +#endif // __CONTOUR_COMBINE_H \ No newline at end of file diff --git a/C3d/Include/contour_graph.h b/C3d/Include/contour_graph.h new file mode 100644 index 0000000..993e2bf --- /dev/null +++ b/C3d/Include/contour_graph.h @@ -0,0 +1,910 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение контуров. + \en Contours construction. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONTOUR_GRAPH_H +#define __CONTOUR_GRAPH_H + + +#include +#include + + +class MATH_CLASS MpEdge; +class MATH_CLASS ProgressBarWrapper; +class IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вершина. + \en Vertex. \~ + \details \ru Вершина цикла. Соединяет два ребра цикла - предыдущее и следующее.\n + \en Vertex of a loop. Connects two edges of a loop - the previous and the next one.\n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MpVertex : public TapeBase { +private: + MbCartPoint point; ///< \ru Точка. \en A point. + MpEdge * begEdge; ///< \ru Предыдущее ребро. \en The previous edge. + MpEdge * endEdge; ///< \ru Последующее ребро. \en The next edge. + +public: + /// \ru Конструктор по точке. \en Constructor by point. + MpVertex( const MbCartPoint & initP ) + : point( initP ) + , begEdge( NULL ) + , endEdge( NULL ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~MpVertex(); + + /**\ru \name Операции с вершиной. + \en \name Operations on vertex. + \{ */ + + /// \ru Выдать декартову точку вершины. \en Get the Cartesian point of a vertex. + const MbCartPoint & GetCartPoint() const { return point; } + /// \ru Выдать декартову точку вершины. \en Get the Cartesian point of a vertex. + void GetCartPoint( MbCartPoint & cp ) const { cp = point; } + /// \ru Установить декартову точку вершины. \en Set the Cartesian point of a vertex. + void SetCartPoint( MbCartPoint & cp ) { point = cp; } + /** \} */ + /**\ru \name Операции с указателями на ребра. + \en \name Operations on pointers to edges. + \{ */ + /// \ru Изменить предыдущее ребро. \en Change the previous edge. + void SetBegEdge( MpEdge * edge ) { begEdge = edge; } + /// \ru Изменить последующее ребро. \en Change the next edge. + void SetEndEdge( MpEdge * edge ) { endEdge = edge; } + /// \ru Предыдущее ребро. \en The previous edge. + MpEdge * GetBegEdge() const { return begEdge; } + /// \ru Последующее ребро. \en The next edge. + MpEdge * GetEndEdge() const { return endEdge; } + /** \} */ + /**\ru \name Операции преобразования. + \en \name Transformation operations. + \{ */ + + /** \brief \ru Преобразовать. + \en Transform. \~ + \details \ru Преобразовать в соответствии с матрицей.\n + \en Transform according to the matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ); + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by a vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move( const MbVector & to ); + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector determining the rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + /** \} */ + +private: + MpVertex( const MpVertex & ); // \ru Не реализовано \en Not implemented + void operator = ( const MpVertex & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MpVertex ) +}; // MpVertex + +IMPL_PERSISTENT_OPS( MpVertex ) + +//------------------------------------------------------------------------------ +/** \brief \ru Ребро. + \en Edge. \~ + \details \ru Ребро цикла.\n + \en A loop edge.\n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MpEdge : public TapeBase { +public : + const MbCurve * baseCurve; ///< \ru Базовая кривая. \en The base curve. + ptrdiff_t name; ///< \ru Имя базовой кривой. \en The base curve name. + double tBeg; ///< \ru Параметр начала ребра. \en The edge start parameter. + double tEnd; ///< \ru Параметр конца ребра. \en The edge end parameter. + bool sense; ///< \ru Признак совпадения направления с кривой. \en Flag of coincidence of direction with the curve. + uint type; ///< \ru Тип кривой. \en Curve type. + MpVertex * begVertex; ///< \ru Вершина-начало. \en The start vertex. + MpVertex * endVertex; ///< \ru Вершина-конец. \en The end vertex. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по кривой.\n + \en Constructor by curve.\n \~ + \param[in] c - \ru Базовая кривая. + \en Base curve. \~ + \param[in] t1 - \ru Начальный параметр ребра. + \en The edge start parameter. \~ + \param[in] t2 - \ru Конечный параметр ребра. + \en The edge end parameter. \~ + \param[in] s - \ru Признак совпадения направления с кривой. + \en Flag of coincidence of direction and the curve. \~ + */ + MpEdge( const MbCurve * c, double t1, double t2, bool s ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по кривой.\n + \en Constructor by curve.\n \~ + \param[in] c - \ru Базовая кривая. + \en Base curve. \~ + \param[in] s - \ru Признак совпадения направления с кривой. + \en Flag of coincidence of direction and the curve. \~ + */ + MpEdge( const MbCurve * c, bool s ); + + /// \ru Копирующий конструктор. \en Copy-constructor. + MpEdge( const MpEdge & ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор ребра с нулевой базовой кривой.\n + \en Constructor of edge with null base curve.\n \~ + \param[in] t1 - \ru Начальный параметр ребра. + \en The edge start parameter. \~ + \param[in] t2 - \ru Конечный параметр ребра. + \en The edge end parameter. \~ + \param[in] s - \ru Признак совпадения направления с кривой. + \en Flag of coincidence of direction and the curve. \~ + \param[in] n - \ru Имя базовой кривой. + \en The base curve name. \~ + \param[in] t - \ru Тип кривой. + \en A curve type. \~ + */ + MpEdge( double t1, double t2, bool s, ptrdiff_t n, uint t ); + + /// \ru Деструктор. \en Destructor. + virtual ~MpEdge(); + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + /// \ru Выдать кривую, по которой проходит ребро. \en Get the curve the edge passes through. + const MbCurve * GetCurve() const { return baseCurve; } + /// \ru Имя базовой кривой. \en The base curve name. + ptrdiff_t GetName() const { return name; } + /// \ru Выдать направление по отношению к кривой. \en Get the direction relative to the curve. + bool GetSense() const { return sense; } + /// \ru Выдать вершину-начало. \en Get the start vertex. + MpVertex * GetBegVertex() const { return begVertex; } + /// \ru Выдать вершину-конец. \en Get the end vertex. + MpVertex * GetEndVertex() const { return endVertex; } + /// \ru Начальный параметр. \en Get the start parameter. + double GetTBeg() const { return tBeg; } + /// \ru Конечный параметр. \en End parameter. + double GetTEnd() const { return tEnd; } + + /// \ru Выдать декартову точку вершины-начала. \en Get the Cartesian point of the start vertex. + void GetBegPoint( MbCartPoint & cp ) const; + /// \ru Выдать декартову точку вершины-конца. \en Get the Cartesian point of the end vertex. + void GetEndPoint( MbCartPoint & cp ) const; + /// \ru Выдать касательный вектор в начальной вершине. \en Get the tangent vector at the start point. + void GetBegTangent( MbDirection & tan ) const; + /// \ru Выдать касательный вектор в конечной вершине. \en Get the tangent vector at the end vertex. + void GetEndTangent( MbDirection & tan ) const; + /// \ru Выдать кривизну в начальной вершине. \en Get the curvature at the start point. + double GetBegCurvature() const; + /// \ru Выдать кривизну в конечной вершине. \en Get the curvature at the end point. + double GetEndCurvature() const; + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + /// \ru Установить имя базовой кривой. \en Set name of the base curve. + void SetName( ptrdiff_t n ) { name = n; } + /// \ru Установить направление по отношению к кривой. \en Set the direction relative to the curve. + void SetSense( bool s ) { sense = s; } + /// \ru Установить вершину-начало. \en Set the start vertex. + void SetBegVertex( MpVertex * vert ) { begVertex = vert; } + /// \ru Установить вершину-конец. \en Set the end vertex. + void SetEndVertex( MpVertex * vert ) { endVertex = vert; } + /// \ru Установить начальный параметр. \en Set the start parameter. + void SetTBeg( double t ) { tBeg = t; } + /// \ru Установить конечный параметр. \en Set the end parameter. + void SetTEnd( double t ) { tEnd = t; } + + /// \ru Изменить ориентацию. \en Change the orientation. + void Reverse(); + /// \ru Создать кривую. \en Create a curve. + MbCurve * MakeCurve() const; + /** \} */ + /**\ru \name Операции преобразования. + \en \name Transformation operations. + \{ */ + + /** \brief \ru Преобразовать. + \en Transform. \~ + \details \ru Преобразовать в соответствии с матрицей.\n + \en Transform according to the matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ); + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by a vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move( const MbVector & to ); + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector determining the rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + /** \} */ + +private: + void operator = ( const MpEdge & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MpEdge ) +}; // MpEdge + +IMPL_PERSISTENT_OPS( MpEdge ) + +//------------------------------------------------------------------------------ +/** \brief \ru Цикл. + \en Loop. \~ + \details \ru Цикл. Набор ребер.\n + \en Loop. Set of edges.\n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MpLoop : public TapeBase { +public : + PArray edgeList; ///< \ru Список ребер. \en List of edges. + bool orientation; ///< \ru Ориентация цикла. \en Loop orientation. + int mode; ///< \ru Направление построения. \en Construction direction. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по ребру и направлению построения.\n + \en Constructor by edge and the direction of construction.\n \~ + \param[in] initEdge - \ru Ребро. + \en Edge. \~ + \param[in] m - \ru Направление построения цикла: + если m > 0 - цикл строится против часовой стрелки, + если m < 0 - по часовой стрелке. + \en Direction of loop construction: + if m > 0 - the loop is constructed counterclockwise, + if m < 0 - clockwise. \~ + */ + MpLoop( MpEdge * initEdge, int m ); + + /// \ru Копирующий конструктор. \en Copy-constructor. + MpLoop( const MpLoop & ); + + /// \ru Деструктор. \en Destructor. + virtual ~MpLoop(); + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Количество ребер. \en Count of edges. + ptrdiff_t GetEdgesCount() const { return edgeList.Count(); } + + /** \brief \ru Ребро по индексу. + \en Edge by index. \~ + \details \ru Ребро по его индексу. Без проверки корректности индекса.\n + \en Edge by its index. Without check for index correctness.\n \~ + \param[in] index - \ru Индекс ребра. + \en An edge index. \~ + */ + MpEdge * GetEdge( ptrdiff_t index ) const { return edgeList[index]; } + /// \ru Выдать последнее ребро. \en Get the last edge. + MpEdge * GetEdge() const; + + /// \ru Дать ориентацию. \en Get the orientation. + bool GetOrientation() const { return orientation; } + /// \ru Направление построения. \en Construction direction. + int GetMode() const { return mode; } + /// \ru Выдать массив вершин. \en Get vertex array. + void GetVerticesArray( RPArray & vertices ) const; + /// \ru Выдать массив кривых. \en Get curve array. + void GetCurvesArray ( RPArray & curves ) const; + /// \ru Выдать массив кривых. \en Get curve array. + void SetCurvesArray ( RPArray & curves ); + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Добавить ребро. \en Add an edge. + void AddEdge( MpEdge * edge ) { edgeList.Add(edge); } + /// \ru Удалить последнее ребро. \en Delete the last edge. + void DeleteEdge(); + + /** \brief \ru Удалить ребро по индексу. + \en Delete an edge by index. \~ + \details \ru Удалить ребро по его индексу. Без проверки корректности индекса.\n + \en Delete an edge by its index. Without check for index correctness.\n \~ + \param[in] index - \ru Индекс ребра. + \en An edge index. \~ + */ + void DeleteEdge( ptrdiff_t index ) { edgeList.RemoveInd(index); } + + /// \ru Установить ориентацию. \en Set the orientation. + void SetOrientation( bool s ) { orientation = s; } + + /** \brief \ru Установить направление обхода. + \en Set the traverse direction. \~ + \details \ru Установить направление обхода цикла.\n + \en Set the direction of traversal of the loop.\n \~ + \param[in] m - \ru Направление обхода.\n + Имеет значение знак числа m:\n + если m > 0, то обход против часовой стрелки,\n + если m < 0, то по часовой стрелки. + \en The traversal direction.\n + Has a value of sign of number m:\n + if m > 0, then traversal is counterclockwise,\n + if m < 0, then it is clockwise. \~ + */ + void SetMode( int m ) { mode=m; } + + /// \ru Изменить ориентацию ребра. \en Change the edge orientation. + void Reverse() { orientation = !orientation; } + /// \ru Построить вершины. \en Construct vertices. + void CreateVertices(); + /// \ru Создать контур по циклу. \en Create a contour by the loop. + MbContour * MakeContour() const; + + /** \} */ + /**\ru \name Операции преобразования. + \en \name Transformation operations. + \{ */ + + /** \brief \ru Преобразование. + \en Transformation. \~ + \details \ru Преобразование в соответствии с матрицей.\n + \en Transform according to matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ); + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by a vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move( const MbVector & to ); + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector determining the rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + /** \} */ + +private: + void operator = ( const MpLoop & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MpLoop ) +}; // Loop + +IMPL_PERSISTENT_OPS( MpLoop ) + +//------------------------------------------------------------------------------ +/** \brief \ru Граф построения контуров. + \en Contours construction graph. \~ + \details \ru Граф построения контуров.\n + Содержит список границ - циклов. + \en Contours construction graph.\n + Contains list of boundaries - loops. \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MpGraph : public TapeBase { +public : + PArray loops; ///< \ru Список границ. \en List of boundaries. + int mode; ///< \ru Направление обхода. \en Traversal direction. + ptrdiff_t nameCount; ///< \ru Количество имен ребер. \en Edge names count. + PArray unusedEdges; ///< \ru Список ребер. \en List of edges. + +private: + VERSION version; ///< \ru Версия чтения. // BUG_57224 \en Read version. // BUG_57224 + +public: + MpGraph(); ///< \ru Конструктор. \en Constructor. + MpGraph( MpLoop * init ); ///< \ru Конструктор по циклу. \en Constructor by loop. + MpGraph( RPArray & init ); ///< \ru Конструктор по набору циклов. \en Constructor by a set of loops. + MpGraph( const MpGraph & ); ///< \ru Копирующий конструктор. \en Copy-constructor. + virtual ~MpGraph(); ///< \ru Деструктор. \en Destructor. + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Количество границ. \en Count of boundaries. + size_t GetLoopsCount() const { return loops.Count(); } + + /** \brief \ru Цикл по индексу. + \en Loop by index. \~ + \details \ru Цикл по индексу без проверки индекса.\n + \en Loop by index without check of index.\n \~ + \param[in] index - \ru Индекс цикла. + \en The loop index. \~ + */ + MpLoop * GetLoop( size_t index ) const { return loops[index]; } + + /// \ru Направление обхода. \en Traversal direction. + int GetMode() const { return mode; } + + /** \brief \ru Выдать точку. + \en Get the point. \~ + \details \ru Выдать точку для сборки графа.\n + \en Get the point for graph building.\n \~ + \param[in] curveList - \ru Набор кривых (без совпадений) для создания графа. + \en A set of curves (without coincidences) for creating the graph. \~ + \param[in] cross - \ru Набор точек пересечения кривых из curveList. + \en Set of intersection points of curves from curveList. \~ + \param[out] p - \ru Результат - двумерная точка. + \en The result is a two-dimensional point. \~ + */ + bool GetPointIn( const RPArray & curveList, SArray & cross, MbCartPoint & p, + double epsilon = Math::LengthEps*c3d::METRIC_DELTA ) const; + + /** \brief \ru Выдать использованные кривые. + \en Get used curves. \~ + \details \ru Выдать использованные кривые и переименовать в соответствии с последними.\n + \en Get used curves and rename in compliance with the last ones.\n \~ + \param[in] curveList - \ru Набор кривых. + \en Set of curves. \~ + \param[out] usedCurves - \ru Результат - использованные кривые. + \en The result are the used curves. \~ + */ + void GetUsedCurves( const RPArray & curveList, RPArray & usedCurves ); + + /** \brief \ru Ориентация цикла по индексу. + \en The orientation of a loop by its index. \~ + \details \ru Ориентация цикла по индексу без проверки индекса.\n + \en The orientation of loop by its index without check of index.\n \~ + \param[in] i - \ru Индекс цикла. + \en The loop index. \~ + \return \ru Ориентацию цикла. + \en The loop orientation. \~ + */ + bool GetLoopOrientation( size_t i ) const { return loops[i]->orientation; } + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Добавить новую границу грани. \en Add a new boundary of the face. + void AddLoop( MpLoop * newLoop ); + /// \ru Добавить новую границу грани в начало списка границ. \en Add a new boundary of the face to the beginning of face list. + void InsertLoop( MpLoop * newLoop ); + /// \ru Установить направление обхода. \en Set the traverse direction. + void SetMode( int m ) { mode = m; } + /// \ru Выдать контуры циклов. \en Get loops' contours. + void MakeContours( RPArray & contours ) const; + + /** \brief \ru Запомнить неиспользованные ребра. + \en Store unused edges. \~ + \details \ru Запомнить неиспользованные ребра, установив им имена.\n + \en Store unused edges giving names for them.\n \~ + \param[in] curveList - \ru Список неиспользованных кривых для установки имен. + \en The list of unused curves for setting the names. \~ + \param[in] g - \ru Граф для поиска неиспользованных ребер.\n + Если в нем или в его массиве неиспользованных ребер + нашлось ребро с только что установленным именем, + то оно запоминается в массиве неиспользованных ребер unusedEdges.\n + \en Graph for searching unused edges.\n + If there is an edge with a name just specified + in the graph or its array of unused edges, + then it is stored in the array of unused edges unusedEdges.\n \~ + */ + void SetAllName( const RPArray & curveList, MpGraph * g ); + + /** \brief \ru Дать имена ребрам. + \en Give names to edges. \~ + \details \ru Дать имена ребрам по списку кривых.\n + \en Give names to edges by the list of curves.\n \~ + \param[in] curveList - \ru Список кривых для именования. + \en The list of curves for naming. \~ + */ + void SetEdgeName( const RPArray & curveList ); + + /** \brief \ru Определить ориентацию контуров. + \en Determine the contours' orientation. \~ + \details \ru Определить ориентацию контуров по их вложенности.\n + \en Determine the contours' orientation by its inclusion.\n \~ + \param[in] contourArray - \ru Список контуров, по которым строился граф. + \en List of contours the graph is built for. \~ + */ + void SetLoopsOrientation( const RPArray & contourArray ); + + /** \brief \ru Перевести параметры ребер в параметры кривых. + \en Convert edges' parameters to curves' parameters. \~ + \details \ru Перевести параметры ребер в параметры кривых, + если кривые ребер нашлись в списках.\n + \en Convert parameters of edges to parameters of curves + if edges' curves are found in lists.\n \~ + \param[in] unchangeCurve - \ru Список имен кривых для изменения. + \en List of curves' names for modification. \~ + \param[in] changeCurve - \ru Список имен кривых для изменения. + \en List of curves' names for modification. \~ + \param[in] curveList - \ru Список кривых для изменения параметризации. + \en List of curves for modification of parametrization. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + */ + // \ru Изменяется параметризация только у отрезков. \en Parametrization can be modified for line segments only. + // \ru Специально для исправления ошибки BUG_57224 \en Especially to fix BUG_57224 + void ConvertEdgesParams( const SArray & unchangeCurve, const SArray & changeCurve, + const RPArray & curveList ) const; + + /** \} */ + /**\ru \name Операции преобразования. + \en \name Transformation operations. + \{ */ + + /** \brief \ru Преобразование. + \en Transformation. \~ + \details \ru Преобразование в соответствии с матрицей.\n + \en Transformation according to the matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ); + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by a vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move( const MbVector & to ); + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector determining the rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + /** \} */ + +private: + + /** \brief \ru Направление обхода цикла. + \en Loop traversal direction. \~ + \details \ru Направление обхода цикла, которому принадлежит вершина.\n + \en Traversal direction of the loop the vertex belongs to.\n \~ + \param[in] vert - \ru Вершина для поиска цикла. + \en The vertex for searching the loop. \~ + \return \ru Направление обхода.\n + Важен знак числа:\n + если > 0 - против часовой стрелки,\n + если < 0 - по часовой стрелке. + \en The traversal direction.\n + Sign of the number is significant:\n + if > 0 - counterclockwise,\n + if < 0 - clockwise. \~ + */ + int GetLoopMode( MpVertex * vert ) const; + + /** \brief \ru Выдать массив вершин. + \en Get vertex array. \~ + \details \ru Выдать массив вершин всех циклов графа.\n + \en Get vertex array of all the loops of the graph.\n \~ + \param[out] vertices - \ru Результат - массив вершин. + \en The result is a vertex array. \~ + */ + void GetVerticesArray( RPArray & vertices ) const; + + /// \ru Количество имен ребер. \en The count of edges' names. + ptrdiff_t GetNameCount() const { return nameCount; } + + /** \brief \ru Выдать имена ребер. + \en Get edges' names. \~ + \details \ru Выдать имена ребер всех циклов графа.\n + Имена складываются в массив без повторений, сортированные по возрастанию. + \en Get names of edges of all the loops of the graph.\n + Names are put to the array without duplications, sorted in the ascending order. \~ + \param[out] curveName - \ru Результат - массив имен. + \en The result is the array of names. \~ + */ + void GetEdgeName( SArray & curveName ) const; + + /** \brief \ru Ориентация ребра. + \en Edge orientation. \~ + \details \ru Ориентация ребра по его имени с учетом направления цикла.\n + \en Edge orientation by its name subject to the loop direction.\n \~ + \param[in] n0 - \ru Имя ребра. + \en The edge name. \~ + \param[out] s - \ru Ориентация ребра. + \en Edge orientation. \~ + \return \ru true, если нашли нужное ребро. + \en True if the required edge is found. \~ + */ + bool GetCurveData( ptrdiff_t n0, int & s ) const; + + /** \brief \ru Ориентация ребра. + \en Edge orientation. \~ + \details \ru Ориентация ребра по его имени без учета направления цикла.\n + \en Edge orientation by its name without taking the loop direction into account.\n \~ + \param[in] n0 - \ru Имя ребра. + \en The edge name. \~ + \param[out] s - \ru Ориентация ребра. + \en Edge orientation. \~ + \return \ru true, если нашли нужное ребро. + \en True if the required edge is found. \~ + */ + bool GetOldData ( ptrdiff_t n0, int & s ) const; + + /** \brief \ru Выдать точку. + \en Get the point. \~ + \details \ru Выдать точку для сборки графа.\n + \en Get the point for graph building.\n \~ + \param[in] vertex - \ru Начальная вершина ребра, которому соответствует кривая curve. + \en The start vertex of the edge the curve 'curve' corresponds to. \~ + \param[in] curve - \ru Кривая для расчета точки. + \en The curve for point calculation. \~ + \param[in] t - \ru Параметр на кривой. + \en A parameter on the curve. \~ + \param[out] p - \ru Результат - двумерная точка. + \en The result is a two-dimensional point. \~ + */ + void GetPoint( MpVertex * vertex, MbCurve * curve, double t, MbCartPoint & p ) const; + + void CurvesSort( const RPArray & curveList, SArray & unchangeCurve, SArray & changeCurve ) const; + +private: + void operator = ( const MpGraph & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MpGraph ) +}; // MpGraph + +IMPL_PERSISTENT_OPS( MpGraph ) + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить вершину. + \en Delete a vertex. \~ + \details \ru Удалить вершину и обнулить указатель.\n + \en Delete a vertex and set the pointer to null.\n \~ + \param[in, out] vertex - \ru Вершина для удаления. + \en A vertex to delete. \~ +*/ // --- +inline void DeleteVertex( MpVertex *& vertex ) { + delete vertex; + vertex = NULL; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить ребро. + \en Delete an edge. \~ + \details \ru Удалить ребро и обнулить указатель.\n + \en Delete an edge and set the pointer to null.\n \~ + \param[in, out] edge - \ru Ребро для удаления. + \en An edge to delete. \~ +*/ // --- +inline void DeleteEdge( MpEdge *& edge ) { + delete edge; + edge = NULL; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить цикл. + \en Delete a loop. \~ + \details \ru Удалить цикл и обнулить указатель.\n + \en Delete a loop and set the pointer to null.\n \~ + \param[in, out] loop - \ru Цикл для удаления. + \en A loop to delete. \~ +*/ // --- +inline void DeleteLoop( MpLoop *& loop ) { + delete loop; + loop = NULL; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить граф. + \en Delete a graph. \~ + \details \ru Удалить граф и обнулить указатель.\n + \en Delete a graph and set the pointer to null.\n \~ + \param[in, out] graph - \ru Граф для удаления. + \en A graph to delete. \~ +*/ // --- +inline void DeleteGraph( MpGraph *& graph ) { + delete graph; + graph = NULL; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Устранить разрывы в контуре. + \en Remove contour gaps. \~ + \details \ru Устранить разрывы в контуре. + \en Remove contour gaps. \~ + \param[in] contour - \ru Контур. + \en A contour. \~ + \param[in] accuracy - \ru Ограничение по размеру разрыва (для вставки сегмента и поиска пересечения соседей. + \en Upper gap size. \~ + \param[in] canInsert - \ru Можно ли вставлять сегменты. + \en Allow insert segments. \~ + \param[in] canReplace - \ru Можно ли заменять сегменты. + \en Allow replace segments. \~ + \return \ru true, если контур изменился. + \en true, if something have changed. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) RemoveContourGaps( MbContour & contour, // контур + double accuracy, // размер разрывов + bool canInsert, // разрешение на вставку сегментов + bool canReplace ); // разрешение на подмену сегментов + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить контуры вокруг заданной точки. + \en Create contours around the given point. \~ + \details \ru Построить контуры вокруг заданной точки. + Строится один внешний и несколько внутренних контуров с одним уровнем вложенности. + На вход не должны приходить составные кривые (контуры и ломаные). + \en Create contours around the given point. + One outer and several inner loops are constructed with single nesting level. + Do not send composite curves (contours and polygons). Lay them on the components. \~ + \param[in] curveList - \ru Список кривых для построения. + \en List of curves for construction. \~ + \param[in] p - \ru Точка, вокруг которой строятся контуры. + \en A point the contours are constructed around. \~ + \param[out] usedCurves - \ru Использованные кривые. + \en Used curves. \~ + \param[out] contourArray - \ru Результат построения - набор контуров. + \en The result of construction is a set of contours. \~ + \param[in] accuracy - \ru Погрешность определения пересечения и близости кривых. + \en The accuracy of determining the intersection of curves and proximity. \~ + \param[in] strict - \ru Если false, сборка производится с загрубленной точностью. + \en If false, the construction is performed roughly. \~ + \param[in] version - \ru Версия построения. Последняя версия Math::DefaultMathVersion(). + \en The version of construction. The last version Math::DefaultMathVersion(). \~ + \param[in] progInd - \ru Индикатора прогресса выполнения. + \en Execution progress indicator. \~ + \return \ru Граф построения контуров. + \en Contours construction graph. \~ + \warning \ru При использовании функций EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor + состояние флага strict и версия version должно использоваться одно в одном процессе обработки. + \en While using functions EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor, + a single state of 'strict' flag and version must be used in one treatment process. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MpGraph *) EncloseContoursBuilder( const RPArray & curveList, + const MbCartPoint & p, + PArray & usedCurves, + PArray & contourArray, + double accuracy, + bool strict, + VERSION version, + IProgressIndicator * progInd = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить объемлющие контуры на основе заданных кривых. + \en Construct enclosing contours on the basis of the given curves. \~ + \details \ru Построить объемлющие контуры на основе заданных кривых. + Строятся внешние и внутренние контуры с произвольным уровнем вложенности. + На вход не должны приходить составные кривые (контуры и ломаные). + \en Construct enclosing contours on the basis of the given curves. + Outer and inner loops are constructed with an arbitrary level of inclusion. + Do not send composite curves (contours and polygons). Lay them on the components. \~ + \param[in] curveList - \ru Список кривых для построения. + \en List of curves for construction. \~ + \param[out] contourArray - \ru Результат построения - набор контуров. + \en The result of construction is a set of contours. \~ + \param[in] accuracy - \ru Погрешность определения пересечения и близости кривых. + \en The accuracy of determining the intersection of curves and proximity. \~ + \param[in] strict - \ru Если false, сборка производится с загрубленной точностью. + \en If false, the construction is performed roughly. \~ + \param[in] version - \ru Версия построения. Последняя версия Math::DefaultMathVersion(). + \en The version of construction. The last version Math::DefaultMathVersion(). \~ + \param[in] progInd - \ru Индикатора прогресса выполнения. + \en Execution progress indicator. \~ + \return \ru Граф построения контуров. + \en Contours construction graph. \~ + \warning \ru При использовании функций EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor + состояние флага strict и версия version должно использоваться одно в одном процессе обработки. + \en While using functions EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor, + a single state of 'strict' flag and version must be used in one treatment process. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MpGraph *) OuterContoursBuilder( const RPArray & curveList, + PArray & contourArray, + double accuracy, + bool strict, + VERSION version, + IProgressIndicator * progInd = NULL ); + +//------------------------------------------------------------------------------ +/** \brief \ru Перестроить контуры, построенные ранее вокруг точки. + \en Reconstruct contours constructed around the point before. \~ + \details \ru Перестроить контуры, построенные ранее вокруг точки. + Функция перестраивает граф, построенный функцией EncloseContoursBuilder. + \en Reconstruct contours constructed around the point before. + The function reconstructs the graph constructed by EncloseContoursBuilder function. \~ + \param[in] curveList - \ru Список кривых для построения. + \en List of curves for construction. \~ + \param[in] graph - \ru Граф для перестроения. + \en A graph to reconstruct. \~ + \param[out] contourArray - \ru Результат построения - набор контуров. + \en The result of construction is a set of contours. \~ + \param[in] accuracy - \ru Погрешность определения пересечения и близости кривых. + \en The accuracy of determining the intersection of curves and proximity. \~ + \param[in] strict - \ru Если false, сборка производится с загрубленной точностью. + \en If false, the construction is performed roughly. \~ + \param[in] version - \ru Версия построения. Последняя версия Math::DefaultMathVersion(). + \en The version of construction. The last version Math::DefaultMathVersion(). \~ + \param[in] progInd - \ru Индикатора прогресса выполнения. + \en Execution progress indicator. \~ + \return \ru Граф построения контуров. + \en Contours construction graph. \~ + \warning \ru При использовании функций EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor + состояние флага strict и версия version должно использоваться одно в одном процессе обработки. + \en While using functions EncloseContoursBuilder, OuterContoursBuilder, ContoursReconstructor, + a single state of 'strict' flag and version must be used in one treatment process. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MpGraph *) ContoursReconstructor( const RPArray & curveList, + MpGraph * graph, + PArray & contourArray, + double accuracy, + bool strict, + VERSION version, + IProgressIndicator * progInd = NULL ); + + +#endif // __CONTOUR_GRAPH_H diff --git a/C3d/Include/conv_annotation_item.h b/C3d/Include/conv_annotation_item.h new file mode 100644 index 0000000..999dfb1 --- /dev/null +++ b/C3d/Include/conv_annotation_item.h @@ -0,0 +1,845 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Объекты, используемые при импорте и экспорте аннотации и размеров. + \en Objects used for import and export of annotation and dimensions \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONV_ANNOTATION_ITEM_H +#define __CONV_ANNOTATION_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип элемента аннотации. + \en Type of annotation element. \~ +*/ +// --- +enum Mae_AnnotationType { + nt_AnnotationItem, ///< \ru Аннотация без объектов привязки. \en Annotation without binding objects. + nt_Dimension, ///< \ru Размер. \en Dimension + nt_LinearDimension, ///< \ru Линейный размер. \en Linear dimension. + nt_DiameterDimension, ///< \ru Диаметральный размер. \en Diameter dimension. + nt_RadialDimension, ///< \ru Радиальный размер. \en Radial dimension. + nt_AngularDimension, ///< \ru Угловой размер. \en Angular dimension. + nt_Callout, ///< \ru Выноска. \en Callout. + nt_Marking, ///< \ru Обозначение. \en Marking. + nt_Datum, ///< \ru База. \en Datum. + nt_Note, ///< \ru Примечание. \en Note. + nt_Centreline, ///< \ru Осевая линия. \en Centreline. + nt_FeatureControlFrame, ///< \ru Рамка управления характеристиками. \en Feature Control Frame. + nt_ReferencePoint, ///< \ru Точка отсчета. \en Reference Point. + nt_SurfaceRoughness, ///< \ru Шероховатость поверхности. \en Surface roughness. + nt_ShapeTolerance ///< \ru Допуск формы. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип текстового объекта. + \en Type of a text object. \~ +*/ +// --- +enum MaeTextType { + xt_CompositeText, ///< \ru Набор текстовых блоков. \en Set of text blocks. + xt_TextLiteral, ///< \ru Текст с указанием ЛСК, шрифта, выравнивания. \en Text with specification of LCS, font, alignment. + xt_TextLiteralExtent, ///< \ru Текст с указанием ЛСК, шрифта, выравнивания, геометрического размера. \en Text with specification of LCS, font, alignment, geometric dimension. + xt_SpecificSymbol ///< \ru Спецсимвол. \en Specific symbol. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тэг, определяющий назначение текстового блока. + \en Purpose tag of a text object. \~ +*/ +// --- +enum MaeTextFormatTag { + xft_Enumeration, ///< \ru Перечисление. \en Enumeration. + xft_Paragraph, ///< \ru Параграф. \en Paragraph. + // Тэги в следующей группе являются взаимосиключающими. Tags of the next group are mutually exclusive. + xft_Ground, ///< \ru Положение текста на базовом уровне. \en Ground level text position. + xft_Upper, ///< \ru Верхний индекс или числитель. \en Upper index or numerator. + xft_Lower, ///< \ru Нижний индекс или знаменатель. \en Lower index or denominator. + // Следующая группа тэгов уточняет смысл тэгов предыдущей группы. Next group of tags gives the exact meaning to the tags frem the previosu group. + xft_Fraction, ///< \ru Дробь. \en Fraction. + xft_Index, ///< \ru Наличие индекс. \en Indexed item. + xft_OverUnder, ///< \ru Наличие надстрочного и подстрочного текста. \en Overline and underline text present. + + xft_Undefined, ///< \ru Неопределённое значение тэга, не назначается. \en Undefined can be never assigned to items. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Направление текста. + \en Text direction. \~ +*/ +// --- +enum eTextPath { + txp_Left, ///< \ru Налево. \en To the left. + txp_Right,///< \ru Направо. \en To the right. + txp_Up, ///< \ru Вверх. \en Upward. + txp_Down ///< \ru Вниз. \en Downward. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Спецсимволы. + \en Special symbols. \~ +*/ +enum MbeDefinedDimensionSymbol { + dds_ArcLength, ///< \ru Длина дуги. \en The arc length. + dds_ConicalTaper, ///< \ru Конусность. \en Conicity. + dds_Counterbore, ///< \ru Зенковка. \en Counterbore. + dds_Countersink, ///< \ru Циковка. \en Countersink. + dds_Depth, ///< \ru Глубина. \en Depth. + dds_Diameter, ///< \ru Диаметр. \en Diameter. + dds_PlusMinus, ///< \ru Одинаковая двусторонняя погрешность. \en Equal double-sided tolerance. + dds_Radius, ///< \ru Радиус. \en Radius. + dds_Slope, ///< \ru Склон. \en Slope. + dds_SphericalDiameter, ///< \ru Сферический диаметр. \en Spherical diameter. + dds_SphericalRadius, ///< \ru Сферический радиус. \en Spherical radius. + dds_Square, ///< \ru Квадрат. \en Square. + dds_MetricThread, ///< \ru Метрическая резьба (при экспорте в STEP преобразуется в букву M). \en Metric thread ( in STEP it corresponds M letter ). + + dds_SurfaceCondition, ///< \ru Шереховатость поверхности в нотации STEP (ISO 10303). \en Surface condition in STEP (ISO 10303) codes. + dds_SurfaceCondition_010, + dds_SurfaceCondition_020, + dds_SurfaceCondition_030, + dds_SurfaceCondition_040, + dds_SurfaceCondition_050, + dds_SurfaceCondition_060, + dds_SurfaceCondition_070, + + dds_SurfaceCondition_001, + dds_SurfaceCondition_011, + dds_SurfaceCondition_021, + dds_SurfaceCondition_031, + dds_SurfaceCondition_041, + dds_SurfaceCondition_051, + dds_SurfaceCondition_061, + dds_SurfaceCondition_071, + + dds_SurfaceCondition_100, + dds_SurfaceCondition_110, + dds_SurfaceCondition_120, + dds_SurfaceCondition_130, + dds_SurfaceCondition_140, + dds_SurfaceCondition_150, + dds_SurfaceCondition_160, + dds_SurfaceCondition_170, + + dds_SurfaceCondition_101, + dds_SurfaceCondition_111, + dds_SurfaceCondition_121, + dds_SurfaceCondition_131, + dds_SurfaceCondition_141, + dds_SurfaceCondition_151, + dds_SurfaceCondition_161, + dds_SurfaceCondition_171, + + dds_SurfaceCondition_200, + dds_SurfaceCondition_210, + dds_SurfaceCondition_220, + dds_SurfaceCondition_230, + dds_SurfaceCondition_240, + dds_SurfaceCondition_250, + dds_SurfaceCondition_260, + dds_SurfaceCondition_270, + + dds_SurfaceCondition_201, + dds_SurfaceCondition_211, + dds_SurfaceCondition_221, + dds_SurfaceCondition_231, + dds_SurfaceCondition_241, + dds_SurfaceCondition_251, + dds_SurfaceCondition_261, + dds_SurfaceCondition_271, + + dds_Angularity, ///< \ru Допуск наклона. \en Angularity. + dds_CircularRunout, ///< \ru Допуск биения. \en Circular runout. + dds_Circularity, ///< \ru Допуск круглости. \en Circularity. + dds_Concentricity, ///< \ru Допуск соосности. \en Concentricity. + dds_Cylindricity, ///< \ru Допуск цилиндричности. \en Cylindricity. + dds_DiameterTol, ///< \ru Допуск диаметра. \en Diameter. + dds_Flatness, ///< \ru Допуск плоскостности. \en Flatness. + dds_LeastMaterialCondition, ///< \ru Требование минимума материала. \en Least material condition. + dds_MaximumMaterialCondition, ///< \ru Требование максимума материала. \en Maximum material condition. + dds_Parallelism, ///< \ru Допуск параллельности. \en Parallelism. + dds_Perpendicularity, ///< \ru Допуск перпендикулярности. \en Perpendicularity. + dds_Position, ///< \ru Позиционный допуск. \en Position. + dds_LineProfile, ///< \ru Допуск формы заданного профиля. \en Line profile. + dds_SurfaceProfile, ///< \ru Допуск формы заданной поверхности. \en Surface profile. + dds_ProjectedToleranceZone, ///< \ru Выступающее поле допуска. \en ProejectedToleranceZone. + dds_RegardlessOfFeatureSize, ///< \ru . \en . + dds_Straightness, ///< \ru Допуск прямолинейности. \en Straightness. + dds_Symmetry, ///< \ru Допуск симметричности. \en .Symmetry + dds_TotlaRunout, ///< \ru Допуск полного радиального (либо торцевого) биения. \en TotlaRunout. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип законцовки. + \en Type of tip. \~ +*/ +enum MbeDefinedTerminatorSymbol { + dts_BlankedArrow, ///< \ru Незакрашенная стрелка. \en Blank arrow. + dts_BlankedBox, ///< \ru Незакрашенный квадрат. \en Blank square. + dts_BlankedDot, ///< \ru Незакрашенная точка. \en Blank point. + dts_DimensionOrigin, ///< \ru Базовsq объект. \en Base object. + dts_FilledArrow, ///< \ru Закрашенная стрелка. \en Filled arrow. + dts_FilledBox, ///< \ru Закрашенный квадрат. \en Filled square. + dts_FilledDot, ///< \ru Закрашенная точка. \en Filled point. + dts_IntegralSymbol, ///< \ru Знак интеграла. \en Integral symbol. + dts_OpenArrow, ///< \ru Открытая стрелка. \en Open arrow. + dts_Slash, ///< \ru Косая черта. \en Slash. + dts_UnfilledArrow ///< \ru Стрелка без заполнения. \en Unfilled arrow. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип кривой с терминаторами. +\en Type of curve with terminators. \~ +*/ +enum MbeDecoratedCurveRole { + dcr_ProjectionCurve, ///< \ru Проекционная кривая размера. \en Projection curve of dimension. + dcr_DimensionCurve, ///< \ru Размерная кривая. \en Dimension curve. + dcr_LeaderCurve, ///< \ru Линия выноски. \en Leader curve. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Текстовый объект. + \en Text object. \~ +*/ +// --- +class CONV_CLASS MaTextItem : public MbRefItem { +protected: + bool visibility; // \ru Признак видимости. \en Visibility. + std::set purposeTags; // \ru Тэги форматирования. \en Gormat tags. +public: + + MaTextItem(); ///< \ru Конструктор по умолчанию. \en Default constructor. + + void SetVisibility( bool v ); ///< \ru Задать видимость; \en Set visibility. + bool IsVisible() const; ///< \ru Получить видимость; \en Get visibility. + + bool IsTag( MaeTextFormatTag tag ) const; ///< \ru Установлен ли тэг. \en Is a tag set. + bool GetTagIfUnique( MaeTextFormatTag& tag ) const; ///< \ru получить тэг, если он единственный. \en Get the tag provided it id qnique. + void SetTag( MaeTextFormatTag tag ); ///< \ru Установить тэг. \en Set a tag. + void ResetTag( MaeTextFormatTag tag ); ///< \ru Сбросить тэг. \en reset a tag. + bool TagUniqueOrUndefined() const; ///< \ru Назначено ли менее 2 тэгов. \en If less than two tags assinged. + bool NoTag() const; ///< \ru Отсутствуют ли тэги. \en If threre are no tags. + + virtual MaeTextType IsA() const = 0; + virtual SPtr Duplicate() const = 0; + virtual ~MaTextItem(); ///< \ru Деструктор. \en Destructor. + + OBVIOUS_PRIVATE_COPY( MaTextItem ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Набор текстовых блоков. + \en Set of text blocks. \~ +*/ +// --- +class CONV_CLASS MaCompositeText : public MaTextItem { + std::vector< SPtr > items; ///< \ru Текстовый блок. \en The text block. + +public: + + MaCompositeText(); ///< \ru Конструктор по умолчанию. \en Default constructor. + + std::vector< SPtr > GetItems() const; ///< \ru Получить элементы. \en Get elements. + void SetItems( const std::vector< SPtr >& it ); ///< \ru Задать элементы. \en Set elements. + void AddItem( MaTextItem* item ); ///< \ru Добавить элемент \en Add an element. + size_t ItemsSize() const; ///< \ru Получить число элементов \en Get count of elements. + MaTextItem* GetItem( size_t idx ); ///< \ru Получить элемент. \en Get element. + const MaTextItem* GetItem( size_t idx ) const; ///< \ru Получить элемент. \en Get element. + + virtual MaeTextType IsA() const; ///< \ru Выдать тип элемента. \en Get element type. + virtual SPtr Duplicate() const; + + /** \brief \ru Вставить объект перед всеми вхождениями указанного. + \en Insert an object before all instances of the specified one. \~ + */ + void InsertBefore( const SPtr& itemToInsert, const SPtr& beforeThis ); + + OBVIOUS_PRIVATE_COPY( MaCompositeText ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Текст с указанием ЛСК, шрифта, выравнивания. + \en Text with specification of LCS, font, align. \~ +*/ +// --- +class CONV_CLASS MaTextLiteral : public MaTextItem { +protected: + std::string text; ///< \ru Текст. \en A text. + MbPlacement location; ///< \ru Положение в аннотационной плоскости \en Position in annotation plane + std::string alignment; ///< \ru Выравнивание. \en Alignment. + eTextPath path; ///< \ru Направление текста. \en Text direction. + std::string font; ///< \ru Шрифт текста. \en Text font. + bool isFontExternal; ///< \ru Является ли шрифт нестандартным. \en Is font non-standard. + +public: + + MaTextLiteral(); ///< \ru Конструктор по умолчанию. \en Default constructor. + + MbPlacement & SetLocation(); ///< \ru Получить положение с возможностью модификации. \en Get position with possibility of modification. + const MbPlacement & GetLocation() const; ///< \ru Получить положение. \en Get position. + eTextPath & SetPath(); ///< \ru Получить направление с возможностью модификации. \en Get direction with possibility of modification. + eTextPath GetPath() const; ///< \ru Получить направление. \en Get direction. + void SetFontExternal( bool value ); ///< \ru Задать признак нестандартного шрифта. \en Set the flag of external font. + bool GetFontExternal() const; ///< \ru Получить признак нестандартного шрифта. \en Get the flag of external font. + + void SetText( const std::string& ); ///< \ru Получить текст. \en Get text. + void GetText( std::string& ) const; ///< \ru Задать текст. \en Set text. + void SetAlignment( const std::string& ); ///< \ru Получить выравнивание. \en Get alignment. + void GetAlignment( std::string& ) const; ///< \ru Задать выравнивание. \en Set alignment. + void SetFont( const std::string& ); ///< \ru Получить шрифт. \en Get font. + void GetFont( std::string& ) const; ///< \ru Задать шрифт. \en Set font. + + virtual MaeTextType IsA() const; + virtual SPtr Duplicate() const; + + OBVIOUS_PRIVATE_COPY( MaTextLiteral ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Текст с указанием ЛСК, шрифта, выравнивания, размера. + \en Text with specification of LCS, font, alignment, size. \~ +*/ +// --- +class CONV_CLASS MaTextLiteralExtent : public MaTextLiteral { + double sizeX, sizeY; ///< \ru Размеры по x и у. \en Size by x and size by y. +public: + + MaTextLiteralExtent(); ///< \ru Конструктор по умолчанию. \en Default constructor. + + double & SetSizeX(); ///< \ru Получить размер по x. \en Get size by x with possibility of modification. + double & SetSizeY(); ///< \ru Получить размер по y. \en Get size by y with possibility of modification. + double GetSizeX() const; ///< \ru Получить размер по x. \en Get size by x. + double GetSizeY() const; ///< \ru Получить размер по y. \en Get size by y. + + virtual MaeTextType IsA() const; + virtual SPtr Duplicate() const; + + OBVIOUS_PRIVATE_COPY( MaTextLiteralExtent ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Спецсимвол. + \en Specific symbol. \~ +*/ +// --- +class CONV_CLASS MaSpecificSymbol : public MaTextItem { + MbPlacement location; ///< \ru Положение в аннотационной плоскости \en Position in annotation plane. + double sizeX; ///< \ru Размер по X. \en Size by x. + double sizeY; ///< \ru Размер по Y. \en Size by Y. + MbeDefinedDimensionSymbol preDefinedSym; ///< \ru Код предопределённого символа. \en The predefined symbol code. +public: + + MaSpecificSymbol( MbeDefinedDimensionSymbol symbol, double szX, double szY ); + + MbeDefinedDimensionSymbol GetSymbol() const; ///< \ru Получить код предопределённого символа. \en Get the predefined symbol code. + bool IsSymbolDimension() const; ///< \ru Является ли символ размерным. \en Is symbol dimension. + bool IsSymbolSurfaceCondition() const; ///< \ru Является ли символ обозначением шероховатости. \en Is symbol surface condition. + bool IsSymbolShapeTolerance() const; ///< \ru Является ли символ допуском формы. \en Is symbol shape tolerance. + MbPlacement& SetLocation(); ///< \ru Получить положение с возможностью модификации. \en Get position with possibility of modification. + const MbPlacement& GetLocation() const; ///< \ru Получить положение. \en Get position. + double GetSizeX() const; ///< \ru Получить размер по x. \en Get size by x. + double GetSizeY() const; ///< \ru Получить размер по y. \en Get size by y. + void GetSize( double& x, double& y ) const; ///< \ru Получить размеры. \en Get sizes. + + OBVIOUS_PRIVATE_COPY( MaSpecificSymbol ) + + virtual MaeTextType IsA() const; + virtual SPtr Duplicate() const; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Описание законцовочного символа. +\en Description of the terminator symbol. \~ +*/ +struct MaTerminatorSymbol { + MbeDefinedTerminatorSymbol type; ///< \ru Тип символа \en Symbol type + double parameter; ///< \ru Значенеи параметра на размерной кривой. Если не указан, должен быть равен UNDEFINED_DBL. \en Parameter value on the dimensional curve. If not known, must be equal UNDEFINED_DBL. + double sizeX; ///< \ru Размер по x. \en Size by x. + double sizeY; ///< \ru Размер по у. \en Size by y. + /// \ru Признак сонаправленности с касательной к кривой в точке размещения. В случае неопределённого значения параметра - признак направленности внутрь. + /// \en Flag of the same direction with the tangent to the curve at the location point. In case parameter id undefined it shows if the arrow's direction is inner. + bool sameDirection; + + MbCartPoint3D location; ///< \ru Положение в пространстве. \en Location in space. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая с терминаторами. + \en Curve and terminators. \~ +*/ +class CONV_CLASS MaDecoratedCurve : public MbRefItem { + c3d::SpaceCurveSPtr curve; + std::vector< MaTerminatorSymbol > terminators; + MbeDecoratedCurveRole curveType; +public: + MaDecoratedCurve( MbeDecoratedCurveRole crvType ); ///< \ru Конструктор. \en Constructor. + MaDecoratedCurve( const MaDecoratedCurve& ); ///< \ru Конструктор копирования. \en Copy constructor. + const MaDecoratedCurve& operator= ( const MaDecoratedCurve& ); ///< \ru Оператор присваивания. \en Assignment operator. + + c3d::SpaceCurveSPtr GetCurve() const; ///< \ru Получить кривую. \en Get curve. + bool CurveEmpty() const; ///< \ru Пуста ли кривая. \en If curve is empty. + void SetCurve( MbCurve3D* crv ); ///< \ru Задать кривую. \en Set curve. + size_t TerminatorsCount() const; ///< \ru Получить число законцовок. \en Set number of terminators. + bool TerminatorInfo( size_t terminatorIndex, MaTerminatorSymbol& term ) const; ///< \ru Получить законцовку с указанным индексом. \en Get terminator. + void AddTerminator( const MaTerminatorSymbol& term ); ///< \ru Добавить законцовку. \en Add terminator. + + bool IsA( MbeDecoratedCurveRole ) const; ///< \ru Проверка типа кривой. \en Check curve type. + + void DuplicateCurve( const MbMatrix3D& transform ); ///< \ru Заменить кривую на преобразованный по матрице дубликат. \en Replace curve by transformed replica. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Объект аннотации. + \en Annotation object. \~ +*/ +class CONV_CLASS MaAnnotationItem : public MbRefItem { +protected: + MbPlacement3D location; ///< \ru Локальная система координат (ЛСК), в плоскости XY которой расположены объекты аннотации. \en Local coordinate system (LCS) the annotation objects are located in XY plane of. + std::vector< const MbItem* > annotationGeometry; ///< \ru Геометрические объекты аннотации. \en Geometric objects of annotation. + std::vector< SPtr > annotationText; ///< \ru Текстовые аннотационные объекты. \en Text annotation objects. + std::string name; ///< \ru Имя. \en Name. + bool visible; ///< \ru Видим ли объект. \en If object is vivible. + // \ru Аналогичным образом реализовать и символьное представление \en Implement symbolic representation similarly. +public: + /// \ru Конструктор по плоскости аннотации. \en Constructor by annotation plane. + MaAnnotationItem( const MbPlacement3D& loc ); + /// \ru Деструктор. \en Destructor. + virtual ~MaAnnotationItem(); + +public: + /// \ru Получить тип объекта. \en Get the object type. + virtual Mae_AnnotationType IsA() const; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual Mae_AnnotationType Type() const; + + /// \ru Пусто ли визуальное представление. \en Whether the visual representation is empty. + virtual bool VisualItemsEmpty() const; + + /// \ru Отсутствуют ли геометрические элементы. \en Whether there are no geometric items. + bool GeometryEmpty() const; + + /// \ru Отсутствуют ли текстовые элементы. \en Whether there are no text items. + bool TextEmpty() const; + + /// \ru Добавить геометрический визуальный аннотационный элемент. \en Add the geometric visual annotation element of the kernel. + void AddGeometricAnnotationElement( const MbItem& ); + + /// \ru Задать аннотационные объекты ядра. \en Set the annotation objects of the kernel. + template< typename In > + void SetAnnotationGeometry( In first, In last ); + /// \ru Выдать аннотационные объекты ядра. У приёмника должен быть определён метод push_back. \en Get the annotation objects of the kernel. Method push_back should be defined for the receiver. + template< typename Out > + void GetAnnotationGeometry( Out dest ) const; + + /// \ru Получить текстовые аннотационные объекты. \en Get the text annotation object. + template< typename In > + void SetAnnotationText( In first, In last ); + /// \ru Выдать текстовые аннотационные объекты. У приёмника должен быть определён метод push_back. \en Get text annotation objects. Method push_back should be defined for the receiver. + template< typename Out > + void GetAnnotationText( Out dest ) const; + + /// \ru Добавить плоские геометрические объекты, преобразуя их в пространственные, используя текущую ЛСК. \en Add planar objects to geometric objects using current location. + void AddPlaneItems( const std::vector >& ); + + /// \ru Задать ЛСК. \en Specify LCS. + void SetLocation( const MbPlacement3D & loc ); + /// \ru Получить ЛСК. \en Get LCS. + MbPlacement3D GetLocation() const; + + /// \ru Задать имя. \en Specify name. + void SetName( const std::string & nm ); + + /// \ru Задать имя. \en Specify name. + void GetName( std::string & nm ) const; + + /// \ru Задать видимость. \en Set visibility. + void SetVisibility( bool v ); + /// \ru Видим ли объект. \en Is object vivible. + bool IsVisible() const; + + /// \ru Создать дубликат и трансформировать его согласно матрице. \en Create a replica then transform it. + virtual SPtr ShallowDuplicateTransform( const MbMatrix3D & ); + + /// \ru Инициализировать все поля за исключением ЛСК данными присланного. \en Init all fields except for location according to the specified item. + void InitExceplLocation( const MaAnnotationItem & init ); + +protected: + + /// \ru Заменить геометрические элементы трансформированными копиями. \en Replace all geometric items by transformed copies. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +typedef SPtr AnnotationSPtr; + + +//------------------------------------------------------------------------------ +/** \brief \ru Размер - родоначальник классов для размеров различных типов. + \en Dimension is the parent of all classes for dimensions of different types. \~ +*/ +// --- +class CONV_CLASS MaDimension : public MaAnnotationItem { + double value; ///< \ru Значение размера. \en A value of dimension. + double valuePlus; ///< \ru Отклонение размера в сторону увеличения. \en Deviation (increase) of size. + double valueMinus; ///< \ru Отклонение размера в сторону уменьшения. \en Deviation (decrease) of size. + bool isRangeSet; ///< \ru Если false, то задан только диапазон изменения, иначе можно вычислить погрешности в обе стороны. \en If it equals false, then only the range of changing is specified, else the tolerances in both directions can be computed. + bool isValueDefined; ///< \ru Задан ли номинал. \en Whether the nominal is given. +protected: + MaDecoratedCurve dimensionCurve; + + OBVIOUS_PRIVATE_COPY( MaDimension ) +protected: + MaDimension( const MbPlacement3D& loc, MbCurve3D* dimCurve ); + MaDimension( const MbPlacement3D& loc, const MaDecoratedCurve& dimCurve ); +public: + /// \ru Получить тип объекта. \en Get the object type. + virtual Mae_AnnotationType IsA() const; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual Mae_AnnotationType Type() const; + + /// \ru Получить размерную кривую. \en Get the dimensional curve. + MbCurve3D* GetDimensionCurve(); + + /// \ru Задать номинал. \en Set a value. + void SetValue( double v ); + /// \ru Задать диапазон и значение. \en Set a range and a value. + void SetRange( double v, double vPlus, double vMinus ); + /// \ru Задать диапазон. \en Set range. + void SetRange( double vPlus, double vMinus ); + /// \ru Получить номинал. \en Get value. + bool GetValue( double& v ); + /// \ru Получить границы диапазона и значение, если они заданы. \en Get bounds of range and a value if they are specified. + bool GetRange( double& v, double& vPlus, double& vMinus ) const; + /// \ru Получить границы диапазона, если они заданы. \en Get bounds of the range if they are specified. + bool GetRange( double& vPlus, double& vMinus ) const; + /// \ru Заданы ли границы диапазона. \en Whether the bounds of range are specified. + bool IsRangeDefined() const; + /// \ru Задано ли значение. \en Whether the value is specified. + bool IsValueDefined() const; + /** \brief \ru Добавить законцовочный символ. + \en Add a terminator. \~ + \param [in] init - \ru Параметры задаваемого символа. + \en Parameters of specified symbol. \~ + \return \ru - true, если задана размерная кривая и хотя бы один из законцовочных символов не был задан. + \en - true, if a dimensional curve is specified and at least one of terminators has not been specified. \~ + */ + bool AddTerminator( const MaTerminatorSymbol& init ); + /// \ru Получить первый законцовочный символ. \en Get the first terminator. + bool GetFirstTerminator( MaTerminatorSymbol& first ); + /// \ru Получить второй законцовочный символ. \en Get the second terminator. + bool GetSecondTerminator( MaTerminatorSymbol& second ); + + void InitValueTerminators( const MaDimension& init ); +protected: + /// \ru Заменить геометрические элементы трансформированными копиями. \en Replace all geometric items by transformed copies. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Линейный размер. + \en Linear dimension. \~ +*/ +// --- +class CONV_CLASS MaLinearDimension : public MaDimension { +private: + SPtr bindBase; ///< \ru Первый объект привязки. \en The first binding object. + SPtr bindTarget; ///< \ru Второй объект привязки. \en The second binding object. + MaDecoratedCurve projectionBase; ///< \ru Проекционная кривая к первому объекту привязки в смысле STEP. \en Projection curve to the first binding object in sense of STEP. + MaDecoratedCurve projectionTarget; ///< \ru Проекционная кривая ко второму объекту привязки в смысле STEP. \en Projection curve to the second binding object in sense of STEP. + SPtr path; ///< \ru Кривая, вдоль которой проводится измерение. Если не задана, то размер есть кратчайший. \en A curve along which the measurement is performed. If not specified, then the size is shortest. + + OBVIOUS_PRIVATE_COPY( MaLinearDimension ) +public: + MaLinearDimension ( const MbRefItem* base, const MbRefItem* target, + MbLineSegment3D* projBase, MbLineSegment3D* projTarget, + MbLineSegment3D* dimensionCurve, const MbPlacement3D& loc ); + + MaLinearDimension ( const MbRefItem* base, const MbRefItem* target, + MbLineSegment3D* projBase, MbLineSegment3D* projTarget, + const MaDecoratedCurve dimensionCurve, const MbPlacement3D& loc ); + + virtual Mae_AnnotationType IsA() const; + + virtual bool VisualItemsEmpty() const; + + /// \ru Получить базовый объект привязки. \en Get the base binding object. + const MbRefItem * GetBindBase(); + /// \ru Получить второй объект привязки. \en Get the second binding object. + const MbRefItem * GetBindTarget(); + + /// \ru Получить проекционную кривую к базовому объекту привязки. \en Get projection curve to the base binding object. + MbLineSegment3D* GetProjectionBase(); + /// \ru Получить проекционную кривую ко второму объекту привязки. \en Get the projection curve to the second binding object. + MbLineSegment3D* GetProjectionTarget(); + + /// \ru Задать кривую, вдоль которой провдится измерение. \en Set the curve the measurement is performed along. + void SetPath( MbCurve3D* inPath ); + /// \ru Получить кривую, вдоль которой провдится измерение. \en Get the curve the measurement is performed along. + MbCurve3D* GetPath(); + + /// \ru Создать дубликат и трансформировать его согласно матрице. \en Create a replica then transform it. + virtual SPtr ShallowDuplicateTransform( const MbMatrix3D& ); + +protected: + // Заменить геометрические элементы трансформированными копиями. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Угловой размер. + \en Angular dimension. \~ +*/ +// --- +class CONV_CLASS MaAngularDimension : public MaDimension { +private: + SPtr bindBase; ///< \ru Первый объект привязки. \en The first binding object. + SPtr bindTarget; ///< \ru Второй объект привязки. \en The second binding object. + MaDecoratedCurve projectionBase; ///< \ru Проекционная кривая к первому объекту привязки в смысле STEP. \en Projection curve to the first binding object in sense of STEP. + MaDecoratedCurve projectionTarget; ///< \ru Проекционная кривая ко второму объекту привязки в смысле STEP. \en Projection curve to the second binding object in sense of STEP. + + OBVIOUS_PRIVATE_COPY( MaAngularDimension ) +public: + MaAngularDimension( const MbRefItem* base, const MbRefItem* target, + MbLineSegment3D* projBase, MbLineSegment3D* projTarget, + MbArc3D* dimensionCurve, const MbPlacement3D& loc ); + + MaAngularDimension( const MbRefItem* base, const MbRefItem* target, + MbLineSegment3D* projBase, MbLineSegment3D* projTarget, + const MaDecoratedCurve&, const MbPlacement3D& loc ); + + virtual Mae_AnnotationType IsA() const ; + + virtual bool VisualItemsEmpty() const; + + /// \ru Получить базовый объект привязки. \en Get the base binding object. + const MbRefItem * GetBindBase(); + /// \ru Получить второй объект привязки. \en Get the second binding object. + const MbRefItem * GetBindTarget(); + + /// \ru Получить проекционную кривую к базовому объекту привязки. \en Get projection curve to the base binding object. + MbLineSegment3D * GetProjectionBase(); + /// \ru Получить проекционную кривую ко второму объекту привязки. \en Get the projection curve to the second binding object. + MbLineSegment3D * GetProjectionTarget(); + /// \ru Если заданы проекционные кривые и если они не параллельны, получить точку пересечения или скрещивания. Метод работает и за пределеми параметрической области. \en If the projection curves are specified and if they are not parallel, get the point of intersection or crossing. The method works outside the bounds of a parametric region too. + bool NearestBetweenProjections( MbCartPoint3D& pnt ); + /// \ru Создать дубликат и трансформировать его согласно матрице. \en Create a replica then transform it. + virtual SPtr ShallowDuplicateTransform( const MbMatrix3D& ); + +protected: + // Заменить геометрические элементы трансформированными копиями. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Радиальный размер. + \en Radial dimension. \~ +*/ +// --- +class CONV_CLASS MaRadialDimension : public MaDimension { +private: + SPtr bindBase; ///< \ru Объект привязки. \en Binding object. + MaDecoratedCurve projectionBase; ///< \ru Проекционная кривая к объекту привязки в смысле STEP. \en Projection curve to the binding object in sense of STEP. + + OBVIOUS_PRIVATE_COPY( MaRadialDimension ) +public: + MaRadialDimension( const MbRefItem* base, MbLineSegment3D* projBase, + MbLineSegment3D* dimensionCurve, const MbPlacement3D& loc ); + + MaRadialDimension( const MbRefItem* base, MbLineSegment3D* projBase, + const MaDecoratedCurve& dimensionCurve, const MbPlacement3D& loc ); + + virtual Mae_AnnotationType IsA() const; + + virtual bool VisualItemsEmpty() const; + + /// \ru Получить базовый объект привязки. \en Get the base binding object. + const MbRefItem * GetBindBase(); + /// \ru Получить проекционную кривую к базовому объекту привязки. \en Get projection curve to the base binding object. + MbLineSegment3D * GetProjectionBase(); + /// \ru Создать дубликат и трансформировать его согласно матрице. \en Create a replica then transform it. + virtual SPtr ShallowDuplicateTransform( const MbMatrix3D& ); + +protected: + // Заменить геометрические элементы трансформированными копиями. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Диаметральный размер. + \en Diameter dimension. \~ +*/ +// --- +class CONV_CLASS MaDiameterDimension : public MaDimension { +private: + SPtr bindBase; ///< \ru Объект привязки. \en Binding object. + MaDecoratedCurve projectionBase; ///< \ru Первая проекционная кривая к объекту привязки в смысле STEP. \en The first projection curve to binding object in sense of STEP. + MaDecoratedCurve projectionTarget; ///< \ru Вторая проекционная кривая к объекту привязки в смысле STEP. \en The second projection curve to binding object in sense of STEP. + + OBVIOUS_PRIVATE_COPY( MaDiameterDimension ) +public: + MaDiameterDimension( const MbRefItem* base, MbLineSegment3D* projBase, + MbLineSegment3D* projTarget, MbLineSegment3D* dimCurve, + const MbPlacement3D& loc ); + + MaDiameterDimension( const MbRefItem* base, MbLineSegment3D* projBase, + MbLineSegment3D* projTarget, const MaDecoratedCurve& dimCurve, + const MbPlacement3D& loc ); + + virtual Mae_AnnotationType IsA() const; + + virtual bool VisualItemsEmpty() const; + + /// \ru Получить базовый объект привязки. \en Get the base binding object. + const MbRefItem * GetBindBase(); + + /// \ru Получить проекционную кривую к базовому объекту привязки. \en Get projection curve to the base binding object. + MbLineSegment3D * GetProjectionBase(); + /// \ru Получить вторую проекционную кривую к объекту привязки. \en Get the first projection curve to the binding object. + MbLineSegment3D * GetProjectionTarget(); + /// \ru Создать дубликат и трансформировать его согласно матрице. \en Create a replica then transform it. + virtual SPtr ShallowDuplicateTransform( const MbMatrix3D& ); + +protected: + // Заменить геометрические элементы трансформированными копиями. + virtual void DuplicateTransformDeometry( const MbMatrix3D & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Выносной элемент - родоначальник классов для обозначений различных типов. +\en Callout is the parent of all classes for callouts of different types. \~ +*/ +// --- +class CONV_CLASS MaCallout : public MaAnnotationItem { + Mae_AnnotationType whatIs; ///< \ru Подтип объекта. \en Object subtype. + std::vector leaderLines; ///< \ru Линии выноски. \en Leader lines. +public: + /// \ru Получить тип объекта. \en Get the object type. + virtual Mae_AnnotationType IsA() const; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual Mae_AnnotationType Type() const; + /// \ru Создать объект заданного типа объекта. \en Create object of specified type. + static MaCallout* Create( const MbPlacement3D& location, Mae_AnnotationType subtype ); + + void AddLeaderLine( const MaDecoratedCurve& leader ); ///< \ru Добавить линию выноски. \en Add leader line. + void AddLeaderLines( const std::vector& leaders ); ///< \ru Добавить линию выноски. \en Add leader line. + size_t LeaderLinesCount() const; ///< \ru Получить число линий выноски. \en Get number of leader lines. + bool LeaderLineInfo( size_t index, MaDecoratedCurve& callout ) const; ///< \ru Получить линию выноски с указанным индексом. \en Get of leader lines at specified index. +private: + MaCallout( const MbPlacement3D& location, Mae_AnnotationType subtype ); ///< \ru Конструктор. \en Constructor. + + OBVIOUS_PRIVATE_COPY(MaCallout) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Шероховатость поверхности. +\en Surface condition. \~ +*/ +// --- +class CONV_CLASS MaSurfaceCondition : public MaAnnotationItem { + SPtr< const MbRefItem > baseObject; + double value; +public: + /// \ru Конструктор. \en Constructor. + MaSurfaceCondition( const MbPlacement3D& location ); + + /// \ru Получить тип объекта. \en Get the object type. + virtual Mae_AnnotationType IsA() const; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual Mae_AnnotationType Type() const; + + OBVIOUS_PRIVATE_COPY( MaSurfaceCondition ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Допуск формы. +\en Shape tolerance. \~ +*/ +// --- +class CONV_CLASS MaShapeTolerance : public MaAnnotationItem { + SPtr< const MbRefItem > baseObject; + double value; +public: + /// \ru Конструктор. \en Constructor. + MaShapeTolerance( const MbPlacement3D& location ); + + /// \ru Получить тип объекта. \en Get the object type. + virtual Mae_AnnotationType IsA() const; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual Mae_AnnotationType Type() const; + + OBVIOUS_PRIVATE_COPY(MaShapeTolerance) +}; + + +//------------------------------------------------------------------------------ +// \ru Задать геометрические объекты аннотации \en Set geometric objects of annotation. +// --- +template< typename In > +void MaAnnotationItem::SetAnnotationGeometry( In first, In last ) { + std::for_each( annotationGeometry.begin(), annotationGeometry.end(), ReleaseItem ); + annotationGeometry.assign( first, last ); + std::for_each( annotationGeometry.begin(), annotationGeometry.end(), AddRefItem ); +} + + +//------------------------------------------------------------------------------ +// \ru Получить геометрические объекты аннотации \en Get geometric objects of annotation. +// --- +template< typename Out > +void MaAnnotationItem::GetAnnotationGeometry( Out dest ) const { + std::copy( annotationGeometry.begin(), annotationGeometry.end(), dest ); +} + + +//------------------------------------------------------------------------------ +// \ru Задать текстовые объекты аннотации \en Set text objects of annotation. +// --- +template< typename In > +void MaAnnotationItem::SetAnnotationText( In first, In last ) { + annotationText.assign( first, last ); +} + + +//------------------------------------------------------------------------------ +// \ru Получить текстовые объекты аннотации \en Get text objects of annotation +// --- +template< typename Out > +void MaAnnotationItem::GetAnnotationText( Out dest ) const { + std::copy( annotationText.begin(), annotationText.end(), dest ); +} + + +#endif // __CONV_ANNOTATION_ITEM_H diff --git a/C3d/Include/conv_error_result.h b/C3d/Include/conv_error_result.h new file mode 100644 index 0000000..e8ad6ae --- /dev/null +++ b/C3d/Include/conv_error_result.h @@ -0,0 +1,374 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Перечисления, используемые при импорте и экспорте. + \en Enumerations for import/export operations.\~ + \details \ru Определены перечисления, определяющие результат конвертирования, + разрешение на чтение и запись различных объектов и передаваемых черезх конвертер строк. + \en Converting result, objects and properties filters, special strings + of enumerations are defined.\~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONV_ERROR_RESULT_H +#define __CONV_ERROR_RESULT_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Константы единиц измерения. + \en Length units constants.\~ +\ingroup Data_Interface +*/ +// --- +/// \ru Миллиметры. \en Millimeters. +#define LENGTH_UNIT_MM 1.0 +/// \ru Сантиметры. \en Centimeters. +#define LENGTH_UNIT_CM 10.0 +/// \ru Дециметры. \en Decimeters. +#define LENGTH_UNIT_DM 100.0 +/// \ru Метры. \en Meters. +#define LENGTH_UNIT_METER 1000.0 +/// \ru Дюймы. \en Inches. +#define LENGTH_UNIT_INCH 25.4 + + +//------------------------------------------------------------------------------ +/** \brief \ru Прикладной протокол. + \en Applied protocol.\~ +\ingroup Data_Interface +*/ +// --- +enum MbeImpExpFormat { + ief_STEP203, ///< \ru STEP прикладной протокол 203 ( Проектирование с управляемой конфигурацией ). \en STEP applied protocol STEP 203 (Configuration controlled design). + ief_STEP214, ///< \ru STEP прикладной протокол 214 ( Проектирование автомобилей ). \en STEP applied protocol STEP 214 (Automotive design). + ief_STEP242, ///< \ru STEP прикладной протокол 242 ( Проектирование автомобилей ). \en STEP applied protocol STEP 242 (Automotive design). +}; + + +#define EXPORT_DEFAULT -1 ///< \ru По умолчанию для заданного формата. \en Default for specified format. +#define EXPORT_STEP_203 203 ///< \ru STEP прикладной протокол 203 ( Проектирование с управляемой конфигурацией ). \en STEP applied protocol STEP 203 (Configuration controlled design). +#define EXPORT_STEP_214 214 ///< \ru STEP прикладной протокол 214 ( Проектирование автомобилей ). \en STEP applied protocol STEP 214 (Automotive design). +#define EXPORT_STEP_242 242 ///< \ru STEP прикладной протокол 242. \en STEP applied protocol STEP 242. +#define EXPORT_ACIS_4 4 ///< \ru ACIS версия 4.0. \en ACIS version 4.0. +#define EXPORT_ACIS_7 7 ///< \ru ACIS версия 7.0 (по умолчанию). \en ACIS version 7.0 (default). +#define EXPORT_ACIS_10 10 ///< \ru ACIS версия 10.0. \en ACIS version 10.0. + + +//------------------------------------------------------------------------------ +/** \brief \ru Обменный формат модели. + \en Model exchange format.\~ +\ingroup Data_Interface +*/ +// --- +enum MbeModelExchangeFormat { + mxf_autodetect, ///< \ru Интерпретировать содержимое по расширению файла. \en File extension defines format. + mxf_ACIS, ///< \ru Интерпретировать содержимое как ACIS (.sat). \en Read data from buffer as ACIS (.sat). + mxf_IGES, ///< \ru Интерпретировать содержимое как IGES (.igs или .iges). \en Read data from buffer as IGES (.igs or .iges). + mxf_JT, ///< \ru Интерпретировать содержимое как JT (.jt). \en Read data from buffer as JT (.jt). + mxf_Parasolid, ///< \ru Интерпретировать содержимое как Parasolid (.x_t, .x_b, .xmt_txt, .xmp_txt, .xmt_bin или .xmp_bin ). \en Read data from buffer as Parasolid (.x_t, .x_b, .xmt_txt, .xmp_txt, .xmt_bin or .xmp_bin ). + mxf_STEP, ///< \ru Интерпретировать содержимое как STEP (.stp или .step). \en Read data from buffer as STEP (.stp or .step). + mxf_STL, ///< \ru Интерпретировать содержимое как STL (.stl). \en Read data from buffer as STL (.stl). + mxf_VRML, ///< \ru Интерпретировать содержимое как VRML (.wrl). \en Read data from buffer as VRML (.wrl). + mxf_GRDECL, ///< \ru Интерпретировать содержимое как GRDECL (.grdecl). \en Read data from buffer as GRDECL (.grdecl). + mxf_ASCIIPoint, ///< \ru Интерпретировать содержимое как облако точек в ASCII (.txt, .asc или .xyz). \en Read data from buffer as ASCII point cloud (.txt, .asc or .xyz). + mxf_C3D, ///< \ru Интерпретировать содержимое как C3D (.c3d). \en Read data from buffer as C3D (.c3d). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Результат конвертирования. + \en Result of converting operation. +\ingroup Data_Interface +*/ +// --- +enum MbeConvResType { + cnv_Success = 0, ///< \ru Успешное завершение. \en Success. + cnv_Error, ///< \ru Ошибка в процессе конвертирования. \en Error. + cnv_UserCanceled, ///< \ru Процесс прерван пользователем. \en Process interrupted by user. + cnv_NoBody, ///< \ru Не найдено тел. \en No solids found. + cnv_NoObjects, ///< \ru Не найдено объектов. \en No objects found. + cnv_FileOpenError, ///< \ru Ошибка открытия файла. \en File open error. + cnv_FileWriteError, ///< \ru Ошибка записи файла. \en File write error. + cnv_FileDeleteError, ///< \ru Ошибка удаления файла. \en Could not delete file. + cnv_ImpossibleReadAssembly,///< \ru Не поддерживает работу со сборками. \en Assemblies are not supported. + cnv_LicenseNotFound, ///< \ru Ошибка получения лицензии. \en License check failure. + cnv_NotEnoughMemory, ///< \ru Недостаточно памяти. \en Not enough memory. + cnv_UnknownExtension ///< \ru Неизвестное расширение файла. \en Unknown file extenstion. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Индексы, управляющие разрешением на чтение или запись объектов. + \en Indeces, which filter imported/exported objects or properties.\~ +\ingroup Data_Interface +*/ +// --- +enum MbeIOPermiss { + iop_rSolid = 0, ///< \ru Разрешение на чтение твёрдых тел. \en Import solid solids. + iop_wSolid, ///< \ru Разрешение на запись твёрдых тел. \en Export solid solids. + iop_rSurface, ///< \ru Разрешение на чтение поверхностей. \en Import surfaces. + iop_wSurface, ///< \ru Разрешение на запись поверхностей. \en Export surfaces. + iop_rCurve, ///< \ru Разрешение на чтение кривых. \en Import curves. + iop_wCurve, ///< \ru Разрешение на запись кривых. \en Export curves. + iop_rDrafts, ///< \ru Разрешение на чтение эскизов (не применяется). \en Import drafts (ignored). + iop_wDrafts, ///< \ru Разрешение на запись эскизов. \en Export drafts. + iop_rInvisible, ///< \ru Разрешение на чтение невидимых объектов (не применяется). \en Import invisible objects (not applied). + iop_wInvisible, ///< \ru Разрешение на запись невидимых объектов. \en Export invisible objects. + iop_rPoint, ///< \ru Разрешение на чтение точек. \en Import points. + iop_wPoint, ///< \ru Разрешение на запись точек. \en Export points. + iop_rDocInfo, ///< \ru Разрешение на чтение информации о документе (автор, организация, комментарии). \en Import components info ( author, organization, description ). + iop_wDocInfo, ///< \ru Разрешение на запись информации о документе (автор, организация, комментарии). \en Export components info ( author, organization, description ). + iop_rTextDescription, ///< \ru Разрешение на чтение технических требований. \en Import technical requirements. + iop_wTextDescription, ///< \ru Разрешение на запись технических требований. \en Export technical requirements. + iop_rDimensions, ///< \ru Разрешение на чтение размеров. \en Import dimensions. + iop_wDimensions, ///< \ru Разрешение на запись размеров. \en Export dimensions. + iop_rAttributes, ///< \ru Разрешение на чтение атрибутов. \en Import attributes. + iop_wAttributes, ///< \ru Разрешение на запись атрибутов. \en Export attributes. + iop_rBRep, ///< \ru Разрешение на чтение форм изделий в граничном представлении (только в JT). \en Import shapes in boundary representation (JT only). + iop_wBRep, ///< \ru Разрешение на запись форм изделий в граничном представлении (только в JT). \en Export shapes in boundary representation (JT only). + iop_rPolygonal, ///< \ru Разрешение на чтение полигональных форм изделий. \en Import polygonal shapes. + iop_wPolygonal, ///< \ru Разрешение на запись полигональных форм изделий. \en Export polygonal shapes. + iop_rLOD0, ///< \ru Разрешение на чтение полигональных форм изделий уровня детализации 0. \en Import polygonal shapes of the 0-th LOD. + iop_wLOD0, ///< \ru Разрешение на запись полигональных форм изделий уровня детализации 0. \en Export polygonal shapes of the 0-th LOD. + iop_rAssociated, ///< \ru Разрешение на чтение ассоциированной геометрии (резьбы и др). \en Import associated geometry (threads etc). + iop_wAssociated, ///< \ru Разрешение на запись ассоциированной геометрии (резьбы и др). \en Export associated geometry (threads etc). + iop_rDensity, ///< \ru Разрешение на чтение единиц плотности. \en Import density units. + iop_wDensity, ///< \ru Разрешение на запись единиц плотности. \en Export density units. + iop_rStyle, ///< \ru Разрешение на чтение элементов оформления (цвет, начертание, и т.п.). \en Import appearance. + iop_wStyle, ///< \ru Разрешение на запись элементов оформления (цвет, начертание, и т.п.). \en Export appearance. + iop_END +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Индексы строк, передаваемых через конвертер. + \en Indeхes of strings, transmitted through converter.\~ +\ingroup Data_Interface +*/ +// --- +enum MbeConverterStrings { + cvs_BEGIN = 0, ///< \ru Для удобства перебора. \en For lookup only. + cvs_STEPAuthor, ///< \ru Автор для конвертера STEP. \en Author of the document, in STEP. + cvs_STEPOrganization, ///< \ru Организация для конвертера STEP. \en The organization, the author is related with, in STEP. + cvs_STEPComment, ///< \ru Комментарий файла формата STEP. \en Annotation, in STEP. + cvs_END ///< \ru Для удобства перебора. \en For lookup only. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ключи строк, соответствующих названию специальных атрибутов. + \en Keys of the strings, which mark special attributes.\~ +\ingroup Data_Interface +*/ +// --- +enum ePromtAttributeKey { + pac_GConverterInternalIsDummy, ///< \ru Является ли элемент пустышкой.\~ + pac_GeneralIsAssembly, ///< \ru Является ли элемент сборкой. \en Is item assembly.\~ + pac_GeneralFileName, ///< \ru Имя файла. \en File name.\~ + pac_STEPHeader, ///< \ru Заголовок STEP. \en STEP header.\~ + pac_STEPProduct, ///< \ru Изделие STEP. \en STEP product.\~ + pac_STEPPersonOrganization, ///< \ru Лицо и организация STEP. \en STEP person and organization.\~ + pac_STEPAssignedRole ///< \ru Назначенная роль STEP. \en The role, assigned to the person.\~ +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Представление текста при экспорте. + \en Representation of exported text.\~ +\ingroup Data_Exchange +*/ +// --- +enum eTextForm { + exf_TextOnly, ///< \ru Только текст. \en Text only. + exf_GeometryOnly, ///< \ru Только геометрия. \en Geometry only. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип сообщения об ошибке при выводе в лог. + \en Type of a log message.\~ +\ingroup Data_Exchange +*/ +// --- +enum eMsgType { + emt_ErrorNoId,///< \ru Ошибка формата. Значение id игнорируется, выводится только текст. \en Error not related with a certain record. The id field is ignored. + emt_TextOnly, ///< \ru Значение id игнорируется, выводится только текст. \en Used to type message only. The id field is ignored. + emt_Info, ///< \ru Рабочая информация. \en Info. + emt_Warning, ///< \ru Предупреждение. \en Warning. + emt_Error ///< \ru Ошибка формата или неустранимая ошибка преобразования. \en Format mismatch or fatal converting error. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Код подробного сообщения об ошибке при выводе в лог. + \en The key of a detailed log message.\~ +\ingroup Data_Interface +*/ +// --- +enum eMsgDetail { + emd_Title, ///< \ru Заголовок файла. \en File header. + emd_HEADError, ///< \ru Тип сообщения - ошибка. \en Error. + emd_HEADWarinig, ///< \ru Тип сообщения - Предупреждение. \en Warning. + emd_HEADInfo, ///< \ru Тип сообщения - Информация. \en Info. + emd_HEADDefaultMsg, ///< \ru Тип сообщения - Сообщение. \en Message. + + emd_STOPFileOpenError, ///< \ru Ошибка открытия файла. \en Cannot open file. + emd_STOPFileOpenErrorOrEmpty, ///< \ru Ошибка открытия файла или файл пуст. \en Cannot open file or file is empty. + emd_STOPHeaderReadError, ///< \ru Не удалось прочитать заголовок файла. \en Cannot read file header. + emd_STOPNoOrBadData, ///< \ru Файл не содержит данных или их не удалось распознать. \en File body does not exist or incorrect. + emd_STOPIncorrectStructure, ///< \ru Неверная структура файла. \en Incorrect file structure. + emd_STOPAddressConflict, ///< \ru Данный адрес имеют два различных объекта. \en Two or more entities have the same id. + + emd_ErrorNoRootObject, ///< \ru Не найден корневой объект. \en Root object not found. + emd_ErrorSyntaxIncorrectFormFloat, ///< \ru Невозможно прочитать действительную константу. \en Error reading floating-point number. + emd_ErrorEmptyLoop, ///< \ru Цикл грани пуст. \en Face has an empty loop. + emd_ErrorEmptyQueriesList, ///< \ru Список запросов пуст. \en + emd_ErrorEmptyObjectsList, ///< \ru Список объектов пуст. \en List of objects is empty. + emd_ErrorEmptyGeomObjectsList, ///< \ru Список геометрических объектов пуст. \en List of geometric objects is empty. + emd_ErrorEmptyShellsList, ///< \ru Список оболочек пуст. \en List of shells is empty. + emd_ErrorEmptyListOfWrieframes, ///< \ru Список каркасов пуст. \en List of frames is empty. + emd_ErrorEmptyCurveCompositesList, ///< \ru Список компонент составной кривой пуст. \en Composite curve has an empty list of composites. + emd_ErrorEmptyBoundCurvesList, ///< \ru Список граничных кривых пуст. \en List of boundary curves is empty. + emd_ErrorEmptyEdgeList, ///< \ru Список рёбер пуст. \en List of edges is empty. + emd_ErrorEmptyFacesList, ///< \ru Список граней пуст. \en List of faces is empty. + emd_ErrorEmptyReferencesList, ///< \ru Список ссылок пуст. \en List of references is empty. + emd_ErrorEmptyOrMore2ReferencesList,///< \ru Список ссылок пуст или содержит более 2 элементов. \en List of references is empty or contains more than 2 items. + emd_ErrorUndefinedFaceSurfaceRef, ///< \ru Ссылка на базовую поверхность грани не определена. \en Invalid reference to base surface. + emd_ErrorUndefinedBaseCurveRef, ///< \ru Ссылка на базовую кривую не определена. \en Invalid reference to base curve. + emd_ErrorRadiusTooCloseToZero, ///< \ru Радиус слишком мал. \en Too small radius. + emd_ErrorRadiusValueNegative, ///< \ru Отрицательное значение радиуса. \en Negative value of radius. + emd_ErrorEllipseAxisTooCloseToZero, ///< \ru Длина полуоси эллипса слишком мала. \en Ellipse axis is too short. + emd_ErrorEllipseAxisNegative, ///< \ru Отрицательная длина полуоси эллипса. \en Ellipse axis length is negative. + emd_ErrorNegativeDegree, ///< \ru Отрицательный порядок сплайна. \en Negative spline order. + emd_ErrorNegativeUDegree, ///< \ru Отрицательный порядок сплайновой поверхности по U. \en Spline surface order along U is negative. + emd_ErrorNegativeVDegree, ///< \ru Отрицательный порядок сплайновой поверхности по V. \en Spline surface order along V is negative. + emd_ErrorDegreeFixImpossible, ///< \ru Невозможно исправить порядок сплайна. \en Cannot fix spline order. + emd_ErrorPolylinePointListLess2, ///< \ru Список точек ломаной содержит менее 2 элементов. \en Polyline contains less then 2 points. + emd_ErrorPointListLess2, ///< \ru Список точек содержит менее 2 элементов. \en List of points contains less then 2 points. + emd_ErrorKnotsListLess2, ///< \ru Список узлов содержит менее 2 элементов. \en List of knots contains less then 2 values. + emd_ErrorWeightsListLess2, ///< \ru Список весов содержит менее 2 элементов. \en List of weights contains less then 2 values. + emd_ErrorUPointListLess2, ///< \ru Список точек по U содержит менее 2 элементов. \en List of points along U contains less then 2 points. + emd_ErrorUKnotsListLess2, ///< \ru Список узлов по U содержит менее 2 элементов. \en List of knots along U contains less then 2 values. + emd_ErrorUWeightsListLess2, ///< \ru Список весов по U содержит менее 2 элементов. \en List of weights along U contains less then 2 values. + emd_ErrorVPointListLess2, ///< \ru Список точек по V содержит менее 2 элементов. \en List of points along V contains less then 2 points. + emd_ErrorVKnotsListLess2, ///< \ru Список узлов по V содержит менее 2 элементов. \en List of knots along V contains less then 2 values. + emd_ErrorVWeightsListLess2, ///< \ru Список весов по V содержит менее 2 элементов. \en List of weights along V contains less then 2 values. + emd_ErrorListsSizeMismatch, ///< \ru Размеры списков не согласуются. \en Lists size mismatch. + emd_ErrorKnotsWeightsListsOrderMismatch, ///< \ru Размеры списков узлов и весов не согласуются с порядком сплайна. \en Sizes of knots and weights lists do not agree with the spline order. + emd_ErrorKnotsWeightsListsSizeMismatch, ///< \ru Размеры списков узлов и весов не согласуются. \en Size of knots list does not agree with the size of the list of weights. + emd_ErrorUKnotsWeightsListsSizeMismatch, ///< \ru Размеры списков узлов и весов по U не согласуются. \en Sizes of knots and weights lists along U do not agree. + emd_ErrorVKnotsWeightsListsSizeMismatch, ///< \ru Размеры списков узлов и весов по V не согласуются. \en Sizes of knots and weights lists along V do not agree. + emd_ErrorSplineCurveNotCreatedUndefinedKnotsVector, ///< \ru Сплайновая кривая не создана - не определёны узлы. \en Cannot create spline, because knots are not defined. + emd_ErrorSplineSurfaceNotCreatedUndefinedKnotsVectors, ///< \ru Сплайновая поверхность не создана - не определёны узлы. \en Cannot create spline surface, because knots are not defined. + emd_ErrorInCorrectSplineSurfaceData, ///< \ru Неверно заданы параметры NURBS поверхности. \en Spline surface parameters are not valid. + + emd_WarningNoSectionTerminator, ///< \ru Маркер завершения раздела не обнаружен. \en Section terminator not found. + emd_WarningSyntaxMultipleDotInFloat, ///< \ru Повторяющаяся точка в действительном числе. \en Too many dots in a floating-point number. + emd_WarningSyntaxMultipleEInFloat, ///< \ru Повторяющаяся E в действительном числе. \en Too many E signs in a floating-point number. + emd_WarningLoopNotClosed, ///< \ru Цикл не замкнут. \en Loop is not closed. + emd_WarningContourNotClosed, ///< \ru Контур не замкнут. \en contour is not closed. + emd_WarningUndefinedRef, ///< \ru Ссылка не определена. \en Invalid reference. + emd_WarningToroidalSurfaceDegenerated, ///< \ru Тороидальная поверхность вырождена. \en Toroidal surface is degenerate. + emd_WarningUndefinedBasisCurve, ///< \ru Не определена базовая кривая. \en Base curve not defined. + emd_WarningUndefinedSweptCurve, ///< \ru Не определена образующая кривая. \en Generatrix curve is not defined. + emd_WarningUndefinedExtrusionDirection, ///< \ru Не определено направление выдавливания. \en Extrusion direction is not defined. + emd_WarningUndefinedAxis, ///< \ru Не определена ось. \en Axis is not defined. + emd_WarningUndefinedAxisOfRevolution, ///< \ru Не определена ось вращения. \en Rotation axis is not defined. + emd_WarningUndefinedBasisSurface, ///< \ru Не определена базовая поверхность. \en Base surface is not defined. + emd_WarningUndefinedRepresentation, ///< \ru Не определено представление. \en Representation is not defined. + emd_WarningUndefinedTransformationOperator, ///< \ru Не определён оператор преобразования. \en Transformation is not defined. + emd_WarningUndefinedObjectTransformBy, ///< \ru Не определён объект, по которому ведётся преобразование. \en Basic object of transformation is not defined. + emd_WarningUndefinedObjectToTransform, ///< \ru Не определён преобразуемый объект. \en No object to transform is defined. + emd_WarningUndefinedCurve, ///< \ru Не определена кривая. \en Curve is not defined. + emd_WarningUndefinedCompositeSegment, ///< \ru Не определён сегмент составной кривой. \en Composite curve segment is not defined. + emd_WarningUndefinedDirection, ///< \ru Не определено направление. \en Direction is not defined. + emd_WarningUndefinedAxisDirection, ///< \ru Не определено направление оси. \en Axis direction is not defined. + emd_WarningDegeneratedItemWasSkipped, ///< \ru Проигнорирован (пропущен) вырожденный объект. \en Degenerate object was missed. + emd_WarningFloatParceFailureDefaultUsed, ///< \ru Ошибка разпознавания числа с плавающей точкой, подставлено значение по умолчанию. \en Floating point value couldn't be parced; default value was used. + emd_WarningIncorrectFaceWasNotAddedToShell, ///< \ru Некорректная грань не была добавлена в оболочку. \en Incorrect face was not added to shell. + emd_WarningBoundsNotConnectedWithSeams, ///< \ru Границы замкнутой грани не стыкуются со швами. \en Bounds of periodic face not connected with seams. + + emd_MessageWeightsFilled, ///< \ru Веса заданы. \en Weights are set. + + emd_ErrorSTEPEdgeCurveFlagTSingleRedefinition, ///< \ru При создании ребра в конвертере STEP дважды указана грань с флагом .T.. \en Double .T. face inclusion in STEP. + emd_ErrorSTEPEdgeCurveFlagFSingleRedefinition, ///< \ru При создании ребра в конвертере STEP дважды указана грань с флагом .F.. \en Double .F. face inclusion in STEP. + emd_ErrorSTEPEdgeCurveFlagTMultipleRedefinition, ///< \ru При создании ребра в конвертере STEP более чем дважды указана грань с флагом .T.. \en Multiple .T. face inclusion in STEP. + emd_ErrorSTEPEdgeCurveFlagFMultipleRedefinition, ///< \ru При создании ребра в конвертере STEP более чем дважды указана грань с флагом .F.. \en Multiple .F. face inclusion in STEP. + emd_ErrorSTEPUndefinedFaceGeometry, ///< \ru Не определена геометрия грани в конвертере STEP. \en Face geometry is not defined in STEP. + emd_ErrorSTEPSyntaxMultipleDotInEnum, ///< \ru Синтаксическая ошибка в файле формата STEP - в перечислении символ "." встречается более 1 раза подряд. \en Too many dots in a enumeration record in STEP. + emd_WarningSTEPPointCorrection, ///< \ru Скорректированы координаты точки. \en Point location corrected. ( by BUG_73871 ) + emd_WarningSTEPEdgeCurveByVertices, ///< \ru Кривая ребра скорректирована с учётом координат вершин. \en Edge curve corrected in accordance with vertices. ( by BUG_73871 ) + emd_MessageSTEPFlagChangedToF, ///< \ru Произведена замена флага на .F.. \en Flag was set as .F. in STEP. + emd_MessageSTEPFlagChangedToT, ///< \ru Произведена замена флага на .T.. \en Flag was set as .T. in STEP. + + emd_WarningACISUnsupportedInterpoleCurveType, ///< \ru Данный подтип ACIS интерполяционной кривой не поддерживается. \en Interpolation curve type is not supported by SAT converter. + emd_WarningACISUnsupportedParametricCurveType, ///< \ru Данный подтип ACIS параметрической кривой не поддерживается. \en Parametric curve type is not supported by SAT converter. + emd_ErrorACISUnsupportedVersion, ///< \ru Данная версия ACIS NT не поддерживается. \en Th version of file is not supported by SAT converter. + emd_WarningACISCannotImportEntityId, ///< \ru Не удалось импортировать объект с данным Id. \en Cannot import this object by SAT converter. + emd_WarningACISIncorrectIntAttribute, ///< \ru Некорректный целочисленный атрибут. \en Incorrect integer attribute. + + emd_ErrorIGESIncorrectExternalReference, ///< \ru Неверное имя внешней ссылки. \en Invalid external reference in IGES. + + emd_ErrorSTLTooManyTrianglesForBinary, ///< \ru Триангуляция исходной модели содержит больше треугольников, чем допустимо стандартом ( не выражается 32-битным беззнаковым числом ) ( by BUG_71422 ). \en Too many triangles (not represented by unsigned 32-bit number) for export to binary STL. + + emd_ErrorXTUnsupportedVersion, ///< \ru Данная версия X_T не поддерживается. \en Th version of file is not supported by X_T converter. + + emd_ErrorJTUnsupportedVersion ///< \ru Данная версия JT не поддерживается. \en Th version of file is not supported by JT converter. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы сообщений индикатора прогресса выполнения конвертации данных. + \en Identifiers of the execution progress indicator messages converters data exchange \~ +\ingroup Data_Exchange +*/ +//--- +enum MbeProgBarId_Converters { + pbarId_Cnv_Beg = pbarId_PointsSurface_End + 1, + + pbarId_Cnv_Parse_Data, // \ru Синтаксический анализ... \en Syntactic analysis... + pbarId_Cnv_Create_Objects, // \ru Создание объектов... \en Creation of objects... + pbarId_Cnv_Process_Surfaces, // \ru Обработка поверхностей... \en Surfaces processing... + pbarId_Cnv_Process_Annotation,// \ru Обработка аннотации... \en Annotation processing... + pbarId_Cnv_Create_Model, // \ru Создание модели... \en Creation of model... + pbarId_Cnv_Write_Model, // \ru Запись модели... \en Writing of model... + + pbarId_Cnv_End, +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы сообщений индикатора прогресса выполнения триангуляции при выполнении конвертации данных. + \en Identifiers of the execution progress indicator messages triangulation. \~ +\ingroup Data_Exchange +*/ +//--- +enum MbeProgBarId_Triangulation { + pbarId_Triangulation_Beg = pbarId_Cnv_End + 1, + + pbarId_Calc_Triangulation, // \ru Расчет триангуляции \en Calculating of triangulation + + pbarId_Triangulation_End, +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы сообщений индикатора прогресса выполнения расчёта + масс-инерционные характеристики детали или сборки при выполнении конвертации данных. + \en Identifiers of the execution progress indicator messages of mass-inertial properties of assembly or a detail. \~ +\ingroup Data_Exchange +*/ +//--- +enum MbeProgBarId_MassInertiaProperties { + pbarId_MassInertiaProperties_Beg = pbarId_Triangulation_End + 1, + + pbarId_Calc_MassInertiaProperties, // \ru Расчет масс-инерционных характеристик \en Mass-inertial properties calculation + + pbarId_MassInertiaProperties_End, +}; + + +#endif // __CONV_ERROR_RESULT_H \ No newline at end of file diff --git a/C3d/Include/conv_i_converter.h b/C3d/Include/conv_i_converter.h new file mode 100644 index 0000000..d899345 --- /dev/null +++ b/C3d/Include/conv_i_converter.h @@ -0,0 +1,901 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Интерфейсы конвертера. + \en Interfaces of the converter. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONV_I_CONVERTER_H +#define __CONV_I_CONVERTER_H + + +#include +#include +#include +#include +#include +#include + + +class IProgressIndicator; +struct IScaleRequestor; +class ItModelDocument; +class MATH_CLASS MbRefItem; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbModel; + + +/** + \addtogroup Exchange_Interface + \{ +*/ + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс свойств конвертера. + \en Interface of converter's properties. \~ + \details \ru Интерфейс свойств конвертера реализует выдачу имени документа и других сведений о нём, таких как автор, + и управление режимами работы - сшивкой поверхностей с возможностью создания твёрдых + тел, фильтрацией объектов, формирование журнала трансляции. + \en Interface of converter's properties realizes getting the document's name and other information about it, such as the author, + and management of modes of operations - stitching of surfaces with possibility of solids creation, + objects filtration, generation of translation journal. \~ +\ingroup Exchange_Interface +*/ +class IConvertorProperty3D { +public : + virtual ~IConvertorProperty3D() {} + +public: + /// \ru Получить имя документа. \en Get document's name. + virtual const std::string GetDocumentName () const = 0; //{ return std::string( GetDocName().get_str() ); }; + /// \ru Получить имя файла для конвертирования. \en Get file name for converting. + virtual const c3d::path_string FullFilePath () const = 0 ;//{ return c3d::path_string( GetFileName().c_str() ); }; + /// \ru Является ли файл текстовым. \en Whether the file is a text file. + virtual bool IsFileAscii () const = 0; + /// \ru Получить версию формата при экспорте. \en Get the version of format for export. + virtual long int GetFormatVersion () const { return EXPORT_DEFAULT; }; + /// \ru Задать формат для экспорта \en Set format for export + DEPRECATE_DECLARE virtual MbeImpExpFormat GetFormat () const { return ief_STEP203; } + /// \ru Следует ли экспортировать только поверхности ( введено для работы конвертера IGES ). \en Whether to export only surfaces (introduced for work with converter IGES ). + virtual bool IsOutOnlySurfaces() const = 0; + /// \ru Является ли экспортируемый документ сборкой. \en Whether the document for export is an assembly. + virtual bool IsAssembling () const = 0; + /// \ru Получить значение разрешения на импорт экспорт объектов определенного типа. \en Get the value of permission for import-export of objects of a certain type. + virtual bool GetIoPermission( MbeIOPermiss nPermission ) const = 0; + /// \ru Получить значения разрешений на импорт экспорт объектов определенных типов. \en Get values of permission for import-export of objects of certain types. + virtual void GetIoPermissions( std::vector& ioPermissions ) const = 0; + /// \ru Установить разрешение на импорт экспорт объектов определенного типа. \en Set permission for import-export of objects of a certain type. + virtual void SetIoPermission( MbeIOPermiss nPermission, bool set ) = 0; + /// \ru Получить значение специфичной строки для конвертера. \en Get the value of a certain string for the converter. + virtual bool GetPropertyString ( MbeConverterStrings nString, std::string & propertyString ) const = 0; + /// \ru Установить значение специфичной строки для конвертера. \en Set the value of a certain string for the converter. + virtual void SetPropertyString ( MbeConverterStrings nString, const std::string & propertyString ) = 0; + /// \ru Представление текста в аннотационных объектах. \en Text representation in annotation objects. + virtual eTextForm GetAnnotationTextRepresentation () const { return exf_TextOnly; } + /// \ru Следует ли компоненты экспортировать в разные файлы (если позволяет формат). \en Export components into separate files ( if provided in format). + virtual bool ExportComponentsSeparately() const { return false; } + /// \ru Получить ЛСК, относительно которой позиционирована модель. \en Get the location, the model is placed in. + virtual MbPlacement3D GetOriginLocation() const = 0; + /// \ru Заменять ли принудительно СК компонент на правые. \en Replace components' placements to right-oriented. + virtual bool ReplaceLocationsToRight() const = 0; + /** \brief \ru Сшивать ли поверхности автоматически. + \en If surfaces should be stitched automatically. \~ + \return \ru true - Сшивать поверхности автоматически, false - Спросить пользователя, сшивать ли поверхности. + \en true - Stitch surfaces automatically, false - Ask user first time. \~ + \param[out] stitchPrecision - \ru Точность сшивки. + \en Stitch precision. \~ + */ + virtual bool EnableAutoStitch( double& /*stitchPrecision*/ ) const = 0; + + /** \brief \ru Получить множитель единиц длины по отношению к миллиметру. + \en Get the factor of the length units to millimeters. \~ + \details \ru При импорте, если единицы измерения не заданы явно с помощью средств, предоставляемых обменным форматом, + все размеры (координаты точек, радиусы) умножаются на возвращаемое значение. При экспорте либо с помощью + средств, предоставляемых обменным форматом, задаются единицы измерения, либо все размеры модели (координаты + точек, радиусы) умножаются на возвращаемое значение. + \en During the import all spatial objects (coordinate values, radiuses) are multiplied by the returned value, + unless the scale factor comes from the exchange file. During the export the exchange format facilities are + used to specify the length units or all spatial objects (coordinate values, radiuses) are multiplied by the + returned value. \~ + */ + virtual double LengthUnitsFactor() const { return LENGTH_UNIT_MM; } + + + /** \brief \ru Получить дополнительный множитель единиц длины по отношению к миллиметру в модели приложения. + \en Get addifional factor of the length units to millimeters in the application model. \~ + \details \ru При импорте из всех форматов за исключением JT, если единицы измерения, в том числе и заданные + явно с помощью средств, предоставляемых обменным форматом, все размеры (координаты точек, радиусы) умножаются + на возвращаемое значение. При экспорте либо с помощью средств, предоставляемых обменным форматом, задаются + единицы измерения, либо все размеры модели (координаты точек, радиусы) умножаются на возвращаемое значение. + \en During the import from all formats except for JT all spatial objects (coordinate values, radiuses) are + multiplied by the returned value, even if the scale factor comes from the exchange file. During the export the + exchange format facilities are used to specify the length units or all spatial objects (coordinate values, + radiuses) are multiplied by the returned value. \~ + */ + virtual double AppLengthUnitsFactor() const { return LENGTH_UNIT_MM; } + + /** \brief \ru Сделать запись в журнал конвертирования. + \en Make a record in the converter report. \~ + \param[in] id - \ru Идентификатор элемента внутри файла стороннего формата. + \en Identifier of an element inside the file of a foreign format. \~ + \param[in] msgType - \ru Тип сообщения. + \en Message type. \~ + \param[in] msgText - \ru Код сообщения. + \en Message code. \~ + */ + virtual void LogReport( ptrdiff_t id, eMsgType msgType, eMsgDetail msgText ) = 0; + +// /** \brief \ru Следует ли показывать сообщения и диалоги пользователю. \en Whether to show messages and dialog to the user. \~ +// \details \ru Обеспечивает работу через API. \en Provide possibility for work via API. \~ +// \return \ru true - обычная работа, false - через API. \en true - ordinary work, false - via API. \~ +// */ + virtual bool CanShowMessages() const = 0; + /// \ru Дать данные вычисления триангуляции (для конвертера JT, STL и VRML). \en Get data for step calculation during triangulation (for JT, STL, VRML only). + virtual MbStepData TesselationParameters() const { return MbStepData(); } + /// \ru Дать данные вычисления триангуляции уровня детализации (для конвертера JT). \en Get data for step calculation during triangulation of LOD0 (for JTonly). + virtual MbStepData LOD0TesselationParameters() const { return TesselationParameters(); } + /// \ru Флаг сохранения совпадающих точек швов. (для конвертера STL и VRML). \en Whether to keep coincident points of seams (for STL, VRML only). + virtual bool DualSeams() const { return true; } + /// \ru Флаг сохранения совпадающих точек швов. (для конвертера STL и VRML). \en Whether to keep coincident points of seams (for STL, VRML only). + virtual void DualSeams( bool ) {} + /// \ru Проводить ли аудит траснляции. \en Whether to audit the translation. + virtual bool TotalAudit() { return false; } + + /// \ru Выполнять ли слияние подобных граней. \en Whether to join similar faces. + virtual bool JoinSimilarFaces() const { return true; } + /// \ru Добавлять ли удаленные грани в качестве оболочек. \en Whether to add removed faces as shells. + virtual bool AddRemovedFacesAsShells() const { return false; } +}; // IConvertorProperty3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс конвертера. + \en Converter's interface. \~ + \details \ru Интерфейс конвертера реализует методы экспорта модели в файлы обменных форматов + и импорта из них. + \en Converter's interface implements methods of export of the model to files of exchange formats + and import from them. \~ +*/ +class IConvertor3D { +public: + virtual ~IConvertor3D() {} + +public: + /** \brief \ru Прочитать файл формата SAT. + \en Read a file of SAT format. \~ + \details \ru Прочитать файл формата SAT или указанный поток. + Если задан поток, то запись производится в присланный поток. + Если поток не задан (нулевой), то открывается поток для файла, заданного в свойствах конвертера. \n + \en Read a file of SAT format or a specified stream. + If a stream is specified, then the record is performed to the given stream. + If a stream is not specified (null), then a stream is being opened for file specified in the properties of the converter. \n \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] stream - \ru Поток, из которого производится чтение (может быть NULL). + \en Stream from which reading is performed (can be NULL). \~ + \param[in] indicator - \ru Индикатор хода процесса (может быть NULL). + \en The process progress indicator (can be NULL). \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ACIS_Exchange + */ + virtual MbeConvResType SATRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, std::iostream * stream, IProgressIndicator * indicator, MbRefItem * qeuryStitch ) = 0; + + /** \brief \ru Записать файл формата SAT. + \en Write file of SAT format. \~ + \details \ru Записать файл формата SAT или указанный поток. + Если задан поток, то запись производится в присланный поток. + Если поток не задан (нулевой), то открывается поток для файла, заданного в свойствах конвертера. \n + \en Write file of SAT format or the specified stream. + If a stream is specified, then the record is performed to the given stream. + If a stream is not specified (null), then a stream is being opened for file specified in the properties of the converter. \n \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] stream - \ru Поток, в который производится запись (может быть NULL). + \en Stream in which the record is performed (can be NULL). \~ + \param[in] indicator - \ru Индикатор хода процесса (может быть NULL). + \en The process progress indicator (can be NULL). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ACIS_Exchange + */ + virtual MbeConvResType SATWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, std::iostream * stream, IProgressIndicator * indicator ) = 0; + + /** \brief \ru Прочитать файл формата SAT. + \en Read a file of SAT format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ACIS_Exchange + */ + virtual MbeConvResType SATRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата SAT. + \en Write file of SAT format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ACIS_Exchange + */ + virtual MbeConvResType SATWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата IGES. + \en Read a file of IGES format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup IGES_Exchange + */ + virtual MbeConvResType IGSRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата IGES. + \en Write a file of IGES format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup IGES_Exchange + */ + virtual MbeConvResType IGSWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата JT. + \en Read a file of JT format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup IGES_Exchange + */ + virtual MbeConvResType JTRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата JT. + \en Write a file of JT format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup IGES_Exchange + */ + virtual MbeConvResType JTWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата Parasolid. + \en Read a file of Parasolid format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Parasolid_Exchange + */ + virtual MbeConvResType XTRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата Parasolid. + \en Write a file of Parasolid format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей. + \en Dialog of request for stitching the surfaces. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Parasolid_Exchange + */ + virtual MbeConvResType XTWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата STEP. + \en Read a file of STEP format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup STEP_Exchange + */ + virtual MbeConvResType STEPRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата STEP. + \en Write a file of STEP format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup STEP_Exchange + */ + virtual MbeConvResType STEPWrite( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата STL. + \en Read a file of STL format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup STL_Exchange + */ + virtual MbeConvResType STLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата STL. + \en Write a file of STL format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup STL_Exchange + */ + virtual MbeConvResType STLWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата VRML. + \en Read a file of VRML format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup VRML_Exchange + */ + virtual MbeConvResType VRMLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата VRML. + \en Write a file of VRML format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \param[in] devSag - \ru Угловой шаг для расчёта триангуляционной сетки. + \en Deviate sag requiref for grid calculateion. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup VRML_Exchange + */ + virtual MbeConvResType VRMLWrite( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл формата GRDECL. + \en Read a file of GRDECL format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup VRML_Exchange + */ + virtual MbeConvResType GRDECLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл формата GRDECL. + \en Write a file of GRDECL format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup STL_Exchange + */ + virtual MbeConvResType GRDECLWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Прочитать файл с облаком точек в формате ASCII. + \en Read a file of ASCII Point Cloud format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ASCII_Exchange + */ + virtual MbeConvResType ASCIIPointCloudRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + + /** \brief \ru Записать файл с облаком точек в формате ASCII.. + \en Write a point cloud file of ASCII format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \param[in] qeuryStitch - \ru Диалог запроса на сшивку поверхностей (не используется). + \en Dialog of request for stitching the surfaces (not used). \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup ASCII_Exchange + */ + virtual MbeConvResType ASCIIPointCloudWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0, MbRefItem * qeuryStitch = 0 ) = 0; + +}; // IConvertor3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить интерфейс конвертера. + \en Get the converter interface. \~ +\ingroup Exchange_Interface +*/ +CONV_FUNC (IConvertor3D *) GetConvertor3D(); + + + +/** \brief \ru Прочитать файл формата SAT. + \en Read a file of SAT format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup ACIS_Exchange +*/ +CONV_FUNC (MbeConvResType ) SATRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator ); + +/** \brief \ru Записать файл формата SAT. + \en Write file of SAT format. \~ +\details \ru Записать файл формата SAT или указанный поток. + Если задан поток, то запись производится в присланный поток. + Если поток не задан (нулевой), то открывается поток для файла, заданного в свойствах конвертера. \n + \en Write file of SAT format or the specified stream. + If a stream is specified, then the record is performed to the given stream. + If a stream is not specified (null), then a stream is being opened for file specified in the properties of the converter. \n \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса (может быть NULL). + \en The process progress indicator (can be NULL). \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup ACIS_Exchange +*/ +CONV_FUNC (MbeConvResType ) SATWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator ); +/** \brief \ru Прочитать файл формата IGES. + \en Read a file of IGES format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup IGES_Exchange +*/ +CONV_FUNC (MbeConvResType ) IGSRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата IGES. + \en Write a file of IGES format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup IGES_Exchange +*/ +CONV_FUNC (MbeConvResType ) IGSWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата JT. + \en Read a file of JT format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup IGES_Exchange +*/ +CONV_FUNC (MbeConvResType ) JTRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата JT. + \en Write a file of JT format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup IGES_Exchange +*/ +CONV_FUNC (MbeConvResType ) JTWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата Parasolid. + \en Read a file of Parasolid format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~\~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup Parasolid_Exchange +*/ +CONV_FUNC (MbeConvResType ) XTRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата Parasolid. + \en Write a file of Parasolid format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup Parasolid_Exchange +*/ +CONV_FUNC (MbeConvResType ) XTWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата STEP. + \en Read a file of STEP format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup STEP_Exchange +*/ +CONV_FUNC (MbeConvResType ) STEPRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата STEP. + \en Write a file of STEP format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup STEP_Exchange +*/ +CONV_FUNC (MbeConvResType ) STEPWrite( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата STL. + \en Read a file of STL format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup STL_Exchange +*/ +CONV_FUNC (MbeConvResType ) STLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата STL. + \en Write a file of STL format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup STL_Exchange +*/ +CONV_FUNC (MbeConvResType ) STLWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата VRML. + \en Read a file of VRML format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup VRML_Exchange +*/ +CONV_FUNC (MbeConvResType ) VRMLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Прочитать файл формата GRDECL. + \en Read a file of GRDECL format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup VRML_Exchange +*/ +CONV_FUNC (MbeConvResType ) GRDECLRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата GRDECL. + \en Write a file of GRDECL format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup STL_Exchange +*/ +CONV_FUNC (MbeConvResType ) GRDECLWrite ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + +/** \brief \ru Записать файл формата VRML. + \en Write a file of VRML format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup VRML_Exchange +*/ +CONV_FUNC (MbeConvResType ) VRMLWrite( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + + +/** \brief \ru Прочитать файл с облаком точек в формате ASCII. + \en Read a file of ASCII Point Cloud format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup ASCII_Exchange +*/ +CONV_FUNC (MbeConvResType ) ASCIIPointCloudRead ( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + + +/** \brief \ru Записать файл с облаком точек в формате ASCII.. + \en Write a point cloud file of ASCII format. \~ +\param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ +\param[in] idoc - \ru Реализация интерфейса документа. + \en Implementation of document interface. \~ +\param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ +\return \ru Код завершения операции. + \en Code of the operation termination. \~ +\ingroup ASCII_Exchange +*/ +CONV_FUNC (MbeConvResType ) ASCIIPointCloudWrite( IConvertorProperty3D & prop, ItModelDocument & idoc, IProgressIndicator * indicator = 0 ); + + +namespace c3d { + + /** \brief \ru Прочитать файл обменного формата в модель. + \en Read a file of an exchange format into model. \~ + \details \ru Если свойства конвертера заданы, аргумент fileName игнорируется, а имя файла берётся из свойств конвертера. + В противном случае импорт идёт с умолчательными параметрами, соответствующими реализации ConvConvertorProperty3D. \~ + \en The fileName argument is not used if converter properties are defined obviously, file path comes from the FullFilePath + method. Otherwise default parameters corresponding ConvConvertorProperty3D implementation are used for import. + \param[out] model - \ru Модель. + \en The model. \~ + \param[in] filePath - \ru Путь файла. + \en File path. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Exchange_Interface + */ + CONV_FUNC (MbeConvResType) ImportFromFile( MbModel & model, + const path_string & fileName, + IConvertorProperty3D * prop = 0, + IProgressIndicator * indicator = 0 ); + + /** \brief \ru Прочитать файл обменного формата в модель. + \en Read a file of an exchange format into model. \~ + \details \ru Если свойства конвертера заданы, аргумент fileName игнорируется, а имя файла берётся из свойств конвертера. + В противном случае импорт идёт с умолчательными параметрами, соответствующими реализации ConvConvertorProperty3D. \~ + \en The fileName argument is not used if converter properties are defined obviously, file path comes from the FullFilePath + method. Otherwise default parameters corresponding ConvConvertorProperty3D implementation are used for import. + \param[out] mDoc - \ru Модельный документ. + \en The model. \~ + \param[in] filePath - \ru Путь файла. + \en File path. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Exchange_Interface + */ + CONV_FUNC (MbeConvResType) ImportFromFile( ItModelDocument & mDoc, + const path_string & filePath, + IConvertorProperty3D * prop, + IProgressIndicator * indicator ); + + /** \brief \ru Записать модель в файл обменного формата. + \en Write the model into an exchange format file. \~ + \details \ru Если свойства конвертера заданы, аргумент fileName игнорируется, а имя файла берётся из свойств конвертера. + В противном случае экспорт идёт с умолчательными параметрами, соответствующими реализации ConvConvertorProperty3D. \~ + \en The fileName argument is not used if converter properties are defined obviously, file path comes from the FullFilePath + method. Otherwise default parameters corresponding ConvConvertorProperty3D implementation are used for export. + \param[out] model - \ru Модель. + \en The model. \~ + \param[in] filePath - \ru Путь файла. + \en File path. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Exchange_Interface + */ + CONV_FUNC (MbeConvResType) ExportIntoFile( MbModel & model, + const path_string & filePath, + IConvertorProperty3D * prop = 0, + IProgressIndicator * indicator = 0 ); + + /** \brief \ru Импортировать данные из буфера в модель. + \en Import data from buffer into model. \~ + \param[out] model - \ru Модель. + \en The model. \~ + \param[in] data - \ru Буфер. + \en Buffer. \~ + \param[in] length - \ru Размер буфера. + \en Buffer size. \~ + \param[in] modelFormat - \ru Формат модели. + \en Model format. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Exchange_Interface + */ + CONV_FUNC (MbeConvResType) ImportFromBuffer( MbModel & model, + const char * data, + size_t length, + MbeModelExchangeFormat modelFormat, + IConvertorProperty3D * prop = 0, + IProgressIndicator * indicator = 0 ); + + /** \brief \ru Экспортировать модель в буфер. + \en Export model into buffer. \~ + \param[in] model - \ru Модель. + \en The model. \~ + \param[in] modelFormat - \ru Формат модели. + \en Model format. \~ + \param[out] data - \ru Буфер. + \en Buffer. \~ + \param[out] length - \ru Размер буфера. + \en Buffer size. \~ + \param[in] prop - \ru Реализация интерфейса свойств конвертера. + \en Implementation of converter's properties interface. \~ + \param[in] indicator - \ru Индикатор хода процесса. + \en The process progress indicator. \~ + \return \ru Код завершения операции. + \en Code of the operation termination. \~ + \ingroup Exchange_Interface + */ + CONV_FUNC (MbeConvResType) ExportIntoBuffer( MbModel & model, + MbeModelExchangeFormat modelFormat, + char *& data, + size_t & length, + IConvertorProperty3D * prop = 0, + IProgressIndicator * indicator = 0 ); +}; + + +/** \} */ + + +#endif // __CONV_I_CONVERTER_H diff --git a/C3d/Include/conv_model_properties.h b/C3d/Include/conv_model_properties.h new file mode 100644 index 0000000..39b2f00 --- /dev/null +++ b/C3d/Include/conv_model_properties.h @@ -0,0 +1,712 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Интерфейсы, используемые при импорте и экспорте. + \en Interfaces used for import and export. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONV_MODEL_PROPERTIES_H +#define __CONV_MODEL_PROPERTIES_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbItem; +class MATH_CLASS MbName; +class ItModelAssembly; +class ItModelPart; + + +/** \brief \ru Контейнер объектов аннотации. + \en Container of annotation objects. \~ +\ingroup Exchange_Base +*/ +typedef std::vector vector_of_annotation; + + +/** \brief \ru Ассоциация наборов аннотационных объектов элементам со счётчиком ссылок. + \en Association of sets of annotation objects with elements with reference counter. \~ +\ingroup Exchange_Base +*/ +typedef std::map< SPtr, vector_of_annotation > map_of_visual_items; + + +/** \brief \ru Контейнер текстовых блоков. + \en Container of text blocks. \~ +\ingroup Exchange_Base +*/ +typedef std::vector< SPtr > vector_of_text; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы линий, передаваемых через конвертер. + \en Types of lines passed via converter. \~ +\ingroup Data_Interface +*/ +// --- +enum MbeLineFontPattern { + lfp_BEGIN = 0, ///< \ru Для удобства перебора. \en For the convenient search. + lfp_STEPcontinuous, ///< \ru Непрерывная в конвертерах STEP и IGES. \en Continuous line in STEP and IGES (Solid) converters. + lfp_STEPchain, ///< \ru Штрих-пунктирная в конвертерах STEP и IGES. \en Chain line( dash-dotted) in STEP and IGES converters. + lfp_STEPchainDoubleDash, ///< \ru Штриховая с двумя пунктирами в конвертерах STEP и IGES. \en Dash-double-dot line in STEP and IGES (Phantom) converter. + lfp_STEPdashed, ///< \ru Штриховая в конвертерах STEP и IGES. \en Dash line in STEP and IGES converters. + lfp_STEPdotted, ///< \ru Пунктирная в конвертерах STEP и IGES. \en Dotted line in STEP and IGES converters. + lfp_END ///< \ru Для удобства перебора. \en For search +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Отображение точек, передаваемых через конвертер. + \en Representation of points passed via converter. \~ +\ingroup Data_Interface +*/ +// --- +enum MbeDotMarkerSymbol { + dms_BEGIN = 0, ///< \ru Для удобства перебора. \en For the convenient search. + dms_STEPdot, ///< \ru Точка. \en A point. + dms_STEPx, ///< \ru Косой крест. \en x - cross. + dms_STEPplus, ///< \ru Прямой крест. \en Plus. + dms_STEPasterisk, ///< \ru Звёздочка. \en Asterisk. + dms_STEPring, ///< \ru Кольцо. \en Ring. + dms_STEPsquare, ///< \ru Квадрат. \en Square. + dms_STEPtriangle, ///< \ru Треугольник. \en Triangle. + dms_END ///< \ru Для удобства перебора. \en For the convenient search. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип объектов, которые необходимо выдать для экспорта или добавить при импорте. + \en Type of objects to be returned for export or to be added while importing. \~ +\ingroup Data_Interface +*/ +// --- +enum MbeGettingItemType { + git_Item = 0, ///< \ru Получить элементы всех типов. \en Get items of all types. + git_Solid, ///< \ru Получить тела. \en Get solids. + git_Surface, ///< \ru Получить поверхности. \en Get surfaces. + git_WireFrame, ///< \ru Получить проволочные каркасы. \en Get wire frames. + git_PlaneInstance, ///< \ru Получить вставки плоских объектов (эскизы). \en Get plane instances (drafts). + git_PointFrame, ///< \ru Получить точечные каркасы. \en Get point frames. + git_AssociatedGeometry ///< \ru Получить ассоциированные геометрические объекты (резьбы). \en Get associated geometry objects (threads). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс свойств вставки, подсборки или детали. + \en Interface of properties of an instance, a subassembly or a part. \~ +\ingroup Exchange_Interface +*/ +// --- +class ItModelInstanceProperties : public MbRefItem +{ +public: + + /// \ru Атрибуты. \en Attributes. + + /// \ru Задать атрибуты. \en Set attributes. + virtual bool SetAttributes( const c3d::AttrSPtrVector& /*attributes*/ ) = 0; + + /// \ru Получить атрибуты. \en Get attributes. + virtual c3d::AttrSPtrVector GetAttributes( ) const = 0;// { return c3d::AttrSPtrVector(); } + + + /// \ru Технические требования. \en Technical requirements. + + /// \ru Получить технические требования. \en Get technical requirements. + virtual void GetRequirements( vector_of_annotation &, eTextForm ) const = 0; + + /// \ru Задать технические требования. \en Set technical requirements. + virtual void SetRequirements( const vector_of_annotation & ) = 0; + + /// \ru Наименование. \en Name. + + /// \ru Задать имя документа. \en Set document's name. + DEPRECATE_DECLARE virtual bool SetName( const std::string& /*name*/ ) { return false; }; + /// \ru Получить имя документа. \en Get document's name. + DEPRECATE_DECLARE virtual std::string Name() const { return std::string(); }; + + /// \ru Обозначение. \en Marking. + + /// \ru Задать обозначение документа. \en Set document marking. + DEPRECATE_DECLARE virtual bool SetMarking( const std::string& /*name*/ ) { return false; }; + /// \ru Получить обозначение документа. \en Get document marking. + DEPRECATE_DECLARE virtual std::string Marking() const { return std::string(); }; + + /// \ru Автор. \en Author. + + /// \ru Задать имя автора. \en Set author's name. + DEPRECATE_DECLARE virtual bool SetAuthor( const std::string& /*name*/ ) { return false; }; + /// \ru Получить имя автора. \en Get author's name. + DEPRECATE_DECLARE virtual std::string Author() const { return std::string(); }; + + /// \ru Организация. \en Organization. + + /// \ru Задать имя автора. \en Set author's name. + DEPRECATE_DECLARE virtual bool SetOrganization( const std::string& /*name*/ ) { return false; }; + /// \ru Получить имя автора. \en Get author's name. + DEPRECATE_DECLARE virtual std::string Organization() const { return std::string(); }; + + /// \ru Комментарий. \en Comment. + + /// \ru Задать комментарии. \en Set the comments. + DEPRECATE_DECLARE virtual bool SetComments( const std::vector< std::string > & /*comments*/ ) { return false; }; + /// \ru Получить следующий комментарий. \en Get the next comment. + DEPRECATE_DECLARE virtual std::vector< std::string > GetComments( ) const { return std::vector< std::string >(); }; + + /// \ru Цвет сборки, детали или вставки. \en Color of an assembly, a part or an instance. + + /// \ru Задать цветовые свойства. \en Set color properties. + DEPRECATE_DECLARE virtual bool SetColor( const MbAttributeContainer & ) { return false; }; + /// \ru Получить цветовые свойства. \en Get color properties. + DEPRECATE_DECLARE virtual bool GetColor( MbAttributeContainer & ) const { return false; }; + + /// \ru Цвет тела. \en Solid color. + + /// \ru Задать цветовые свойства оболочки. \en Set color properties of a shell. + DEPRECATE_DECLARE virtual bool SetColor( const MbAttributeContainer &, size_t ) { return false; }; + + /// \ru Цвет грани. \en Face color. + + /// \ru Задать цветовые свойства грани \en Set color properties of a face. + DEPRECATE_DECLARE virtual bool SetColor( const MbAttributeContainer &, const MbName & ) { return false; }; + /// \ru Получить цветовые свойства грани. \en Get color properties of a face. + DEPRECATE_DECLARE virtual bool GetColor( MbAttributeContainer &, const MbName & ) const { return false; }; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс вставки компоненты. + \en Interface of the component instance. \~ +\ingroup Exchange_Interface +*/ +// --- +class ItModelInstance : public ItModelInstanceProperties +{ +public: + // \ru Выдать идентификатор сборки или детали \en Get identifier of an assembly or a part + virtual void * GetId() = 0; + /// \ru Выдать расположение этой вставки в координатах родителя. \en Get the placement of this instance in parent's coordinates. + virtual bool GetPlacement( MbPlacement3D & ) const = 0; + /// \ru Это сборка? \en Is it an assembly? + virtual bool IsAssembly() const = 0; + /// \ru Это ни сборка, ни деталь? \en Is it neither an assembly nor a part? + virtual bool IsEmpty() const = 0; + + /** \brief \ru Создать пустую сборку при импорте и увеличить счётчик ссылок на 1. + \en Create an empty assembly while importing and increase the reference counter by 1. \~ + \param[in] place - \ru ЛСК сборки в родительской модели. + \en LCS of the assembly in the parent's model. \~ + \param[in] fileName - \ru Имя сборки. + \en Assembly name. \~ + \return \ru Экземпляр сборки, если операция прошла успешно, NULL в противном случае. + \en Instance of an assembly if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr CreateAssembly( const MbPlacement3D &place, const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ) = 0; + + /** \brief \ru Создать деталь при импорте. + \en Create a part while importing. \~ + \details \ru Увеличить счётчик ссылок детали на 1. + \en Increase the reference counter of a part by 1. \~ + \param[in] place - \ru ЛСК детали. + \en LCS of a part. \~ + \param[in] solids - \ru Тела, включаемые в деталь. + \en Solids included in the part. \~ + \param[in] fileName - \ru Название детали. + \en Solid's name. \~ + \return \ru Экземпляр детали, если операция прошла успешно, NULL в противном случае. + \en Instance of the part if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr CreatePart( const MbPlacement3D &place, const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ) = 0; + + /** \brief \ru Получить сборку для экспорта. + \en Get an assembly for export. \~ + \return \ru Экземпляр сборки, если операция прошла успешно, NULL в противном случае. + \en Instance of an assembly if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr GetInstanceAssembly( ) = 0; + + + /** \brief \ru Получить деталь для экспорта. + \en Get the detail for export. \~ + \return \ru Экземпляр детали, если операция прошла успешно, NULL в противном случае. + \en Instance of the part if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr GetInstancePart( ) = 0; + + /** \brief \ru Создать подсборку при импорте, и её вставку. + \en Create a subassembly and its instance while importing. \~ + \param[in] place - \ru ЛСК сборки в родительской модели. + \en LCS of the assembly in the parent's model. \~ + \param[in] existing - \ru Сборка, подлежащая вставке. + \en An assembly to insert. \~ + \return \ru true, если операция прошла успешно, false в противном случае. + \en true if the operation succeeded, false - otherwise. \~ + */ + virtual bool SetAssembly( const MbPlacement3D & place, const ItModelAssembly * existing ) = 0; + + /** \brief \ru Создать деталь при импорте, и её вставку. + \en Create a part while importing and its instance. \~ + \param[in] place - \ru ЛСК детали в родительской модели. + \en LCS of a part in the parent's model. \~ + \param[in] existing - \ru Деталь, подлежащая вставке. + \en Detail to insert. \~ + \return \ru true, если операция прошла успешно, false в противном случае. + \en true if the operation succeeded, false - otherwise. \~ + */ + virtual bool SetPart( const MbPlacement3D & place, const ItModelPart * existing ) = 0; + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс сборки. + \en Interface of the assembly. \~ + \details \ru Экземпляр должен порождаться в методах CreateAssembly реализаций + интерфейсов ItModelDocument и ItModelAInstance. Собственные элементы детали + должны передаваться как параметры конструктора. \~ \en The object should be + created in the CreateAssembly method of the implementations of the + ItModelDocument and ItModelInstance interfaces. Own Items of the detail should + be arguments of the constructor. +\ingroup Exchange_Interface +*/ +// --- +class ItModelAssembly : public ItModelInstanceProperties +{ +public: + /** \brief \ru Получить имя файла сборки без пути и расширения для экспорта. + \en Get the file name of an assembly without the path and the extension for export. \~ + \return \ru Имя файла сборки. + \en An assembly file name. \~ + */ + virtual c3d::path_string PureFileName() const = 0; + + /** \brief \ru Получить пустой интерфейс вставки для создания подсборки или детали при импорте. + \en Get an empty interface of the insertion for creation of subassembly or a part while importing. \~ + \details \ru Увеличить счётчик ссылок на 1. + \en Increase the reference counter by 1. \~ + \return \ru Интерфейс вставки, если операция прошла успешно или NULL в противном случае. + \en Interface of the instance if the operation succeeded and NULL otherwise. \~ + */ + virtual SPtr PrepareInstance() = 0; + + /** \brief \ru Получить интерфейс следующей вставки для создания подсборки или детали при экспорте. + \en Get the interface of the next insertion for creation of a subassembly or a part while exporting. \~ + \return \ru Интерфейс вставки, если операция прошла успешно или NULL в противном случае. + \en Interface of the insertion if the operation succeeded and NULL otherwise. \~ + */ + virtual SPtr NextInstance( bool includeInvisible ) = 0; + + /// \ru Выдать ЛСК, общую для элементов компонента. \en Get the placement, which all the items of the component use for transformation. + virtual bool GetPlacement( MbPlacement3D & ) const { return false; }; + + /** \brief \ru Получить объекты из корня сборки при экспорте. + \en Get objects from the assembly root while exporting. \~ + \param[out] items - \ru Наполняемый массив (состоит из объектов классов MbSolid, MbCurve3D, MbCartPoint3D). + \en Array to fill (consist of objects of classes MbSolid, MbCurve3D, MbCartPoint3D). \~ + \param[in] includeInvisible - \ru Если true, то выдаются все тела, включая невидимые, если false - только видимые. + \en If true, then all the solids are returned, including invisible ones, if false - only visible ones. \~ + */ + virtual void GetItems( std::vector< SPtr > & items, MbeGettingItemType itemType, bool includeInvisible ) const = 0; + + /** \brief \ru Добавить объекты в корень сборки при импорте. + \en Add objects to the assembly root while importing. \~ + \param[in] items - \ru Объекты, добавляемые в модель (тела, кривые и точки). + \en Objects to add to the model (solids, curves and points). \~ + */ + virtual void AddItems( const std::vector< SPtr > & items ) = 0; + + /** \brief \ru Получить элементы аннотации из сборки. + \en Get elements of annotation from the assembly. \~ + \param[in] eTextForm - \ru Форма представления текста. + \en Text representation form. \~ + \param[in] includeInvisible - \ru Если true, то выдаются все объекты аннотации, включая невидимые, если false - только видимые. + \en If true, all the annotation objects are returned, including invisible ones, if false - only visible ones. \~ + \return \ru Контейнер объектов аннотации. + \en Vector of annotation objects. \~ + */ + virtual vector_of_annotation GetAnnotationItems( eTextForm, bool ) const { return vector_of_annotation(); }; // Реализация будет удалена после того, как она будет осуществлена на стороне 3D + virtual vector_of_annotation GetAnnotationItems( eTextForm ) const { return vector_of_annotation(); }; // Будет удалена после её реализации на стороне 3D + + /** \brief \ru Задать элементы аннотации в сборке. + \en Set elements of annotation in the assembly. \~ + \param[in] sourceDim - \ru Элементы аннотации + \en Elements of annotation. \~ + */ + virtual void SetAnnotationItems( const vector_of_annotation & ) = 0; + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс детали. + \en Interface of a part. \~ + \details \ru Экземпляр должен порождаться в методах CreatePart реализаций + интерфейсов ItModelDocument и ItModelAInstance. Собственные элементы детали + должны передаваться как параметры конструктора. \~ \en The object should be + created in the CreatePart method of the implementations of the + ItModelDocument and ItModelInstance interfaces. Own Items of the detail should + be arguments of the constructor. +\ingroup Exchange_Interface +*/ +// --- +class ItModelPart : public ItModelInstanceProperties +{ +public: + /** \brief \ru Получить имя файла детали без пути и расширения для экспорта. + \en Get the file name of a part without the path and extension for export. \~ + \return \ru Имя файла детали. + \en A part file name. \~ + */ + virtual c3d::path_string PureFileName() const = 0; + + /** \brief \ru Получить пустой интерфейс вставки для создания подсборки или детали при импорте. + \en Get an empty interface of the insertion for creation of subassembly or a part while importing. \~ + \details \ru Увеличить счётчик ссылок на 1. + \en Increase the reference counter by 1. \~ + \return \ru Интерфейс вставки, если операция прошла успешно или NULL в противном случае. + \en Interface of the instance if the operation succeeded and NULL otherwise. \~ + */ + virtual SPtr PrepareInstance() = 0; + + /** \brief \ru Получить интерфейс следующей вставки для создания подсборки или детали при экспорте. + \en Get the interface of the next insertion for creation of a subassembly or a part while exporting. \~ + \return \ru Интерфейс вставки, если операция прошла успешно или NULL в противном случае. + \en Interface of the insertion if the operation succeeded and NULL otherwise. \~ + */ + virtual SPtr NextInstance( bool includeInvisible ) = 0; + + /// \ru Выдать ЛСК, общую для элементов компонента. \en Get the placement, which all the items of the component use for transformation. + virtual bool GetPlacement( MbPlacement3D & ) const { return false; }; + + /** \brief \ru Получить объекты из детали при экспорте. + \en Get objects from the part while exporting. \~ + \param[out] items - \ru Наполняемый массив (состоит из объектов классов MbSolid, MbWireFrame, MbPointFrame). + \en Array to fill (consists of objects of classes MbSolid, MbWireFrame, MbPointFrame). \~ + \param[in] itemType - \ru Тип объектов, которыми нужно наполнить массив. + \en Type of objects the array should be filled with. \~ + \param[in] includeInvisible - \ru Если true, то выдаются все тела, включая невидимые, если false - только видимые. + \en If true, all the solids are returned, including invisible ones, if false - only visible ones. \~ + */ + virtual void GetItems( std::vector< SPtr > & items, MbeGettingItemType itemType, bool includeInvisible ) const = 0; + + /** \brief \ru Добавить объекты в деталь при импорте. + \en Add objects to a part while importing. \~ + \param[in] items - \ru Объекты, добавляемые в модель (кривые и точки). + \en Objects to be added to the model (curves and points). \~ + */ + virtual void AddItems( const std::vector< SPtr > & items ) = 0; + + /** \brief \ru Получить элементы аннотации из детали. + \en Get elements of annotation from the detail. \~ + \param[in] eTextForm - \ru Форма представления текста. + \en Text representation form. \~ + \param[in] includeInvisible - \ru Если true, то выдаются все объекты аннотации, включая невидимые, если false - только видимые. + \en If true, all the annotation objects are returned, including invisible ones, if false - only visible ones. \~ + \return \ru Контейнер объектов аннотации. + \en Vector of annotation objects. \~ + */ + virtual vector_of_annotation GetAnnotationItems( eTextForm, bool ) const { return vector_of_annotation(); }; // Реализация будет удалена после того, как она будет осуществлена на стороне 3D + virtual vector_of_annotation GetAnnotationItems( eTextForm ) const { return vector_of_annotation(); }; // Будет удалена после её реализации на стороне 3D + + + /** \brief \ru Задать элементы аннотации в детали. + \en Set elements of annotation in the part. \~ + \param[in] sourceDim - \ru Элементы аннотации + \en Elements of annotation. \~ + */ + virtual void SetAnnotationItems( const vector_of_annotation & ) = 0; + +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс документа модели сборки или детали. + \en Interface of document of an assembly model or a part model. \~ +\ingroup Exchange_Interface +*/ +// --- +class ItModelDocument : public MbRefItem +{ +public: + /// \ru Это сборка? \en Is it an assembly? + virtual bool IsAssembly() const = 0; + /// \ru Это ни сборка, ни деталь? \en Is it neither an assembly nor a part? + virtual bool IsEmpty() const = 0; + + /** \brief \ru Прообраз новой интерфейсной функции - задать модель ЛСК, относительно которой позиционируется модель. + \en Prototype of a new interface function - get the placement the model is defined in. \~ + */ + //virtual MbPlacement3D GetOriginLocation() const = 0; + + /** \brief \ru Прообраз новой интерфейсной функции - задать модель для наполнения. + \en Prototype of a new interface function - set a model to fill. \~ + */ + virtual void SetContent( MbItem* /*content*/) = 0; + + /** \brief \ru Прообраз новой интерфейсной функции - получить наполнение. + \en Prototype of a new interface function - get the filling. \~ + */ + virtual MbItem * GetContent() /*{ return NULL; }*/ = 0; + + /** \brief \ru Создать документ с новой сборкой при импорте. + \en Create a document with a new assembly while importing. \~ + \details \ru Увеличить счётчик ссылок результирующего документа на 1. + \en Increase the reference counter of the resultant document by 1. \~ + \param[in] fileName - \ru Имя сборки. + \en Assembly name. \~ + \param[in] solids - \ru Тела, добавляемые в сборку. + \en Solids to add into the assembly. \~ + \return \ru Экземпляр сборки, если операция прошла успешно, NULL в противном случае. + \en Instance of an assembly if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr CreateAssembly( const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ) = 0; + + + /** \brief \ru Создать документ с новой деталью при импорте. + \en Create a document with a new part while importing. \~ + \details \ru Увеличить счётчик ссылок результирующего документа на 1. + \en Increase the reference counter of the resultant document by 1. \~ + \param[in] solids - \ru Тела, добавляемые в деталь. + \en Solids to add into a part. \~ + \param[in] fileName - \ru Имя детали. + \en A part name. \~ + \return \ru Экземпляр детали, если операция прошла успешно, NULL в противном случае. + \en Instance of the part if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr CreatePart( const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ) = 0; + + /** \brief \ru Получить сборку для экспорта. + \en Get an assembly for export. \~ + \details \ru Увеличить счётчик ссылок результирующей сборки на 1. + \en Increase the reference counter of the resultant assembly by 1. \~ + \return \ru Экземпляр сборки, если операция прошла успешно, NULL в противном случае. + \en Instance of an assembly if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr GetInstanceAssembly( ) = 0; + + + /** \brief \ru Получить деталь для экспорта. + \en Get the detail for export. \~ + \details \ru Увеличить счётчик ссылок результирующей детали на 1. + \en Increase the reference counter of the resultant part by 1. \~ + \return \ru Экземпляр детали, если операция прошла успешно, NULL в противном случае. + \en Instance of the part if the operation succeeded, NULL - otherwise. \~ + */ + virtual SPtr GetInstancePart( ) = 0; + + /** \brief \ru Завершить импорт и сохранить документ. + \en Complete the import and save the document. \~ + \return \ru true, если операция прошла успешно, false в противном случае. + \en true if the operation succeeded, false - otherwise. \~ + \param[in] \ru indicator Объект для отображения хода процесса. + \en indicator An object indicating a process progress. \~ + */ + virtual bool FinishImport( IProgressIndicator * indicator ) = 0; + + /** \brief \ru Получить элементы аннотации, соответствующие элементам геометрической модели. + \en Get elements of annotation, corresponding items of geometric model. \~ + \param[in] eTextForm - \ru Форма представления текста. + \en Text representation form. \~ + \return \ru Контейнер объектов аннотации. + \en Vector of annotation objects. \~ + */ + virtual map_of_visual_items GetAnnotationItems( eTextForm ) const = 0; + + /// \ru Задать размеры. \en Set sizes. + virtual void SetAnnotationItems( const map_of_visual_items& ) = 0; + + /// \ru Открыть документ. \en Open a document. + virtual void OpenDocument() = 0; + +}; + + + +//------------------------------------------------------------------------------ +/** \brief \ru Реализация документа модели, формирующая регулярную структуру. + \en Implementation of model document which has regular structure. \~ +\ingroup Exchange_Interface +*/ +// --- +class CONV_CLASS C3dModelDocument: public ItModelDocument { + + SPtr part; ///< \ru Представление в виде детали. \en Representation as detail. + SPtr assembly; ///< \ru Представление в виде сборки. \en Representation as assembly. + map_of_visual_items visualItems; ///< \ru Элементы аннотации. \en Annotation items. + c3d::ItemSPtr rawContent; +public: + + virtual ~C3dModelDocument(); ///< \ru Деструктор. \en Descructor. + + // Является ли сборкой. + virtual bool IsAssembly() const; + // Пуст ли. + virtual bool IsEmpty() const; + // Задать модель напрямую. + virtual void SetContent( MbItem* /*content*/); + // Выдать модель напрямую. + virtual MbItem * GetContent(); + // Создать сборку. + virtual SPtr CreateAssembly( const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ); + // Создать деталь. + virtual SPtr CreatePart( const std::vector< SPtr > & componentItems, const c3d::string_t& fileName ); + // Выдать сборку. + virtual SPtr GetInstanceAssembly( ); + // Выдать деталь. + virtual SPtr GetInstancePart( ); + // Завершить импорт. + virtual bool FinishImport( IProgressIndicator * ); + // Выдать элементы аннотации. + virtual map_of_visual_items GetAnnotationItems( eTextForm ) const; + // Задать элементы аннотации. + virtual void SetAnnotationItems( const map_of_visual_items& vi ); + // Открыть документ. + virtual void OpenDocument(); + + /// \ru Зарегистрировать элемент аннотации. \en Register annotation object. + void RegisterAnnotation( c3d::ItemSPtr component, const vector_of_annotation& annotation, const vector_of_annotation& requirements ); +}; + + +typedef C3dModelDocument RegularModelDocument; +typedef C3dModelDocument ConvModelDocument; + + +//------------------------------------------------------------------------------ +/** \brief \ru Упрощенная реализация интерфейса свойств конвертера. + \en Simple implementation of converter's properties. \~ +\ingroup Exchange_Interface +*/ +class CONV_CLASS ConvConvertorProperty3D : public IConvertorProperty3D { +public: + std::string docName; ///< \ru Имя документа. \en Document name. + c3d::path_string fileName; ///< \ru Имя файла. \en File name. + bool fileASCII; ///< \ru Экспортировать ли в текстовый файл (если формат поддерживает двоичный). \en Export to text file (if format supports binary one). + long int formatVersion; /// \ru Версия формата при экспорте. \en The version of format for export. + bool exportIGESTopology; ///< \ru Экспортировать ли топологию в IGES. \en Export topology items into IGES. + std::vector ioPermissions; ///< \ru Фильтр объектов по типам. \en Type objects filter. + std::map propertyStrings; ///< \ru Особые значения сведений о документе. \en Specific values of documents properties. + eTextForm annotTextReprSTEP; ///< \ru Представление текста элементов аннотации. \en Text representation in annotation items. + MbPlacement3D originLocation; ///< \ru ЛСК документа. \en Own placement of the document. + bool replaceLocationsToRight; ///< \ru Следует ли принудительно преобразовывать ЛСК объектов к правым (для форматов, допускающих левые). \en Force replacement of locations to right ones. + bool enableAutostitch; ///< \ru Сшивать ли поверхности автоматически. \en Automatically stitch surfaces into shells. + double autostitchPrecision; ///< \ru Точность сшивки. \en Stitch precision. + bool showMessages; ///< \ru Отображать ли сообщения. \en Invoke messages show. + MbStepData tesseleationStepData; ///< \ru Параметры триангуляции при экспорте в STL и VRML. \en Tessellation parameters for export into STL and VRML. + MbStepData LOD0StepData; ///< \ru Параметры триангуляции при экспорте в JT. \en Tessellation parameters for export into JT. + bool dualSeams; ///< \ru Признак сдваивания швов при экспорте в STL и VRML. \en Make dual seams when export into STL and VRML. + bool joinSimilarFaces; ///< \ru Выполнять ли слияние подобных граней. \en Whether to join similar faces. + bool addRemovedFacesAsShells; ///< \ru Добавлять ли удаленные грани в качестве отдельных оболочек. \en Whether to add removed faces as shells. + double lengthUnitsFactor; ///< \ru Единицы длины модели. \en Length units of the model. + double appUnitsFactor; ///< \ru Единицы длины модели пользовательского приложения. \en Length units of the model used in user application. + bool auditEnabled; + + /// \ru Сведения о сообщениях конвертера. \en Converter message data. + struct LogRecord { + ptrdiff_t id; ///< \ru Идентификатор записи. \en Record id. + eMsgType msgType; ///< \ru Тип сообщения. \en Message type. + eMsgDetail msgText; ///< \ru Код сообщения. \en Message code. + }; + + std::vector< LogRecord > logRecords; ///< \ru Сообщения конвертера. \en Converter messages. + +public: + + ConvConvertorProperty3D(); ///< \ru Конструктор. \en Constructor. + + /// \ru Получить имя документа. \en Get document's name. + virtual const std::string GetDocumentName () const { return docName; }; + /// \ru Получить имя файла для конвертирования. \en Get file name for converting. + virtual const c3d::path_string FullFilePath () const { return fileName; }; + /// \ru Является ли файл текстовым. \en Whether the file is a text file. + virtual bool IsFileAscii () const; + /// \ru Получить версию формата при экспорте. \en Get the version of format for export. + virtual long int GetFormatVersion () const; + /// \ru Следует ли экспортировать только поверхности ( введено для работы конвертера IGES ). \en Whether to export only surfaces (introduced for work with converter IGES ). + virtual bool IsOutOnlySurfaces() const; + /// \ru Является ли экспортируемый документ сборкой. \en Whether the document for export is an assembly. + virtual bool IsAssembling () const { return true; }; + /// \ru Получить значение разрешения на импорт экспорт объектов определенного типа. \en Get the value of permission for import-export of objects of a certain type. + virtual bool GetIoPermission( MbeIOPermiss nPermission ) const; + /// \ru Получить значения разрешений на импорт экспорт объектов определенных типов. \en Get values of permission for import-export of objects of certain types. + virtual void GetIoPermissions( std::vector& ioPermissions ) const; + /// \ru Установить разрешение на импорт экспорт объектов определенного типа. \en Set permission for import-export of objects of a certain type. + virtual void SetIoPermission( MbeIOPermiss nPermission, bool isSet ); + /// \ru Получить значение специфичной строки для конвертера. \en Get the value of a certain string for the converter. + virtual bool GetPropertyString ( MbeConverterStrings nString, std::string & propertyString ) const; + /// \ru Установить значение специфичной строки для конвертера. \en Set the value of a certain string for the converter. + virtual void SetPropertyString ( MbeConverterStrings nString, const std::string & propertyString ); + /// \ru Представление текста в аннотационных объектах. \en Text representation in annotation objects. + virtual eTextForm GetAnnotationTextRepresentation () const; + /// \ru Следует ли компоненты экспортировать в разные файлы (если позволяет формат). \en Export components into separate files ( if provided in format). + virtual bool ExportComponentsSeparately() const; + /// \ru Получить ЛСК, относительно которой позиционирована модель. \en Get the location, the model is placed in. + virtual MbPlacement3D GetOriginLocation() const; + /// \ru Заменять ли принудительно СК компонент на правые. \en Replace components' placements to right-oriented. + virtual bool ReplaceLocationsToRight() const; + /** \brief \ru Сшивать ли поверхности автоматически. + \en If surfaces should be stitched automatically. \~ + \return \ru true - Сшивать поверхности автоматически, false - Спросить пользователя, сшивать ли поверхности. + \en true - Stitch surfaces automatically, false - Ask user first time. \~ + \param[out] stitchPrecision - \ru Точность сшивки. + \en Stitch precision. \~ + */ virtual bool EnableAutoStitch( double& /*stitchPrecision*/ ) const; + + /// \ru Получить множитель единиц длины по отношению к миллиметру. \en Get the factor of the length units to millimeters. + virtual double LengthUnitsFactor() const; + + /** \brief \ru Получить множитель единиц длины по отношению к миллиметру в модели приложения. + \en Get the factor of the length units to millimeters in the application model. \~ + */ + virtual double AppLengthUnitsFactor() const; + + /** \brief \ru Сделать запись в журнал конвертирования. + \en Make a record in the converter report. \~ + \param[in] id - \ru Идентификатор элемента внутри файла стороннего формата. + \en Identifier of an element inside the file of a foreign format. \~ + \param[in] msgType - \ru Тип сообщения. + \en Message type. \~ + \param[in] msgText - \ru Код сообщения. + \en Message code. \~ + */ + virtual void LogReport( ptrdiff_t id, eMsgType msgType, eMsgDetail msgText ); + +// /** \brief \ru Следует ли показывать сообщения и диалоги пользователю. \en Whether to show messages and dialog to the user. \~ +// \details \ru Обеспечивает работу через API. \en Provide possibility for work via API. \~ +// \return \ru true - обычная работа, false - через API. \en true - ordinary work, false - via API. \~ +// */ + virtual bool CanShowMessages() const; + + /// \ru Дать данные вычисления триангуляции (для конвертера STL и VRML). \en Get data for step calculation during triangulation (for STL, VRML only). + virtual MbStepData TesselationParameters() const; + /// \ru Дать данные вычисления триангуляции уровня детализации (для конвертера JT). \en Get data for step calculation during triangulation of LOD0 (for JTonly). + virtual MbStepData LOD0TesselationParameters() const; + /// \ru Получить флаг сохранения совпадающих точек швов. (для конвертера STL и VRML). \en Whether to keep coincident points of seams (for STL, VRML only). + virtual bool DualSeams() const; + /// \ru Задать флаг сохранения совпадающих точек швов. (для конвертера STL и VRML). \en Whether to keep coincident points of seams (for STL, VRML only). + virtual void DualSeams( bool ); + /// \ru Проводить ли аудит траснляции. \en Whether to audit the translation. + virtual bool TotalAudit(); + /// \ru Выполнять ли слияние подобных граней. \en Whether to join similar faces. + virtual bool JoinSimilarFaces() const { return joinSimilarFaces; } + /// \ru Добавлять ли удаленные грани в качестве оболочек. \en Whether to add removed faces as shells. + virtual bool AddRemovedFacesAsShells() const { return addRemovedFacesAsShells; } + + OBVIOUS_PRIVATE_COPY( ConvConvertorProperty3D ) + +}; // IConvertorProperty3D + + + +#endif // __CONV_MODEL_PROPERTIES_H diff --git a/C3d/Include/conv_requestor.h b/C3d/Include/conv_requestor.h new file mode 100644 index 0000000..f53d5d3 --- /dev/null +++ b/C3d/Include/conv_requestor.h @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Интерфейс запроса масштаба. Интерфейс запроса сшивки. + \en Interface of scale request. Interface of stitching request. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CONV_REQUESTOR_H +#define __CONV_REQUESTOR_H + + +#include + + +//------------------------------------------------------------------------------ +/// \ru Интерфейс запроса масштаба. \en Interface of scale request. +// --- +struct IScaleRequestor : public MbRefItem +{ + virtual double ScaleRequest() = 0; +}; + + +//------------------------------------------------------------------------------ +/// \ru Интерфейс запроса сшивки. \en Interface of stitching request. +// --- +struct IStitchRequestor : public MbRefItem +{ + virtual bool StitchRequest() = 0; +}; + + +#endif // __CONV_REQUESTOR_H diff --git a/C3d/Include/cr_attribute_provider.h b/C3d/Include/cr_attribute_provider.h new file mode 100644 index 0000000..a242ca2 --- /dev/null +++ b/C3d/Include/cr_attribute_provider.h @@ -0,0 +1,153 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поставщик атрибутов для топологических объектов. + \en Topological objects attributes provider. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_ATTRIBURE_PROVIDER_H +#define __CR_ATTRIBURE_PROVIDER_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbNamedAttributeContainer; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поставщик атрибутов для топологических объектов. + \en Topological objects attributes provider. \~ + \details \ru Поставщик атрибутов для топологических объектов создаёт атрибуты для журнала построений. \n + \en Topological objects attributes provider creates attributes for history tree. \n \~ + \ingroup Model_Creators + */ +class MATH_CLASS MbAttributeProvider : public MbCreator +{ +private: + struct NamedAttrCondDuplicator + { + public: + MbAttributeProvider & target_; + NamedAttrCondDuplicator( MbAttributeProvider & target ) : target_(target) {} + void operator () ( MbNamedAttributeContainer * source ); + private: + void operator = ( const NamedAttrCondDuplicator & ); + }; + + struct NamedAttrCondComparer + { + public: + MbName target_; + NamedAttrCondComparer( const MbName & target ) : target_(target) {} + bool operator () ( MbNamedAttributeContainer * source ); + private: + void operator = ( const NamedAttrCondComparer & ); + }; + + struct NamedAttrCondSetter + { + public: + MbFaceShell & target_; + NamedAttrCondSetter( MbFaceShell & target ) : target_(target) {} + void operator () ( MbNamedAttributeContainer * source ); + private: + void operator = ( const NamedAttrCondSetter & ); + }; + + typedef std::vector::iterator ContIter; + +private: + std::vector attrConts; // \ru Передаваемые атрибуты \en Attributes to pass + +public: + MbAttributeProvider( const MbSNameMaker & n ); + ~MbAttributeProvider(); + + virtual MbeCreatorType IsA() const; // \ru Выдать тип элемента. \en Get an element type. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным. \en Make equal. + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию. \en Create a copy. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction. + + // \ru Добавить отдельный атрибут (забрать во владение) \en Add a separate attribute. + void AddAttribute( const MbName & name, MbAttribute * attr ); + // \ru Добавить контейнер атрибутов (забрать во владение) \en Add an attribute container. + void AddNamedCont( MbNamedAttributeContainer * attr ); + // \ru Добавить контейнер атрибутов (сделать себе копию) \en Add an attribute container (make a copy). + void AddNamedCont( MbNamedAttributeContainer & attr ); + +protected: + MbAttributeProvider( const MbAttributeProvider & ); + void operator = ( const MbAttributeProvider & ); // \ru Не реализовано \en Not implemented + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbAttributeProvider ) +}; + +IMPL_PERSISTENT_OPS( MbAttributeProvider ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Контейнер атрибутов. + \en Attribute container. \~ + \details \ru Контейнер атрибутов для одного топологического объекта. \n + \en An attribute container for a topological object. \n \~ + \ingroup Model_Attributes + */ +class MATH_CLASS MbNamedAttributeContainer +{ + typedef c3d::AttrVector::iterator AttrIter; + +private: + MbName target; // \ru Имя топологического объекта, которому будут отданы хранимые атрибуты. \en Name of the topological object the stored attributes will be passed to. + c3d::AttrVector attributes; // \ru Передаваемые атрибуты. \en Attributes to pass. + +public: + MbNamedAttributeContainer( const MbName & ); + virtual ~MbNamedAttributeContainer(); + +public: + /// \ru Записать полученные атрибуты. \en Save the received attributes. + void ReceiveAttributes ( c3d::AttrVector & attrs ); + /// \ru Скопировать атрибуты. \en Copy attributes. + void DuplicateAttributes( c3d::AttrVector & attrs, MbRegDuplicate * iReg = NULL ) const; + /// \ru Дать количество атрибутов. \en Get the attributes count. + size_t AttributesCount() const { return attributes.size(); } + /// \ru Добавить атрибут. \en Add an attribute. + void AddAttribute( MbAttribute & ) ; + const MbAttribute * _GetAttribute( size_t k ) const { return attributes[k]; } + +public: + /// \ru Дать имя топологического объекта. \en Get the topological object name. + const MbName & GetName() const { return target; } + + /// \ru Читать из потока. \en Read from stream. + void ReadAttrCont ( reader & ); + /// \ru Записать в поток. \en Write to stream. + void WriteAttrCont( writer & ) const; + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + +protected: + MbNamedAttributeContainer( const MbNamedAttributeContainer & ); + void operator = ( const MbNamedAttributeContainer & ); // \ru Не реализовано \en Not implemented +}; + + +#endif // __CR_ATTRIBURE_PROVIDER_H diff --git a/C3d/Include/cr_boolean_solid.h b/C3d/Include/cr_boolean_solid.h new file mode 100644 index 0000000..d8953c1 --- /dev/null +++ b/C3d/Include/cr_boolean_solid.h @@ -0,0 +1,172 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель булевой операции. + \en Boolean operation constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_BOOLEAN_SOLID_H +#define __CR_BOOLEAN_SOLID_H + + +#include + + +class MATH_CLASS MbSolid; +struct MATH_CLASS MbBooleanFlags; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель булевой операции. + \en Boolean operation constructor. \~ + \details \ru Строитель булевой операции выполняет операции объединения, пересечения и вычитания множеств точек двух тел. \n. + \en The Boolean operation constructor performs union, intersection and subtraction operations for sets of points of two solids. \n. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBooleanSolid : public MbCreator { +protected : + RPArray creators; ///< \ru Журнал построения: 0<=i & solid2, + bool sameCreators2, + OperationType operType, + const MbBooleanFlags & booleanFlags, + const MbSNameMaker & n ); + + MbBooleanSolid( const RPArray & solids12, + size_t firstCount, + bool sameCreators1, + bool sameCreators2, + OperationType operType, + const MbBooleanFlags & booleanFlags, + const MbSNameMaker & n ); +private : + MbBooleanSolid( const MbBooleanSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBooleanSolid( const MbBooleanSolid & init ); +public : + virtual ~MbBooleanSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента. \en A type of element. + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * ireg = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual size_t GetCreatorsCount ( MbeCreatorType ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными. \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal. + + // \ru Общие функции твердого тела. \en Common functions of solid. + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual void SetYourVersion( VERSION version, bool forAll ); + +public: + /// \ru Тип булевой операции над телами. \en Type of Boolean operation on solids. + OperationType GetOperationType() const { return operation; } + /// \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + double GetBuildSag() const { return buildSag; } + + /// \ru Количество общих строителей тел. \en The number of common creators. + size_t GetSharedCount() const { return sharedCount; } + /// \ru Количество строителей первого тела. \en The number of first-solid creators. + size_t GetFirstCount() const { return firstCount; } + /// \ru Общее количество строителей. \en Total count of creators. + size_t GetCreatorsCount() const { return creators.size(); } + /// \ru Дать строитель. \en Get the creator. + const MbCreator * GetCreator( size_t k ) const { return ( (k < creators.size()) ? creators[k] : NULL ); } + /// \ru Удалить из журнала строители первого тела. \en Delete first-solid creators from the history tree. + bool DeleteFirstCreators(); +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbBooleanSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBooleanSolid ) +}; + +IMPL_PERSISTENT_OPS( MbBooleanSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку булевой операции. + \en Create the shell of Boolean operation. \~ + \details \ru Для указанных оболочек построить оболочку как результат булевой операции над оболочками тел. + Одновременно с построением оболочки функция создаёт её строитель. \n + \en Create a shell as a result of Boolean operation on the given shells of solids. + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] shell1 - \ru Набор граней первого тела. + \en The set of faces of the first solid. \~ + \param[in] sameShell1 - \ru Способ копирования граней первого тела. + \en Method of copying the faces of the first solid. \~ + \param[in] shell2 - \ru Набор граней второго тела. + \en The second solid face set. \~ + \param[in] sameShell2 - \ru Способ копирования граней второго тела. + \en Method of copying the faces of the second solid. \~ + \param[in] creators - \ru Набор строителей первого и второго набора граней. + \en The set of creators of the first and the second face sets. \~ + \param[in] sharedCount - \ru Количество общих строителей обоих наборов граней. + \en The number of shared creators of the both face sets. \~ + \param[in] firstCount - \ru Количество строителей первого набора граней. + \en The number of creators of the first face set. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] flags - \ru Управляющие флаги булевой операции. + \en Control flags of the Boolean operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateBoolean( MbFaceShell * shell1, + MbeCopyMode sameShell1, + MbFaceShell * shell2, + MbeCopyMode sameShell2, + const RPArray & creators, + size_t & sharedCount, + size_t & firstCount, + OperationType oType, + const MbSNameMaker & operNames, + const MbBooleanFlags & flags, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_BOOLEAN_SOLID_H diff --git a/C3d/Include/cr_chamfer_solid.h b/C3d/Include/cr_chamfer_solid.h new file mode 100644 index 0000000..5f74396 --- /dev/null +++ b/C3d/Include/cr_chamfer_solid.h @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель тела с фасками рёбер. + \en Constructor of solid with edges' chamfers. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_CHAMFER_SOLID_H +#define __CR_CHAMFER_SOLID_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель тела с фасками рёбер. + \en Constructor of solid with edges' chamfers. \~ + \details \ru Строитель тела с фасками рёбер, выполняющий замену указанных рёбер линейчатыми гранями, + стыкующимися со смежными гранями обрабатываемых ребер. + \en Constructor of solid with edges' chamfers performing the replacement of the specified edges by ruled faces + connected with the adjacent faces of the edges being processed. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbChamferSolid : public MbSmoothSolid { +public : + +public : + MbChamferSolid( SArray & _indexes, + const SmoothValues & params, const MbSNameMaker & n ); +private : + MbChamferSolid( const MbChamferSolid & init, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbChamferSolid( const MbChamferSolid & init ); +public : + virtual ~MbChamferSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual( const MbCreator &init ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private : + virtual void ReadDistances ( reader &in ); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbChamferSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbChamferSolid ) +}; // MbChamferSolid + +IMPL_PERSISTENT_OPS( MbChamferSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку с фасками ребeр. + \en Create a shell with edges' chamfers. \~ + \details \ru Для указанной оболочки построить оболочку, в которой выполнены фаски указанных рёбер.\n + \en For the given shell create a shell with chamfers of the specified edges.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] initCurves - \ru Обрабатываемые рёбра исходной оболочки. + \en The source shell edges to be processed. \~ + \param[in] parameters - \ru Правметры обработки рёбер. + \en Parameters of edges processing. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateChamfer( MbFaceShell * solid, + MbeCopyMode sameShell, + RPArray & initCurves, + const SmoothValues & parameters, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_CHAMFER_SOLID_H diff --git a/C3d/Include/cr_connecting_curve.h b/C3d/Include/cr_connecting_curve.h new file mode 100644 index 0000000..58e90f9 --- /dev/null +++ b/C3d/Include/cr_connecting_curve.h @@ -0,0 +1,182 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель кривой сопряжения двух кривых. + \en Constructor of curve connecting two curves. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_CONNECTING_CURVE_H +#define __CR_CONNECTING_CURVE_H + + +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbElementarySurface; +class MATH_CLASS MbEdge; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель кривой сопряжения двух кривых. + \en Constructor of curve connecting two curves. \~ + \details \ru Строитель кривой сопряжения двух кривых.\n + \en Constructor of curve connecting two curves.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbConnectingCurveCreator : public MbCreator { +private: + MbCurve3D * curve1; ///< \ru Первая скругляемая кривая \en The first curve to connect + MbCurve3D * curve2; ///< \ru Вторая скругляемая кривая \en The second curve to connect + double init1; ///< \ru Исходное приближение параметра первой скругляемой кривой (для ft_Fillet и ft_OnSurface) \en The initial approximation of parameter of the first curve to be connected (for ft_Fillet and ft_OnSurface) + double init2; ///< \ru Исходное приближение параметра второй скругляемой кривой (для ft_Fillet и ft_OnSurface) \en The initial approximation of parameter of the second curve to be connected (for ft_Fillet and ft_OnSurface) + double param1; ///< \ru Параметр точки стыковки первой скругляемой кривой (кроме ft_Double) \en Connection point parameter of the first curve (except ft_Double) + double param2; ///< \ru Параметр точки стыковки второй скругляемой кривой (кроме ft_Double) \en Connection point parameter of the second curve (except ft_Double) + double radius1; ///< \ru Исходное приближение радиуса (кроме ft_Bridge, для ft_Double - радиус скругления первого участка, для ft_Spline - tension) \en The initial approximation of radius (except ft_Bridge, for ft_Double - the first segment fillet radius, for ft_Spline - tension) + double radius2; ///< \ru Результат расчета радиуса (кроме ft_Bridge, для ft_Double - радиус скругления второго участка, для ft_Spline - tension) \en The radius calculation result (except ft_Bridge, for ft_Double - the second segment fillet radius, for ft_Spline - tension) + bool sense1; ///< \ru Совпадение направления кривой скругления и первой кривой (кроме ft_Spline, для ft_Double - начало/конец кривой) \en Coincidence of the connecting curve direction and the first curve (except ft_Spline, for ft_Double - start/end point of the curve) + bool sense2; ///< \ru Совпадение направления кривой скругления и второй кривой (кроме ft_Spline, для ft_Double - начало/конец кривой) \en Coincidence of the connecting curve direction and the second curve (except ft_Spline, for ft_Double - start/end point of the curve) + MbeMatingType mating1; ///< \ru Тип сопряжения с первой кривой (для ft_Spline) \en Type of mating with the first curve (for ft_Spline) + MbeMatingType mating2; ///< \ru Тип сопряжения со второй кривой (для ft_Spline) \en Type of mating with the second curve (for ft_Spline) + MbeConnectingType type; ///< \ru Тип скругления (обычное или на поверхности) \en Connection type (ordinary or on a surface) + +protected: + MbConnectingCurveCreator( const MbConnectingCurveCreator & , MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbConnectingCurveCreator( const MbConnectingCurveCreator & ); // \ru Не реализовано \en Not implemented + MbConnectingCurveCreator(); // \ru Не реализовано \en Not implemented + +public: + MbConnectingCurveCreator( const MbSNameMaker & n, + const MbCurve3D & c1, double t1, double p1, double r1, bool s1, MbeMatingType m1, + const MbCurve3D & c2, double t2, double p2, double r2, bool s2, MbeMatingType m2, MbeConnectingType t ); + +public : + virtual ~MbConnectingCurveCreator(); + + // \ru Общие функции строителя \en The common functions of the creator + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateSpaceCurve( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbConnectingCurveCreator & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbConnectingCurveCreator ) +}; + +IMPL_PERSISTENT_OPS( MbConnectingCurveCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создание строителя скругления двух кривых. + \en Create two curves fillet constructor. \~ + \details \ru Создание строителя скругления двух кривых.\n + \en Create two curves fillet constructor.\n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateFilletEdge( const MbCurve3D & curve1, double & t1, + const MbCurve3D & curve2, double & t2, + double & radius, bool sense, + MbeConnectingType type, + const MbSNameMaker & names, + MbResultType & res, + bool & unchanged, // \ru Для ft_Fillet и ft_OnSurface \en For ft_Fillet and ft_OnSurface + MbElementarySurface *& surface, // \ru Для ft_Fillet и ft_OnSurface \en For ft_Fillet and ft_OnSurface + MbEdge *& edge ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание строителя сопряжения двух кривых сплайном. + \en Create constructor of two curves connection by a spline. \~ + \details \ru Создание строителя сопряжения двух кривых сплайном.\n + \en Create constructor of two curves connection by a spline.\n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateSplineEdge( const MbCurve3D & curve1, double t1, MbeMatingType mating1, + const MbCurve3D & curve2, double t2, MbeMatingType mating2, + double tension1, double tension2, + const MbSNameMaker & names, + MbResultType & res, + MbEdge *& edge ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание строителя сопряжения концов двух кривых составной кривой плавного соединения. + \en Create a constructor of conjugation of two curves end points by a composite curve of smooth connection. \~ + \details \ru Создание строителя сопряжения концов двух кривых составной кривой плавного соединения.\n + \en Create a constructor of conjugation of two curves end points by a composite curve of smooth connection.\n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateConnectingEdge( const MbCurve3D & curve1, bool isBegin1, double radius1, + const MbCurve3D & curve2, bool isBegin2, double radius2, + const MbSNameMaker & names, + MbResultType & res, + MbEdge *& edge ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздание строителя сопряжения двух кривых кубическим сплайном Эрмита (кривой-мостиком). + \en Create a constructor of two curves conjugation by a cubic Hermite spline (transition curve). \~ + \details \ru Cоздание строителя сопряжения двух кривых кубическим сплайном Эрмита (кривой-мостиком).\n + \en Create a constructor of two curves conjugation by a cubic Hermite spline (transition curve).\n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateBridgeEdge( const MbCurve3D & curve1, double t1, bool sense1, + const MbCurve3D & curve2, double t2, bool sense2, + const MbSNameMaker & names, + MbResultType & res, + MbEdge *& edge ); + + +#endif // __CR_CONNECTING_CURVE_H \ No newline at end of file diff --git a/C3d/Include/cr_cutting_solid.h b/C3d/Include/cr_cutting_solid.h new file mode 100644 index 0000000..ffc5c89 --- /dev/null +++ b/C3d/Include/cr_cutting_solid.h @@ -0,0 +1,141 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель разрезанного тела. + \en Cut solid constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_CUTTING_SOLID_H +#define __CR_CUTTING_SOLID_H + +#include +#include +#include +#include + + +class MATH_CLASS MbSurface; +class MATH_CLASS MbContour; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель разрезанного тела. + \en Cut solid constructor. \~ + \details \ru Строитель тела, разрезанного поверхностью или набором граней, полученного выдавливанием плоского контура.\n + \en Constructor of a solid cut by a surface or a set of faces obtained by extrusion of a planar contour.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCuttingSolid : public MbCreator { +private: + typedef MbShellCuttingParams::ProlongState CuttingProlongState; +protected : + // Surface + c3d::SurfaceSPtr surface; ///< \ru Режущая поверхность. \en Cutting surface. + // Sketch contour + c3d::PlaneContourSPtr contour; ///< \ru Режущий контур (вместо поверхности). \en Cutting contour (instead of surface). + MbPlacement3D place; ///< \ru Местная система координат контура. \en Local coordinate system of the contour. + MbVector3D direction; ///< \ru Направление и длина выдавливания контура. \en Direction and distance of the contour extrusion. + // Solid + c3d::CreatorsSPtrVector creators; ///< \ru Строители оболочки. \en Shell creators. + + ThreeStates part; ///< \ru Оставляемая часть (если part больше 0, то оставляем часть тела со стороны нормали поверхности). \en A part to be kept (if part is bigger than 0, then keep a part of solid from the side of surface normal). + CuttingProlongState prolongState; ///< \ru Тип продления режущей поверхности. \en Prolongation type of cutter surface. + + bool closed; ///< \ru Замкнутоcть оболочки разрезаемого объекта. \en Closedness of the shell of the object being cut. + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool mergeEdges; ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). + double buildSag; ///< \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + +public : + MbCuttingSolid( const MbShellCuttingParams & cuttingParams, bool sameCutterObject ); + DEPRECATE_DECLARE + MbCuttingSolid( const MbSurface & surface, bool sameSurface, int part, + bool closed, const MbMergingFlags & flags, const MbSNameMaker & n ); + DEPRECATE_DECLARE + MbCuttingSolid( const MbPlacement3D & place, const MbContour & contour, const MbVector3D & direction, int part, + bool closed, const MbMergingFlags & flags, const MbSNameMaker & n ); +private : + MbCuttingSolid( const MbCuttingSolid &, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbCuttingSolid( const MbCuttingSolid & ); +public : + virtual ~MbCuttingSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&, MbeCopyMode sameShell, + RPArray * = NULL ); // \ru Построение \en Construction + + // \ru Оставляемая часть (если part больше 0, то оставляем часть тела со стороны нормали поверхности). \en A part to be kept (if part is bigger than 0, then keep a part of solid from the side of surface normal). + ThreeStates GetPart() const { return part; } + void SetPart( ThreeStates p ) { part = p; } + void SetOppositePart() { if ( part == ts_negative ) + part = ts_positive; + else if ( part == ts_positive ) + part = ts_negative; } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCuttingSolid & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCuttingSolid ) +}; // MbCuttingSolid + +IMPL_PERSISTENT_OPS( MbCuttingSolid ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезать от оболочки некоторую её часть. + \en Cut a part of the shell. \~ + \details \ru Для указанной оболочки построить оболочку без части граней, отрезанных от неё : + (1) указанной поверхностью, (2) набором граней, полученной выдавливанием плоского контура, (3) оболочкой. \n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell create a shell without a part of faces cut from it by : + (1) the given surface, (2) a set of faces obtained by extrusion of a planar contour, (3) the given shell. \n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] cuttingParams - \ru Параметры операции. + \en Operation parameters. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell1 - \ru Построенный первый набор граней. + \en Constructed first set of faces. \~ + \param[out] shell2 - \ru Построенный второй набор граней. + \en Constructed second set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCuttingSolid *) CreatePart( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbShellCuttingParams & cuttingParams, + MbResultType & res, + MbFaceShell *& shell1, + MbFaceShell *& shell2 ); + +#endif // __CR_CUTTING_SOLID_H diff --git a/C3d/Include/cr_detach_solid.h b/C3d/Include/cr_detach_solid.h new file mode 100644 index 0000000..5240389 --- /dev/null +++ b/C3d/Include/cr_detach_solid.h @@ -0,0 +1,134 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Разделение набора граней на связные части. + \en Subdivision of face set into connected parts. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_DETACH_SOLID_H +#define __CR_DETACH_SOLID_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель, разделяющий набор граней на связные части. + \en Constructor subdividing a set of faces into connected parts. \~ + \details \ru Строитель, разделяющий набор граней на связные части в виде оболочек и + сортирующий отдельные оболочки по убыванию диагоналей габаритных кубов частей. \n + \en Constructor subdividing a set of faces into connected parts in form of shells and + sorting separate shells by decreasing of the parts's bounding boxes diagonals. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbDetachSolid : public MbCreator { +protected : + ptrdiff_t part; ///< \ru Номер оболочки, выделенной из общего набора граней. \en Number of a shell extracted from the common set of faces. + bool sort; ///< \ru Сортированы ли оболочки по габаритам. \en Whether the shells are sorted by sizes. + +public : + MbDetachSolid( ptrdiff_t p, bool s, const MbSNameMaker & n ); +private : + MbDetachSolid( const MbDetachSolid & init, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbDetachSolid( const MbDetachSolid & init ); +public : + virtual ~MbDetachSolid(); + + /** \ru \name Общие функции математического объекта. + \en \name Common functions of the mathematical object. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \brief \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными? \en Whether the objects are similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным. \en Make equal. + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + /** \} */ + /** \ru \name Функции строителя, разделяющие отдельные части оболочки. + \en \name Functions of the creator subdividing separate parts of the shell. + \{ */ + /// \ru Дать номер части, выделенной из общей оболочки. \en Get number of the part extracted from the common shell. + ptrdiff_t GetPartNumber() const { return part; } + /// \ru Установить номер части, выделенной из общей оболочки. \en Set number of the part extracted from the common shell. + void SetPartNumber( ptrdiff_t p ) { part = p; } + /// \ru Сортированы ли части по габаритам (диагоналям). \en Whether the parts are sorted by bounding boxes (diagonals). + bool IsSort() const { return sort; } + /** \} */ +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbDetachSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbDetachSolid ) +}; // MbDetachSolid + +IMPL_PERSISTENT_OPS( MbDetachSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить несвязанные части набора граней на связанные наборы граней. + \en Divide disconnected parts of a face set into connected sets of faces. \~ + \details \ru Разделить несвязанные части набора граней на связанные наборы граней - оболочки. + Одна связная оболочка (если sort=true, то наибольшая по диагонали габаритного куба) остаётся в исходном наборе граней solid. + Отделенные наборы граней складываются в контейнер partSolid. + \en Divide disconnected parts of a face set into connected sets of faces - shells. + One connected shell (if sort=true, then it is the greatest by the bounding box diagonal) remains in the initial set of faces 'solid'. + Separated face sets are put into container partSolid. \~ + \param[in, out] solid - \ru Исходный набор граней, на выходе - одна из связных оболочек. + \en Initial face set, in output - one of the connected shells. \~ + \param[out] partSolid - \ru Набор всех связных частей кроме одной. + \en Set of all connected parts except one. \~ + \param[in] sort - \ru Если true, то в partSolid сортировать оболочки по убыванию диагоналей габаритного куба. + \en If true, then the shells should be sorted in partSolid by decreasing the bounding box diagonals. \~ + \result \ru Количество оболочек в контейнере partSolid. + \en Number of shells in container partSolid. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (size_t) MakeDetachShells( MbFaceShell & solid, + RPArray & partSolid, + bool sort ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Разделить несвязанные части набора граней на связанные наборы граней. + \en Divide disconnected parts of a face set into connected sets of faces. \~ + \details \ru Разделить несвязанные части набора граней на связанные наборы граней - оболочки. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Divide disconnected parts of a face set into connected sets of faces - shells. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in, out] solid - \ru Исходная оболочка. + \en The initial shell. \~ + \param[out] partSolid - \ru Набор всех связных частей - оболочек. + \en Set of all the connected parts - shells. \~ + \param[in] sort - \ru Если true, то в partSolid сортировать оболочки по убыванию диагоналей габаритного куба. + \en If true, then the shells should be sorted in partSolid by decreasing the bounding box diagonals. \~ + \param[in] n - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateDetach( MbFaceShell & solid, + RPArray & partSolid, + bool sort, + const MbSNameMaker & n, + MbResultType & res ); + + +#endif // __CR_DETACH_SOLID_H diff --git a/C3d/Include/cr_draft_solid.h b/C3d/Include/cr_draft_solid.h new file mode 100644 index 0000000..c15ef1f --- /dev/null +++ b/C3d/Include/cr_draft_solid.h @@ -0,0 +1,156 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки с уклонёнными гранями. + \en Constructor of a shell with drafted faces. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_DRAFT_SOLID_H +#define __CR_DRAFT_SOLID_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки с уклонёнными гранями. + \en Constructor of a shell with drafted faces. \~ + \details \ru Строитель оболочки с уклонёнными гранями для создания литейных уклонов.\n + \en Constructor of a shell with drafted faces for pattern drafts creation. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbDraftSolid: public MbCreator { +protected: + double angle; ///< \ru Угол уклона. \en Draft angle. + c3d::ItemIndices faceIndices; ///< \ru Номера множества уклоняемых граней. \en Indices of faces to draft. + MbeFacePropagation fp; ///< \ru Признак захвата граней ( face propagation ). \en Flag of face propagation. + // \ru Атрибуты, определяющие направление тяги (pull direction) и нейтральную изолинию уклона. \en Attributes determining the pull direction and the neutral isoline of the draft. + MbPlacement3D * np; ///< \ru Нейтральная плоскость ( neutral plane ) ( не обязателен ). \en Neutral plane (optional). + ptrdiff_t edgeNb; ///< \ru Номер прямолинейного ребра, направляющего уклон ( не обязателен ). \en The index of straight edge specifying the draft (optional). + SArray * pl; ///< \ru Линии разъема (ребра) ( parting line ) ( не обязателен ). \en Parting lines (of edge) (optional). + bool reverse; ///< \ru Обратное направление тяги. \en Reverse pull direction. + bool step; ///< \ru Ступенчатый способ уклона. \en Stepwise method of draft. + +public: + /// \ru Конструктор уклона по известной нейтральной плоскости. \en Constructor of drafting by the given neutral plane. + MbDraftSolid( const MbPlacement3D & nPlace, // нейтральная плоскость ( neutral plane ) + double ang, // угол уклона + const std::vector & faceInds, // номера множества уклоняемых граней + MbeFacePropagation faceProp, // признак захвата граней + bool rev, // обратное направление тяги + const MbSNameMaker & n ) + : MbCreator ( n ) + , angle ( ang ) + , faceIndices( faceInds ) + , fp ( faceProp ) + , np ( new MbPlacement3D( nPlace ) ) + , edgeNb ( -1 ) + , pl ( NULL ) + , reverse ( rev ) + , step ( false ) + { + } + // \ru Конструктор уклона по линии разъема \en Constructor of drafting by the parting line + MbDraftSolid( double ang, // угол уклона + const MbPlacement3D * nPlace, // нейтральная плоскость ( neutral plane ) + ptrdiff_t edgeInd, // номер прямолинейного ребра - направляющего уклон ( не обязателен ) + MbeFacePropagation faceProp, // признак захвата граней + const SArray & partLines, // линии разъема (ребра) (parting line) (не обязателен) + bool rev, // обратное направление тяги + bool st, // ступенчатый способ уклона + const MbSNameMaker & n ) + : MbCreator ( n ) + , angle ( ang ) + , faceIndices( ) + , fp ( faceProp ) + , np ( nPlace ? new MbPlacement3D( *nPlace ) : NULL ) + , edgeNb ( edgeInd ) + , pl ( new SArray( partLines ) ) + , reverse ( rev ) + , step ( st ) + { + } +private : + MbDraftSolid( const MbDraftSolid &, MbRegDuplicate * ); // \ru Конструктор копирования \en Copy-constructor + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbDraftSolid( const MbDraftSolid & ); +public : + virtual ~MbDraftSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&, MbeCopyMode sameShell, + RPArray * = NULL ); // \ru Построение \en Construction + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbDraftSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbDraftSolid ) +}; + +IMPL_PERSISTENT_OPS( MbDraftSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку с уклоном граней. + \en Create a shell with drafted faces. \~ + \details \ru Для исходной оболочки построить оболочку с уклоном граней от нейтральной изоплоскости для создания литейных уклонов. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en For the source shell create a shell with faces drafted from the neutral isoplane for pattern tapers creation. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] np - \ru Локальная система координат, плоскость XY которой является нейтральной плоскостью ( neutral plane ). + \en The local coordinate system XY plane of which is a neutral plane. \~ + \param[in] angle - \ru Угол уклона. + \en Draft angle. \~ + \param[in] faces - \ru Уклоняемые грани. + \en The faces to draft. \~ + \param[in] fp - \ru Признак захвата граней ( face propagation ). + \en Flag of face propagation. \~ + \param[in] reverse - \ru Флаг для обратного направления тяги. + \en Flag for reverse pull direction. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateDraft( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & np, + double angle, + const RPArray & faces, + MbeFacePropagation fp, + bool reverse, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_DRAFT_SOLID_H diff --git a/C3d/Include/cr_duplication_solid.h b/C3d/Include/cr_duplication_solid.h new file mode 100644 index 0000000..0207d16 --- /dev/null +++ b/C3d/Include/cr_duplication_solid.h @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель размноженого набора граней. + \en Constructor of duplication face sets . \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CR_ELEMENTARY_SOLID_H +#define CR_ELEMENTARY_SOLID_H + + +#include +#include + + +class MATH_CLASS MbFaceShell; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель размноженого набора граней. + \en Constructor of duplication face sets . \~ + \details \ru Строитель выполняет размножение тела согласно параметрам и объединяет копии в одно тело\n + \en Creator makes duplication of face sets accordind to parameters and unite its into a single face set\~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbDuplicationSolid : public MbCreator { +protected: + DuplicationValues * parameters; ///< \ru Параметры размножения. \en Parameters of duplication. + +public: + /// \ru Конструктор по параметрам. \en Constructor by parameters. + MbDuplicationSolid( const DuplicationValues & p, const MbSNameMaker & n ); +private: + MbDuplicationSolid( const MbDuplicationSolid & init, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbDuplicationSolid( const MbDuplicationSolid & init ); +public: + virtual~MbDuplicationSolid(); + + /** \ru \name Общие функции строителя оболочки. + \en \name Common functions of the shell creator. + \{ */ + /// \ru Получить регистрационный тип (для копирования, дублирования). \en Get the registration type (for copying, duplication). + virtual MbeCreatorType IsA() const; + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru сделать копию \en create a copy + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru выдать свойства объекта \en get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru записать свойства объекта \en set properties of the object + virtual MbePrompt GetPropertyName(); // \ru выдать заголовок свойства объекта \en get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru являются ли объекты подобными \en whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru сделать равным \en make equal + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + /** \} */ + +private : +// \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbDuplicationSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbDuplicationSolid ) +}; // MbDuplicationSolid + +IMPL_PERSISTENT_OPS( MbDuplicationSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку размножения исходной оболочки. + \en Create a shell of duplication of original shell. \~ + \details \ru По данной оболочке и параметрам размножения построить оболочку как результат объединения копий.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell and duplication parameters construct a shell as a result of a union of copies. \n + The function simultaneously constructs the shell and creates its constructor.\~ + \param[in] solid - \ru Исходная оболочка. + \en Original face set. \~ + \param[in] params - \ru Параметры размножения. + \en Parameters of duplication. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] duplSolid - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Solid_Modeling +*/ +MATH_FUNC (MbCreator *) CreateDuplication( const MbFaceShell & solid, + const DuplicationValues & params, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // CR_ELEMENTARY_SOLID_H \ No newline at end of file diff --git a/C3d/Include/cr_elementary_solid.h b/C3d/Include/cr_elementary_solid.h new file mode 100644 index 0000000..1879a6f --- /dev/null +++ b/C3d/Include/cr_elementary_solid.h @@ -0,0 +1,220 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки элементарного тела. + \en Construction of shell for elementary solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_ELEMENTARY_SOLID_H +#define __CR_ELEMENTARY_SOLID_H + + +#include +#include + + +class MATH_CLASS MbElementarySurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки элементарного тела. + \en Constructor of shell for elementary solid. \~ + \details \ru Строитель оболочки элементарного тела по набору опорных точек и типу: \n + solidType = et_Sphere - шар (3 точки), \n + solidType = et_Torus - тор (3 точки), \n + solidType = et_Cylinder - цилиндр (3 точки), \n + solidType = et_Cone - конус (3 точки), \n + solidType = et_Block - блок (4 точки), \n + solidType = et_Wedge - клин (4 точки), \n + solidType = et_Prism - призма (количество вершин основания+1 точка), \n + solidType = et_Pyramid - пирамида (количество вершин основания+1 точка), \n + solidType = et_Plate - плита (4 точки). \n + \en Constructor of shell for elementary solid by a set of support points and a type: \n + solidType = et_Sphere - a sphere (3 points), \n + solidType = et_Torus - a torus (3 points), \n + solidType = et_Cylinder - a cylinder (3 points), \n + solidType = et_Cone - a cone (3 points), \n + solidType = et_Block - a block (4 points), \n + solidType = et_Wedge - a wedge (4 points), \n + solidType = et_Prism - a prism (points count is equal to the base vertices count + 1), \n + solidType = et_Pyramid - a pyramid (points count is equal to the base vertices count + 1), \n + solidType = et_Plate - a plate (4 points). \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbElementarySolid : public MbCreator { +protected : + SArray points; ///< \ru Опорные точки оболочки тела. \en Support points of a solid shell. + ElementaryShellType type; ///< \ru Тип тела. \en Type of a solid. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по точкам и типу тела. + \en Constructor by points and a type of a solid. \~ + + \param[in] pnts - \ru Опорные точки. \n + pnts[0] определяет начало локальной системы координат. \n + Для сферы, тора, цилиндра и конуса: \n + pnts[1] определяет направление оси Z локальной системы. \n + pnts[2] определяет направление оси X локальной системы. \n + Для блока, клина и плиты: \n + pnts[1] определяет направление оси X локальной системы. \n + pnts[2] определяет направление оси Y локальной системы. \n + Кроме того, \n + pnts[1] определяет высоту цилиндра, высоту конуса, + большой радиус тора, длину блока, длину клина. \n + pnts[2] определяет радиус цилиндра, радиус конуса, радиус сферы, + малый радиус тора, ширину блока, ширину клина. \n + Последняя точка определяет высоту блока, клина, плиты, вершину пирамиды. + \en Support points. \n + pnts[0] determines a local coordinate system origin. \n + For a sphere, a torus, a cylinder or a cone: \n + pnts[1] determines the direction of Z-axis of a local coordinate system. \n + pnts[2] determines the direction of X-axis of a local coordinate system. \n + For a block, a plate or a wedge: \n + pnts[1] determines the direction of X-axis of a local coordinate system. \n + pnts[2] determines the direction of Y-axis of a local coordinate system. \n + Also, \n + pnts[1] determines the height of a cylinder or a cone, + the major radius of a torus, the length of a block or a wedge. \n + pnts[2] determines the radius of a cylinder or a cone, radius of a sphere, + the minor radius of a torus, the width of a block or a wedge. \n + The last point determines the height of a block, a wedge or a plate, the vertex of a pyramid. \~ + \param[in] t - \ru Тип элементарного тела. + \en Elementary solid type. \~ + \param[in] n - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + template + MbElementarySolid( const Points & pnts, ElementaryShellType t, const MbSNameMaker & n ) + : MbCreator( n ) + , points ( ) + , type ( t ) + { + size_t cnt = pnts.size(); + points.reserve( cnt ); + for ( size_t k = 0; k < cnt; ++k ) { + points.push_back( pnts[k] ); + } + } + +private : + MbElementarySolid( const MbElementarySolid &, MbRegDuplicate * iReg ); // \ru Конструктор копирования с регистратором \en Copy-constructor with the registrator + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbElementarySolid( const MbElementarySolid & ); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbElementarySolid(); + + /** \ru \name Общие функции строителя оболочки. + \en \name Common functions of the shell creator. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems( RPArray & s ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual bool CreateShell( MbFaceShell *&, MbeCopyMode sameShell, + RPArray * = NULL ); // \ru Построение \en Construction + /** \} */ + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbElementarySolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbElementarySolid ) +}; // MbElementarySolid + +IMPL_PERSISTENT_OPS( MbElementarySolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку элементарного тела. + \en Create a shell of an elementary solid. \~ + \details \ru Создать оболочку элементарного тела по набору опорных точек и типу:\n + solidType = et_Sphere - шар (3 точки), \n + solidType = et_Torus - тор (3 точки), \n + solidType = et_Cylinder - цилиндр (3 точки), \n + solidType = et_Cone - конус (3 точки), \n + solidType = et_Block - блок (4 точки), \n + solidType = et_Wedge - клин (4 точки), \n + solidType = et_Prism - призма (количество вершин основания+1 точка), \n + solidType = et_Pyramid - пирамида (количество вершин основания+1 точка), \n + solidType = et_Plate - плита (4 точки). \n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en Create an elementary solid shell by a set of support points and type:\n + solidType = et_Sphere - a sphere (3 points), \n + solidType = et_Torus - a torus (3 points), \n + solidType = et_Cylinder - a cylinder (3 points), \n + solidType = et_Cone - a cone (3 points), \n + solidType = et_Block - a block (4 points), \n + solidType = et_Wedge - a wedge (4 points), \n + solidType = et_Prism - a prism (points count is equal to the base vertices count + 1), \n + solidType = et_Pyramid - a pyramid (points count is equal to the base vertices count + 1), \n + solidType = et_Plate - a plate (4 points). \n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] points - \ru Набор опорных точек. + \en Set of support points. \~ + \param[in] t - \ru Тип элементарного тела. + \en Elementary solid type. \~ + \param[in] n - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Оболочка - результат построения. + \en Shell - the result of construction. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateElementary( const SArray & points, + ElementaryShellType t, + const MbSNameMaker & n, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку элементарного тела. + \en Create a shell of an elementary solid. \~ + \details \ru Создать оболочку элементарного тела по элементарной поверхности.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en Create an elementary solid shell by an elementary surface.\n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] surface - \ru Элементарная поверхность.\n + Допускается тип поверхности - шар, тор, цилиндр, конус. + \en Elementary surface.\n + The acceptable surface types are sphere, torus, cylinder, cone. \~ + \param[in] n - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Оболочка - результат операции. + \en Shell - the result of operation. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateElementary( const MbElementarySurface & surface, + const MbSNameMaker & n, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_ELEMENTARY_SOLID_H diff --git a/C3d/Include/cr_evolution_solid.h b/C3d/Include/cr_evolution_solid.h new file mode 100644 index 0000000..c776ebc --- /dev/null +++ b/C3d/Include/cr_evolution_solid.h @@ -0,0 +1,271 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки кинематического тела. + \en Constructor of shell of evolution solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_EVOLUTION_SOLID_H +#define __CR_EVOLUTION_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки кинематического тела. + \en Constructor of shell of evolution solid. \~ + \details \ru Строитель оболочки тела путём движения образующей кривой по направляющей кривой. \n + \en Constructor of solid shell by moving generating curve along a spine curve. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCurveEvolutionSolid : public MbCurveSweptSolid { +protected : + MbSweptData sweptData; ///< \ru Данные об образующей. \en Generating curve data. + SPtr spineCurve; ///< \ru Направляющая кривая. \en Spine curve. + SPtr directionCurve; ///< \ru Кривая вектора ориентации матрицы преобразования (может быть NULL для простой траектории). \en A curve of the transformation matrix orientation (it may be NULL for a simple trajectory). + MbVector3D direction; ///< \ru Вектор ориентации матрицы преобразования (может быть нулевой, в случае автоопределения). \en Vector of transformation matrix orientation (it's equal zero in the mode of automatic direction calculation). + MbSNameMaker spineNames; ///< \ru Именователь направляющей. \en An object defining the name of the spine curve. + EvolutionValues parameters; ///< \ru Параметры. \en Parameters. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по одному контуру на поверхности. + \en Constructor by one contour on a surface. \~ + \param[in] surface_ - \ru Поверхность образующей. + \en Surface of a generating curve. \~ + \param[in] contour_ - \ru Контур в параметрах поверхности. + \en Contour in surface parameters domain. \~ + \param[in] spine_ - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип булевой операции с предыдущим результатом. + \en Type of Boolean operation with the previous result. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contourNames - \ru Имена контуров образующей для именования граней. + \en Generatix contours' names for naming faces. \~ + \param[in] spineNames - \ru Имена направляющей. + \en Generating curve names. \~ + */ + MbCurveEvolutionSolid( const MbSurface & surface_, + const MbContour & contour_, + const MbCurve3D & spine_, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const MbSNameMaker & contourNames, + const MbSNameMaker & spineNames_ ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по смешанной образующей. + \en Constructor by combined generating curve. \~ + \param[in] sweptData_ - \ru Образующая. + \en Generating curve. \~ + \param[in] spine_ - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип булевой операции с предыдущим результатом. + \en Type of Boolean operation with the previous result. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contourNames - \ru Имена контуров образующей для именования граней. + \en Generatix contours' names for naming faces. \~ + \param[in] spineNames - \ru Имена направляющей. + \en Generating curve names. \~ + */ + MbCurveEvolutionSolid( const MbSweptData & sweptData_, + const MbCurve3D & spine_, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames_ ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по смешанной образующей. + \en Constructor by combined generating curve. \~ + \param[in] sweptData_ - \ru Образующая. + \en Generating curve. \~ + \param[in] spine_ - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип булевой операции с предыдущим результатом. + \en Type of Boolean operation with the previous result. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contourNames - \ru Имена контуров образующей для именования граней. + \en Generatix contours' names for naming faces. \~ + \param[in] spineNames - \ru Имена направляющей. + \en Generating curve names. \~ + */ + MbCurveEvolutionSolid( const MbSweptData & sweptData_, + const MbSpine & spine_, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames_ ); + +private : + MbCurveEvolutionSolid( const MbCurveEvolutionSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbCurveEvolutionSolid( const MbCurveEvolutionSolid & ); +public : + virtual ~MbCurveEvolutionSolid(); + + /** \ru \name Общие функции математического объекта. + \en \name Common functions of the mathematical object. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + /** \} */ + /** \ru \name Общие функции твердого тела (формообразующей операции). + \en \name Common functions of the rigid solid (forming operations). + \{ */ + virtual MbFaceShell * InitShell( bool in ); + virtual void InitBasis( RPArray & items ); + virtual bool GetPlacement( MbPlacement3D & p ) const; + virtual void SetYourVersion( VERSION version, bool forAll ); + /** \} */ + /** \ru \name Функции строителя оболочки кинематического тела. + \en \name Functions of creator of evolution solid shell. + \{ */ + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( EvolutionValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const EvolutionValues & params ) { parameters = params; } + /** \} */ + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCurveEvolutionSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveEvolutionSolid ) +}; // MbCurveEvolutionSolid + +IMPL_PERSISTENT_OPS( MbCurveEvolutionSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку кинематического тела. + \en Create a shell of evolution solid. \~ + \details \ru Построить оболочку путём движения образующей кривой по направляющей кривой + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell by moving the generating curve along the spine curve + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Набор граней, к которым дополняется построение. + \en Face set the construction is complemented with respect to. \~ + \param[in] sameShell - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] spine - \ru Направляющая кривая. + \en The spine curve. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип операции дополнения построения. + \en Type of operation of construction complement. \~ + \param[in] operNames - \ru Именователь операции. + \en Name-maker with version for a Boolean operation with the source solid. \~ + \param[in] contoursNames - \ru Имена образующей. + \en Names of the generating curve. \~ + \param[in] spineNames - \ru Имена пути. + \en Names of the path. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveEvolution( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbCurve3D & spine, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames, + MbResultType & res, + MbFaceShell *& shell ); + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку кинематического тела. + \en Create a shell of evolution solid. \~ + \details \ru Построить оболочку путём движения образующей кривой по направляющей кривой + и выполнить булуву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell by moving the generating curve along the spine curve + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Набор граней, к которым дополняется построение. + \en Face set the construction is complemented with respect to. \~ + \param[in] sameShell - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] spine - \ru Направляющая кривая c дополнительной информацией. + \en The spine curve with additional data. \~ + \param[in] params - \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \param[in] oType - \ru Тип операции дополнения построения. + \en Type of operation of construction complement. \~ + \param[in] operNames - \ru Именователь с версией для булевой с исходным телом. + \en Name-maker with version for a Boolean operation with the source solid. \~ + \param[in] contoursNames - \ru Имена образующей. + \en Names of the generating curve. \~ + \param[in] spineNames - \ru Имена пути. + \en Names of the path. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveEvolution( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbSpine & spine, + const EvolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const MbSNameMaker & spineNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_EVOLUTION_SOLID_H diff --git a/C3d/Include/cr_extension_shell.h b/C3d/Include/cr_extension_shell.h new file mode 100644 index 0000000..01a0f35 --- /dev/null +++ b/C3d/Include/cr_extension_shell.h @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение удлинённой грани оболочки. + \en Construction of an extended face of a shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_EXTENSION_SHELL_H +#define __CR_EXTENSION_SHELL_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель удлинённой грани оболочки. + \en Constructor of an extended face of a shell. \~ + \details \ru Строитель удлинённой грани оболочки. Удлинение может быть выполнено следующими способами. + Может быть ублинена на заданное расстояние указанная грань. + К указанной грани может быть добавлена гладко стыкующаяся с ней грань. + К указанной грани может быть добавлена грань, полученная выдавливанием крайнего ребра в заданном направлении. + \en Constructor of an extended face of a shell. Extension can be performed in the following ways: + The specified faces can be extended on the given distance. + A smoothly connected face can be added to the given face. + A face obtained by extrusion of boundary edge in the given direction can be added to the specified face. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbExtensionShell : public MbCreator { +protected : + MbItemIndex faceIndex; ///< \ru Идентификатор удлиняемой грани в оболочке. \en Identifier of a shell face to extend. + SArray edgeIndexes; ///< \ru Идентификаторы ребер в грани. \en Identifier of edges in the face. + ExtensionValues parameters; ///< \ru Параметры построения удлинённой оболочки. \en Parameters of the extended shell construction. + +public : + MbExtensionShell( const MbItemIndex & fInd, const SArray & inds, + const ExtensionValues & p, const MbSNameMaker & n ); +private : + MbExtensionShell( const MbExtensionShell &, MbRegDuplicate * ireg ); +public : + virtual ~MbExtensionShell(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( ExtensionValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const ExtensionValues & params ) { parameters = params; } + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbExtensionShell ) +OBVIOUS_PRIVATE_COPY( MbExtensionShell ) +}; // MbExtensionShell + +IMPL_PERSISTENT_OPS( MbExtensionShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить удлинённую грань оболочки. + \en Construct the extended face of a shell. \~ + \details \ru Построить удлинённую грань оболочки. Удлинение может быть выполнено следующими способами. + Может быть ублинена на заданное расстояние указанная грань. + К указанной грани может быть добавлена гладко стыкующаяся с ней грань. + К указанной грани может быть добавлена грань, полученная выдавливанием крайнего ребра в заданном направлении. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct the extended face of a shell. Extension can be performed in the following ways: + The specified faces can be extended on the given distance. + A smoothly connected face can be added to the given face. + A face obtained by extrusion of a boundary edge in the given direction can be added to the specified face. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] face - \ru Удлиняемая грагнь. + \en Face to extend. \~ + \param[in] edges - \ru Крайние рёбра удлиняемой грани. + \en Boundary edges of a face to extend. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateExtensionShell( MbFaceShell * solid, + MbeCopyMode sameShell, + MbFace & face, + const RPArray & edges, + const ExtensionValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_EXTENSION_SHELL_H diff --git a/C3d/Include/cr_extrusion_solid.h b/C3d/Include/cr_extrusion_solid.h new file mode 100644 index 0000000..ef6c1de --- /dev/null +++ b/C3d/Include/cr_extrusion_solid.h @@ -0,0 +1,180 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки тела выдавливания. + \en Constructor of an extrusion solid's shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_EXTRUSION_SOLID_H +#define __CR_EXTRUSION_SOLID_H + + +#include + + +class MATH_CLASS MbRect; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки тела выдавливания. + \en Constructor of an extrusion solid's shell. \~ + \details \ru Строитель оболочки тела путём движения образующих кривых вдоль заданного вектора на заданное расстояние. \n + \en Constructor of a solid's shell by moving generating curves along the given vector at the given distance. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCurveExtrusionSolid : public MbCurveSweptSolid { +protected: + MbSweptData sweptData; ///< \ru Данные об образующей. \en Generating curve data. + MbVector3D direction; ///< \ru Направление выдавливания. \en Extrusion direction. + ExtrusionValues parameters; ///< \ru Параметры. \en Parameters. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. + \en Constructor. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] direction - \ru Направление выдавливания. + \en An extrusion direction. \~ + \param[in] parameters - \ru Параметры выдавливания. + \en The extrusion parameters. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров для именования граней. + \en An object defining contours' names for faces naming. \~ + \param[in] creators - \ru Построители тела, используемого в опции "До ближайшего объекта". + \en Creators of a solid used with option "To the nearest object (solid)". \~ + \param[in] sameCreators - \ru Признак использования оригиналов построителей. + \en Flag of using the original creators. \~ + */ + MbCurveExtrusionSolid( const MbSweptData & sweptData, + const MbVector3D & direction, + const ExtrusionValues & parameters, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + const c3d::CreatorsSPtrVector * creators = NULL, + bool sameCreators = true ); + +private : + MbCurveExtrusionSolid( const MbCurveExtrusionSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbCurveExtrusionSolid( const MbCurveExtrusionSolid & ); +public : + virtual ~MbCurveExtrusionSolid(); + + /** \ru \name Общие функции математического объекта. + \en \name Common functions of the mathematical object. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию. \en Make a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным. \en Make equal. + + /** \} */ + /** \ru \name Общие функции твердого тела (формообразующей операции). + \en \name Common functions of the rigid solid (forming operations). + \{ */ + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение. \en Construction. + + virtual MbFaceShell * InitShell( bool in ); + virtual void InitBasis( RPArray & items ); + virtual bool GetPlacement( MbPlacement3D & ) const; + /** \} */ + /** \ru \name Функции строителя оболочки тела выдавливания. + \en \name Functions of an extrusion solid's shell creator. + \{ */ + /// \ru Поверхность двумерных контуров. \en A surface of two-dimensional contours. + const MbSurface * GetSurface() const { return sweptData.GetSurface(); } + /// \ru Направление выдавливания. \en An extrusion direction. + const MbVector3D & GetDirection() const { return direction; } + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( ExtrusionValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const ExtrusionValues & params ) { parameters = params; } + /// \ru Дать габарит контуров на плейсменте. \en Get bounding boxes of contours in the placement. + void AddPlacementRect( MbRect & r ) const; + /** \} */ + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCurveExtrusionSolid & ); // \ru НЕЛЬЗЯ!!! \en NOT ALLOWED!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveExtrusionSolid ) +}; + +IMPL_PERSISTENT_OPS( MbCurveExtrusionSolid ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку тела выдавливания. + \en Create an extrusion solid's shell. \~ + \details \ru Построить оболочку тела путём движения образующих кривых вдоль заданного вектора на заданное расстояние + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a boy's shell by moving generating curves along the given vector at the given distance + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Набор граней, к которым дополняется построение. + \en Face set the construction is complemented with respect to. \~ + \param[in] sameShell - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] creators - \ru Строители тела solid. + \en Creators of the solid. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] direction - \ru Направление выдавливания + \en Extrusion direction. \~ + \param[in, out] params - \ru Параметры выдавливания. + Возвращают информацию для построения элементов массива операций до поверхности. + \en The extrusion parameters. + Returns the information for construction of the up-to-surface operation array elements. \~ + \param[in] oType - \ru Тип операции дополнения построения. + \en Type of operation of construction complement. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров. + \en An object defining the names of contours. \~ + \param[out] resType - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveExtrusion( MbFaceShell * solid, + MbeCopyMode sameShell, + const c3d::CreatorsSPtrVector * solidCreators, + const MbSweptData & sweptData, + const MbVector3D & direction, + const ExtrusionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbResultType & resType, + MbFaceShell *& shell ); + + +#endif // __CR_EXTRUSION_SOLID_H diff --git a/C3d/Include/cr_fillet_solid.h b/C3d/Include/cr_fillet_solid.h new file mode 100644 index 0000000..90bbb6a --- /dev/null +++ b/C3d/Include/cr_fillet_solid.h @@ -0,0 +1,169 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель cкругления ребeр. + \en Edges fillet constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_FILLET_SOLID_H +#define __CR_FILLET_SOLID_H + + +#include +#include + + +struct MATH_CLASS MbEdgeFunction; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель cкругления ребeр. + \en Edges fillet constructor. \~ + \details \ru Строитель cкругления ребeр содержит параметры для выполнения операции, функции изменения радиуса, + идентификаторы граней остановки скруглений, идентификаторы скругляемых вершин. \n + Скругление ребра заключается в его замене на грань, гладко сопрягающую соединяемые ребром грани. + Построенная грань в сечении может иметь форму дуги окружности, эллипса, параболы и гиперболу. + Дуга окружности может иметь постоянный или переменный радиус, а также постоянную хорду. \n + \en Edges fillet constructor contains parameters for performing the operation, radius law, + identifiers of faces terminating fillets, fillet vertices identifiers. \n + Edge fillet consists in its replacement with a face smoothly connecting the faces incident at the edge. + The section of the constructed face can be an arc of circle, ellipse, parabola or hyperbola. + A circular arc can have a constant or variable radius and also a constant chord. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbFilletSolid : public MbSmoothSolid { +public : + RPArray functions; ///< \ru Функции изменения радиусов сопряжения. \en Functions of changing conjugation radii. + SArray boundaries; ///< \ru Номера граней для обрезки краёв скругления / фаски. \en Indices of faces for trimming the fillet / chamfer boundaries. + SArray vertices; ///< \ru Номера скругляемых вершин. \en Indices of vertices to fillet. + CornerValues cornerData; ///< \ru Параметры скругления вершин. \en Parameters of vertices fillet. + +public : + MbFilletSolid( SArray & inds, + RPArray & funcs, + SArray & bounds, + SArray & verts, + const SmoothValues & params, + const CornerValues & data, + const MbSNameMaker & n ); +private : + MbFilletSolid( const MbFilletSolid & init, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbFilletSolid( const MbFilletSolid & init ); +public : + virtual ~MbFilletSolid(); + + // \ru Общие функции математического объекта. \en Common functions of the mathematical object. + + virtual MbeCreatorType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual( const MbCreator & init ); // \ru Сделать равным. \en Make equal. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private : + virtual void ReadDistances ( reader &in ); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbFilletSolid & ); // \ru НЕЛЬЗЯ!!! \en NOT ALLOWED!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFilletSolid ) +}; // MbFilletSolid + +IMPL_PERSISTENT_OPS( MbFilletSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку со cкруглением ребeр. + \en Create a shell with edges fillet. \~ + \details \ru Для указанной оболочки построить оболочку, в которой выполнено cкругление или фаска рёбер с постоянными параметрами.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell create a shell with edges fillet or chamfer with constant parameters.\n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] initCurves - \ru Скругляемые рёбра исходной оболочки. + \en The source shell's edges to fillet. \~ + \param[in] initBounds - \ru Грани исходной оболочки для обрезки cкругления или фаски. + \en The source shell faces to trim the fillet of chamfer. \~ + \param[in] initVertices - \ru Скругляемые вершины "чемоданных углов". + \en Vertices for blending of three surfaces. \~ + \param[in] parameters - \ru Параметры обработки рёбер. + \en Parameters of edges processing. \~ + \param[in] cornerData - \ru Параметры скругления вершин "чемоданных углов". + \en Parameters of blending three surfaces. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateFillet( MbFaceShell * solid, + MbeCopyMode sameShell, + RPArray & initCurves, + RPArray & initBounds, + RPArray & initVertices, + const SmoothValues & parameters, + const CornerValues & cornerData, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку со cкруглением ребeр. + \en Create a shell with edges fillet. \~ + \details \ru Для указанной оболочки построить оболочку, в которой выполнено cкругление рёбер переменным радиусом.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en For a given shell create a shell with edges fillet with a variable radius.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] initCurves - \ru Обрабатываемые рёбра исходной оболочки и значения переменного радиуса. + \en The source shell edges to process and values of variable radius. \~ + \param[in] initBounds - \ru Грани исходной оболочки для обрезки cкругления или фаски. + \en The source shell faces to trim the fillet or chamfer. \~ + \param[in] parameters - \ru Параметры обработки рёбер. + \en Parameters of edges processing. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateFillet( MbFaceShell * solid, MbeCopyMode sameShell, + SArray & initCurves, + RPArray & initBounds, + const SmoothValues & parameters, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_FILLET_SOLID_H diff --git a/C3d/Include/cr_hole_solid.h b/C3d/Include/cr_hole_solid.h new file mode 100644 index 0000000..df9908d --- /dev/null +++ b/C3d/Include/cr_hole_solid.h @@ -0,0 +1,171 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки отверстия, кармана, фигурного паза. + \en Constructor of shell of hole, pocket, groove. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_HOLE_SOLID_H +#define __CR_HOLE_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки отверстия, кармана, фигурного паза. + \en Constructor of shell of hole, pocket, groove. \~ + \details \ru Строитель оболочки отверстия, кармана, фигурного паза. \n + Построение отверстия происходит следующим образом : + создается контур сверла в конструктивной плоскости, + вращением контура строится сверло, затем оно вычитается из присланного тела. + Построение кармана/бобышки происходит следующим образом : + создается прямоугольный контур в конструктивной плоскости, + который затем выдавливается в зависимости от типа объекта + либо в положительном направлении Z, либо в отрицательном, + затем скругляются боковые ребра и ребра на дне, + далее вычитается карман из присланного тела или приклеивается бобышка. + Построение фигурного паза происходит следующим образом : + создается контур паза в конструктивной плоскости, + выдавливанием контура строится паз, затем он вычитается из присланного тела. + \en Constructor of shell of hole, pocket, groove. \n + Construction of a hole is performed as follows: + a contour of a drill is created in the constructive plane, + and a drill is constructed by revolution of the contour; then the drill is subtracted from the given solid. + A pocket/boss is constructed as follows: + a rectangular contour is created in the constructive plane + which is extruded then + either in the positive direction of Z or in the negative one subject to the object type; + then the side edges and edges on the bottom are filleted; + then the obtained pocket is subtracted from the given solid or the obtained boss is attached to the solid. + The groove is constructed as follows: + a contour of a groove is created in the constructive plane; + the groove is constructed by extrusion of the contour; then it is subtracted from the given solid. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbHoleSolid : public MbCurveSweptSolid { +protected : + MbPlacement3D placement; ///< \ru Плоскость отверстия. \en Plane of the hole. + HoleValues * parameters; ///< \ru Параметры отверстия. \en The hole parameters. + +private : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbHoleSolid( const MbHoleSolid & init ); + MbHoleSolid( const MbHoleSolid & init, MbRegDuplicate * ireg ); +public : + /// \ru Конструктор по параметрам. \en Constructor by parameters. + MbHoleSolid( const MbPlacement3D & pl, const HoleValues & p, + OperationType op, const MbSNameMaker & n ); + /// \ru Деструктор. \en Destructor. + virtual ~MbHoleSolid(); + +public : + + // \ru Переопределение функций базового класса \en The base class functions override + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual MbFaceShell * InitShell( bool in ); + virtual void InitBasis( RPArray & items ); + virtual bool GetPlacement( MbPlacement3D & p ) const; + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbHoleSolid & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbHoleSolid ) +}; + +IMPL_PERSISTENT_OPS( MbHoleSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку с отверстием, карманом, или фигурным пазом. + \en Create a shell with a hole, a pocket or a groove. \~ + \details \ru Для указанной оболочки построить оболочку с отверстием, карманом, или фигурным пазом. \n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell construct a shell with a hole, a pocket or a groove. \n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Набор граней, к которым дополняется построение. + \en Face set the construction is complemented with respect to. \~ + \param[in] sameShell - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] par - \ru Параметры. + \en Parameters. \~ + \param[in] ns - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateHole( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const HoleValues & par, + const MbSNameMaker & ns, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить глубину отверстия "до указанной поверхности" при построении оболочки с отверстием. + \en Determine the hole depth "to the specified surface" while creating a shell with a hole. \~ + \details \ru Определить глубину отверстия "до указанной поверхности" при построении оболочки с отверстием. + Глубина отверстия "до поверхности" определяться расстоянием между + точкой привязки отверстия на поверхности расположения и + точкой пересечения оси отверстия с указанной поверхностью ограничения глубины. + \en Determine the hole depth "to the specified surface" while creating a shell with a hole. + The hole depth "to the surface" is defined by the distance between + the fasten point of the hole on the location surface and + a point of intersection of the hole axis with the given surface limiting the depth. \~ + \param[in] face - \ru Грань, до которой надо ограничить глубину. + \en A face terminating the depth. \~ + \param[in] place - \ru Плоскость отверстия. + \en Plane of the hole. \~ + \param[in] pars - \ru Параметры отверстия. + \en The hole parameters. \~ + \param[out] depth - \ru Глубина. + \en Depth. \~ + \return \ru true в случае , если расстояние было найдено \n false - если ось не пересекает грань + \en True if the distance was found \n false - if the axis does not intersect the face \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) GetDepthToFace( const MbFace & face, + const MbPlacement3D & place, + HoleValues & pars, + double & depth ); + + +#endif // __CR_HOLE_SOLID_H diff --git a/C3d/Include/cr_intersection_curve.h b/C3d/Include/cr_intersection_curve.h new file mode 100644 index 0000000..dc2e656 --- /dev/null +++ b/C3d/Include/cr_intersection_curve.h @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель кривой пересечения. + \en Intersection curve constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_INTERSECTION_CURVE_H +#define __CR_INTERSECTION_CURVE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель кривой пересечения. + \en Intersection curve constructor. \~ + \details \ru Строитель кривой пересечения.\n + \en Intersection curve constructor.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbIntCurveCreator : public MbCreator { +private: + RPArray creators1; // \ru Журнал построения первой оболочки. \en The first shell history tree. + RPArray creators2; // \ru Журнал построения второй оболочки. \en The second shell history tree. + +protected: + MbIntCurveCreator( const MbIntCurveCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbIntCurveCreator( const MbIntCurveCreator & ); // \ru Не реализовано \en Not implemented + MbIntCurveCreator(); // \ru Не реализовано \en Not implemented +public: + MbIntCurveCreator( const RPArray & creators1, bool same1, + const RPArray & creators2, bool same2, + const MbSNameMaker & snMaker ); +public: + virtual ~MbIntCurveCreator(); + + // \ru Общие функции строителя. \en The common functions of the creator. + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateWireFrame( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbIntCurveCreator & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbIntCurveCreator ) +}; + +IMPL_PERSISTENT_OPS( MbIntCurveCreator ) + +#endif // __CR_INTERSECTION_CURVE_H diff --git a/C3d/Include/cr_join_shell.h b/C3d/Include/cr_join_shell.h new file mode 100644 index 0000000..dd25c8b --- /dev/null +++ b/C3d/Include/cr_join_shell.h @@ -0,0 +1,239 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки соединения. + \en Construction of a join shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_JOIN_SHELL_H +#define __CR_JOIN_SHELL_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки соединения. + \en Constructor of a join shell. \~ + \details \ru Строитель оболочки, соединяющей две грани по двум кривым на них. \n + \en Constructor of a shell joining two faces by two curves on them. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbJoinShell : public MbCreator { +protected: + MbCurve3D * curve1; ///< \ru Первая образующая кривая. \en The first generating curve. + MbCurve3D * curve2; ///< \ru Вторая образующая кривая. \en The second generating curve. + JoinSurfaceValues parameters; ///< \ru Параметры поверхности соединения. \en Parameters of a join surface. +public : + MbJoinShell( MbCurve3D & c1, MbCurve3D & c2, const JoinSurfaceValues & p, const MbSNameMaker & n ); +private : + MbJoinShell( const MbJoinShell & init, MbRegDuplicate * ireg ); +public : + virtual ~MbJoinShell(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; ///< \ru Тип элемента \en Element type + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; ///< \ru Сделать копию \en Make a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); ///< \ru Преобразовать элемент согласно матрице \en Transform an element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); ///< \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); ///< \ru Поворот вокруг оси \en Rotation about an axis + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными. \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual MbePrompt GetPropertyName (); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties ( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); ///< \ru Построение \en Construction + + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( JoinSurfaceValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const JoinSurfaceValues & params ) { parameters = params; } + + const MbCurve3D & GetCurve( ptrdiff_t num ) const; + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbJoinShell ) +OBVIOUS_PRIVATE_COPY( MbJoinShell ) +}; + +IMPL_PERSISTENT_OPS( MbJoinShell ) + +//------------------------------------------------------------------------------ +/* \brief \ru Проверить необходимость модификации второй кривой. + \en Check if a modification of the second curve is necessary. \~ + \details \ru Проверить необходимость модификации второй кривой для построения оболочки соединения на этих кривых. \n + \en Check whether a modification of the second curve is necessary for construction of a join shell on these curves. \n \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \param[out] isInverted1 - \ru Была ли первая кривая инвертирована. + \en Whether the first curve was inverted. \~ + \param[out] isShifted1 - \ru Было ли смещено начало второй кривой. + \en Whether the beginning of the first curve was shifted. \~ + \param[in] version - \ru Версия построения. + \en The version of construction. \~ + \result \ru Возвращает построенную оболочку. + \en Returns the constructed shell. \~ + \ingroup Model_Creators +*/ +//--- +void CheckJoinedShellCurve( const MbCurve3D & curve1, + const MbCurve3D & curve2, + bool & isInverted1, + bool & isShifted1, + VERSION version ); + + +//------------------------------------------------------------------------------ +/* \brief \ru Построить кривую по набору рёбер. + \en Construct a curve given a set of edges. \~ + \details \ru Построить кривую по набору рёбер для поверхности соединения. + \en Construct a curve given a set of edges for a join surface. \~ + \param[in] edges - \ru Набор ребер. + \en A set of edges. \~ + \param[in] orients - \ru Ориентация рёбер набора. + \en Orientation of edges from the set. \~ + \param[in] matr - \ru Матрица преобразования рёбер набора. + \en Transformation matrix of edges from the set. \~ + \param[out] res - \ru Код результата построения. + \en Construction result code. \~ + \result \ru Возвращает построенную кривую. + \en Returns the constructed curve. \~ + \ingroup Model_Creators +*/ +//--- +MbCurve3D * CreateJoinedShellCurve( const RPArray & edges, + const SArray & orients, + const MbMatrix3D & matr, + MbResultType & res ); + + +//------------------------------------------------------------------------------ +/* \brief \ru Построить оболочку соединения. + \en Construct a join shell. \~ + \details \ru Построить оболочку, соединяющую две грани по двум кривым на них. \n + \en Construct a shell joining two faces by two curves on them. \n \~ + \param[in] curve1 - \ru Кривая на первой соединяемой поверхности. + \en A curve on the first surface to join. \~ + \param[in] curve2 - \ru Кривая на второй соединяемой поверхности. + \en A curve on the second surface to join. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] res - \ru Код результата построения. + \en Construction result code. \~ + \result \ru Возвращает построенную оболочку. + \en Returns the constructed shell. \~ + \ingroup Model_Creators +*/ +// --- +MbFaceShell * MakeJoinShell( MbSurfaceCurve & curve1, + MbSurfaceCurve & curve2, + JoinSurfaceValues & parameters, + const MbSNameMaker & names, + bool isPhantom, + MbResultType & res ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку соединения. + \en Construct a join shell. \~ + \details \ru Построить оболочку, соединяющую две грани по двум кривым на них. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell joining two faces by two curves on them. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] curve1 - \ru Кривая на первой соединяемой поверхности. + \en A curve on the first surface to join. \~ + \param[in] curve2 - \ru Кривая на второй соединяемой поверхности. + \en A curve on the second surface to join. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата построения. + \en Construction result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateJoinShell( MbSurfaceCurve & curve1, + MbSurfaceCurve & curve2, + JoinSurfaceValues & parameters, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку соединения. + \en Construct a join shell. \~ + \details \ru Построить оболочку соединения по двум наборам ребер. + Рёбра двух наборов определяют набор граней соединения, каждая из которых побстроена по двум кривым. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell of join given two sets of edges. + Edges of two sets define a set of join faces each of which is constructed by two curves. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] edges1 - \ru Первый набор ребер. + \en The first set of edges. \~ + \param[in] orients1 - \ru Ориентация рёбер первого набора. + \en Orientation of edges from the first set. \~ + \param[in] edges2 - \ru Второй набор ребер. + \en The second set of edges. \~ + \param[in] orients2 - \ru Ориентация рёбер второго набора. + \en Orientation of edges of the second set. \~ + \param[in] matr1 - \ru Матрица преобразования рёбер первого набора. + \en Transformation matrix of edges from the first set. \~ + \param[in] matr2 - \ru Матрица преобразования рёбер второго набора. + \en Transformation matrix of edges from the second set. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateJoinShell( const RPArray & edges1, + const SArray & orients1, + const RPArray & edges2, + const SArray & orients2, + const MbMatrix3D & matr1, + const MbMatrix3D & matr2, + JoinSurfaceValues & parameters, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell, + bool isPhantom ); + + +#endif // __CR_JOIN_SHELL_H diff --git a/C3d/Include/cr_lofted_solid.h b/C3d/Include/cr_lofted_solid.h new file mode 100644 index 0000000..3407b37 --- /dev/null +++ b/C3d/Include/cr_lofted_solid.h @@ -0,0 +1,217 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки тела по плоским сечениям. + \en Constructor of a lofted shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_LOFTED_SOLID_H +#define __CR_LOFTED_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки тела по сечениям. + \en Constructor of a lofted shell. \~ + \details \ru Строитель оболочки тела, проходящей по заданным сечениям и вдоль заданной осевой линии и направляющих. \n + \en Constructor of solid's shell passing through the given sections along the specified spine curve and guide curves. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCurveLoftedSolid : public MbCurveSweptSolid { +protected : + RPArray curves; ///< \ru Плоские сечения. \en Plane sections. + SPtr spine; ///< \ru Осевая линия (может отсутствовать). \en Spine curve (can be absent). + LoftedValues parameters; ///< \ru Параметры. \en Parameters. + RPArray * guideCurves; ///< \ru Массив направляющих кривых (может быть NULL). \en An array of guide curves (can be NULL). + SArray * userPnts; ///< \ru Пользовательские точки на сечениях. \en Custom points on the sections. + +public: + /// \ru Конструктор. \en Constructor. + MbCurveLoftedSolid( const RPArray & surfs, + const RPArray & cntrs, + const LoftedValues & p, + OperationType op, + const MbSNameMaker & n, + RPArray & ns, + RPArray * guideCrvs, + SArray * userPnts ); + /// \ru Конструктор. \en Constructor. + MbCurveLoftedSolid( const MbCurve3D & s, + const RPArray & surfs, + const RPArray & cntrs, + const LoftedValues & p, + OperationType op, + const MbSNameMaker & n, + RPArray & ns, + RPArray * guideCrvs, + SArray * userPnts ); + +private : + MbCurveLoftedSolid( const MbCurveLoftedSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbCurveLoftedSolid( const MbCurveLoftedSolid & init ); + +public : + virtual ~MbCurveLoftedSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать \en Transform + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual MbFaceShell * InitShell( bool /*in*/ ); + virtual void InitBasis( RPArray & items ); + virtual bool GetPlacement( MbPlacement3D & ) const; + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( LoftedValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const LoftedValues & params ) { parameters = params; } + /// \ru Направляющая кривая. \en The spine curve. + const MbCurve3D * GetSpine() const { return spine.get(); } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCurveLoftedSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveLoftedSolid ) +}; + +IMPL_PERSISTENT_OPS( MbCurveLoftedSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по плоским сечениям. + \en Create a solid from a planar sections. \~ + \details \ru Построить оболочку тела, проходящую по заданным сечениям + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a solid's shell passing through the given sections + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveLofted( MbFaceShell * solid, + MbeCopyMode sameShell, + SArray & pl, + RPArray & c, + const LoftedValues & p, + OperationType oType, + const MbSNameMaker & operNames, + RPArray & ns, + SArray * ps, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по пространственным сечениям. + \en Create a solid from sections on surfaces. \~ + \details \ru Построить оболочку тела, проходящую по заданным сечениям + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a solid's shell passing through the given sections + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveLofted( MbFaceShell * solid, + MbeCopyMode sameShell, + RPArray & surfs, + RPArray & c, + const LoftedValues & p, + OperationType oType, + const MbSNameMaker & operNames, + RPArray & ns, + RPArray * guideCurves, + SArray * ps, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по плоским сечениям. + \en Create a solid from a planar sections. \~ + \details \ru Построить оболочку тела, проходящую по заданным сечениям вдоль заданной направляющей + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a solid's shell passing through the given sections along the specified spine curve + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveLofted( MbFaceShell * solid, + MbeCopyMode _sameShell, + SArray & pl, + RPArray & c, + const MbCurve3D & centre_line, + const LoftedValues & p, + OperationType oType, + const MbSNameMaker & operNames, + RPArray & ns, + SArray * ps, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать тело по пространственным сечениям. + \en Create a solid from a space sections. \~ + \details \ru Построить оболочку тела, проходящую по заданным сечениям вдоль заданной осевой линии и направляющих + и выполнить булеву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a solid's shell passing through the given sections along the specified spine curve and guide curves + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveLofted( MbFaceShell * solid, + MbeCopyMode _sameShell, + RPArray & surfs, + RPArray & c, + const MbCurve3D & centre_line, + const LoftedValues & p, + OperationType oType, + const MbSNameMaker & operNames, + RPArray & ns, + RPArray * guideCurves, + SArray * ps, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_LOFTED_SOLID_H diff --git a/C3d/Include/cr_median_shell.h b/C3d/Include/cr_median_shell.h new file mode 100644 index 0000000..57af1ed --- /dev/null +++ b/C3d/Include/cr_median_shell.h @@ -0,0 +1,115 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение срединной оболочки между гранями тела. + \en Construction of a median shell between faces of solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_MEDIAN_SHELL_H +#define __CR_MEDIAN_SHELL_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MedianShellFaces; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель срединной оболочки тела. + \en Constructor of a median shell of solid. \~ + \details \ru Строитель осуществляет построение срединной оболочки между выбранными парами граней тела. + Поверхности выбранные граней должны быть эквидистантны по отношению друг к другу. \n + \en Constructor performs the building of a median shell between suitable selected face pairs of solid. + Suitable face pairs should be equidistant from each other. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbMedianShell : public MbCreator { +private : + MedianShellFaces faces; ///< \ru Выбранные грани. \en Selected faces . + MedianShellValues parameters; ///< \ru Параметры срединной оболочки. \en Parameters of median shell. + +public: + /// \ru Конструктор по выбранным граням и параметрам срединной оболочки. \en Constructor by selected faces and parameters of median shell. + MbMedianShell( const MedianShellFaces & faces, const MedianShellValues & params, const MbSNameMaker & snMaker ); + /// \ru Деструктор. \en Destructor. + virtual ~MbMedianShell(); + +private: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbMedianShell( const MbMedianShell &, MbRegDuplicate * ); + +public: + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Построение оболочки по исходным данным \en Construction of a shell from the given data + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( MedianShellValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const MedianShellValues & params ) { parameters = params; } + + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMedianShell ) +OBVIOUS_PRIVATE_COPY( MbMedianShell ) +}; + +IMPL_PERSISTENT_OPS( MbMedianShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить срединную оболочку между выбранными парами граней тела. + \en Build a median shell between selected faces of solid. \~ + \details \ru Построить срединную оболочку между выбранными парами граней тела. + Выбранные грани должны быть эквидистантны по отношению друг к другу. + Грани должны принадлежать одному и тому же телу. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Build a median shell between suitable selected face pairs of solid. + Suitable face pairs should be offset from each other. + The faces must belong to the same body. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] faces - \ru Выбранные пары граней. + \en Selected face pairs. \~ + \param[in] parameters - \ru Параметры операции. + \en Parameters of operation. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная срединная оболочка. + \en Constructed median shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateMedianShell( const MbFaceShell & solid, + const std::vector & faceIndexes, + const MedianShellValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_MEDIAN_SHELL_H \ No newline at end of file diff --git a/C3d/Include/cr_mesh_shell.h b/C3d/Include/cr_mesh_shell.h new file mode 100644 index 0000000..3a2cef5 --- /dev/null +++ b/C3d/Include/cr_mesh_shell.h @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки на сетке кривых. + \en Construction of a shell from a mesh of curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_MESH_SHELL_H +#define __CR_MESH_SHELL_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbFaceShell; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки на сетке кривых. + \en Constructor of a shell from a mesh of curves. \~ + \details \ru Строитель оболочки на сетке кривых, образованной двумя сечействами кривых. \n + \en Constructor of a shell from a mesh of curves formed by two sets of curves. \n \~ + \ingroup Model_Creators +*/ +//--- +class MATH_CLASS MbMeshShell : public MbCreator { +private : + MeshSurfaceValues parameters; ///< \ru Параметры построения. \en Construction parameters. + mutable bool changed; ///< \ru Флаг изменения параметров. \en Flag of parameters modification. +private: + /// \ru Конструктор копирования. \en Copy-constructor. + MbMeshShell( const MbMeshShell & obj, MbRegDuplicate * ireg ); +public: + /// \ru Конструктор по параметрам операции и именователю на оригиналах кривых и копиях поверхностей. \en Constructor by operation parameters and name-maker for original curves and copies of surfaces. + MbMeshShell( const MeshSurfaceValues & pars, const MbSNameMaker & n ); + virtual ~MbMeshShell(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; ///< \ru Тип элемента \en Element type + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; ///< \ru Сделать копию \en Make a copy + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); ///< \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); ///< \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); ///< \ru Сдвиг по вектору \en Translation by the vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); ///< \ru Поворот вокруг оси \en Rotation about an axis + + virtual MbePrompt GetPropertyName(); ///< \ru Выдать заголовок свойства объекта \en Get name of object property + virtual void GetProperties( MbProperties & ); ///< \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); ///< \ru Записать свойства объекта \en Write properties of the object + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + +public: + /// \ru Построение оболочки \en Creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MeshSurfaceValues & params ) const; + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MeshSurfaceValues & params ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMeshShell ) +OBVIOUS_PRIVATE_COPY( MbMeshShell ) +}; // MbMeshShell + +IMPL_PERSISTENT_OPS( MbMeshShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку на сетке кривых. + \en Construct a shell from a mesh of curves. \~ + \details \ru Построить оболочку на сетке кривых, образованной двумя сечействами кривых. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell from a mesh of curves formed by two sets of curves. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateMeshShell( MeshSurfaceValues & parameters, + const MbSNameMaker & operNames, + bool isPhantom, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_MESH_SHELL_H diff --git a/C3d/Include/cr_modified_nurbs_.h b/C3d/Include/cr_modified_nurbs_.h new file mode 100644 index 0000000..c499843 --- /dev/null +++ b/C3d/Include/cr_modified_nurbs_.h @@ -0,0 +1,217 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки c деформируемыми гранями. + \en Constructor of a shell with deformable faces. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_MODIFIED_NURBS_H +#define __CR_MODIFIED_NURBS_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки c деформируемыми гранями. + \en Constructor of a shell with deformable faces. \~ + \details \ru Строитель оболочки, выполняющий замену поверхностей указанных граней деформируемыми поверхностями. \n + \en Constructor of a shell performing replacement of the surfaces of the specified faces with deformable surfaces. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbModifiedNurbsItem : public MbCreator { +protected: + NurbsValues parameters; ///< \ru Параметры модифицированных поверхностей. \en Parameters of modified surfaces. + SArray itemIndices; ///< \ru Идентификаторы модифицируемых граней. \en Identifiers of faces being modified. + RPArray surfaces; ///< \ru Множество поверхностей модифицированных граней. \en A set of surfaces of the modified faces. + +public: // \ru конструктор по параметрам \en constructor by parameters + MbModifiedNurbsItem( const NurbsValues & p, const SArray & faces, + RPArray & surfs, const MbSNameMaker & names ); +private: // \ru конструктор дублирующий \en duplication constructor + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbModifiedNurbsItem( const MbModifiedNurbsItem & init ); + MbModifiedNurbsItem( const MbModifiedNurbsItem & init, MbRegDuplicate * ireg ); + +public: // \ru деструктор \en destructor + virtual ~MbModifiedNurbsItem(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru сделать копию \en create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru сделать равным \en make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru сдвиг по вектору \en translation by a vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru выдать заголовок свойства объекта \en get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru выдать свойства объекта \en get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru записать свойства объекта \en set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /// \ru Построение оболочки. \en creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & outer ); ///< \ru обновить форму оболочки \en update shape of the shell + // \ru Выдать базовые объекты. \en Get basis objects. + virtual void GetBasisItems( RPArray & s ); + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( NurbsValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const NurbsValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbModifiedNurbsItem & ); + void SurfacesFree(); // \ru Удалить поверхности \en Delete the surfaces + void SurfacesAddRef(); // \ru Учесть поверхности \en Consider the surfaces + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbModifiedNurbsItem ) +}; + +IMPL_PERSISTENT_OPS( MbModifiedNurbsItem ) + +//------------------------------------------------------------------------------ +/** \brief \ru Модификатор оболочки c деформируемой гранью. + \en Modifier of a shell with a deformable face. \~ + \details \ru Модификатор оболочки выполняет деформацию поверхности указанной грани. + Указанная грань должна быть дефолрмируемой. \n + \en Modifier of a shell performs deformation of a surface of the specified face. + The specified face should be deformable. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbNurbsModification : public MbCreator { +protected: + MbItemIndex faceIndex; ///< \ru Идентификатор деформируемой грани. \en Identifier of the deformable face. + MbSurface * faceSurface; ///< \ru Поверхность деформируемой грани. \en Surface of the deformable face. + Array2 fixedPoints; ///< \ru Матрица положений неизменяемых контрольных точек модифицируемой поверхности. \en Matrix of positions of the invariant control points of the modifiable surface. + +public: // \ru конструктор по параметрам \en constructor by parameters + MbNurbsModification( const MbItemIndex & index, MbSurface & fSurface, Array2 & fPoints, + const MbSNameMaker & names ); +private: // \ru конструктор дублирующий \en duplication constructor + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbNurbsModification( const MbNurbsModification & init ); + MbNurbsModification( const MbNurbsModification & init, MbRegDuplicate * ireg ); + +public: // \ru деструктор \en destructor + virtual ~MbNurbsModification(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru сделать копию \en create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru сделать равным \en make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru сдвиг по вектору \en translation by a vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru выдать заголовок свойства объекта \en get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru выдать свойства объекта \en get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru записать свойства объекта \en set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /// \ru построение оболочки \en creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & outer ); ///< \ru обновить форму оболочки \en update shape of the shell + // \ru Выдать базовые объекты. \en Get basis objects. + virtual void GetBasisItems( RPArray & s ); + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbNurbsModification & ); // \ru не реализован!!! \en not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbsModification ) +}; + +IMPL_PERSISTENT_OPS( MbNurbsModification ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку c деформируемыми гранями. + \en Construct a shell with deformable faces. \~ + \details \ru Построить оболочку c заменjq указанных граней исходной оболочки деформируемыми гранями. + Поверхности выбранных граней аппроксимируются NURBS поверхностями или + деформируемыми поверхностями для последующего редактирования. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell with replacement of the specified faces of the source shell with deformable faces. + Surfaces of the selected faces are approximated with NURBS surfaces or + deformable surfaces for the further editing. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] outer - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Параметры модификации. + \en Parameters of the modification. \~ + \param[in] faces - \ru Изменяемые грани тела. + \en Faces to be modified. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateModifiedNurbsItem( MbFaceShell * outer, + MbeCopyMode sameShell, + const NurbsValues & parameters, + const RPArray & faces, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку, в которой деформирована указанная грань. + \en Construct a shell in which the specified face is deformed. \~ + \details \ru Построить оболочку, в которой деформирована указанная грань путём + подстановки контрольных точек присланной NURBS-поверхности с фиксацией указанных точек.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell in which the specified face is deformed by + replacement of the control points of the given NURBS surface with fixing the specified points.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] outer - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Деформируемая грань оболочки. + \en Deformable face of the shell. \~ + \param[in] faceSurface - \ru Новая деформируемая поверхность для грани. + \en The new deformable surface of the face. \~ + \param[in] fixedPoints - \ru Матрица положений неизменяемых контрольных точек деформируемой поверхности (false). + \en Matrix of positions of invariant control points of the deformable surface (false). \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateNurbsModification( MbFaceShell * outer, + MbeCopyMode sameShell, + MbFace * face, + MbSurface & faceSurface, + Array2 & fixedPoints, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_MODIFIED_NURBS_H diff --git a/C3d/Include/cr_modified_solid.h b/C3d/Include/cr_modified_solid.h new file mode 100644 index 0000000..862e4cc --- /dev/null +++ b/C3d/Include/cr_modified_solid.h @@ -0,0 +1,152 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель модифицированной оболочки. + \en Constructor of a modified shell. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_MODIFIED_SOLID_H +#define __CR_MODIFIED_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель модифицированной оболочки. + \en Constructor of a modified shell. \~ + \details \ru Строитель оболочки, выполняющий модификацию исходной оболочки. + Строитель выполняет следующие модификации исходной оболочки: \n + удаление из тела выбранных граней с окружением, \n + создание тела из выбранных граней с окружением, \n + перемещение выбранных граней с окружением относительно оставшихся граней тела, \n + замена выбранных граней тела эквидистантными гранями (перемещение по нормали, изменение радиуса), \n + замена выбранных граней тела деформируемыми гранями (превращение в NURBS для редактирования).\n + \en Constructor of a shell performing modification of the source shell. + Constructor performs the following modifications of the source shell: \n + deletion the selected faces with neighborhood from the solid, \n + creation of the solid from the selected faces with the neighborhood, \n + translation of the selected faces with the neighborhood relative to the remained faces of the solid, \n + replacement of the selected faces of the solid with the offset faces (translation along the normal, changing the radius), \n + replacement of the specified faces of the solid with the deformable faces (conversion to the NURBS for editing).\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbFaceModifiedSolid : public MbCreator { +protected: // \ru Данные класса. \en Data of class. + ModifyValues parameters; ///< \ru Параметры редактирования оболочки. \en Shell editing parameters. + SArray faceIndices; ///< \ru Идентификаторы модифицированных граней. \en Identifiers of the modified faces. + SArray edgeIndices; ///< \ru Идентификаторы модифицированных рёбер. \en Identifiers of the modified edges. + RPArray surfaces; ///< \ru Массив-указателей на nurbs поверхности граней. \en Array of pointers to NURBS surfaces of the faces. + +public: + // \ru Конструктор по параметрам. \en Constructor by parameters. + MbFaceModifiedSolid( const ModifyValues & p, const SArray & faces, + RPArray & surfs, const MbSNameMaker & names ); + // \ru Конструктор по параметрам. \en Constructor by parameters. + MbFaceModifiedSolid( const ModifyValues & p, const SArray edges, + const MbSNameMaker & names ); +private: + // \ru Конструктор дублирующий. \en Duplicating constructor. + MbFaceModifiedSolid( const MbFaceModifiedSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbFaceModifiedSolid( const MbFaceModifiedSolid & init ); + +public: // \ru Деструктор \en Destructor + ~MbFaceModifiedSolid(); + +public: + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг по вектору \en Translation by the vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /// \ru Построение оболочки \en Creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & outer ); ///< \ru Обновить форму оболочки \en Update shape of the shell + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( ModifyValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const ModifyValues & params ) { parameters = params; } + + void GetFaceIndices( SArray & faces ) const { faces = faceIndices; } // \ru Идентификаторы модифицированных граней. \en Identifiers of the modified faces. + void GetEdgeIndices( SArray & edges ) const { edges = edgeIndices; } // \ru Идентификаторы модифицированных рёбер. \en Identifiers of the modified edges. + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbFaceModifiedSolid & ); + void SurfacesFree(); // \ru Удалить поверхности \en Delete the surfaces + void SurfacesAddRef(); // \ru Учесть поверхности \en Consider the surfaces + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFaceModifiedSolid ) +}; + +IMPL_PERSISTENT_OPS( MbFaceModifiedSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить модифицированную оболочку. + \en Construct the modified shell. \~ + \details \ru Построить оболочку тела путём модификации исходной оболочки. + В зависимости от параметров возможны следующие модификации исходной оболочки: \n + удаление из тела выбранных граней с окружением, \n + создание тела из выбранных граней с окружением, \n + перемещение выбранных граней с окружением относительно оставшихся граней тела, \n + замена выбранных граней тела эквидистантными гранями (перемещение по нормали, изменение радиуса), \n + замена выбранных граней тела деформируемыми гранями (превращение в NURBS для редактирования).\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct the solid's shell by modification the source shell. + The following modifications of the source shell are possible depend on the parameters: \n + deletion the selected faces with neighborhood from the solid, \n + creation of the solid from the selected faces with the neighborhood, \n + translation of the selected faces with the neighborhood relative to the remained faces of the solid, \n + replacement of the selected faces of the solid with the offset faces (translation along the normal, changing the radius), \n + replacement of the specified faces of the solid with the deformable faces (conversion to the NURBS for editing).\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] outer - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Параметры модификации. + \en Parameters of the modification. \~ + \param[in] faces - \ru Изменяемые грани тела. + \en Faces to be modified. \~ + \param[in] edges - \ru Изменяемые рёроа тела. + \en Edges to be modified. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateFaceModifiedSolid( MbFaceShell * outer, + MbeCopyMode sameShell, + const ModifyValues & parameters, + const RPArray & faces, + const RPArray & edges, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_MODIFIED_SOLID_H diff --git a/C3d/Include/cr_nurbs3d.h b/C3d/Include/cr_nurbs3d.h new file mode 100644 index 0000000..d5dbc14 --- /dev/null +++ b/C3d/Include/cr_nurbs3d.h @@ -0,0 +1,129 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель пространственного сплайна с сопряжениями. + \en Constructor of the spatial spline with tangents. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_NURBS3D_H +#define __CR_NURBS3D_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель пространственного сплайна. + \en Spatial spline constructor. \~ + \details \ru Строитель пространственного сплайна.\n + \en Spatial spline constructor.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbNurbs3DCreator : public MbCreator { +private: + SArray points; // \ru Точки, через которые проходит сплайн \en Points which the spline passes through + SArray weights; // \ru Веса \en Weights + SArray knots; // \ru Узлы \en Knots + RPArray< MbPntMatingData > matingData; // \ru Данные сопряжения в точках \en Data about mating in the points + MbeSplineParamType paramType; // \ru Тип параметризации \en Parametrization type + size_t degree; // \ru Степень сплайна \en Spline degree + bool closed; // \ru Замкнутость сплайна \en Spline closedness + bool throughPnts; // \ru через точки \en Through points + +protected: + MbNurbs3DCreator( const MbNurbs3DCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbNurbs3DCreator( const MbNurbs3DCreator & ); // \ru Не реализовано \en Not implemented + MbNurbs3DCreator(); // \ru Не реализовано \en Not implemented +public: + MbNurbs3DCreator( const SArray & spacePnts, bool throughPnts, + MbeSplineParamType paramType, size_t degree, bool closed, + const SArray * weights, + const SArray * knots, + const RPArray< MbPntMatingData > & matingData, + const MbSNameMaker & snMaker ); +public: + virtual ~MbNurbs3DCreator(); + + // \ru Общие функции строителя. \en The common functions of the creator. + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateWireFrame( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbNurbs3DCreator & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbs3DCreator ) +}; + +IMPL_PERSISTENT_OPS( MbNurbs3DCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать пространственный сплайн через точки и с сопряжениями. + \en Create a spatial spline through points and with the given tangents. \~ + \details \ru Создать пространственный сплайн через точки и с сопряжениями + Если есть сопряжения, то количество сопряжений д.б. равно количеству точек. + Отсутствующие сопряжения должны быть представлены нулевыми указателями в массиве. + \en Create a spatial spline through points with tangents + If the tangents are specified, then the number of tangents should be equal to the number of points. + The missing tangents should be represented as the null pointers in the array. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCreator *) CreateSplineThrough( const SArray & points, // \ru Точки \en Points + MbeSplineParamType paramType, // \ru Тип параметризации \en Parametrization type + size_t degree, // \ru Порядок сплайна \en Spline degree + bool closed, // \ru Замкнуть \en Make close + RPArray< MbPntMatingData > & transitions, // \ru Сопряжения \en Tangents + const MbSNameMaker & snMaker, // \ru Именователь \en An object for naming the new objects + MbResultType & resType, + MbCurve3D *& resCurve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать пространственный сплайн по точкам и сопряжениями. + \en Create a spatial spline from points and tangents. \~ + \details \ru Создать пространственный сплайн по точкам и сопряжениями.\n + \en Create a spatial spline from points and tangents.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCreator *) CreateSplineBy( const SArray & points, // \ru Точки \en Points + size_t degree, // \ru Порядок сплайна \en Spline degree + bool closed, // \ru Замкнуть \en Make close + const SArray * weights, // \ru Веса \en Weights + const SArray * knots, // \ru Узлы \en Knots + MbPntMatingData * begData, // \ru Сопряжение в начале \en Tangent at the start point + MbPntMatingData * endData, // \ru Сопряжение в конце \en Tangent at the end point + const MbSNameMaker & snMaker, // \ru Именователь \en An object for naming the new objects + MbResultType & resType, + MbCurve3D *& resCurve ); + + +#endif // __CR_NURBS3D_H diff --git a/C3d/Include/cr_nurbs_block_solid.h b/C3d/Include/cr_nurbs_block_solid.h new file mode 100644 index 0000000..1b2aeff --- /dev/null +++ b/C3d/Include/cr_nurbs_block_solid.h @@ -0,0 +1,111 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель блока из nurbs-поверхностей. + \en Constructor of a block from NURBS-surfaces. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_NURBS_BLOCK_SOLID_H +#define __CR_NURBS_BLOCK_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки в форме блока. + \en Constructor of a shell in the form of block. \~ + \details \ru Строитель оболочки в форме блока, имеющего шесть четырёхугольных граней на базе Nurbs-поверхностей. \n + \en Constructor of a shell in the form of a block with six quadrangular faces on the base of NURBS-surfaces. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbNurbsBlockSolid : public MbCreator { +protected: + RPArray surfaces; ///< \ru Множество поверхностей граней nurbs-блока. \en A set of surfaces of NURBS-block faces. + bool out; ///< \ru Направление нормалей граней (out = true - нормали направлены наружу блока). \en The faces normals direction (out = true - normals are directed outside the block). + SimpleName name; ///< \ru Имя объекта. \en A name of an object. + +public: // \ru Конструктор по параметрам \en Constructor by parameters + MbNurbsBlockSolid( RPArray & surf, bool bOutDir, const MbSNameMaker & names, SimpleName name ); +private: // \ru Конструктор дублирующий \en Duplication constructor + MbNurbsBlockSolid( const MbNurbsBlockSolid &, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbNurbsBlockSolid( const MbNurbsBlockSolid & ); +public: // \ru Деструктор \en Destructor + virtual ~MbNurbsBlockSolid(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг по вектору \en Translation by a vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + +public: + /// \ru Построение оболочки \en Creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & outer ); ///< \ru Обновить форму оболочки \en Update shape of the shell + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbNurbsBlockSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbsBlockSolid ) +}; + +IMPL_PERSISTENT_OPS( MbNurbsBlockSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить модифицированную оболочку. + \en Construct the modified shell. \~ + \details \ru Построить оболочку в форме блока, имеющего шесть четырёхугольных граней на базе Nurbs-поверхностей. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell in the form of a block with six quadrangular faces on the base of NURBS-surfaces. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] place - \ru Локальная система координат, вдоль осей которой будут стороиться ребра оболочки. + \en The local coordinate system along axes of which the shell's edges will be constructed. \~ + \param[in] ax - \ru Размер блока вдоль первой оси локальной системы координат. + \en The block size along the first axis of the local coordinate system. \~ + \param[in] ay - \ru Размер блока вдоль второй оси локальной системы координат. + \en The block size along the second axis of the local coordinate system. \~ + \param[in] az - \ru Размер блока вдоль третьей оси локальной системы координат. + \en The block size along the third axis of the local coordinate system. \~ + \param[in] out - \ru Направление нормалей граней (out = true - нормали наравлены наружу блока). + \en The faces normals direction (out = true - the normals are directed outside the block). \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] name - \ru Имя объекта. + \en A name of an object. \~ + \param[out] parameters - \ru Параметры построения оболочки. + \en The shell construction parameters. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateNurbsBlock( const MbPlacement3D & place, + double ax, double ay, double az, + bool out, + const MbSNameMaker & names, + SimpleName name, + NurbsBlockValues & parameters, + MbFaceShell *& shell ); + + +#endif // __CR_NURBS_BLOCK_SOLID_H diff --git a/C3d/Include/cr_nurbs_surfaces_shell.h b/C3d/Include/cr_nurbs_surfaces_shell.h new file mode 100644 index 0000000..623ab2c --- /dev/null +++ b/C3d/Include/cr_nurbs_surfaces_shell.h @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Создание оболочки из нурбс-поверхностей +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __NURBS_SURFACES_SHELL_H +#define __NURBS_SURFACES_SHELL_H + +#include +#include +#include + + +class MATH_CLASS MbCreator; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbFaceShell; +struct NurbsSurfaceValues; +class IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из NURBS-поверхностей. + \en Construct a shell from NURBS-surfaces. \~ + \details \ru Построить оболочку из NURBS-поверхностей MbSplineSurface по заданному множеству точек условно расположенных в узлах четырехугольной сетки. \n + \en Construct a shell from NURBS-surfaces MbSplineSurface by a given set of points conventionally located at the nodes of a quadrangle grid. \n \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \param[out] indicator - \ru Индикатор хода построения позволяющий прервать построение. + \en Construction process indicator which allow to interrupt the construction. \~ + \result \ru Возвращает оболочку. + \en Returns the constructуed shell. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbFaceShell *) CreateNurbsSurfacesShell( NurbsSurfaceValues & params, + const MbSNameMaker & operNames, + bool isPhantom, + MbResultType & res, + IProgressIndicator * = NULL ); + + +//------------------------------------------------------------------------------ +// проверить оболочку из нурбс-поверхностей +/** \brief \ru Построить оболочку из NURBS-поверхностей. + \en Construct a shell from NURBS-surfaces. \~ + \details \ru Построить оболочку из NURBS-поверхностей MbSplineSurface по заданному множеству точек условно расположенных в узлах четырехугольной сетки. \n + \en Construct a shell from NURBS-surfaces MbSplineSurface by a given set of points conventionally located at the nodes of a quadrangle grid. \n \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] shell - \ru Оболочка, построенная по заданным параметрам. + \en The shell constructed by given parameters. \~ + \param[out] indicator - \ru Индикатор хода построения позволяющий прервать построение. + \en Construction process indicator which allow to interrupt the construction. \~ + \result \ru Возвращает код результата операции. + \en Returns operation result code. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbResultType) CheckNurbsSurfacesShell( const NurbsSurfaceValues & params, + const MbFaceShell & shell, + IProgressIndicator * = NULL ); + + +#endif // __NURBS_SURFACES_SHELL_H diff --git a/C3d/Include/cr_nurbs_surfaces_solid.h b/C3d/Include/cr_nurbs_surfaces_solid.h new file mode 100644 index 0000000..32516a7 --- /dev/null +++ b/C3d/Include/cr_nurbs_surfaces_solid.h @@ -0,0 +1,116 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки из NURBS-поверхностей. + \en Construction of a sell from NURBS-surfaces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_NURBS_SURFACES_SOLID_H +#define __CR_NURBS_SURFACES_SOLID_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbCreator; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbFaceShell; +struct MATH_CLASS NurbsSurfaceValues; +class IProgressIndicator; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из NURBS-поверхностей. + \en Constructor of a shell from NURBS-surfaces. \~ + \details \ru Строитель оболочки из NURBS-поверхностей MbSplineSurface. + Аббревиатура NURBS получена из первых букв словосочетания Non-Uniform Rational B-Spline. + \en Constructor of a shell from NURBS-surfaces MbSplineSurface. + Abbreviation of NURBS is obtained from the first letters of "Non-Uniform Rational B-Spline" phrase. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbNurbsSurfacesSolid : public MbCreator { +protected: + NurbsSurfaceValues parameters; ///< \ru Параметры построения. \en Construction parameters. + mutable bool changed; ///< \ru Флаг изменения параметров. \en Flag of parameters modification. + +public: + // \ru конструктор, копирующий параметры \en constructor copying the parameters + MbNurbsSurfacesSolid( const NurbsSurfaceValues & params, const MbSNameMaker & names ); +private: + MbNurbsSurfacesSolid( const MbNurbsSurfacesSolid &, MbRegDuplicate * ireg ); +public: + // \ru деструктор \en destructor + ~MbNurbsSurfacesSolid(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru сделать копию \en create a copy + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru сделать равным \en make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru сдвиг по вектору \en translation by a vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru выдать заголовок свойства объекта \en get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru выдать свойства объекта \en get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru записать свойства объекта \en set properties of the object + virtual void GetBasisItems ( RPArray & s ); // \ru дать базовые объекты \en get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + +public: + /// \ru построение оболочки \en creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & outer ); ///< \ru обновить форму оболочки \en update shape of the shell + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( NurbsSurfaceValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const NurbsSurfaceValues & params ) { parameters = params; } + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbsSurfacesSolid ) +OBVIOUS_PRIVATE_COPY( MbNurbsSurfacesSolid ) +}; + +IMPL_PERSISTENT_OPS( MbNurbsSurfacesSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из NURBS-поверхностей. + \en Construct a shell from NURBS-surfaces. \~ + \details \ru Построить оболочку из NURBS-поверхностей MbSplineSurface. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from NURBS-surfaces MbSplineSurface. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of a shell creation. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \param[out] indicator - \ru Индикатор хода построения. + \en Construction process indicator. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateNurbsShell( NurbsSurfaceValues & parameters, + const MbSNameMaker & operNames, + bool isPhantom, + MbResultType & res, + MbFaceShell *& shell, + IProgressIndicator * indicator = NULL ); + + +#endif // __CR_NURBS_SURFACES_SOLID_H diff --git a/C3d/Include/cr_offset_curve.h b/C3d/Include/cr_offset_curve.h new file mode 100644 index 0000000..6e3952c --- /dev/null +++ b/C3d/Include/cr_offset_curve.h @@ -0,0 +1,167 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель эквидистантной кривой. + \en Offset curve constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_OFFSET_CURVE_H +#define __CR_OFFSET_CURVE_H + + +#include +#include +#include + + +class MATH_CLASS MbCurve3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель эквидистантной кривой. + \en Offset curve constructor. \~ + \details \ru Строитель эквидистантной кривой.\n + \en Offset curve constructor.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbOffsetCurveCreator : public MbCreator { +private: + // \ru Основные параметры \en The basic parameters + SPtr curve; // \ru Исходная кривая. \en The initial curve. + MbVector3D dir; // \ru Направление смещения. \en The offset direction. + double dist; // \ru Величина смещения. \en The offset distance. + bool fromBeg; // \ru Вектор смещения привязан к началу кривой (иначе к концу). \en The translation vector is associated with the beginning (with the end otherwise). + + // \ru Дополнительные параметры (эквидистанта в пространстве) \en Auxiliary parameters (spatial offset) + bool useFillet; // \ru Заполнять ли разрывы скруглениями (иначе продлять сегменты). \en Whether to fill the gaps with fillets (extend segments otherwise). + bool keepRadius; // \ru Сохранять ли радиусы в скруглениях. \en Whether to keep the radii at fillets. + bool bluntAngle; // \ru Притуплять острые углы стыков сегментов \en Whether to blunt the sharp edges of segments joints. + + // \ru Дополнительные параметры (эквидистанта на поверхности грани оболочки) \en Auxiliary parameters (offset on the shell face surface) + c3d::CreatorsSPtrVector shellCreators; // \ru Журнал построения оболочки. \en The shell history tree. + +protected: + MbOffsetCurveCreator( const MbOffsetCurveCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbOffsetCurveCreator( const MbOffsetCurveCreator & ); // \ru Не реализовано \en Not implemented + MbOffsetCurveCreator(); // \ru Не реализовано \en Not implemented +public: + // \ru Конструктор эквидистанты в пространстве \en Constructor of offset in the space + MbOffsetCurveCreator( const MbCurve3D &, bool fromBeg, const MbVector3D & dir, double dist, + bool useFillet, bool keepRadius, bool bluntAngle, + const MbSNameMaker & snMaker ); + // \ru Конструктор эквидистанты на поверхности грани оболочки \en Constructor of offset on the shell face surface + MbOffsetCurveCreator( const MbCurve3D &, bool fromBeg, const MbVector3D & dir, double dist, + const RPArray & shellCreators, bool sameCreators, + const MbSNameMaker & snMaker ); +public : + virtual ~MbOffsetCurveCreator(); + + // \ru Общие функции строителя. \en The common functions of the creator. + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateWireFrame( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbOffsetCurveCreator & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbOffsetCurveCreator ) +}; + +IMPL_PERSISTENT_OPS( MbOffsetCurveCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать офсетную кривую по трехмерной кривой и вектору направления. + \en Create an offset curve from three-dimensional curve and direction. \~ + \details \ru Создать офсетную кривую по трехмерной кривой и вектору направления. \n + \en Create an offset curve from three-dimensional curve and direction. \n \~ + \param[in] initCurve - \ru Постранственная кривая, к которой строится эквидистантная. + \en A space curve for which to construct the offset curve. \~ + \param[in] offsetVect - \ru Вектор, задающий смещение в точке кривой. + \en The displacement vector at a point of the curve. \~ + \param[in] useFillet - \ru Если true, то разрывы заполнять скруглением, иначе продолженными кривыми. + \en If 'true', the gaps are to be filled with fillet, otherwise with the extended curves. \~ + \param[in] keepRadius - \ru Если true, то в существующих скруглениях сохранять радиусы. + \en If 'true', the existent fillet radii are to be kept. \~ + \param[in] fromBeg - \ru Вектор смещения привязан к началу. + \en The translation vector is associated with the beginning. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] resType - \ru Код результата операции + \en Operation result code \~ + \param[out] resCurve - \ru Эквидистантная кривая. + \en The offset curve. \~ + \return \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCreator *) CreateOffsetCurve( const MbCurve3D & initCurve, + const MbVector3D & offsetVect, + const bool useFillet, + const bool keepRadius, + const bool bluntAngle, + const bool fromBeg, + const MbSNameMaker & snMaker, + MbResultType & resType, + MbCurve3D *& resCurve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать офсетную кривую по поверхностной кривой и значению смещения. + \en Create an offset curve from a spatial curve and offset value. \~ + \details \ru Создать офсетную кривую по поверхностной кривой и значению смещения. \n + \en Create an offset curve from a spatial curve and offset value. \n \~ + \param[in] curve - \ru Кривая на поверхности грани face. + \en A curve on face 'face' surface. \~ + \param[in] face - \ru Грань, на которой строится эквидистанта. + \en The edge on which to build the offset curve. \~ + \param[in] dirAxis - \ru Направление смещения с точкой приложения. + \en The offset direction with a point of application. \~ + \param[in] dist - \ru Величина смещения. + \en The offset distance. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] resType - \ru Код результата операции + \en Operation result code \~ + \param[out] resCurves - \ru Множество эквидистантных кривых. + \en Offset curve array. \~ + \return \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCreator *) CreateOffsetCurve( const MbCurve3D & curve, + const MbFace & face, + const MbAxis3D & dirAxis, + double dist, + const MbSNameMaker & snMaker, + MbResultType & resType, + RPArray & resCurves ); + + +#endif // __CR_OFFSET_CURVE_H diff --git a/C3d/Include/cr_patch_creator.h b/C3d/Include/cr_patch_creator.h new file mode 100644 index 0000000..185a412 --- /dev/null +++ b/C3d/Include/cr_patch_creator.h @@ -0,0 +1,170 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки в форме заплатки. + \en Construction of a patch-shaped shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_PATCH_CREATOR_H +#define __CR_PATCH_CREATOR_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFaceShell; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки в форме заплатки. + \en Constructor of a patch-shaped shell. \~ + \details \ru Строитель оболочки в форме заплатки на заданных ребрах или кривых. \n + \en Constructor of a patch-shaped shell from the given edges or curves. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbPatchCreator : public MbCreator { +protected: + RPArray initCurves; ///< \ru Кривые, определяющие края заплатки. \en Curves determining the boundaries of a patch. + PatchValues parameters; ///< \ru Параметры построения заплатки. \en Parameters of patch construction. + /// \ru Cледующие данные имеются только, если обрабатываются ребра. \en The following data are defined only when edges are being processed. + SArray orientations; ///< \ru Ориентация кривых для замыкания в цепь. \en Orientation of curves for enclosing into a chain. + SArray tolerances; ///< \ru Толерантности стыков кривых для замыкания в цепь. \en Tolerances of joints of curves for enclosing into a chain. + SArray surfInds; ///< \ru Номер поверхности кривой пересечения, отвечающей существующей грани. \en Number of surface of the intersection curve corresponding to the existent face. + +private : + MbPatchCreator( const MbPatchCreator &, MbRegDuplicate * ireg ); + +public : + MbPatchCreator( const RPArray & curves, + const PatchValues & params, + const MbSNameMaker & n, + const SArray * surfInds, + const SArray * orientations, + const SArray * tolerances ); + virtual ~MbPatchCreator(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; + virtual bool SetEqual ( const MbCreator & ); + + // \ru Построение оболочки по исходным данным \en Construction of a shell from the given data + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( PatchValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const PatchValues & params ) { parameters = params; } + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPatchCreator ) +OBVIOUS_PRIVATE_COPY( MbPatchCreator ) +}; + +IMPL_PERSISTENT_OPS( MbPatchCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку в форме заплатки. + \en Construct a patch-shaped shell. \~ + \details \ru Построить оболочку в форме заплатки на заданных кривых. + \en Construct a patch-shaped shell from the given curves. \~ + \param[in] initEdges - \ru Кривые, определяющие края заплатки. + \en Curves determining the bounds of the patch. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \result \ru Возвращает построенную оболочку. + \en Returns the constructed shell. \~ + \ingroup Model_Creators +*/ +// --- +MbFaceShell * CreatePatchShell( const RPArray & initCurves, + const PatchValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку в форме заплатки. + \en Construct a patch-shaped shell. \~ + \details \ru Построить оболочку в форме заплатки на заданных ребрах. + Одновременно с построением оболочки функция создает её строитель.\n + \en Construct a patch-shaped shell from the given edges. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initEdges - \ru Рёбра, определяющие края заплатки. + \en Edges determining the bounds of the patch. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreatePatchSet( const RPArray & initEdges, + const PatchValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку в форме заплатки. + \en Construct a patch-shaped shell. \~ + \details \ru Построить оболочку в форме заплатки на заданных кривых. + Одновременно с построением оболочки функция создает её строитель.\n + \en Construct a patch-shaped shell from the given curves. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initEdges - \ru Кривые, определяющие края заплатки. + \en Curves determining the bounds of the patch. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *)CreatePatchSet( const RPArray & initCurves, + const PatchValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_PATCH_CREATOR_H diff --git a/C3d/Include/cr_projection_curve.h b/C3d/Include/cr_projection_curve.h new file mode 100644 index 0000000..23ea950 --- /dev/null +++ b/C3d/Include/cr_projection_curve.h @@ -0,0 +1,86 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель проволочного каркаса из проекционных кривых. + \en Projection wireframe constructor. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_PROJECTION_CURVE_H +#define __CR_PROJECTION_CURVE_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель проволочного каркаса из проекционных кривых. + \en Projection wireframe constructor. \~ + \details \ru Строитель проволочного каркаса из проекционных кривых.\n + \en Projection wireframe constructor.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbProjCurveCreator : public MbCreator { +private: + MbWireFrame * wireFrame; // \ru Проецируемый проволочный каркас. \en Wireframe to project. + RPArray shellCreators; // \ru Протокол построения оболочки, на которую выполняется проецирование \en History tree of the shell the projection is performed onto + MbVector3D dir; // \ru Вектор направления (если нулевой, то проекция по нормали) \en Direction vector (if zero, the normal projection) + bool createExact; // \ru Создавать проекционную кривую при необходимости \en Create the projection curve if necessary + bool truncateByBounds; // \ru Усечь границами \en Truncate by bounds + +protected: + MbProjCurveCreator( const MbProjCurveCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbProjCurveCreator( const MbProjCurveCreator & ); // \ru Не реализовано \en Not implemented + MbProjCurveCreator(); // \ru Не реализовано \en Not implemented +public: + MbProjCurveCreator( const MbCurve3D & curve, + const RPArray & shellCreators, bool sameCreators, + const MbVector3D * dir, bool exact, bool truncate, + const MbSNameMaker & snMaker ); + + MbProjCurveCreator( const MbWireFrame &wf, const bool sameWire, + const RPArray & shellCreators, bool sameCreators, + const MbVector3D * dir, bool exact, bool truncate, + const MbSNameMaker & snMaker ); +public: + virtual ~MbProjCurveCreator(); + + // \ru Общие функции строителя. \en The common functions of the creator. + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateWireFrame( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbProjCurveCreator & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbProjCurveCreator ) +}; + +IMPL_PERSISTENT_OPS( MbProjCurveCreator ) + +#endif // __CR_PROJECTION_CURVE_H diff --git a/C3d/Include/cr_revolution_solid.h b/C3d/Include/cr_revolution_solid.h new file mode 100644 index 0000000..665e662 --- /dev/null +++ b/C3d/Include/cr_revolution_solid.h @@ -0,0 +1,161 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки тела вращения. + \en Constructor of a revolution shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_REVOLUTION_SOLID_H +#define __CR_REVOLUTION_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки тела вращения. + \en Constructor of a revolution shell. \~ + \details \ru Строитель оболочки тела путём вращения образующих кривых вокруг заданной оси на заданный угол. \n + \en Constructor of a solid's shell by revolution of generating curves around the given axis at the given angle. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCurveRevolutionSolid : public MbCurveSweptSolid { +protected : + MbSweptData sweptData; ///< \ru Данные об образующей. \en Generating curve data. + MbAxis3D axis; ///< \ru Ось вращения образующих кривых. \en Rotation axis of the generating curves. + RevolutionValues parameters; ///< \ru Параметры. \en Parameters. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. + \en Constructor. \~ + \param[in] sweptData_ - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] axis_ - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] parameters_ - \ru Параметры вращения. + \en The revolution parameters. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров для именования граней. + \en An object defining contours' names for faces naming. \~ + */ + MbCurveRevolutionSolid( const MbSweptData & sweptData_, + const MbAxis3D & axis_, + const RevolutionValues & parameters_, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames ); + +private : + MbCurveRevolutionSolid( const MbCurveRevolutionSolid & init, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbCurveRevolutionSolid( const MbCurveRevolutionSolid & init ); +public : + virtual ~MbCurveRevolutionSolid(); + + /** \ru \name Общие функции математического объекта. + \en \name Common functions of the mathematical object. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + /** \} */ + /** \ru \name Общие функции твердого тела (формообразующей операции). + \en \name Common functions of the rigid solid (forming operations). + \{ */ + virtual MbFaceShell * InitShell( bool in ); + virtual void InitBasis( RPArray & items ); + virtual bool GetPlacement( MbPlacement3D & p ) const; + /** \} */ + /** \ru \name Функции строителя оболочки тела вращения. + \en \name Functions of the revolution solid's shell creator. + \{ */ + const MbSurface * GetSurface() const { return sweptData.GetSurface(); } ///< \ru Поверхность двумерных контуров. \en Surface of two-dimensional contours. + const MbAxis3D & GetAxis() const { return axis; } ///< \ru Ось вращения. \en Rotation axis. + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( RevolutionValues & p ) const { p = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const RevolutionValues & p ) { parameters = p; } + /** \} */ + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCurveRevolutionSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveRevolutionSolid ) +}; + +IMPL_PERSISTENT_OPS( MbCurveRevolutionSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку тела вращения. + \en Create a shell of the revolution solid. \~ + \details \ru Построить оболочку тела путём вращения образующих кривых кривых вокруг заданной оси на заданный угол + и выполнить булуву операцию с оболочкой, если последняя задана. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell of a solid by rotating the generating curves around the given axis at the specified angle. + and perform the Boolean operation with the shell if it is specified. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Набор граней, к которым дополняется построение. + \en Face set the construction is complemented with respect to. \~ + \param[in] sameShell - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] sweptData - \ru Данные об образующей. + \en The generating curve data. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in, out] params - \ru Параметры выдавливания. + Возвращают информацию для построения элементов массива операция до поверхности. + \en The extrusion parameters. + Returns the information for construction of elements of operation-to-surface array. \~ + \param[in] oType - \ru Тип операции дополнения построения. + \en Type of operation of construction complement. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] contoursNames - \ru Именователь контуров. + \en An object defining the names of contours. \~ + \param[out] resType - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateCurveRevolution( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbSweptData & sweptData, + const MbAxis3D & axis, + const RevolutionValues & params, + OperationType oType, + const MbSNameMaker & operNames, + const RPArray & contoursNames, + MbResultType & resType, + MbFaceShell *& shell ); + + +#endif // __CR_REVOLUTION_SOLID_H diff --git a/C3d/Include/cr_rib_solid.h b/C3d/Include/cr_rib_solid.h new file mode 100644 index 0000000..3744a18 --- /dev/null +++ b/C3d/Include/cr_rib_solid.h @@ -0,0 +1,157 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель тела с ребром жёсткости. + \en Constructor of a solid with a rib. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_RIB_SOLID_H +#define __CR_RIB_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель тела с ребром жёсткости. + \en Constructor of a solid with a rib. \~ + \details \ru Строитель тела с ребром жёсткости, форма которого задана плоским контуром. + \en Constructor of a solid with a rib whose shape is specified by a planar contour. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbRibSolid : public MbCreator { +protected : + MbPlacement3D place; ///< \ru Подложка для формообразующей кривой, точки и вектора уклона. \en Placement of the forming curve, point and inclination vector. + MbContour * spine; ///< \ru Формообразующая кривая (хребет ребра жёсткости). \en Forming curve (rib's spine). + size_t index; ///< \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. \en The segment index in the contour from which the inclination direction will be set. + RibValues parameters; ///< \ru Параметры формообразования ребра жёсткости. \en Forming parameters of the rib. + +public : + MbRibSolid( const MbPlacement3D & place, const MbContour & contour, + size_t index, const RibValues & param, const MbSNameMaker & n ); +private : + MbRibSolid( const MbRibSolid & bres, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbRibSolid( const MbRibSolid & bres ); +public : + virtual ~MbRibSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual void Transform ( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray *items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( RibValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const RibValues & params ) { parameters = params; } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbRibSolid & ); // \ru НЕЛЬЗЯ!!! \en NOT ALLOWED!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRibSolid ) +}; // MbRibSolid + +IMPL_PERSISTENT_OPS( MbRibSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку с ребром жёсткости. + \en Create a shell with a rib. \~ + \details \ru Для указанной оболочки построить оболочку с ребром жёсткости, форма которого задана плоским контуром.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a specified shell create a shell with a rib which shape is given by the planar contour.\n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которай расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур ребра жесткости расположен в плоскости XY локальной системы координат. + \en Two-dimensional contour of a rib located in XY plane of the local coordinate system. \~ + \param[in] index - \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. + \en Index of a segment in the contour at which the inclination direction will be set. \~ + \param[in] parameters - \ru Правметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateRib( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + RibValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать отдельное ребро жёсткости. + \en Create a separate rib. \~ + \details \ru Для указанной оболочки построить оболочку в виде отдельного ребра жёсткости. + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For the specified shell create a shell as a separate rib. + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которай расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур ребра жесткости расположен в плоскости XY локальной системы координат. + \en Two-dimensional contour of a rib located in XY plane of the local coordinate system. \~ + \param[in] index - \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. + \en Index of a segment in the contour at which the inclination direction will be set. \~ + \param[in] parameters - \ru Правметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateRibElement( MbFaceShell * solid, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + RibValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_RIB_SOLID_H diff --git a/C3d/Include/cr_ruled_shell.h b/C3d/Include/cr_ruled_shell.h new file mode 100644 index 0000000..d170850 --- /dev/null +++ b/C3d/Include/cr_ruled_shell.h @@ -0,0 +1,109 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построить линейчатую оболочку. + \en Construct a ruled shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_RULED_SHELL_H +#define __CR_RULED_SHELL_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbOrientedEdge; +class MATH_CLASS MbLoop; +struct MATH_CLASS RuledSurfaceValues; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель линейчатой оболочки. + \en Constructor of a ruled shell. \~ + \details \ru Строитель линейчатой оболочки по двум кривым. \n + \en Constructor of a ruled shell from two curves. \n \~ + \ingroup Model_Creators +*/ +//--- +class MATH_CLASS MbRuledShell : public MbCreator { + +private : + RuledSurfaceValues parameters; ///< \ru Параметры построения. \en Construction parameters. +private: + MbRuledShell( const MbRuledShell & obj, MbRegDuplicate * ireg ); +public: + /// \ru Конструктор по параметрам операции и именователю. \en Constructor by operation parameters and name-maker. + MbRuledShell( const RuledSurfaceValues & pars, const MbSNameMaker & n ); + virtual ~MbRuledShell(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; ///< \ru Тип элемента \en Element type + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; ///< \ru Сделать копию \en Make a copy + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); ///< \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); ///< \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); ///< \ru Сдвиг по вектору \en Translation by the vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); ///< \ru Поворот вокруг оси \en Rotation about an axis + + virtual void GetProperties( MbProperties & properties ); ///< \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); ///< \ru Записать свойства объекта \en Write properties of the object + virtual MbePrompt GetPropertyName(); ///< \ru Выдать заголовок свойства объекта \en Get name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + +public: + /// \ru Построение оболочки \en Creation of a shell + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + // \ru Дать параметры. \en Get the parameters. + void GetParameters( RuledSurfaceValues & params ) const; + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const RuledSurfaceValues & params ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRuledShell ) +OBVIOUS_PRIVATE_COPY( MbRuledShell ) +}; // MbRuledShell + +IMPL_PERSISTENT_OPS( MbRuledShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить линейчатую оболочку. + \en Construct a ruled shell. \~ + \details \ru Построить линейчатую оболочку по двум кривым. + Кривые могут быть составными. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a ruled shell from two curves + Curves can be composite. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] isPhantom - \ru Режим создания фантома. + \en Create in the phantom mode. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateRuledShell( RuledSurfaceValues & parameters, + const MbSNameMaker & operNames, + bool isPhantom, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_RULED_SHELL_H \ No newline at end of file diff --git a/C3d/Include/cr_sheet_bend_any_solid.h b/C3d/Include/cr_sheet_bend_any_solid.h new file mode 100644 index 0000000..799360a --- /dev/null +++ b/C3d/Include/cr_sheet_bend_any_solid.h @@ -0,0 +1,122 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки тела с выполнеными сгибами. + \en Construction of a shell from any solid with bends. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_BEND_ANY_SOLID_H +#define __CR_SHEET_BEND_ANY_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с выполненым сгибом/разгибом. + \en Constructor of a shell from sheet material with bend/unbend. \~ + \details \ru Строитель оболочки из листового материала с выполненым сгибом/разгибом. + Построение сгиба/разгиба на касательную плоскость к указанной грани в указанной + точке с индивидуальными для каждого сгиба параметрами. \n + \en Constructor of a shell from sheet material with bend/unbend. + Construction of a bend/unbend to the tangent plane to the specified face at + the given point with parameters individual for each bend. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBendAnySolid : public MbCreator { + MbPlane cutPlane; + SArray bends; + +public : + MbBendAnySolid( const MbPlane & cutPlane, + const SArray & bends, + const MbSNameMaker & names ); +private: + MbBendAnySolid( const MbBendAnySolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBendAnySolid( const MbBendAnySolid & ); + +public: + virtual ~MbBendAnySolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbBendAnySolid & operator = ( const MbBendAnySolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBendAnySolid ) +}; + +IMPL_PERSISTENT_OPS( MbBendAnySolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку с выполнеными сгибами. + \en Construct a shell with bends. \~ + \details \ru Построить оболочку любого тела с выполнеными сгибами. + Построение сгиба/разгиба на касательную плоскость к указанной грани в указанной + точке с индивидуальными для каждого сгиба параметрами. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from sheet material with bend/unbend. + Construction of a bend/unbend to the tangent plane to the specified face at + the given point with parameters individual for each bend. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] bends - \ru Сгибы оболочки. + \en Bends of a shell. \~ + \param[in] fixedFace - \ru Неподвижная грань. + \en Fixed face. \~ + \param[in] fixedPoint - \ru Неподвижная точка. + \en Fixed point. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateAnyBend( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const MbPlane & cutPlane, + const SArray & bends, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + + +#endif // __CR_SHEET_BEND_ANY_SOLID_H + diff --git a/C3d/Include/cr_sheet_bend_by_edge_solid.h b/C3d/Include/cr_sheet_bend_by_edge_solid.h new file mode 100644 index 0000000..8d4972b --- /dev/null +++ b/C3d/Include/cr_sheet_bend_by_edge_solid.h @@ -0,0 +1,146 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение сгибов по рёбрам оболочки тела из листового материала. + \en Construction of bends by edges of a shell of a solid from sheet material. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_BEND_BY_EDGE_SOLID_H +#define __CR_SHEET_BEND_BY_EDGE_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель сгибов по рёбрам оболочки тела из листового материала. + \en Constructor of bends by edges of a shell of a solid from sheet material. \~ + \details \ru Строитель сгибов по рёбрам оболочки тела из листового материала. \n + От заданных рёбер строятся сгибы с продолжением. + В зависимости от параметров операции они могут быть смещены от рёбер внутрь или наружу тела, + строиться от всей длины ребра или от его части, иметь уклон на сгибе и/или его продолжении, + расширение продолжения с каждой стороны. + Сгиб может быть построен с освобождением, а также с подрезкой сгибов, + с которыми он стыкуется своими боковыми сторонами. + \en Constructor of bends by edges of a shell of a solid from sheet material. \n + Bends with extensions are built from the given edges. + Depending on parameters of the operation they can be shifted from the edges inside or outside the solid, + they can be built from the whole length of the edge or from its part, they can have a slope at the bend and/or its extension, + an expansion of the extension from each side. + A bend can be constructed with release and also with trimming of the bends + it meets with by its side boundaries. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBendsByEdgesSolid : public MbCreator { + SArray edgesIndices; ///< \ru Идентификаторы рёбер, по которым строятся сгибы. \en Identifiers of edges the bends are built by. + bool unbended; ///< \ru Флаг построения сгиба в разогнутом виде. \en Flag of construction of a bend in unbent form. + MbBendByEdgeValues parameters; ///< \ru Параметры построения. \en Construction parameters. + RPArray bendsParams; ///< \ru Множество параметров для каждого формируемого сгиба. \en Set of parameters for each bend. + +public : + MbBendsByEdgesSolid( const SArray & edgesIndices, + const bool unbended, + const MbBendByEdgeValues & params, + const RPArray & bendsParams, + const MbSNameMaker & nameMaker ); +private: + MbBendsByEdgesSolid( const MbBendsByEdgesSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBendsByEdgesSolid( const MbBendsByEdgesSolid & ); + +public: + virtual ~MbBendsByEdgesSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbBendByEdgeValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbBendByEdgeValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbBendsByEdgesSolid & operator = ( const MbBendsByEdgesSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBendsByEdgesSolid ) +}; + +IMPL_PERSISTENT_OPS( MbBendsByEdgesSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить сгибы вдоль рёбер оболочки. + \en Construct bends along edges of a shell. \~ + \details \ru Построить сгибы по рёбрам оболочки тела из листового материала. + От заданных рёбер строятся сгибы с продолжением. + В зависимости от параметров операции они могут быть смещены от рёбер внутрь или наружу тела, + строиться от всей длины ребра или от его части, иметь уклон на сгибе и/или его продолжении, + расширение продолжения с каждой стороны. + Сгиб может быть построен с освобождением, а также с подрезкой сгибов, + с которыми он стыкуется своими боковыми сторонами. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct bends by edges of a shell of a solid from sheet material. + Bends with extensions are built from the given edges. + Depending on parameters of the operation they can be shifted from the edges inside or outside the solid, + they can be built from the whole length of the edge or from its part, they can have a slope at the bend and/or its extension, + an expansion of the extension from each side. + A bend can be constructed with release and also with trimming of the bends + it meets with by its side boundaries. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] edges - \ru Рёбра, по которым строятся сгибы. + \en Edges the bends are built along. \~ + \param[in] unbended - \ru Флаг построения сгиба в разогнутом виде. + \en Flag of construction of a bend in unbent form. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateBendsByEdges( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const RPArray & edges, + const bool unbended, + const MbBendByEdgeValues & parameters, + MbSNameMaker & names, + RPArray & resultBends, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_BEND_BY_EDGE_SOLID_H diff --git a/C3d/Include/cr_sheet_bend_over_seg_solid.h b/C3d/Include/cr_sheet_bend_over_seg_solid.h new file mode 100644 index 0000000..2afdebd --- /dev/null +++ b/C3d/Include/cr_sheet_bend_over_seg_solid.h @@ -0,0 +1,131 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки из листового материала, согнутого вдоль отрезка. + \en Construction of a shell from sheet material bent along a segment. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_BEND_OVER_SEG_SOLID_H +#define __CR_SHEET_BEND_OVER_SEG_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала, согнутой вдоль отрезка. + \en Constructor of a shell from sheet material bent along a segment. \~ + \details \ru Строитель оболочки из листового материала, согнутой слева или справа от отрезка, + либо указанных граней, либо, в случае отсутствия таковых, всех подходящих для сгиба граней. \n + \en Constructor of a shell from sheet material bent to the left or to the right from a segment + or from the specified faces or, if they are absent, from all the faces appropriate for bending. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBendOverSegSolid : public MbCreator { + SArray bendingFacesIndices; ///< \ru Идентификаторы указанных для сгиба граней (сортированы и не повторяются). \en Identifiers of faces given for the bend (sorted and not duplicated). + MbCurve3D * curve; ///< \ru Линия по которой гнуть. \en Line along which to bend. + bool unbended; ///< \ru Флаг построения сгиба в разогнутом состоянии. \en Flag of construction of a bend in unbent form. + MbBendOverSegValues parameters; ///< \ru Параметры операции. \en The operation parameters. + +public : + MbBendOverSegSolid( const SArray & bendingFacesIndices, + MbCurve3D & curve, + const bool unbended, + const MbBendOverSegValues & pars, + const MbSNameMaker & names ); +private: + MbBendOverSegSolid( const MbBendOverSegSolid &, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBendOverSegSolid( const MbBendOverSegSolid & ); + +public: + virtual ~MbBendOverSegSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbBendOverSegValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbBendOverSegValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbBendOverSegSolid & operator = ( const MbBendOverSegSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBendOverSegSolid ) +}; + +IMPL_PERSISTENT_OPS( MbBendOverSegSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала, согнутую вдоль отрезка. + \en Create a shell from sheet material bent along a segment. \~ + \details \ru Построить оболочку из листового материала, согнутую слева или справа от отрезка, + либо указанных граней, либо, в случае отсутствия таковых, всех подходящих для сгиба граней. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from sheet material bent to the left and to the right from a segment + or from the specified faces or, if they are absent, from all the faces appropriate for bending. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] bendingFaces - \ru Грани, которые гнуть. + \en Faces to bend. \~ + \param[in] curve - \ru Кривая, по которой сгибать. + \en A curve along which to bend. \~ + \param[in] unbended - \ru Флаг построения сгиба в разогнутом виде. + \en Flag of construction of a bend in unbent form. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateBendOverSegment( MbFaceShell & initialShell, + MbeCopyMode sameShell, + const RPArray & bendingFaces, + MbCurve3D & curve, + const bool unbended, + const MbBendOverSegValues & parameters, + MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_BEND_OVER_SEG_SOLID_H diff --git a/C3d/Include/cr_sheet_bend_unbend_solid.h b/C3d/Include/cr_sheet_bend_unbend_solid.h new file mode 100644 index 0000000..d5f6164 --- /dev/null +++ b/C3d/Include/cr_sheet_bend_unbend_solid.h @@ -0,0 +1,129 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки из листового материала с выполненым сгибом/разгибом. + \en Construction of a shell from sheet material with bend/unbend. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_BEND_UNBEND_SOLID_H +#define __CR_SHEET_BEND_UNBEND_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с выполненым сгибом/разгибом. + \en Constructor of a shell from sheet material with bend/unbend. \~ + \details \ru Строитель оболочки из листового материала с выполненым сгибом/разгибом. + Построение сгиба/разгиба на касательную плоскость к указанной грани в указанной + точке с индивидуальными для каждого сгиба параметрами. \n + \en Constructor of a shell from sheet material with bend/unbend. + Construction of a bend/unbend to the tangent plane to the specified face at + the given point with parameters individual for each bend. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBendUnbendSolid : public MbCreator { + PArray bendIndices; ///< \ru Идентификаторы сгибаемых/разгибаемых граней и параметры сгибов. \en Identifiers of faces to bend/unbend and parameters of bends. + MbItemIndex fixedFaceIndex; ///< \ru Идентификатор грани, на касательную к которой разгибаем. \en Identifier of the face on a tangent to which to unbend. + MbCartPoint fixedPoint; ///< \ru Точка в параметрической области фиксированной грани, определяющая касательную плоскость, на которую будет выполняться разгиб. \en A point in parametric domain of a fixed face determining the tangent plane on which to perform the bend. + bool bend; ///< \ru Флаг, определяющий тип операции: сгиб или разгиб. \en Flag determining the operation type: bend or unbend + +public : + MbBendUnbendSolid( const RPArray & bendInd, + const MbItemIndex fixedFaceIndex, + const MbCartPoint & fixedPoint, + const bool bend, + const MbSNameMaker & names ); +private: + MbBendUnbendSolid( const MbBendUnbendSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBendUnbendSolid( const MbBendUnbendSolid & ); + +public: + virtual ~MbBendUnbendSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbBendUnbendSolid & operator = ( const MbBendUnbendSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBendUnbendSolid ) +}; + +IMPL_PERSISTENT_OPS( MbBendUnbendSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку с выполненым сгибом/разгибом. + \en Construct a shell with bend/unbend. \~ + \details \ru Построить оболочку из листового материала с выполненым сгибом/разгибом. + Построение сгиба/разгиба на касательную плоскость к указанной грани в указанной + точке с индивидуальными для каждого сгиба параметрами. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from sheet material with bend/unbend. + Construction of a bend/unbend to the tangent plane to the specified face at + the given point with parameters individual for each bend. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] bends - \ru Сгибы оболочки. + \en Bends of a shell. \~ + \param[in] fixedFace - \ru Неподвихная грань. + \en Fixed face. \~ + \param[in] fixedPoint - \ru Неподвихная точка. + \en Fixed point. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \param[out] ribContours - \ru Набор контуров содержащих кривые границ ребер жесткости(при их наличии) в разогнутом виде. + \en The set of contours, which are containing edges of stamp rib in unfolded state. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateBendUnbend( MbFaceShell & initialShell, + MbeCopyMode sameShell, + const RPArray & bends, + const MbFace & fixedFace, + const MbCartPoint & fixedPoint, + bool bend, + MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell, + RPArray * ribContours = NULL ); + + + +#endif // __CR_SHEET_BEND_UNBEND_SOLID_H diff --git a/C3d/Include/cr_sheet_closed_corner_solid.h b/C3d/Include/cr_sheet_closed_corner_solid.h new file mode 100644 index 0000000..f5f60cd --- /dev/null +++ b/C3d/Include/cr_sheet_closed_corner_solid.h @@ -0,0 +1,131 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки из листового материала с замыканием угла. + \en Construction of a shell from sheet material with corner enclosure. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_CLOSED_CORNER_SOLID_H +#define __CR_SHEET_CLOSED_CORNER_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с замыканием угла. + \en Constructor of a shell from sheet material with corner enclosure. \~ + \details \ru Строитель оболочки из листового материала с замыканием угла. + В зависимости от параметров замыкание продолжений сгибов может быть с перекрытием, встык и плотное, + а сами сгибы могут остаться без замыкания или замкнуться по хорде или по кромке. + Возможно также построение замыкания с зазором. \n + \en Constructor of a shell from sheet material with corner enclosure. + Subject to the parameters closure of bends extensions can be overlapping, butted or tight, + the bends themselves can remain unclosed or can be closed by a chord or a boundary. + Construction of corner closure with a gap is also possible. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbClosedCornerSolid : public MbCreator { + MbEdgeFacesIndexes edgeIndexPlus; ///< \ru Идентификатор ребра сгиба, условно принятого за положительное. \en Identifier of an edge of the bend considered to be positive. + MbEdgeFacesIndexes edgeIndexMinus; ///< \ru Идентификатор ребра сгиба, условно принятого за отрицательное. \en Identifier of an edge of the bend considered to be negative. + MbClosedCornerValues parameters; ///< \ru Параметры замыкания угла. \en Parameters of a corner closure. + +public : + MbClosedCornerSolid( const MbEdgeFacesIndexes edgeIndexPlus, + const MbEdgeFacesIndexes edgeIndexMinus, + const MbClosedCornerValues & params, + const MbSNameMaker & nameMaker ); +private: + MbClosedCornerSolid( const MbClosedCornerSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbClosedCornerSolid( const MbClosedCornerSolid & ); + +public: + virtual ~MbClosedCornerSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbClosedCornerValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbClosedCornerValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbClosedCornerSolid & operator = ( const MbClosedCornerSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbClosedCornerSolid ) +}; + +IMPL_PERSISTENT_OPS( MbClosedCornerSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала с замыканием угла. + \en Construct a shell form sheet material with corner closure. \~ + \details \ru Построить оболочку из листового материала с замыканием угла. + В зависимости от параметров замыкание продолжений сгибов может быть с перекрытием, встык и плотное, + а сами сгибы могут остаться без замыкания или замкнуться по хорде или по кромке. + Возможно также построение замыкания с зазором. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell form sheet material with corner closure. + Subject to the parameters closure of bends extensions can be overlapping, butted or tight, + the bends themselves can remain unclosed or can be closed by a chord or a boundary. + Construction of corner closure with a gap is also possible. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] curveEdgePlus - \ru Ребро сгиба, условно принятого за положительное. + \en Edge of the bend considered as positive. \~ + \param[in] curveEdgeMinus - \ru Ребро сгиба, условно принятого за отрицательное. + \en Edge of the bend considered as negative. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateClosedCorner( MbFaceShell & initialShell, + MbeCopyMode sameShell, + MbCurveEdge * curveEdgePlus, + MbCurveEdge * curveEdgeMinus, + const MbClosedCornerValues & parameters, + MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_CLOSED_CORNER_SOLID_H diff --git a/C3d/Include/cr_sheet_joint_bend_solid.h b/C3d/Include/cr_sheet_joint_bend_solid.h new file mode 100644 index 0000000..82ac1ce --- /dev/null +++ b/C3d/Include/cr_sheet_joint_bend_solid.h @@ -0,0 +1,146 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение комбинированного сгиба. + \en A composite bend construction. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_JOINT_BEND_SOLID_H +#define __CR_SHEET_JOINT_BEND_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель комбинированного сгиба. + \en Construction of a composite bend. \~ + \details \ru Строитель сгибов, заданных эскизом, по рёбрам оболочки тела из листового материала. \n + По заданному контуру, состоящему из отрезков и дуг, строит листовое тело, формируя сгибы на месте + дуг и между отрезками по параметрам, заданным в bendsParams, и присоединяет его к каждому ребру, + указанному в edgesIndices. + \en Construction of bends specified by a sketch, along edges of solid's shell from sheet material. \n + From the given contour consisting of segments and arcs it constructs a sheet solid with forming bends at + the arcs and between segments using parameters specified in bendsParams, and attaches it to each edge + specified in edgesIndices. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbJointBendSolid : public MbCreator { + MbPlacement3D placement; ///< \ru Локальная система координат образующего контура. \en The local coordinate system of the generating contour. + MbContour contour; ///< \ru Образующий контур. \en Generating contour. + SArray edgesIndices; ///< \ru Идентификаторы направляющих рёбер. \en Identifiers of guide edges. + bool unbended; ///< \ru Флаг построения сгибов в разогнутом состоянии. \en Flag of construction of bends in unbent form. + MbJointBendValues parameters; ///< \ru Параметры операции. \en The operation parameters. + RPArray< RPArray > bendsParams; ///< \ru Множество параметров для каждого формируемого сгиба. \en Set of parameters for each bend. + +public : + MbJointBendSolid( const MbPlacement3D & placement, + const MbContour & contour, + const SArray & edgesIndices, + const bool unbended, + const MbJointBendValues & parameters, + const RPArray< RPArray > & bendsParams, + const MbSNameMaker & nameMaker ); + +private: + MbJointBendSolid( const MbJointBendSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbJointBendSolid( const MbJointBendSolid & ); + +public: + virtual ~MbJointBendSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbJointBendValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbJointBendValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbJointBendSolid & operator = ( const MbJointBendSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbJointBendSolid ) +}; + +IMPL_PERSISTENT_OPS( MbJointBendSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить комбинированные сгибы. + \en Construct composite bends. \~ + \details \ru Построить сгибы, заданные эскизом, по рёбрам оболочки тела из листового материала. + По заданному контуру, состоящему из отрезков и дуг, строит листовое тело, формируя сгибы на месте + дуг и между отрезками по параметрам, заданным в bendsParams, и присоединяет его к каждому ребру, + указанному в edgesIndices. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct bends specified by a sketch, along edges of solid's shell from sheet material. + From the given contour consisting of segments and arcs it constructs a sheet solid with forming bends at + the arcs and between segments using parameters specified in bendsParams, and attaches it to each edge + specified in edgesIndices. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположен контур сгиба. + \en A local coordinate system the bend contour is located in XY plane of. \~ + \param[in] contours - \ru Контур сгиба. + \en The bend contour. \~ + \param[in] edges - \ru Рёбра, по которым строятся сгибы. + \en Edges the bends are built along. \~ + \param[in] unbended - \ru Флаг построения сгиба в разогнутом виде. + \en Flag of construction of a bend in unbent form. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] nameMaker - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] resultBends - \ru Имена построенных сгибов. + \en Constructed bends names. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateJointBend( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const MbPlacement3D & placement, + const MbContour & contour, + const RPArray & edges, + const bool unbended, + const MbJointBendValues & parameters, + MbSNameMaker & nameMaker, + RPArray< RPArray > & resultBends, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_JOINT_BEND_SOLID_H diff --git a/C3d/Include/cr_sheet_metal_solid.h b/C3d/Include/cr_sheet_metal_solid.h new file mode 100644 index 0000000..369958d --- /dev/null +++ b/C3d/Include/cr_sheet_metal_solid.h @@ -0,0 +1,184 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки из листового материала. + \en Construction of a shell from sheet material. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_METAL_SOLID_H +#define __CR_SHEET_METAL_SOLID_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала. + \en Constructor of a shell from sheet material. \~ + \details \ru Строитель оболочки из листового материала операциями "Листовое тело", "Пластина", "Отверстие", "Вырез". \n + Листовое тело строится по замкнутому или разомкнутому контурам. + В случае замкнутых контуров строится листовое тело, ограниченное этими контурами. + Если контуров несколько, то один из них должен содержать внутри себя остальные, + в этом случае он формирует внешнее очертание листа, а остальные контуры формируют + очертания вырезов в создаваемом листовом теле. + Разомкнутый контур может быть только один и состоять из дуг и отрезков, причём дуги + должны обязательно гладко стыковаться с соседними элементами контура. В процессе построения + листового тела негладкие стыковки отрезков скругляются радиусом, + заданным в параметрах операции (для построения фантома) или параметрах сгибов (в остальных случаях). + В случае незамкнутого контура отрезки формируют плоские участки + листового тела определённой в параметрах операции ширины, а дуги и скругления формируют сгибы. + Операция "Пластина" расширяет плоский участок листового тела на заданные контуры. + Операции "Отверстие" и "Вырез" с опцией "по толщине" строятся, как если бы вырезы выполнялись + в полностью разогнутом теле с последующим выполнением необходимых сгибов. + \en Constructor of a shell from sheet material using operations "Sheet solid", "Plate", "Hole", "Cutout \n + Sheet solid is built from a closed or open contour. + In case of closed contours a sheet solid bounded by these contours are built. + If there are several contours, then one of them should contain others inside itself, + in this case it forms an external profile of a sheet, the other contours form + profiles of cutouts in the sheet solid being created. + An open contour can be only one and it should consist of arcs and segments, besides arcs + should be smoothly connected with the neighboring elements of the contour. During the construction + of a sheet solid unsmooth joints of segments are filleted with radius + specified in the operation parameters (for phantom construction) or in the bends parameters (in other cases). + In case of open contour the segments form flat regions + of a sheet solid which are specified in parameters of width operation, and arcs and fillets form bends. + "Plate" operation extends flat part of a sheet solid to the given contours. + Operations "Hole" and "Cutout" with option "By width" are constructed as if cutouts were performed + in completely unbent solid with further performing the necessary bends. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSheetMetalSolid : public MbCreator { +protected: + MbPlacement3D placement; ///< \ru Локальная система координат образующих контуров. \en The local coordinate system of the generating contours. + std::vector > curves; ///< \ru Образующие контуры. \en Generating contours. + bool unbended; ///< \ru Флаг построения листового тела в разогнутом виде. \en Flag of construction of a sheet solid in unbent state. + MbSheetMetalValues parameters; ///< \ru Параметры построения. \en Construction parameters. + RPArray bendParams; ///< \ru Параметры формируемых сгибов. \en Parameters of bends being formed. + OperationType operation; ///< \ru Тип булевой операции. \en Boolean operation type. + double buildSag; ///< \ru Максимальное отклонение нормали между соседними расчитанными точками линии пересечения. \en Maximal deviation of normal between the neighboring calculated points of the intersection line. + +public : + MbSheetMetalSolid( const MbPlacement3D & pl, + std::vector > & c, + bool unbended, + const MbSheetMetalValues & p, + const RPArray & bendNames, + OperationType op, + double sag, + const MbSNameMaker & n ); +private : + MbSheetMetalSolid( const MbSheetMetalSolid & init ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSheetMetalSolid( const MbSheetMetalSolid & init, MbRegDuplicate * ireg ); +public : + virtual ~MbSheetMetalSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual MbFaceShell * InitShell( bool in ); + + const MbPlacement3D & GetPlacement() const; + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbSheetMetalValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbSheetMetalValues & params ) { parameters = params; } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbSheetMetalSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSheetMetalSolid ) +}; + +IMPL_PERSISTENT_OPS( MbSheetMetalSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала. + \en Construct a shell from sheet material. \~ + \details \ru Построить оболочку из листового материала операциями "Листовое тело", "Пластина", "Отверстие", "Вырез". \n + Листовое тело строится по замкнутому или разомкнутому контурам. + В случае замкнутых контуров строится листовое тело, ограниченное этими контурами. + Если контуров несколько, то один из них должен содержать внутри себя остальные, + в этом случае он формирует внешнее очертание листа, а остальные контуры формируют + очертания вырезов в создаваемом листовом теле. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from sheet material using operations "Sheet solid", "Plate", "Hole", "Cutout". \n + Sheet solid is built from a closed or open contour. + In case of closed contours a sheet solid bounded by these contours are built. + It there are several contours, then one of them should contain others inside itself, + in this case it forms an external profile of a sheet, the other contours form + profiles of cutouts in the sheet solid being created. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположены контуры построния. + \en Local coordinate system the construction contours is located in XY plane of. \~ + \param[in] contours - \ru Контуры построния. + \en Construction contours. \~ + \param[in] unbended - \ru Флаг построения сгиба в разогнутом виде. + \en Flag of construction of a bend in unbent form. \~ + \param[in] parameters - \ru Параметры построения. + \en Parameters of shell creation. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] sag - \ru Угловой шаг для булевой операции. + \en Sag for a Boolean operation. \~ + \param[in] nameMaker - \ru Именователи граней. + \en An object for naming faces. \~ + \param[in] resultBends - \ru Имена построенных сгибов. + \en Constructed bends names. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSheetMetal( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & placement, + RPArray & contours, + bool unbended, + const MbSheetMetalValues & parameters, + OperationType oType, + double sag, + RPArray * nameMaker, + RPArray & resultBends, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_METAL_SOLID_H diff --git a/C3d/Include/cr_sheet_restored_edges_solid.h b/C3d/Include/cr_sheet_restored_edges_solid.h new file mode 100644 index 0000000..8066fc3 --- /dev/null +++ b/C3d/Include/cr_sheet_restored_edges_solid.h @@ -0,0 +1,115 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение боковых рёбер сгибов. + \en Construction of side edges of bends. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_RESTORED_EDGES_SOLID_H +#define __CR_SHEET_RESTORED_EDGES_SOLID_H + + +#include +#include + + +struct MATH_CLASS MbSheetMetalBend; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель боковых рёбер сгибов. + \en Constructor of side edges of bends. \~ + \details \ru Строитель оболочки c восстановлением боковых рёбер сгибов. \n + \en Constructor of a shell with restored side edges of bends. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbRestoredEdgesSolid : public MbCreator { + SArray outerFacesIndices; ///< \ru Идентификаторы внешних граней сгибов. \en Identifiers of external faces of bends. + bool strict; ///< \ru При false - восстанавить рёбра, где это возможно. \en If it equals false then restore edges where it is possible. + +public : + MbRestoredEdgesSolid( const SArray & outerFacesIndices, + const bool strict, + const MbSNameMaker & nameMaker ); +private: + MbRestoredEdgesSolid( const MbRestoredEdgesSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbRestoredEdgesSolid( const MbRestoredEdgesSolid & ); + +public: + virtual ~MbRestoredEdgesSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbRestoredEdgesSolid & operator = ( const MbRestoredEdgesSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRestoredEdgesSolid ) +}; + +IMPL_PERSISTENT_OPS( MbRestoredEdgesSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить боковых рёбер сгибов. + \en Construct side edges of bends. \~ + \details \ru Построить оболочку c восстановлением боковых рёбер сгибов. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell with restored side edges of bends. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] outerFaces - \ru Грани сгибов. + \en Faces of bends. \~ + \param[in] strict - \ru Восстановить все рёбра. + \en Restore all edges. \~ + \param[in] resultBends - \ru Имена построенных сгибов. + \en Constructed bends names. \~ + \param[in] nameMaker - \ru Именователи граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) RestoreSideEdges( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const RPArray & outerFaces, + const bool strict, + RPArray & resultBends, + const MbSNameMaker & nameMaker, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_RESTORED_EDGES_SOLID_H diff --git a/C3d/Include/cr_sheet_simplified_flat_solid.h b/C3d/Include/cr_sheet_simplified_flat_solid.h new file mode 100644 index 0000000..4e4b5b6 --- /dev/null +++ b/C3d/Include/cr_sheet_simplified_flat_solid.h @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение упрощённой развёртки листового тела. + \en Construction of the simplified flat pattern. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_SIMPLIFIED_FLAT_SOLID_H +#define __CR_SHEET_SIMPLIFIED_FLAT_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель упрощения развёртки тела из листового материала. + \en Constructor of the simplified flat pattern. \~ + \details \ru Строитель упрощения развёртки тела из листового материала. + Возможно два вида упрощения: обработка углов и слияние подобных граней. \n + \en Constructor of the simplified flat pattern. + There are two types of simplification. The first one is the corners treatment. The second one is the similar faces unification. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSimplifyFlatSolid : public MbCreator { + MbSimplifyFlatPatternValues parameters; + +public : + MbSimplifyFlatSolid( const MbSimplifyFlatPatternValues & params, + const MbSNameMaker & names ); +private: + MbSimplifyFlatSolid( const MbSimplifyFlatSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSimplifyFlatSolid( const MbSimplifyFlatSolid & ); + +public: + virtual ~MbSimplifyFlatSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbSimplifyFlatSolid & operator = ( const MbSimplifyFlatSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSimplifyFlatSolid ) +}; + +IMPL_PERSISTENT_OPS( MbSimplifyFlatSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Упростить развёртку листового тела. + \en Simplify flattened sheet solid. \~ + \details \ru Упростить развёртку листового тела. \n + \en Simplify flattened sheet solid. \n \~ + \param[in] solid - \ru Исходное тело. + \en The source solid. \~ + \param[in] sameShell - \ru Флаг удаления оболочки исходного тела. + \en Whether to delete the shell of the source solid. \~ + \param[in] params - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru - Код результата операции. + \en - The operation result code. \~ + \ingroup Sheet_Metal_Modeling +*/ +// --- +MATH_FUNC (MbCreator *) CreateSimplifiedFlatPattern( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const MbSimplifyFlatPatternValues & params, + const MbSNameMaker & nameMaker, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_SIMPLIFIED_FLAT_SOLID_H + diff --git a/C3d/Include/cr_sheet_union_solid.h b/C3d/Include/cr_sheet_union_solid.h new file mode 100644 index 0000000..5029aaf --- /dev/null +++ b/C3d/Include/cr_sheet_union_solid.h @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель операции объединения листовых тел по торцу. + \en Constructor of operation of union of sheet solids by butt. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SHEET_UNION_SOLID_H +#define __CR_SHEET_UNION_SOLID_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель операции объединения листовых тел по торцу. + \en Constructor of operation of union of sheet solids by butt. \~ + \details \ru Строитель операции объединения листовых тел по торцу объединяет тела + только по указанному с помощью ориентированных рёбер торцу, + независимо от возможных пересечений тел в других местах.\n. + \en Constructor of operation of union of sheet solids by butt unites solids + only by the bound specified using oriented edges + independently of possible intersections of solids in other places.\n. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSheetUnionSolid : public MbCreator { +protected : + RPArray creators; ///< \ru Журнал построения: 0<=i & solid2, const bool same2, const MbSNameMaker & n ); +private : + MbSheetUnionSolid( const MbSheetUnionSolid & init, MbRegDuplicate *ireg ); + +public : + virtual ~MbSheetUnionSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * ireg = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual void SetYourVersion( VERSION version, bool forAll ); + + /// \ru Количество строителей первого тела. \en Count of creators of the first solid. + size_t GetCountOne() const { return countOne; } + /// \ru Общее количество строителей. \en Total count of creators. + size_t GetCreatorsCount() const { return creators.Count(); } + /// \ru Добавить в журнал. \en Add to the history tree. + void AddCreator ( MbCreator & creator ); + /// \ru Дать строитель. \en Get the constructor. + MbCreator * GetCreator ( const size_t ind ) const; + void DeleteCreator( const size_t ind ); + +private : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSheetUnionSolid( const MbSheetUnionSolid & init ); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbSheetUnionSolid & operator = ( const MbSheetUnionSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSheetUnionSolid ) +}; + +IMPL_PERSISTENT_OPS( MbSheetUnionSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку объединённых по торцу листовых тел. + \en Create a shell of sheet solids united by a butt. \~ + \details \ru Для указанных оболочек построить оболочку как результат операции объединения над множествами граней двух тел. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en For the specified shells create a shell using operation of union of face sets of two solids. + The function simultaneously creates the shell and its constructor.\n \~ + \result \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSheetUnion( MbFaceShell & faceShell1, + const MbeCopyMode sameShell1, + const RPArray & creators2, + MbFaceShell & faceShell2, + const MbeCopyMode sameShell2, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SHEET_UNION_SOLID_H diff --git a/C3d/Include/cr_simple_creator.h b/C3d/Include/cr_simple_creator.h new file mode 100644 index 0000000..79d29d2 --- /dev/null +++ b/C3d/Include/cr_simple_creator.h @@ -0,0 +1,279 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки тела без истории. + \en Constructor of solid shell without history. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SIMPLE_CREATOR_H +#define __CR_SIMPLE_CREATOR_H + + +#include + + +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbSolid; + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки тела без истории. + \en Constructor of a solid shell without history. \~ + \details \ru Строитель оболочки тела без истории построения. \n + \en Constructor of a solid shell without history tree. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSimpleCreator : public MbCreator { +public : + MbFaceShell * outer; ///< \ru Набор граней без истории. \en Face set without history. + OperationType operation; ///< \ru Тип булевой операции. \en Boolean operation type. + double buildSag; ///< \ru Шаг построения булевой операции. \en Sag of Boolean operation construction. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по оболочке с возможностью использования ее оригинала или копии. + \en Constructor by a shell with possibility of using the original or a copy. \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] n - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] same - \ru Признак использования оригинала оболочки. + \en Flag of using the original shell. \~ + */ + MbSimpleCreator( const MbFaceShell & shell, const MbSNameMaker & n, bool same ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по оболочке и типу операции. + \en Constructor by a shell and a type of operation. \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] n - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] op - \ru Тип булевой операции. + \en A Boolean operation type. \~ + */ + MbSimpleCreator( const MbFaceShell & shell, const MbSNameMaker & n, OperationType op ); + +private : + MbSimpleCreator( const MbSimpleCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования с регистратором \en Copy-constructor with the registrator +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbSimpleCreator(); + + /** \ru \name Общие функции строителя оболочки. + \en \name Common functions of the shell creator. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + /** \} */ + + const MbFaceShell * GetShell() const { return outer; } /// \ru Дать оболочку. \en Get a shell. + void SetShell( const MbFaceShell & ); /// \ru Заменить оболочку. \en Replace a shell. + OperationType GetOperationType() { return operation; } /// \ru Дать оболочку. \en Get a shell. + void SetOperationType( OperationType t ) { operation = t; } /// \ru Заменить оболочку. \en Replace a shell. + + /// \ru Удалить копии оболочек в простых построителях (MbSimpleCreator). \en Delete shell copies in simple creators (MbSimpleCreator). + template + static bool DeleteShellCopies( const CreatorsVector & ); + /// \ru Есть ли в каком-то простом построителе (MbSimpleCreator) заданная оболочка. \en Is there a simple builder (MbSimpleCreator) that contains a given shell?. + template + static bool IsThisShell( const MbFaceShell &, const CreatorsVector & ); + /// \ru Есть ли в каком-то простом построителе (MbSimpleCreator) заданная оболочка. \en Is there a simple builder (MbSimpleCreator) that contains a given shell?. + static bool IsThisShell( const MbSolid & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSimpleCreator ) +OBVIOUS_PRIVATE_COPY( MbSimpleCreator ) +}; // MbSimpleCreator + +IMPL_PERSISTENT_OPS( MbSimpleCreator ) + + +//------------------------------------------------------------------------------ +// Sort by shell pointers (ascending) +// --- +inline +bool SortByShellPointers( const c3d::IndexConstShell & is1, const c3d::IndexConstShell & is2 ) +{ + if ( is1.second < is2.second ) + return true; + return false; +} + +//------------------------------------------------------------------------------ +// Sort by shell pointers (ascending) +// --- +inline +bool AreEqualShellPointers( const c3d::IndexConstShell & is1, const c3d::IndexConstShell & is2 ) +{ + if ( is1.second == is2.second ) + return true; + return false; +} + +//------------------------------------------------------------------------------ +// Sort by index (ascending) +// --- +inline +bool SortByIndex( const c3d::IndexConstShell & is1, const c3d::IndexConstShell & is2 ) +{ + if ( is1.first < is2.first ) + return true; + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Удалить копии оболочек в простых построителях. \en Delete shell copies in creators MbSimpleCreator. +// --- +template +bool MbSimpleCreator::DeleteShellCopies( const CreatorsVector & creators ) +{ // KOMPAS-25604, KOMPAS-28405 + bool res = false; + + const size_t creatorsCnt = creators.size(); + std::vector simpleShells; + simpleShells.reserve( creatorsCnt ); + + size_t i; + for ( i = 0; i < creatorsCnt; ++i ) { + MbCreator * creator = creators[i]; + if ( creator != NULL ) { + if ( creator->IsA() == ct_SimpleCreator ) { + MbSimpleCreator * simpleCreator = static_cast(creator); + simpleShells.push_back( std::make_pair( i, simpleCreator->GetShell() ) ); + } + } + } + if ( simpleShells.size() > 1 ) { + std::sort( simpleShells.begin(), simpleShells.end(), ::SortByShellPointers ); + simpleShells.erase( std::unique( simpleShells.begin(), simpleShells.end(), ::AreEqualShellPointers ), simpleShells.end() ); + std::sort( simpleShells.begin(), simpleShells.end(), ::SortByIndex ); + + if ( simpleShells.size() > 1 ) { + bool isReplaced = false; + size_t checkCnt = simpleShells.size(); + for ( i = 0; i < checkCnt; ++i ) { + size_t ind1 = simpleShells[i].first; + MbSimpleCreator & sc1 = static_cast(*creators[ind1]); + const MbFaceShell * shell1 = sc1.GetShell(); + for ( size_t j = i + 1; j < checkCnt; ++j ) { + size_t ind2 = simpleShells[j].first; + MbSimpleCreator & sc2 = static_cast(*creators[ind2]); + const MbFaceShell * shell2 = sc2.GetShell(); + if ( shell1 && shell2 && (shell1 != shell2) ) { + if ( shell1->IsSame( *shell2, LENGTH_EPSILON ) ) { + sc2.SetShell( *shell1 ); + simpleShells[j].second = NULL; + isReplaced = true; + } + } + } + } + if ( isReplaced && (simpleShells.size() > 1) ) { + std::sort( simpleShells.begin(), simpleShells.end(), ::SortByShellPointers ); + simpleShells.erase( std::unique( simpleShells.begin(), simpleShells.end(), ::AreEqualShellPointers ), simpleShells.end() ); + if ( simpleShells.size() > 1 ) { + if ( simpleShells.front().second == NULL ) + simpleShells.erase( simpleShells.begin() ); + } + } + } + } + + return res; +} + +//------------------------------------------------------------------------------ +// \ru Есть ли в каком-то простом построителе (MbSimpleCreator) заданная оболочка. \en Is there a simple builder (MbSimpleCreator) that contains a given shell?. +// --- +template +bool MbSimpleCreator::IsThisShell( const MbFaceShell & shell, const Creators & creators ) +{ + bool res = false; + + if ( creators.size() > 0 ) { + for ( size_t i = creators.size(); i--; ) { + const MbCreator * creator = creators[i]; + if ( (creator != NULL) && (creator->IsA() == ct_SimpleCreator) ) { + const MbSimpleCreator & simpleCreator = static_cast(*creator); + if ( simpleCreator.GetShell() == &shell ) { + res = true; + break; + } + } + } + } + + return res; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель вывернутого "наизнанку" тела. + \en Constructor of a reversed solid. \~ + \details \ru Строитель вывернутого "наизнанку" тела. \n + \en Constructor of a reversed solid. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbReverseCreator : public MbCreator { + +public : + /// \ru Конструктор. \en Constructor. \~ + MbReverseCreator( const MbSNameMaker & ); + +private : + MbReverseCreator( const MbReverseCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования с регистратором \en Copy-constructor with the registrator +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbReverseCreator(); + + /** \ru \name Общие функции строителя оболочки. + \en \name Common functions of the shell creator. + \{ */ + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbReverseCreator ) +OBVIOUS_PRIVATE_COPY( MbReverseCreator ) +}; // MbReverseCreator + +IMPL_PERSISTENT_OPS( MbReverseCreator ) + +#endif // __CR_SIMPLE_CREATOR_H diff --git a/C3d/Include/cr_smooth_solid.h b/C3d/Include/cr_smooth_solid.h new file mode 100644 index 0000000..3956d04 --- /dev/null +++ b/C3d/Include/cr_smooth_solid.h @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель фаски или скругления ребeр тела. + \en Constructor of chamfer or fillet of solid's edges. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SMOOTH_SOLID_H +#define __CR_SMOOTH_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель фаски или скругления ребeр тела. + \en Constructor of chamfer or fillet of solid's edges. \~ + \details \ru Строитель фаски или скругления ребeр тела содержит идентификаторы обрабатываемых рёбер и параметры для выполнения операции. \n + \en Constructor of solid's edges chamfer or fillet contains identifiers of edges being processed and parameters for performing operation. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSmoothSolid : public MbCreator { +protected : + SArray indexes; ///< \ru Номера ребер и номера смежных (сопрягаемых) граней. \en Indices of edges and indices of adjacent (conjugated) faces. + SmoothValues parameters; ///< \ru Параметры скругления или фаски. \en Parameters of fillet or chamfer. + double buildSag; ///< \ru Шаг построения. \en Build step. + +private: + MbSmoothSolid( const MbSmoothSolid & bres ); // \ru Не реализовано. \en No realize. +protected : + MbSmoothSolid( const MbSNameMaker & n, SArray & _indexes, + const SmoothValues & params ); + // \ru Конструктор копирования. \en Copy-constructor. + MbSmoothSolid( const MbSmoothSolid & bres, MbRegDuplicate * iReg ); +public : + virtual ~MbSmoothSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const = 0; // \ru Тип элемента \en A type of element + virtual MbeCreatorType Type() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate *iReg = NULL ) const = 0; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName() = 0; // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator & other, double accuracy ) const = 0; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual( const MbCreator & ) = 0; // \ru Сделать равным \en Make equal + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray * items = NULL ) = 0; // \ru Построение \en Construction + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( SmoothValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const SmoothValues & params ) { parameters = params; } + +private : + virtual void ReadDistances ( reader &in ) = 0; + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbSmoothSolid & ); + + DECLARE_PERSISTENT_CLASS( MbSmoothSolid ) +}; // MbSmoothSolid + +IMPL_PERSISTENT_OPS( MbSmoothSolid ) + +#endif // __CR_SMOOTH_SOLID_H diff --git a/C3d/Include/cr_split_data.h b/C3d/Include/cr_split_data.h new file mode 100644 index 0000000..579ed47 --- /dev/null +++ b/C3d/Include/cr_split_data.h @@ -0,0 +1,523 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Усекающие элементы оболочки. + \en Truncating elements of a shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SPLIT_DATA_H +#define __CR_SPLIT_DATA_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class reader; +class writer; +class MATH_CLASS MbProperties; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbSpaceItem; +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbSNameMaker; +class MATH_CLASS MbSolid; +struct MATH_CLASS MbControlData3D; +class MbRegDuplicate; +class MbRegTransform; +enum MbeSenseValue; +enum MbeCopyMode; + + +//------------------------------------------------------------------------------ +/** \brief \ru Усекающие элементы. + \en Truncating elements. \~ + \details \ru Усекающие элементы используются для разделения граней на части и усечения оболочек. + Усечение может выполняться двумерными кривыми, расположенными в плоскости XY локальной системы координат, + трёхмерными кривыми, поверхностями и оболочками. + Усекающие элементы используются в строителе усеченной оболочки MbTruncatedShell и + строителе оболочки с разбиением граней MbSplitShell. \n + \en Truncating elements are used for splitting faces into parts and truncation of shells. + Truncating can be performed by two-dimensional curves located in the XY plane of the local coordinate system, + by three-dimensional curves, surfaces and shells. + Truncating elements are used in the creator of truncated shell MbTruncatedShell and + in the creator of shell with face splitting MbSplitShell. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MbSplitData : public MbRefItem { + /// \ru Типы усекающих объектов. \en Truncating objects types. + enum MbeSplitItemsType { + sit_NoItems = 0, ///< \ru Нет объектов. \en No objects. + sit_Curves2d = 1, ///< \ru Двумерные кривые в локальной системе координат. \en Two-dimensional curves in the local coordinate system. + sit_Curves3d = 2, ///< \ru Трехмерные кривые. \en Three-dimensional curves. + sit_Surfaces = 3, ///< \ru Поверхности. \en Surfaces. + sit_Creators = 4, ///< \ru Строители тела. \en Solid creators. + }; + +private: + // Sketch contours + c3d::PlaneContoursSPtrVector sketchContours; ///< \ru Двумерные кривые. \en Two-dimensional curves. + MbPlacement3D place; ///< \ru Локальная система координат двумерных кривых. \en Local coordinate system of two-dimensional curves. + MbVector3D direction; ///< \ru Вектор выдавливания двумерных кривых. \en Extrusion direction vector of two-dimensional curves. + MbeSenseValue sense; ///< \ru Направление выдавливания двумерных кривых относительно вектора. \en Extrusion direction of two-dimensional curves relative to direction vector. + // Space Curves + c3d::SpaceCurvesSPtrVector spaceCurves; ///< \ru Пространственные кривые. \en Spatial curves. + // Surfaces + c3d::SurfacesSPtrVector surfaces; ///< \ru Поверхности. \en Surfaces. + // Shell + c3d::CreatorsSPtrVector creators; ///< \ru Строители оболочки. \en Shell creators. + c3d::ShellSPtr solidShell; ///< \ru Оболочка. \en A shell. + +public: + /// \ru Конструктор. \en Constructor. + MbSplitData() + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + } + /// \ru Конструктор по двумерному контуру в локальной системе координат. \en Constructor by two-dimensional contour in the local coordinate system. + MbSplitData( const MbPlacement3D & pl, MbeSenseValue dirSense, const MbContour & item, bool same ) + : place ( pl ) + , direction ( ) + , sense ( dirSense ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + SPtr sketchContour; + sketchContour = same ? const_cast(&item) : static_cast(&item.Duplicate()); + sketchContours.push_back( sketchContour ); + } + /// \ru Конструктор по двумерному контуру в локальной системе координат. \en Constructor by two-dimensional contour in the local coordinate system. + MbSplitData( const MbPlacement3D & pl, const MbVector3D & dir, const MbContour & item, bool same ) + : place ( pl ) + , direction ( dir ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + C3D_ASSERT( (direction.MaxFactor() < LENGTH_EPSILON) || !direction.Orthogonal( place.GetAxisZ(), ANGLE_EPSILON ) ); + + SPtr sketchContour; + sketchContour = same ? const_cast(&item) : static_cast(&item.Duplicate()); + sketchContours.push_back( sketchContour ); + } + /// \ru Конструктор по двумерным контурам в локальной системе координат. \en Constructor by two-dimensional contours in the local coordinate system. + template + MbSplitData( const MbPlacement3D & pl, MbeSenseValue dirSense, const PlaneContoursVector & items, bool same ) + : place ( pl ) + , direction ( ) + , sense ( dirSense ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + ::AddRefItems( items, same, sketchContours ); + } + /// \ru Конструктор по двумерным контурам в локальной системе координат. \en Constructor by two-dimensional contours in the local coordinate system. + template + MbSplitData( const MbPlacement3D & pl, const MbVector3D & dir, const PlaneContoursVector & items, bool same ) + : place ( pl ) + , direction ( dir ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + C3D_ASSERT( (direction.MaxFactor() < LENGTH_EPSILON) || !direction.Orthogonal( place.GetAxisZ(), ANGLE_EPSILON ) ); + + ::AddRefItems( items, same, sketchContours ); + } + /// \ru Конструктор по пространственным кривым. \en Constructor by spatial curves. + MbSplitData( const c3d::ConstSpaceCurvesSPtrVector & items, bool same ) + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + ::AddRefItems( items, same, spaceCurves ); + } + /// \ru Конструктор по пространственным кривым. \en Constructor by spatial curves. + MbSplitData( const c3d::ConstSpaceCurvesVector & items, bool same ) + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + ::AddRefItems( items, same, spaceCurves ); + } + /// \ru Конструктор по поверхности. \en Constructor by a surface. + MbSplitData( const MbSurface & item, bool same ) + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + SPtr surface; + surface = same ? const_cast(&item) : static_cast(&item.Duplicate()); + surfaces.push_back( surface ); + } + /// \ru Конструктор по поверхностям. \en Constructor by surfaces. + MbSplitData( const c3d::ConstSurfacesSPtrVector & items, bool same ) + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + ::AddRefItems( items, same, surfaces ); + } + /// \ru Конструктор по поверхностям. \en Constructor by surfaces. + MbSplitData( const c3d::ConstSurfacesVector & items, bool same ) + : place ( ) + , direction ( ) + , sense ( orient_BOTH ) + , sketchContours( ) + , spaceCurves ( ) + , surfaces ( ) + , creators ( ) + , solidShell ( NULL ) + { + ::AddRefItems( items, same, surfaces ); + } + /// \ru Конструктор по телу. \en Constructor by a solid. + MbSplitData( const MbSolid & solid, bool same, bool keepShell ); + /// \ru Конструктор копирования с регистратором копирования. \en Copy constructor with registrator of copying. + explicit MbSplitData( const MbSplitData &, bool same, MbRegDuplicate * iReg ); + /// \ru Деструктор. \en Destructor. + ~MbSplitData(); + +public: + /// \ru Инициализировать по двумерному контуру в локальной системе координат. \en Initialize by two-dimensional contour in the local coordinate system. + bool InitPlaneContour( const MbPlacement3D & pl, MbeSenseValue dirSense, const MbContour & item, bool same ) + { + DeleteItems(); + place.Init( pl ); + direction.SetZero(); + sense = dirSense; + + SPtr sketchContour; + sketchContour = same ? const_cast( &item ) : static_cast(&item.Duplicate()); + sketchContours.push_back( sketchContour ); + return true; + } + /// \ru Инициализировать по двумерному контуру в локальной системе координат. \en Initialize by two-dimensional contour in the local coordinate system. + bool InitPlaneContour( const MbPlacement3D & pl, const MbVector3D & dir, const MbContour & item, bool same ) + { + DeleteItems(); + place.Init( pl ); + direction.Init( dir ); + C3D_ASSERT( (direction.MaxFactor() < LENGTH_EPSILON) || !direction.Orthogonal( place.GetAxisZ(), ANGLE_EPSILON ) ); + sense = orient_BOTH; + + SPtr sketchContour; + sketchContour = same ? const_cast( &item ) : static_cast(&item.Duplicate()); + sketchContours.push_back( sketchContour ); + return true; + } + /// \ru Инициализировать по двумерным контурам в локальной системе координат. \en Initialize by two-dimensional contours in the local coordinate system. + template + bool InitPlaneContours( const MbPlacement3D & pl, MbeSenseValue dirSense, const PlaneContoursVector & items, bool same ) + { + if ( items.size() > 0 ) { + DeleteItems(); + place.Init( pl ); + direction.SetZero(); + sense = dirSense; + + ::AddRefItems( items, same, sketchContours ); + return true; + } + return false; + } + /// \ru Инициализировать по двумерным контурам в локальной системе координат. \en Initialize by two-dimensional contours in the local coordinate system. + template + bool InitPlaneContours( const MbPlacement3D & pl, const MbVector3D & dir, const PlaneContoursVector & items, bool same ) + { + if ( items.size() > 0 ) { + DeleteItems(); + place.Init( pl ); + direction.Init( dir ); + C3D_ASSERT( (direction.MaxFactor() < LENGTH_EPSILON) || !direction.Orthogonal( place.GetAxisZ(), ANGLE_EPSILON ) ); + sense = orient_BOTH; + + ::AddRefItems( items, same, sketchContours ); + return true; + } + return false; + } + /// \ru Инициализировать по пространственным кривым. \en Initialize by spatial curves. + template + bool InitSpaceCurves( const SpaceCurvesVector & items, bool same ) + { + if ( items.size() > 0 ) { + DeleteItems(); + + ::AddRefItems( items, same, spaceCurves ); + return true; + } + return false; + } + /// \ru Инициализировать по поверхностям. \en Initialize by surfaces. + template + bool InitSurfaces( const SurfacesVector & items, bool same ) + { + if ( items.size() > 0 ) { + DeleteItems(); + + ::AddRefItems( items, same, surfaces ); + return true; + } + return false; + } + /// \ru Инициализировать по телу. \en Initialize by a solid. + bool InitSolid( const MbSolid & solid, bool same, bool keepShell ); + /// \ru Инициализировать по построителям тела. \en Initialize by solid creators. + template + bool InitSolid( const CreatorsVector & solidCreators, bool sameCreators ) + { + DeleteItems(); + size_t creatorsCnt = solidCreators.size(); + if ( creatorsCnt > 0 ) { + MbRegDuplicate * iReg = NULL; + MbAutoRegDuplicate autoReg( iReg ); + SPtr creator; + creators.reserve( creatorsCnt ); + for ( size_t k = 0; k < creatorsCnt; ++k ) { + if ( solidCreators[k] != NULL ) { + creator = sameCreators ? &const_cast( *solidCreators[k] ) : static_cast( &solidCreators[k]->Duplicate( iReg ) ); + creators.push_back( creator ); + ::DetachItem( creator ); + } + } + if ( creators.size() > 0 ) + return true; + } + return false; + } + /// \ru Сделать равным. \en Make equal. + bool SetEqual ( const MbSplitData & ); + /// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + bool IsSimilar( const MbSplitData & ) const; + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Сдвинуть по вектору. \en Shift by a vector. + void Move ( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Повернуть вокруг оси. \en Rotate about an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + /// \ru Отсутствуют ли объекты? \en Are the objects absent? + bool IsEmpty() const { + return ( sketchContours.empty() && + spaceCurves.empty() && + surfaces.empty() && + (creators.empty() && (solidShell == NULL)) ); } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSplitData &, double accuracy ) const; + + /** \ru \name Доступ к эскизу. + \en \name Access to a sketch. + \{ */ + /// \ru Выдать количество двумерных кривых. \en Get number of two-dimensional curves. + size_t GetSketchCurvesCount() const { return sketchContours.size(); } + /// \ru Получить локальную систему координат двумерных кривых. \en Get the local coordinate system of two-dimensional curves. + const MbPlacement3D & GetSketchPlace() const { return place; } + /// \ru Получить локальную систему координат двумерных кривых. \en Get the local coordinate system of two-dimensional curves. + MbPlacement3D & SetSketchPlace() { return place; } + /// \ru Получить вектор направления выдавливания двумерных кривых. \en Get the extrusion direction vector of two-dimensional curves. + const MbVector3D & GetSketchDirection() const { return direction; } + /// \ru Получить вектор направления выдавливания двумерных кривых. \en Get the extrusion direction vector of two-dimensional curves. + MbVector3D & SetSketchDirection() { return direction; } + /// \ru Выдать направление выдавливания двумерных кривых. \en Get extrusion direction of two-dimensional curves. + const MbeSenseValue GetSketchSense() const { return sense; } + /// \ru Выдать направление выдавливания двумерных кривых. \en Get extrusion direction of two-dimensional curves. + MbeSenseValue & SetSketchSense() { return sense; } + /// \ru Установить направление выдавливания двумерных кривых. \en Set extrusion direction of two-dimensional curves. + void SetSketchSense( MbeSenseValue zdir ) { sense = zdir; } + /// \ru Получить двумерную кривую по индексу. \en Get two-dimensional curve by index. + const MbContour * GetSketchCurve( size_t k ) const { return ((k < sketchContours.size()) ? sketchContours[k].get() : NULL ); } + /// \ru Получить двумерную кривую по индексу. \en Get two-dimensional curve by index. + MbContour * SetSketchCurve( size_t k ) { return ((k < sketchContours.size()) ? sketchContours[k].get() : NULL ); } + /// \ru Получить все двумерные кривые. \en Get all two-dimensional curves. + template + void GetSketchCurves( PlaneContoursVector & curvs ) const + { + curvs.reserve( curvs.size() + sketchContours.size() ); + c3d::PlaneContourSPtr sketchContour; + for ( size_t k = 0, addCnt = sketchContours.size(); k < addCnt; ++k ) { + sketchContour = const_cast( sketchContours[k].get() ); + curvs.push_back( sketchContour ); + } + } + /// \ru Удалить двумерную кривую по индексу. \en Delete two-dimensional curve by index. + bool DeleteSketchCurve( size_t k ); + + /** \} */ + /** \ru \name Доступ к пространственным кривым. + \en \name Access to spatial curves. + \{ */ + /// \ru Выдать количество пространственных кривых. \en Get number of spatial curves. + size_t GetSpaceCurvesCount() const { return spaceCurves.size(); } + /// \ru Получить пространственную кривую по индексу. \en Get a spatial curve by index. + const MbCurve3D * GetSpaceCurve( size_t k ) const { return ((k < spaceCurves.size()) ? spaceCurves[k].get() : NULL ); } + /// \ru Получить пространственную кривую по индексу. \en Get a spatial curve by index. + MbCurve3D * SetSpaceCurve( size_t k ) { return ((k < spaceCurves.size()) ? spaceCurves[k].get() : NULL ); } + /// \ru Получить все пространственные кривые. \en Get all spatial curves. + template + void GetSpaceCurves( SpaceCurvesVector & curvs ) const + { + curvs.reserve( curvs.size() + spaceCurves.size() ); + c3d::SpaceCurveSPtr spaceCurve; + for ( size_t k = 0, addCnt = spaceCurves.size(); k < addCnt; ++k ) { + spaceCurve = const_cast( spaceCurves[k].get() ); + curvs.push_back( spaceCurve ); + } + } + /// \ru Установить пространственную кривую по индексу. \en Set spatial curve by index. + bool SetSpaceCurve( const MbCurve3D & curve, size_t k ); + + /** \} */ + /** \ru \name Доступ к поверхностям. + \en \name Access to surfaces. + \{ */ + /// \ru Выдать количество поверхностей. \en Get number of surfaces. + size_t GetSurfacesCount() const { return surfaces.size(); } + /// \ru Получить поверхность по индексу. \en Get a surface by index. + const MbSurface * GetSurface( size_t k ) const { return ((k < surfaces.size()) ? surfaces[k].get() : NULL); } + /// \ru Получить поверхность по индексу. \en Get a surface by index. + MbSurface * SetSurface( size_t k ) { return ((k < surfaces.size()) ? surfaces[k].get() : NULL); } + /// \ru Получить все поверхности. \en Get all surfaces. + template + void GetSurfaces( SurfacesVector & surfs ) const + { + surfs.reserve( surfs.size() + surfaces.size() ); + c3d::SurfaceSPtr surface; + for ( size_t k = 0, addCnt = surfaces.size(); k < addCnt; ++k ) { + surface = const_cast( surfaces[k].get() ); + surfs.push_back( surface ); + } + } + /// \ru Установить поверхность по индексу. \en Set a surface by index. + bool SetSurface( const MbSurface & surface, size_t k ); + + /** \} */ + /** \ru \name Доступ к строителям. + \en \name Access to creators. + \{ */ + /// \ru Выдать количество строителей тела. \en Get number of solid creators. + size_t GetCreatorsCount() const { return creators.size(); } + /// \ru Получить строитель по индексу. \en Get constructor by index. + const MbCreator * GetCreator( size_t k ) const { return ((k < creators.size()) ? creators[k].get() : NULL ); } + /// \ru Получить строитель по индексу. \en Get constructor by index. + MbCreator * SetCreator( size_t k ) { return ((k < creators.size()) ? creators[k].get() : NULL ); } + /// \ru Получить все строители. \en Get all creators. + template + void GetCreators( CreatorsVector & crs ) const + { + crs.reserve( crs.size() + creators.size() ); + c3d::ConstCreatorSPtr creator; + for ( size_t k = 0, addCnt = creators.size(); k < addCnt; ++k ) { + creator = creators[k]; + crs.push_back( creator ); + ::DetachItem( creator ); + } + } + /// \ru Получить все строители. \en Get all creators. + template + void GetCreatorsCopies( CreatorsVector & crs ) const + { + MbRegDuplicate * iReg = NULL; + MbAutoRegDuplicate autoReg( iReg ); + + crs.reserve( crs.size() + creators.size() ); + c3d::CreatorSPtr creator; + for ( size_t k = 0, addCnt = creators.size(); k < addCnt; ++k ) { + if ( creators[k] != NULL ) + creator = static_cast( &creators[k]->Duplicate( iReg ) ); + crs.push_back( creator ); + ::DetachItem( creator ); + creator = NULL; + } + } + /// \ru Получить все строители. \en Get all creators. + template + void SetCreators( CreatorsVector & crs ) + { + crs.reserve( crs.size() + creators.size() ); + c3d::CreatorSPtr creator; + for ( size_t k = 0, addCnt = creators.size(); k < addCnt; ++k ) { + creator = creators[k]; + crs.push_back( creator ); + ::DetachItem( creator ); + } + } + /// \ru Получить хранимую оболочку. \en Get stored shell. + const MbFaceShell * GetSolidShell() const { return solidShell; } + /// \ru Создать оболочку по строителям (solidShell остается нетронутой). \en Create a shell by creators (solidShell remains unchanged). + MbFaceShell * CreateShell( MbeCopyMode copyMode ); + /// \ru Создать оболочку по строителям. \en Create a shell by creators (solidShell remains unchanged). + bool UpdateShell( MbeCopyMode copyMode ); + /// \ru Удалить данные. \en Delete data. + void DeleteItems(); + /// \ru Прочитать данные. \en Read data. + void ReadItems ( reader & ); + /// \ru Записать данные. \en Write data. + void WriteItems( writer & ) const; + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /// \ru Дать базовые объекты. \en Get the base objects. + void GetBasisItems ( RPArray & ); + /// \ru Выдать контрольные точки объекта. \en Get control points of object. + void GetBasisPoints( MbControlData3D & ) const; + /// \ru Изменить объект по контрольным точкам. \en Change the object by control points. + void SetBasisPoints( const MbControlData3D & ); + /** \} */ +OBVIOUS_PRIVATE_COPY( MbSplitData ) +}; + + +#endif // __CR_SPLIT_DATA_H diff --git a/C3d/Include/cr_split_shell.h b/C3d/Include/cr_split_shell.h new file mode 100644 index 0000000..04fcadb --- /dev/null +++ b/C3d/Include/cr_split_shell.h @@ -0,0 +1,160 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки с разбиением граней. + \en Construction of a shell with splitting of faces. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SPLIT_SHELL_H +#define __CR_SPLIT_SHELL_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки с разбиением граней. + \en Construction of a shell with splitting of faces. \~ + \details \ru Строитель оболочки с разбиением граней по указанным кривым на них. \n + \en Constructor of a shell with splitting of faces by the specified curves on them. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSplitShell : public MbCreator { +protected: + SArray faceIndices; ///< \ru Идентификаторы разбиваемых граней. \en Identifiers of faces to split. + MbSplitData splitItems; ///< \ru Порождающие объекты линии разъема. \en Generating objects of parting lines. + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool mergeEdges; ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). + +public: + MbSplitShell( const MbSplitData & spItems, bool sameItems, const SArray & spFaceIndices, const MbMergingFlags & mf, const MbSNameMaker & n ); +private : + MbSplitShell( const MbSplitShell &, MbRegDuplicate * iReg ); +public : + virtual ~MbSplitShell(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: // \ru Не реализовано \en Not implemented + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSplitShell( const MbSplitShell & ); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbSplitShell & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSplitShell ) +}; + +IMPL_PERSISTENT_OPS( MbSplitShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку с разбиением граней выдавливанием. + \en Create a shell with faces splitting by extrusion. \~ + \details \ru Построить оболочку подразбиением граней поверхностями, + полученными выдавливанием контуров на плоскости XY локальной системы координат.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell by faces splitting by surfaces + obtained by extrusion of contours on XY plane of the local coordinate system.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] splitPlace - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] splitType - \ru Способ разбиения. + \en Method of splitting. \~ + \param[in] splitContours - \ru Двумерные контуры на плоскости XY локальной системы координат. + \en Two-dimensional contours on XY plane of the local coordinate system. \~ + \param[in] splitSame - \ru Флаг копирования объектов. + \en Flag of objects' copying. \~ + \param[in] selFaces - \ru Разбиваемые грани. + \en Faces to split. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSplitSolid( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & splitPlace, + MbeSenseValue splitType, + const RPArray & splitContours, + bool splitSame, + RPArray & selFaces, + const MbMergingFlags & mergingFlags, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку с разбиением граней пространственными объектами. + \en Create a shell with faces splitting by spatial objects. \~ + \details \ru Построить оболочку с разбиением граней пространственными кривыми, поверхностями и оболочками. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell with faces splitting by spatial curves, surfaces and shells. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] splitItems - \ru Пространственные объекты. + \en Spatial objects. \~ + \param[in] splitSame - \ru Флаг копирования объектов. + \en Flag of objects' copying. \~ + \param[in] selFaces - \ru Разбиваемые грани. + \en Faces to split. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSplitSolid( MbFaceShell * solid, + MbeCopyMode sameShell, + const RPArray & splitItems, + bool splitSame, + RPArray & selFaces, + const MbMergingFlags & mergingFlags, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SPLIT_SHELL_H diff --git a/C3d/Include/cr_stamp_bead_solid.h b/C3d/Include/cr_stamp_bead_solid.h new file mode 100644 index 0000000..6f02c0f --- /dev/null +++ b/C3d/Include/cr_stamp_bead_solid.h @@ -0,0 +1,160 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала с буртиком. + \en Constructor of a shell from sheet material with a bead. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_BEAD_SOLID_H +#define __CR_STAMP_BEAD_SOLID_H + + +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurveBoundedSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с буртиком. + \en Constructor of a shell from sheet material with a bead. \~ + \details \ru Строитель оболочки из листового материала с буртиком. \n + В зависимости от параметров может быть построен буртик: + круглый - с образующей в виде дуги окружности, + V-образный - с образующей в виде дуги с касательными отрезками с каждой стороны или + U-образный - с образующей в виде трёх отрезков со скруглениями или без них. + \en Constructor of a shell from sheet material with a bead. \n + Subject to the parameters a bead can be constructed of the following type: + circular - with generating curve in the form of circular arc, + V-shaped - with generating curve in the form of an arc with the tangent segments in each sides or + U-shaped - with generating curve in the form of three segments with fillets or without them. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbBeadSolid : public MbCreator { + MbItemIndex faceIndex; ///< \ru Индекс грани, на которой строится буртик \en Index of face on which the bead is constructed. + MbItemIndex pairFaceIndex; ///< \ru Индекс грани парной к грани буртика. \en Index of the face which is pair to the bead face. + MbCurveBoundedSurface * boundSurface; ///< \ru Поверхность, границами которой надо подрезать буртик. \en Surface, by which bounds the bead is cutted. + MbPlacement3D placement; ///< \ru Локальная система координат, в плоскости XY которй расположены направляющие буртика. \en The local coordinate system in XY plane of which the spine curves of the bead is located. + RPArray contours; ///< \ru Направляющие буртика. \en Spine curves of the bead. + SArray centers; ///< \ru Центры сферических штамповок. \en The spherical stamps' centers. + MbBeadValues parameters; ///< \ru Параметры операции. \en The operation parameters. + double thickness; ///< \ru Толщина листа. \en The thickness of the sheet metal. + bool add; ///< \ru Создавать добавляемую или вычитаемую часть буртика. \en Create additional or subtructional part of a bead. + +public : + MbBeadSolid( const MbItemIndex & faceIndex, + const MbItemIndex & pairFaceIndex, + const MbCurveBoundedSurface * boundSurface, + const MbPlacement3D & placement, + const RPArray & contours, + const SArray & centers, + const MbBeadValues & params, + const double thickness, + const bool add, + const MbSNameMaker & names ); +private: + MbBeadSolid( const MbBeadSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbBeadSolid( const MbBeadSolid & ); + +public: + virtual ~MbBeadSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties ( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbBeadValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbBeadValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbBeadSolid & operator = ( const MbBeadSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBeadSolid ) +}; + +IMPL_PERSISTENT_OPS( MbBeadSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала с буртиком. + \en Construct a shell from sheet material with a bead. \~ + \details \ru Построить оболочку из листового материала с буртиком, + который может быть круглым - с образующей в виде дуги окружности, + V-образным - с образующей в виде дуги с касательными отрезками с каждой стороны или + U-образный - с образующей в виде трёх отрезков со скруглениями или без них. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell from sheet material with a bead + which can be circular - with generating curve in the form of circular arc, + V-shaped - with generating curve in the form of an arc with the tangent segments in each sides or + U-shaped - with generating curve in the form of three segments with fillets or without them. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Грань буртика. + \en The bead face. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположены контуры буртика. + \en The local coordinate system in XY plane of which the contours of the bead is located. \~ + \param[in] contours - \ru Контуры буртика. + \en The bead contours. \~ + \param[in] parameters - \ru Параметры буртика. + \en The bead parameters. \~ + \param[in] thickness - \ru Толщина пластины. + \en The thickness of the plate. \~ + \param[in] add - \ru Создавать добавляемую компоненту буртика. + \en To create the added part of the bead. \~ + \param[in] nameMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] resultShell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateBead( MbFaceShell * initialShell, + const MbeCopyMode sameShell, + const MbFace * face, + const MbPlacement3D & placement, + const RPArray & contours, + const SArray & centers, + const MbBeadValues & parameters, + const double thickness, + const bool add, + MbSNameMaker & nameMaker, + MbResultType & res, + SPtr & resultShell ); + + +#endif // __CR_STAMP_BEAD_SOLID_H diff --git a/C3d/Include/cr_stamp_jalousie_solid.h b/C3d/Include/cr_stamp_jalousie_solid.h new file mode 100644 index 0000000..b52a413 --- /dev/null +++ b/C3d/Include/cr_stamp_jalousie_solid.h @@ -0,0 +1,150 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала с жалюзи. + \en Constructor of a shell form sheet material with jalousie. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_JALOUSIE_SOLID_H +#define __CR_STAMP_JALOUSIE_SOLID_H + +#include +#include +#include + + +class MATH_CLASS MbCurveBoundedSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с жалюзи. + \en Constructor of a shell form sheet material with jalousie. \~ + \details \ru Строитель оболочки из листового материала с жалюзи. \n + В зависимости от параметров строятся вытянутые или подрезанные жалюзи. + В случае подрезанных жалюзи материал плоского участка листового тела + подрезается с трёх сторон образующего прямоугольника и отгибается относительно четвёртой стороны. + В случае вытянутых жалюзи отгибаемый материал принимает цилиндрическую форму вдоль + отрезка построения и сферическую форму на его концах. + \en Constructor of a shell form sheet material with jalousie. \n + Subject to the parameters stretched or trimmed jalousie are constructed. + In the case of trimmed jalousie the material of the planar part of the sheet solid + is trimmed from three sides of the generating rectangle and deflected relative to the fourth side. + In the case of stretched jalousie the deflected material take the cylindric shape along + the construction segment and the spherical shape at its ends. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbJalousieSolid : public MbCreator { + MbItemIndex faceIndex; ///< \ru Индекс грани, на которой строятся жалюзи. \en Index of the face on which jalousie are constructed. + MbItemIndex pairFaceIndex; ///< \ru Индекс грани парной к грани жалюзи. \en Index of the face which is pair to the jalousie face. + MbCurveBoundedSurface * boundSurface; ///< \ru Поверхность, границами которой надо подрезать жалюзи. \en Surface, by which bounds the jalousie is cutted. + MbPlacement3D placement; ///< \ru Локальная система координат, в плоскости XY которй расположены отрезки, по которым строятся жалюзи. \en The local coordinate system in the XY plane of which the segments are located by which jalousie are constructed. + RPArray lineSegments; ///< \ru Отрезки, по которым строятся жалюзи. \en The segments by which jalousie are constructed. + MbJalousieValues parameters; ///< \ru Параметры жалюзи. \en Jalousie parameters. + double thickness; ///< \ru Толщина листа. \en The thickness of the sheet metal. + bool add; ///< \ru Создавать добавляемую или вычитаемую часть жалюзи. \en Create additional or subtructional part of a jalousie. + +public : + MbJalousieSolid( const MbItemIndex & faceIndex, + const MbItemIndex & pairFaceIndex, + const MbCurveBoundedSurface * boundSurface, + const MbPlacement3D & placement, + const RPArray & lineSegments, + const MbJalousieValues & params, + const double thickness, + const bool add, + const MbSNameMaker & names ); +private: + MbJalousieSolid( const MbJalousieSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbJalousieSolid( const MbJalousieSolid & ); + +public: + virtual ~MbJalousieSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties ( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbJalousieValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbJalousieValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbJalousieSolid & operator = ( const MbJalousieSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbJalousieSolid ) +}; + +IMPL_PERSISTENT_OPS( MbJalousieSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала с жалюзи. + \en Construct a shell from a sheet material with jalousie. \~ + \details \ru Построить оболочку из листового материала с вытянутыми или подрезанными жалюзи. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from a sheet material with stretched or trimmed jalousie. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Грань жалюзи. + \en A face of jalousie. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположены отрезки жалюзи. + \en The local coordinate system in the XY plane of which the segments of are located. \~ + \param[in] lineSegments - \ru Отрезки жалюзи. + \en The segments of jalousie. \~ + \param[in] parameters - \ru Параметры жалюзи. + \en The parameters of jalousie. \~ + \param[in] thickness - \ru Толщина пластины. + \en The thickness of the plate. \~ + \param[in] add - \ru Создавать добавляемую компоненту жалюзи. + \en To create the added part of the jalousie. \~ + \param[in] nameMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] resultShell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateJalousie( MbFaceShell * initialShell, + const MbeCopyMode sameShell, + const MbFace * face, + const MbPlacement3D & placement, + const RPArray & lineSegments, + const MbJalousieValues & parameters, + const double thickness, + const bool add, + MbSNameMaker & nameMaker, + MbResultType & res, + SPtr & resultShell ); + + +#endif // __CR_STAMP_JALOUSIE_SOLID_H diff --git a/C3d/Include/cr_stamp_jog_solid.h b/C3d/Include/cr_stamp_jog_solid.h new file mode 100644 index 0000000..bf1189e --- /dev/null +++ b/C3d/Include/cr_stamp_jog_solid.h @@ -0,0 +1,155 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала с подсечкой. + \en Constructor of a shell from sheet material with a jog. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_JOG_SOLID_H +#define __CR_STAMP_JOG_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с подсечкой. + \en Constructor of a shell from sheet material with a jog. \~ + \details \ru Строитель оболочки из листового материала с подсечкой. \n + С помощью подсечки плоская часть листового тела лежащая по левую или правую + сторону отрезка смещается компланарно относительно своего изначального положения + вдоль нормали или под углом к ней. Операция выполняется с помощью двух коллинеарных + сгибов по линии и бывает двух типов: с добавлением и без добавления материала. + Без добавления материала - это просто два сгиба по линии. С добавлением - материал + наращивается таким образом, чтобы проекция поднятого участка совпала с контуром + его первоначального положения. + \en Constructor of a shell from sheet material with a jog. \n + Using a jog the planar part of a sheet solid lying on the left or on the right of + the segment is shifted complanarly relative to its initial position + along the normal or at angle to the normal. The operation is performed using two collinear + bends by a line and can be of two types: with and without addition of the material. + Without addition of the material - is simply two bends by a line. With addition of the material - the material + is grown so as the projection of the raised part coincides with the contour of + its initial state. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbJogSolid : public MbCreator { +private: + SArray bendingFacesIndices; ///< \ru Индексы подсекаемых граней (сортированы и не повторяются). \en Indices of faces for a jog (are sorted and not duplicated). + MbCurve3D * curve; ///< \ru Отрезок подсечки. \en A jog segment. + bool unbended; ///< \ru Флаг построения подсечки в разогнутом виде. \en Flag of a jog construction in unfolded state. + MbJogValues jogParameters; ///< \ru Параметры подсечки совместно с параметрами первого сгиба. \en Parameters of a jog together with the parameters of the first bend. + MbBendValues secondBendParameters; ///< \ru Параметры второго сгиба. \en Parameters of the second bend. + +public : + MbJogSolid( const SArray & bendingFacesIndices, + MbCurve3D & curve, + const bool unbended, + const MbJogValues & jogPars, + const MbBendValues & secondBendPars, + const MbSNameMaker & names ); +private: + MbJogSolid( const MbJogSolid &, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbJogSolid( const MbJogSolid & ); + +public: + virtual ~MbJogSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbJogValues & params ) const { params = jogParameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbJogValues & params ) { jogParameters = params; } + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbBendValues & params ) const { params = secondBendParameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbBendValues & params ) { secondBendParameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbJogSolid & operator = ( const MbJogSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbJogSolid ) +}; + +IMPL_PERSISTENT_OPS( MbJogSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочки из листового материала с подсечкой. + \en Construct shells from the sheet material with a jog. \~ + \details \ru На базе исходной оболочки из листового материала построить оболочку с подсечкой.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en A shell with a jog is to be created on the basis of the source shell from the sheet material.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] bendingFaces - \ru Грани сгибов. + \en Faces of bends. \~ + \param[in] curve - \ru Кривая формы подсечки. + \en Curve of a jog shape. \~ + \param[in] unbended - \ru Флаг разогнутого состояния. + \en Flag of unfolded state. \~ + \param[in] parameters - \ru Параметры подсечки. + \en The jog parameters. \~ + \param[in] secondBendParams - \ru Параметры сгибов. + \en The bends parameters. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] firstBendFaces - \ru Грани первого сгиба. + \en The first bend faces. \~ + \param[in] secondBendFaces - \ru Грани второго сгиба. + \en The second bend faces. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSheetSolidJog( MbFaceShell & solid, + MbeCopyMode sameShell, + const RPArray & bendingFaces, + MbCurve3D & curve, + const bool unbended, + const MbJogValues & parameters, + const MbBendValues & secondBendParams, + MbSNameMaker & names, + RPArray & firstBendFaces, + RPArray & secondBendFaces, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_STAMP_JOG_SOLID_H diff --git a/C3d/Include/cr_stamp_remove_solid.h b/C3d/Include/cr_stamp_remove_solid.h new file mode 100644 index 0000000..c5a431b --- /dev/null +++ b/C3d/Include/cr_stamp_remove_solid.h @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки тела с без указанной операции. + \en Construction of a shell without the specified operation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_REMOVE_SOLID_H +#define __CR_STAMP_REMOVE_SOLID_H + + +#include +//#include +//#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала с удалёнными элементами указанной операции. + \en The constructor of a shell from sheet material without elements of the specified operation. \~ + \details \ru Строитель оболочки из листового материала с удалёнными элементами указанной операции. + Удаляет грани с указанным главным именем операции и затягивает образовавшуюся дыру расширением соседних граней. \n + \en The constructor of a shell from sheet material without elements of the specified operation. + It removes faces with specified main name and then mends the hole by stretching the neighbour faces. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbRemoveOperationSolid : public MbCreator { + SimpleName removeName; + +public : + MbRemoveOperationSolid( const SimpleName removeName, + const MbSNameMaker & names ); +private: + MbRemoveOperationSolid( const MbRemoveOperationSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbRemoveOperationSolid( const MbRemoveOperationSolid & ); + +public: + virtual ~MbRemoveOperationSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbRemoveOperationSolid & operator = ( const MbRemoveOperationSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRemoveOperationSolid ) +}; + +IMPL_PERSISTENT_OPS( MbRemoveOperationSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку без указанной операции. + \en Constructs a shell without the specified operation. \~ + \details \ru Построить оболочку без указанной операции. + Удаляет грани с указанным главным именем операции и затягивает образовавшуюся дыру расширением соседних граней. \n + \en Constructs a shell without the specified operation. + It removes faces with specified main name and then mends the hole by stretching the neighbour faces. \n \~ + \param[in] initialShell - \ru Исходная оболочка. + \en The initial shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] removeName - \ru Главное имя операции которую надо удалить. + \en The main name of the operation to be removed. \~ + \param[in] names - \ru Именователь граней. + \en An object for naming faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateRemovedOperationResult( MbFaceShell & initialShell, + const MbeCopyMode sameShell, + const SimpleName removeName, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + + +#endif // __CR_STAMP_REMOVE_SOLID_H + + diff --git a/C3d/Include/cr_stamp_rib_solid.h b/C3d/Include/cr_stamp_rib_solid.h new file mode 100644 index 0000000..b89ed07 --- /dev/null +++ b/C3d/Include/cr_stamp_rib_solid.h @@ -0,0 +1,135 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель листового тела с ребром жёсткости. + \en Constructor of a sheet solid with a rib. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_RIB_SOLID_H +#define __CR_STAMP_RIB_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель тела с ребром жёсткости. + \en Constructor of a sheet solid with a rib. \~ + \details \ru Строитель тела с ребром жёсткости, форма которого задана плоским контуром. + \en Constructor of a solid with a rib whose shape is specified by a planar contour. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbStampRibSolid : public MbCreator { +protected : + MbPlacement3D place; ///< \ru Подложка для формообразующей кривой, точки и вектора уклона. \en Placement of the forming curve, point and inclination vector. + MbContour * spine; ///< \ru Формообразующая кривая (хребет ребра жёсткости). \en Forming curve (rib's spine). + size_t index; ///< \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. \en The segment index in the contour from which the inclination direction will be set. + SheetRibValues parameters; ///< \ru Параметры формообразования. \en Forming parameters. + +public : + MbStampRibSolid( const MbPlacement3D & place, + const MbContour & contour, + size_t index, + const SheetRibValues & param, + const MbSNameMaker & names ); +private : + MbStampRibSolid( const MbStampRibSolid & bres, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbStampRibSolid( const MbStampRibSolid & bres ); +public : + virtual ~MbStampRibSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA () const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual void Transform ( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray *items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( SheetRibValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const SheetRibValues & params ) { parameters = params; } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbStampRibSolid & ); // \ru НЕЛЬЗЯ!!! \en NOT ALLOWED!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStampRibSolid ) +}; // MbRibSolid + +IMPL_PERSISTENT_OPS( MbStampRibSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку с ребром жёсткости. + \en Create a shell with a rib. \~ + \details \ru Для указанной листовой оболочки построить оболочку с ребром жёсткости, форма которого задана плоским контуром.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a specified sheet shell create a shell with a rib which shape is given by the planar contour.\n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которай расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур ребра жесткости расположен в плоскости XY локальной системы координат. + \en Two-dimensional contour of a rib located in XY plane of the local coordinate system. \~ + \param[in] index - \ru Индекс сегмента в контуре, от которого будет установлено направление уклона. + \en Index of a segment in the contour at which the inclination direction will be set. \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSheetRib( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + size_t index, + SheetRibValues & parameters, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +// Построение элементов ребра жёсткости. +// --- +MATH_FUNC (MbResultType) CreateSheetRibParts( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbPlacement3D & place, + const MbContour & contour, + const size_t index, + const SheetRibValues & pars, + const MbSNameMaker & names, + MbFaceShell *& shellToAdd, + MbFaceShell *& shellToSubtract ); + +#endif // __CR_STAMP_RIB_SOLID_H diff --git a/C3d/Include/cr_stamp_ruled_solid.h b/C3d/Include/cr_stamp_ruled_solid.h new file mode 100644 index 0000000..c30dbc7 --- /dev/null +++ b/C3d/Include/cr_stamp_ruled_solid.h @@ -0,0 +1,120 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель листовой линейчатой оболочки. + \en Constructor of a sheet ruled shell. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_RULED_SOLID_H +#define __CR_STAMP_RULED_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель листовой линейчатой оболочки. + \en Constructor of a sheet ruled shell. \~ + \details \ru Строитель оболочки по заданным контурам, соединением их линейчатой поверхностью и приданием толщины. \n + Второй контур и его локальная система координат могут отсутствовать, + в этом случае они создаются по параметрам операции - высоте и углу уклона. + Углы контуров скругляются радиусом, заданным в параметрах. + \en Constructor of a shell from the given contours by connecting them with a ruled surface and supplying with thickness. \n + The second contour and the local coordinate system can be absent, + in this case they are created from the parameters of the operation - the height and the slope angle. + Corners of the contours are rounded with the radius given as a parameter. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbRuledSolid : public MbCreator { +private: + MbRuledSolidValues parameters; ///< \ru Параметры операции. \en The operation parameters. + PArray bendParams; ///< \ru Параметры формируемых сгибов. \en Parameters of bends being formed. + +public : + MbRuledSolid( const MbRuledSolidValues & parameters, + const MbSNameMaker & nameMaker, + const PArray & bendParams ); + +private: + MbRuledSolid( const MbRuledSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbRuledSolid( const MbRuledSolid & ); + +public: + virtual ~MbRuledSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела. \en Common functions of solid. + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisItems( RPArray & s ); + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbRuledSolidValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbRuledSolidValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbRuledSolid & operator = ( const MbRuledSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRuledSolid ) +}; + +IMPL_PERSISTENT_OPS( MbRuledSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить линейчатую оболочку по контуру. + \en Create a ruled shell from the contour. \~ + \details \ru Построить листовую оболочку выдавливанием плоского контура с уклоном и приданием ему толщины.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a sheet shell by extruding of a planar contour with a slope and supplying it with thickness.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] parameters - \ru Параметры операции. + \en The operation parameters. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] resultBends - \ru Параметры и имена элементов сгиба. + \en Parameters and names of bend's elements. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateRuledSolid( MbRuledSolidValues & parameters, + const MbSNameMaker & operNames, + RPArray & resultBends, + MbContour *& resultContour, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_STAMP_RULED_SOLID_H diff --git a/C3d/Include/cr_stamp_solid.h b/C3d/Include/cr_stamp_solid.h new file mode 100644 index 0000000..5884f77 --- /dev/null +++ b/C3d/Include/cr_stamp_solid.h @@ -0,0 +1,147 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала штамповкой. + \en Constructor of a shell from the sheet material with stamping. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_SOLID_H +#define __CR_STAMP_SOLID_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbCurveBoundedSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала штамповкой. + \en Constructor of a shell from the sheet material with stamping. \~ + \details \ru Строитель оболочки из листового материала закрытой или открытой штамповкой. \n + Строятся штамповки двух типов: \n + закрытая - донышко штамповки закрыто листовым материалом, \n + открытая - когда лист пробит штамповкой насквозь. \n + \en Constructor of a shell from the sheet material by open or closed stamping. \n + Stamping of two types are constructed: \n + closed - bottom of stamping is closed by a sheet material, \n + open - when a sheet is punched through by stamping. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbStampSolid : public MbCreator { +private: + MbItemIndex faceIndex; ///< \ru Индекс грани, на которой строится штамповка. \en Index of the face the stamping is constructed on. + MbItemIndex pairFaceIndex; ///< \ru Индекс грани парной к грани штамповки. \en Index of the face which is pair to the stamp face. + MbCurveBoundedSurface * boundSurface; ///< \ru Поверхность, границами которой надо подрезать штамповку. \en Surface, by which bounds the stamp is cutted. + MbPlacement3D placement; ///< \ru Локальная система координат контура штамповки. \en The local coordinate system of contour of stamping. + MbContour contour; ///< \ru Контур донышка штамповки. \en Stamping bottom contour. + MbStampingValues parameters; ///< \ru Параметры штамповки. \en Stamping parameters. + double thickness; ///< \ru Толщина листа. \en The thickness of the sheet metal. + bool add; ///< \ru Создавать добавляемую или вычитаемую часть штамповки. \en Create additional or subtructional part of a stamp. + +public : + MbStampSolid( const MbItemIndex & faceIndex, + const MbItemIndex & pairFaceIndex, + const MbCurveBoundedSurface * boundSurface, + const MbPlacement3D & placement, + const MbContour & contour, + const MbStampingValues & params, + const double thickness, + const bool add, + const MbSNameMaker & names ); +private: + MbStampSolid( const MbStampSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbStampSolid( const MbStampSolid & ); + +public: + virtual ~MbStampSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties ( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray *items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbStampingValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbStampingValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbStampSolid & operator = ( const MbStampSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStampSolid ) +}; + +IMPL_PERSISTENT_OPS( MbStampSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала штамповкой. + \en Construct a shell form sheet material by stamping. \~ + \details \ru На базе исходной оболочки из листового материала построить оболочку методом закрытой или открытой штамповкой. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en A shell is to be constructed on the basis of the source shell by the method of closed or open stamping. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположен контур штамповки. + \en The local coordinate system in the XY plane of which the stamping contour is located. \~ + \param[in] contour - \ru Контур штамповки. + \en The stamping contour. \~ + \param[in] parameters - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateStamp( MbFaceShell * initialShell, // исходная оболочка + const MbeCopyMode sameShell, // флаг способа использования исходной оболочки + const MbFace * face, // грань штамповки + const MbPlacement3D & placement, // локальная система координат контура + const MbContour & contour, // контур штамповки + const MbStampingValues & params, // параметры штамповки + const double thickness, // толщина листа + const bool add, // создать добавляемую часть + MbSNameMaker & nameMaker, // именователь + MbResultType & res, // флаг успешности операции + SPtr & resultShell ); // результирующая оболочка + + +#endif // __CR_STAMP_SOLID_H diff --git a/C3d/Include/cr_stamp_spherical_solid.h b/C3d/Include/cr_stamp_spherical_solid.h new file mode 100644 index 0000000..773d3ef --- /dev/null +++ b/C3d/Include/cr_stamp_spherical_solid.h @@ -0,0 +1,147 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала сферической штамповкой. + \en Constructor of a shell from the sheet material with spherical stamping. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STAMP_SPHERICAL_SOLID_H +#define __CR_STAMP_SPHERICAL_SOLID_H + + +#include +#include +#include + + +class MATH_CLASS MbCurveBoundedSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала сферической штамповкой. + \en Constructor of a shell from the sheet material with spherical stamping. \~ + \details \ru Строитель оболочки из листового материала сферической штамповкой. \n + Строится только закрытая штамповка. \n + \en Constructor of a shell from the sheet material by spherical stamping. \n + Stamping of closed type only are constructed. \n + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSphericalStampSolid : public MbCreator { +private: + MbItemIndex faceIndex; ///< \ru Индекс грани, на которой строится штамповка. \en Index of the face the stamping is constructed on. + MbItemIndex pairFaceIndex; ///< \ru Индекс парной грани. \en Index of the pair face. + MbCurveBoundedSurface * boundSurface; ///< \ru Поверхность, границами которой надо подрезать штамповку. \en Surface, by which bounds the stamp is cutted. + MbPlacement3D placement; ///< \ru Локальная система координат контура штамповки. \en The local coordinate system of contour of stamping. + MbStampingValues parameters; ///< \ru Параметры штамповки. \en Stamping parameters. + double thickness; ///< \ru Толщина листа. \en Thickness of the plate. + bool add; ///< \ru Создавать добавляемую или вычитаемую часть штамповки. \en Create additional or subtructional part of a stamp. + MbCartPoint center; ///< \ru Центр донышка штамповки. \en Center of the bottom of the stamping. + +public : + MbSphericalStampSolid( const MbItemIndex & faceIndex, + const MbItemIndex & pairFaceIndex, + const MbCurveBoundedSurface * boundSurface, + const MbPlacement3D & placement, + const MbStampingValues & params, + const double thickness, + const bool add, + const MbCartPoint & center, + const MbSNameMaker & names ); +private: + MbSphericalStampSolid( const MbSphericalStampSolid &, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSphericalStampSolid( const MbSphericalStampSolid & ); + +public: + virtual ~MbSphericalStampSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties ( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray *items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( MbStampingValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbStampingValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbSphericalStampSolid & operator = ( const MbSphericalStampSolid & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSphericalStampSolid ) +}; + +IMPL_PERSISTENT_OPS( MbSphericalStampSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала со сферической штамповкой. + \en Construct a shell form sheet material by spherical stamping. \~ + \details \ru На базе исходной оболочки из листового материала построить оболочку методом сферической штамповки или части сферической штамповки без исходного листового тела. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en A shell is to be constructed on the basis of the source shell by the method of spherical stamping or parts of spherical stamp without the basis sheet solid. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] placement - \ru Локальная система координат, в плоскости XY которй расположен контур штамповки. + \en The local coordinate system in the XY plane of which the stamping contour is located. \~ + \param[in] parameters - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] thickness - \ru Толщина листа. + \en The thickness of the sheet solid. + \param[in] add - \ru Какую часть сферической штамповки создавать. + \en Which part of the spherical stamp to create. + \param[in] center - \ru Центр штамповки. + \en The center of the stamping. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSphericalStamp( MbFaceShell * solid, + const MbeCopyMode sameShell, + const MbFace * face, + const MbPlacement3D & placement, + const MbStampingValues & parameters, + const double thickness, + const bool add, + const MbCartPoint & center, + MbSNameMaker & operNames, + MbResultType & res, + SPtr & shell ); + + +#endif // __CR_STAMP_SPHERICAL_SOLID_H + diff --git a/C3d/Include/cr_stamp_user_solid.h b/C3d/Include/cr_stamp_user_solid.h new file mode 100644 index 0000000..a675b6d --- /dev/null +++ b/C3d/Include/cr_stamp_user_solid.h @@ -0,0 +1,141 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки из листового материала штамповкой телом-инструментом. + \en Constructor of a shell from the sheet material with stamping by a tool solid. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_USERSTAMP_SOLID_H +#define __CR_USERSTAMP_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки из листового материала штамповкой телом-инструментом. + \en Constructor of a shell from the sheet material with stamping by tool solid. \~ + \details \ru Строитель оболочки из листового материала закрытой или открытой штамповкой телом-инструментом. + Тело-инструмент может являться пуансоном или матрицей.\n + Строятся штамповки двух типов: \n + закрытая - не указаны вскрываемые грани тела-инструмента, \n + открытая - когда лист пробит штамповкой насквозь, указаны вскрываемые грани. \n + \en Constructor of a shell from the sheet material by open or closed stamping by tool solid. + The tool solid may be a punch or a die. \n + Stamping of two types are constructed: \n + closed - pierce faces of tool solid are not specified, \n + open - when a sheet is punched through by stamping, pierce faces of tool solid are specified. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbUserStampSolid : public MbCreator { +private: + MbItemIndex faceIndex; ///< \ru Индекс грани, на которой строится штамповка. \en Index of the face the stamping is constructed on. + MbItemIndex pairFaceIndex; ///< \ru Индекс грани парной к грани штамповки. \en Index of the face which is pair to the stamp face. + SArray pierceIndices; ///< \ru Индексы граней для вырубки. \en Face indicies for opening. + RPArray creators; ///< \ru Журнал построения оболочки тела-инструмента. \en History tree of the shell of the tool solid. + size_t countOne; ///< \ru Разделитель строителей тел-операндов. \en Separator of operand solids creators. + MbUserStampingValues parameters; ///< \ru Параметры штамповки. \en Stamping parameters. + double thickness; ///< \ru Толщина листа. \en The thickness of the sheet metal. + bool punch; ///< \ru Является тело-инструмент пуансоном или матрицей? \en Is tool body a punch or a die. + +public : + MbUserStampSolid( const RPArray & creatorsTool, + const bool sameTool, + const MbItemIndex & faceIndex, + const MbItemIndex & pairFaceIndex, + SArray & pierceIndices, + const MbUserStampingValues & params, + const double thickness, + const bool isPunch, + const MbSNameMaker & names ); +private: + MbUserStampSolid( const MbUserStampSolid &, MbRegDuplicate * iReg ); + +public: + virtual ~MbUserStampSolid(); + + // \ru Общие функции математического объекта. \en Common functions of the mathematical object. + + virtual MbeCreatorType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию. \en Create a copy. + + virtual bool IsSame ( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & item ) const; // \ru Являются ли объекты подобными? \en Determine whether an object is similar? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным. \en Make equal. + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties ( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties ( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта. \en Get a name of object property. + + // \ru Общие функции твердого тела. \en Common functions of solid. + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray *items = NULL ); // \ru Построение оболочки штамповки. \en Construction of a stamping shell. + + // \ru Получить параметры. \en Get the parameters. + void GetParameters( MbUserStampingValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const MbUserStampingValues & params ) { parameters = params; } + +private: + OBVIOUS_PRIVATE_COPY( MbUserStampSolid ) + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbUserStampSolid ) +}; + +IMPL_PERSISTENT_OPS( MbUserStampSolid ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку из листового материала штамповкой телом-инструментом. + \en Construct a shell form sheet material by tool body stamping. \~ + \details \ru На базе исходной оболочки из листового материала построить оболочку методом закрытой или открытой штамповки. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en A shell is to be constructed on the basis of the source shell by the method of closed or open stamping. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] face - \ru Грань штамповки. + \en The face for stamping. \~ + \param[in] toolSolid - \ru Оболочка тела-инструмента. + \en A shell of tool solid. \~ + \param[in] sameShellTool - \ru Режим копирования оболочки тела-инструмента. + \en Mode of copying the tool shell. \~ + \param[in] punch - \ru Является тело-инструмент пуансоном или матрицей. + \en Is tool body a punch or a die. \~ + \param[in] pierceFaces - \ru Вскрываемые для вырубки грани инструмента, + \en Pierce faces of tool body. \~ + \param[in] params - \ru Параметры штамповки. + \en The parameters of stamping. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[out] result - \ru Результирующее тело. + \en The resultant solid. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateUserStamp( MbFaceShell & initialShell, // Исходная оболочка, + const MbeCopyMode sameShell, // флаг способа использования исходной оболочки, + const MbFace & targetFace, // грань штамповки, + const RPArray & creatorsTool, // журнал построения инструмента, + MbFaceShell & toolShell, // оболочка тела-инструмента, + const MbeCopyMode sameShellTool, // флаг способа использования оболочки инструмента, + bool isPunch, // является инструмент пуансоном или матрицей, + const RPArray & pierceFaces, // вскрываемые для вырубки грани инструмента, + const MbUserStampingValues & params, // параметры штамповки, + const MbSNameMaker & nameMaker, // именователь, + MbResultType & res, // флаг успешности операции, + SPtr & resultShell ); // результирующая оболочка. + + +#endif // __CR_USERSTAMP_SOLID_H diff --git a/C3d/Include/cr_stitch_solid.h b/C3d/Include/cr_stitch_solid.h new file mode 100644 index 0000000..cbd268a --- /dev/null +++ b/C3d/Include/cr_stitch_solid.h @@ -0,0 +1,225 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки путём сшивки граней. + \en Constructor of a shell by stitching the faces. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_STITCH_SOLID_H +#define __CR_STITCH_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки путём сшивки граней. + \en Constructor of a shell by stitching the faces. \~ + \details \ru Строитель оболочки путём сшивки граней. \n + Операция принимает в качестве исходных данных незамкнутые оболочки и отдельные грани, + ищет среди их граничных рёбер совпадающие полностью или частично и "сшивает" их, т.е. + устанавливает связи между гранями, рёбрами и вершинами. В ходе выполнения операции рёбра + и вершины уточняются при необходимости путём пересечения стыкующихся граней. Алгоритм работы + следующий:\n + 1. Для каждой вершины насчитывается габарит, в котором будет осуществляться поиск совпадающих вершин. + Этот габарит зависит от длин стыкующихся в ней рёбер и от толщины тонкой стенки, если такая ситуация обнаружена.\n + 2. С помощью насчитанных габаритов все вершины разбиваются на группы, каждая из которых сформирует одну + вершину результата.\n + 3. Все рёбра разбиваются на группы с одинаковыми конечными группами вершин.\n + 4. В каждой группе рёбер ищутся пары совпадающих с заданной точностью рёбер.\n + 5. Каждое непарное ребро разбивается лежащими на нём вершинами, и для них повторяются пункты с 1 по 4.\n + 6. С помощью пересечений стыкующихся граней парные рёбра уточняются и сшиваются, а каждая группа вершин + заменяется одной вершиной. + \en Constructor of a shell by stitching the faces. \n + The operation takes open shells and separate faces as input data, + and looks for the entirely or partially coincident edges among their boundary edges and "stitches" them, i.e. + makes associations between faces, edges and vertices. During the operation edges + and vertices can be defined more precisely by intersection of adjacent faces if necessary. The algorithm + is the following:\n + 1. For each vertex the bounding box is calculated in which the search of the coincident vertices will be performed. + This bounding box depends on the length of the edges adjacent to the vertex and on thickness of the thin wall if such a situation is detected.\n + 2. Using the calculated bounding boxes all the vertices are subdivided into the groups each of which will form a single + resultant vertex.\n + 3. All the edges are divided into groups with similar resultant groups of vertices.\n + 4. In each group of edges pairs of edges coincident with the given tolerance are searched for.\n + 5. Each unpaired edge is split by vertices lying on it, and pt.1 to 4 are repeated for them.\n + 6. Using intersections of adjacent faces paired edges are refined and stitched, and each group of vertices + is replaced with a single vertex. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbStitchedSolid : public MbCreator { +private: + PArray< RPArray > creatorsArray; ///< \ru Множества строителей для каждой сшиваемой оболочки. \en Set of creators for each shell being stitched. + bool formSolidBody; ///< \ru Флаг необходимости формирования замкнутой оболочки. \en Whether to construct a closed shell. + double stitchPrecision; ///< \ru Максимально допустимое расстояние между сшиваемыми рёбрами. \en Maximal acceptable distance between edges being stitched. + +public : + template + MbStitchedSolid( const PArray & creatorsData, + bool tryClosed, + double precision, + const MbSNameMaker & names ) + : MbCreator( names ) + , creatorsArray( creatorsData.size(), 1, true ) + , formSolidBody( tryClosed ) + , stitchPrecision( precision ) + { + size_t i, setsCnt = creatorsData.size(); + + c3d::CreatorsSPtrVector simpleCreators; + { + size_t estSimpleCnt = 0; + for ( i = 0; i < setsCnt; ++i ) { + Creators * creatorsSet = creatorsData[i]; + if ( creatorsSet != NULL ) { + size_t count = creatorsSet->size(); + for ( size_t j = 0; j < count; ++j ) { + MbCreator * creator = (*creatorsSet)[j]; + if ( creator != NULL ) + estSimpleCnt += creator->GetCreatorsCount( ct_SimpleCreator ); + } + } + } + simpleCreators.reserve( estSimpleCnt ); + } + + SPtr creator; + for ( i = 0; i < setsCnt; ++i ) { + Creators * creatorsSet = creatorsData[i]; + if ( creatorsSet != NULL ) { + size_t count = creatorsSet->size(); + RPArray * creators = new RPArray( count, 1 ); + creatorsArray.push_back( creators ); + for ( size_t j = 0; j < count; ++j ) { // важен порядок перебора + creator = (*creatorsSet)[j]; + if ( creator != NULL ) { + creators->push_back( creator ); + if ( creator->IsA() == ct_SimpleCreator ) + simpleCreators.push_back( creator ); + else { + creator->SetInternalCreators( ct_SimpleCreator, simpleCreators ); + } + creator->AddRef(); + } + } + } + } + if ( !simpleCreators.empty() ) { + MbSimpleCreator::DeleteShellCopies( simpleCreators ); + } + } +private: + MbStitchedSolid( const MbStitchedSolid & init, + MbRegDuplicate * ireg ); + +public: + virtual ~MbStitchedSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, + MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual void SetYourVersion( VERSION version, bool forAll ); + +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbStitchedSolid( const MbStitchedSolid & ); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbStitchedSolid & operator = ( const MbStitchedSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbStitchedSolid ) +}; + +IMPL_PERSISTENT_OPS( MbStitchedSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построение оболочки сшивки. + \en Construction of a shell of stitching. \~ + \details \ru Построение оболочки сшивки. \n + \en Construction of a shell of stitching. \n \~ + \param[in] initialShells - \ru Множество оболочек для сшивки. + \en A set of shells for stitching. \~ + \param[in] formSolidBody - \ru Создавать тело? + \en Whether to create a solid. \~ + \param[in] stitchPrecision - \ru Максимально допустимое расстояние между сшиваемыми рёбрами. + \en Maximal acceptable distance between edges being stitched. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \result \ru Возвращает построенную оболочку, если операция была выполнена успешно. + \en Returns the constructed shell if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbFaceShell *) CreateStitchShell( const RPArray & initialShells, + bool formSolidBody, + double stitchPrecision, + const MbSNameMaker & operNames, + MbeStitchResType & res ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку путём сшивки граней. + \en Create a shell by faces stitching. \~ + \details \ru Создание строителя сшитого тела.\n + \en Creation of a stitched solid creator.\n \~ + \details \ru Построить оболочку путём сшивки граней исходных оболочек и множеств граней. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell by stitching faces of the source shells and sets of faces. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] creatorsArray - \ru Множества строителей для сшиваемых оболочек. + \en Sets of creator for stitched shells. \~ + \param[in] shells - \ru Множества сшиваемых оболочек. + \en Sets of shells to stitch. \~ + \param[in] formSolidBody - \ru Флаг необходимости формирования замкнутой оболочки. + \en Whether to create a closed shell. \~ + \param[in] stitchPrecision - \ru Максимально допустимое расстояние между сшиваемыми рёбрами. + \en Maximal acceptable distance between edges being stitched. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] resultShell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateStitchedSolid( const PArray< RPArray > & creatorsArray, + const RPArray & shells, + bool formSolidBody, + double stitchPrecision, + const MbSNameMaker & operNames, + MbeStitchResType & res, + MbFaceShell *& resultShell ); + + +#endif // __CR_STITCH_SOLID_H \ No newline at end of file diff --git a/C3d/Include/cr_surface_spline.h b/C3d/Include/cr_surface_spline.h new file mode 100644 index 0000000..8b95545 --- /dev/null +++ b/C3d/Include/cr_surface_spline.h @@ -0,0 +1,141 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель сплайна на поверхности по точками. + \en Constructor of spline on a surface by points. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SURFACE_SPLINE_H +#define __CR_SURFACE_SPLINE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель пространственного сплайна. + \en Spatial spline constructor. \~ + \details \ru Строитель пространственного сплайна.\n + \en Spatial spline constructor.\n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSurfaceSplineCreator : public MbCreator { +private: + MbSurface * surface; // \ru Поверхность \en Surface + bool throughPnts; // \ru через точки \en Through points + SArray paramPnts; // \ru Параметрические точки \en Parametric points + SArray paramWts; // \ru Веса параметрических точек \en Parametric points weights + bool paramClosed; // \ru Замкнуть параметрический сплайн \en Make the parametric spline close + RPArray< MbPntMatingData > spaceTransitions; // \ru Сопряжения в точках \en Tangents at the points + +protected: + MbSurfaceSplineCreator( const MbSurfaceSplineCreator &, MbRegDuplicate * iReg ); // \ru Конструктор копирования \en Copy-constructor + MbSurfaceSplineCreator( const MbSurfaceSplineCreator & ); // \ru Не реализовано \en Not implemented + MbSurfaceSplineCreator(); // \ru Не реализовано \en Not implemented + +public: + MbSurfaceSplineCreator( const MbSurface &, bool sameSurf, bool thrPnts, + const SArray & pnts, + const SArray & wts, bool parCls, + RPArray< MbPntMatingData > & transitions, + const MbSNameMaker & snMaker ); +public : + virtual ~MbSurfaceSplineCreator(); + + // \ru Общие функции строителя. \en The common functions of the creator. + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual bool IsSame ( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual MbePrompt GetPropertyName(); // \ru Дать имя свойства объекта \en Get the object property name + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Построить кривую по журналу построения \en Create a curve from the history tree + virtual bool CreateWireFrame( MbWireFrame *&, MbeCopyMode, RPArray * items = NULL ); + + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbSurfaceSplineCreator & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSurfaceSplineCreator ) +}; + +IMPL_PERSISTENT_OPS( MbSurfaceSplineCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кривую на поверхности. + \en Create a curve on a surface. \~ + \details \ru Создать кривую на поверхности. \n + Примечания: \n + 1. Если есть сопряжения, то количество сопряжений д.б. равно количеству точек. \n + Отсутствующие сопряжения должны быть представлены нулевыми указателями в массиве \n + 2. Если сплайн строится через точки, то сопряжения могуть быть заданы произвольно. \n + 2. Если сплайн строится по полюсам и он незамкнут, то сопряжения могут быть только на концах. \n + 3. Если сплайн строится по полюсам и он замкнут, то сопряжения должны отсутствовать. \n + 4. Множество весов д.б. пуст или синхронизирован с массивом точек по количеству (с опцией throughPoints веса игнорируются). \n + \en Create a curve on a surface. \n + Notes: \n + 1. If the tangents are specified, then the number of tangents should be equal to the number of points. \n + Missing tangents should be represented by null pointers in the array \n + 2. If the spline is created from points, arbitrary tangents can be defined. \n + 2. If the spline is created from poles and it is open, only the end tangents can be specified. \n + 3. If the spline is constructed from poles and it is closed, the tangents cannot be specified. \n + 4. The weight array should be empty or synchronized with the point array by size (with option throughPoints the weights are ignored). \n \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] throughPoints - \ru Провести сплайн через точки. + \en Create a spline through points. \~ + \param[in] paramPnts - \ru Множество параметрических точкек. + \en Parametric point array. \~ + \param[in] paramWts - \ru Множество весов параметрических точек. + \en An array of parametric point weights. \~ + \param[in] paramClosed - \ru Строить замкнутый параметрический сплайн. + \en Create a closed parametric spline. \~ + \param[in] spaceTransitions - \ru Сопряжения в точках. + \en Tangents at the points. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[out] resType - \ru Код результата операции + \en Operation result code \~ + \param[out] resCurves - \ru Множество эквидистантных кривых. + \en Offset curve array. \~ + \return \ru Возвращает строитель. + \en Returns the constructor. \~ + \ingroup Curve3D_Modeling +*/ +//--- +MATH_FUNC (MbCreator *) CreateSurfaceSpline( const MbSurface & surface, + bool throughPoints, + SArray & paramPnts, + SArray & paramWts, + bool paramClosed, + RPArray< MbPntMatingData > & spaceTransitions, + const MbSNameMaker & snMaker, + MbResultType & resType, + RPArray & resCurves ); + + +#endif // __CR_SURFACE_SPLINE_H diff --git a/C3d/Include/cr_swept_solid.h b/C3d/Include/cr_swept_solid.h new file mode 100644 index 0000000..bcd499c --- /dev/null +++ b/C3d/Include/cr_swept_solid.h @@ -0,0 +1,122 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель оболочки тела формообразующей операции. + \en Constructor of a solid's shell of forming operation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SWEPT_SOLID_H +#define __CR_SWEPT_SOLID_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки тела по формообразующим кривым. + \en Constructor a solid's shell by forming curves. \~ + \details \ru Строитель оболочки тела, заданного формообразующими кривыми. \n + \en Constructor a shell of a solid specified by forming curves. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCurveSweptSolid : public MbCreator { +protected : + RPArray faceNames; ///< \ru Именователи граней. \en An object for naming faces. + RPArray creators; ///< \ru Построители тела, используемого в опции "До ближайшего объекта". \en Creators of a solid used with option "To the nearest object (solid)". + OperationType operation; ///< \ru Тип булевой операции над оболочками. \en Type of Boolean operation on shells. + double buildSag; ///< \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + +protected : + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. + \en Constructor. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] fNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] creators - \ru Построители тела, используемого в опции "До ближайшего объекта". + \en Creators of a solid used with option "To the nearest object (solid)". \~ + \param[in] sameCreators - \ru Признак использования оригиналов построителей. + \en Flag of using the original creators. \~ + */ + MbCurveSweptSolid( const MbSNameMaker & operNames, + const RPArray & fNames, + OperationType oType, + const c3d::CreatorsSPtrVector * creators, + bool sameCreators = false ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. + \en Constructor. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] fNames - \ru Именователи граней. + \en An object for naming faces. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + */ + MbCurveSweptSolid( const MbSNameMaker & operNames, + const MbSNameMaker & fNames, + OperationType oType ); + + /// \ru Конструктор копии. \en Copy-constructor. + MbCurveSweptSolid( const MbCurveSweptSolid & init, MbRegDuplicate * ); +public : + virtual ~MbCurveSweptSolid(); + + /** \ru \name Общие функции математического объекта. + \en \name Common functions of the mathematical object. + \{ */ + virtual MbeCreatorType IsA() const = 0; // \ru Тип элемента \en A type of element + virtual MbeCreatorType Type() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual bool IsSame( const MbCreator &, double accuracy ) const = 0; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const = 0; // \ru Являются ли объекты подобными. \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ) = 0; // \ru Сделать равным \en Make equal + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName() = 0; // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + /** \} */ + /** \ru \name Общие функции твердого тела (формообразующей операции). + \en \name Common functions of the rigid solid (forming operations). + \{ */ + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual MbFaceShell * InitShell( bool in ) = 0; + virtual void InitBasis( RPArray & ) = 0; + virtual bool GetPlacement( MbPlacement3D & ) const = 0; + virtual void SetYourVersion( VERSION version, bool forAll ); + void SetOperation( OperationType op ) { operation = op; } + /** \} */ +protected : + /// \ru Удалить строители ближайшего тела. \en Delete internal creators. + void DeleteCreators(); +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCurveSweptSolid & ); + + DECLARE_PERSISTENT_CLASS( MbCurveSweptSolid ) +}; // MbCurveSweptSolid + +IMPL_PERSISTENT_OPS( MbCurveSweptSolid ) + +#endif // __CR_SWEPT_SOLID_H diff --git a/C3d/Include/cr_symmetry_solid.h b/C3d/Include/cr_symmetry_solid.h new file mode 100644 index 0000000..0044ef6 --- /dev/null +++ b/C3d/Include/cr_symmetry_solid.h @@ -0,0 +1,119 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель симметричного тела. + \en Constructor of a symmetric solid. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_SYMMETRY_SOLID_H +#define __CR_SYMMETRY_SOLID_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель симметричного тела. + \en Constructor of a symmetric solid. \~ + \details \ru Строитель симметричного тела разрезает тело плоскостью на две части, удаляет одну из них, + для оставшейся части строит симметричную относительно плоскости копию и склеивает её с оставшейся частью. + \en Constructor of a symmetric solid cuts a solid by a plane onto to parts, deletes one of them, + for the remained part it builds a copy symmetric relative to the plane and glues it with the remained part. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbSymmetrySolid : public MbCreator { +protected : + MbCartPoint3D origin; ///< \ru Начало плоскости симметрии. \en Symmetry plane origin. + MbVector3D axisX; ///< \ru Ось плоскости симметрии. \en Symmetry plane axis. + MbVector3D axisY; ///< \ru Ось плоскости симметрии. \en Symmetry plane axis. + int side; ///< \ru Оставляемая часть (если side>0, то оставляем часть тела со стороны нормали плоскости симметрии). \en Remained part (if side>0, then a part of solid from the side of symmetric plane's normal is to be remained). + double buildSag; ///< \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + +public : + MbSymmetrySolid( const MbCartPoint3D & p, const MbVector3D & ax, const MbVector3D & ay, + int s, const MbSNameMaker & n ); +private : + MbSymmetrySolid( const MbSymmetrySolid & init, MbRegDuplicate * iReg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSymmetrySolid( const MbSymmetrySolid & init ); +public : + virtual ~MbSymmetrySolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbSymmetrySolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSymmetrySolid ) +}; // MbSymmetrySolid + +IMPL_PERSISTENT_OPS( MbSymmetrySolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать симметричную оболочку. + \en Create a symmetric shell. \~ + \details \ru Для указанной оболочки построить симметричную относительно указанной плоскости оболочку. + функция разрезает оболочку плоскостью на две части, удаляет одну из них, + для оставшейся части строит симметричную относительно плоскости копию и склеивает её с оставшейся частью. \n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell build a shell symmetric relative to the specified plane. + the function cuts the shell by the plane onto two parts, deletes one of them, + for the remained part it builds a copy symmetric relative to the plane and glues it with the remained part. \n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Способ копирования граней исходной оболочки. + \en Method of copying the source shell faces. \~ + \param[in] origin - \ru Точка плоскости симметрии. + \en A point of plane of symmetry. \~ + \param[in] axisX - \ru Первая ось плоскости симметрии. + \en The first axis of symmetry. \~ + \param[in] axisY - \ru Вторая ось плоскости симметрии. + \en The second axis of symmetry. \~ + \param[in] side - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateSymmetry( MbFaceShell * solid, + MbeCopyMode sameShell, + const MbCartPoint3D & origin, + const MbVector3D & axisX, + const MbVector3D & axisY, + int side, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_SYMMETRY_SOLID_H diff --git a/C3d/Include/cr_thin_sheet.h b/C3d/Include/cr_thin_sheet.h new file mode 100644 index 0000000..c6bf0d3 --- /dev/null +++ b/C3d/Include/cr_thin_sheet.h @@ -0,0 +1,181 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение оболочки по поверхности. + \en Construction of a shell from a surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_THIN_SHEET_H +#define __CR_THIN_SHEET_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель оболочки по поверхности. + \en Constructor of a shell from a surface. \~ + \details \ru Строитель создаёт оболочку по заданной поверхности приданием ей толщины. \n + \en The constructor creates a shell from a given surface by supplying it with a thickness. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbThinShellCreator : public MbCreator { +protected : + MbSurface * surface; ///< \ru Поверхность. \en Surfaces. + bool sameSense; ///< \ru Совпадение нормали основной ргани оболочки и поверхности. \en Coincidence of the normal to the basic face of a shell and the normal to the surface. + SweptValues parameters; ///< \ru Параметры построения. \en Construction parameters. + SimpleName name; ///< \ru Имя операции. \en Operation name. + +public : + MbThinShellCreator( const MbSurface & surf, bool sense, SweptValues p, + bool same, const MbSNameMaker & n, SimpleName & m ); +private : + MbThinShellCreator( const MbThinShellCreator &, MbRegDuplicate *ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbThinShellCreator( const MbThinShellCreator & ); +public : + virtual ~MbThinShellCreator(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid solid + + virtual bool CreateShell( MbFaceShell *&shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( SweptValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const SweptValues & params ) { parameters = params; } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbThinShellCreator & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbThinShellCreator ) +}; // MbThinShellCreator + +IMPL_PERSISTENT_OPS( MbThinShellCreator ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку по поверхности. + \en Construct a shell from a surface. \~ + \details \ru Построить оболочку по заданной поверхности приданием ей толщины. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from a given surface by thickening. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] surface - \ru Исходная поверхность. + \en The initial surface. \~ + \param[in] sense - \ru Признак совпадения нормали основной ргани оболочки и поверхности. + \en Flag of coincidence of the normal to the basic face of the shell and to the surface. \~ + \param[in] parameters - \ru Параметры построения оболочки. + \en The shell construction parameters. \~ + \param[in] same - \ru Признак не копировать поверхность. + \en Not to copy the surface. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] name - \ru Имя операции. + \en Operation name. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateThinShell( const MbSurface & surface, + bool sense, + const SweptValues & parameters, + bool same, + const MbSNameMaker & operNames, + SimpleName & name, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку по наборам точек. + \en Construct a shell from point sets. \~ + \details \ru Построить оболочку по заданным наборам точек. По заданным наборам точек строятся кривые, по кривым создаётся + поверхность MbLoftedSurface, которой придаётся толщина. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from given point sets. The curves are created from the given sets of points, from these curves the surface + MbLoftedSurface with a certain thickness is created. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] points - \ru Исходные наборы точек. + \en Initial point sets. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] name - \ru Имя операции. + \en Operation name. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateLoftedShell( const RPArray< SArray > & points, + const MbSNameMaker & operNames, + SimpleName & name, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить оболочку по кривым. + \en Construct a shell from curves. \~ + \details \ru Построить оболочку по заданным кривым. По заданным кривым создаётся + поверхность MbLoftedSurface, которой придаётся толщина. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a shell from given curves. A surface MbLoftedSurface is created from the given curves, + and it is supplied with a thickness. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] curves - \ru Исходные кривые. + \en Initial curves. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] name - \ru Имя операции. + \en Operation name. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateLoftedShell( const RPArray & curves, + const MbSNameMaker & operNames, + SimpleName & name, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_THIN_SHEET_H diff --git a/C3d/Include/cr_thin_shell_solid.h b/C3d/Include/cr_thin_shell_solid.h new file mode 100644 index 0000000..564eb75 --- /dev/null +++ b/C3d/Include/cr_thin_shell_solid.h @@ -0,0 +1,225 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель эквидистантной оболочки. + \en Constructor of an offset shell. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_THIN_SHELL_SOLID_H +#define __CR_THIN_SHELL_SOLID_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель эквидистантной оболочки. + \en Constructor of an offset shell. \~ + \details \ru Строитель эквидистантной оболочки предназначен для выполнения следующих операций: + эквидистантная оболочка, тонкостенное тело, придание толщины. \n + Условия построения эквидистантной оболочки: исходная оболочка не замкнута, конечная оболочка замкнута. + Условия построения тонкостенного тела: исходная оболочка замкнута, конечная оболочка замкнута. + Условия построения придания толщины: исходная оболочка незамкнута, конечная оболочка замкнута. \n + Построение тонкостенного тела и придания толщины упрощенно можно описать следующим образом: \n + у заданного тела удалим указанные грани, а оставшимся граням придадим конечную толщину. \n + Придание конечной толщины граням достигнем путем построения к оставшейся после удаления указанных граней + незамкнутой оболочке эквидистантной оболочки и соединения этих незамкнутых оболочек частями удаленных граней + (тонкостенное тело) или новыми гранями (придание толщины). \n + \en Constructor of an offset shell is intended for performing the following operations: + offset shell, thin-walled solid, thickening. \n + Conditions of the offset shell construction: the source shell is not closed, the resultant shell is closed. + Conditions of a thin-walled solid construction: the source shell is closed, the resultant shell is closed. + Conditions of thickening construction: the source shell is not closed, the resultant shell is closed. \n + Construction of a thin-walled solid and thickening can be simply described in the following way: \n + delete the specified faces from the given solid and supply the remained faces with a finite thickness. \n + Supplying the faces with a thickness is performed by construction the offset shell to the open shell + remained after deletion of the specified faces and by connection of these open shells with parts of deleted faces + (thin-walled solid) or new faces (thickening). \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbShellSolid : public MbCreator { +protected : + SweptValues parameters; ///< \ru Общее эквидистантное смещение от исходной оболочки и замкнутость результирующей оболочки. \en The common offset distance from the source shell and closedness of the resultant shell. + SArray outIndices; ///< \ru Номера вскрываемых граней. \en Indices of faces to open. + SArray offIndParams; ///< \ru Номера граней и их индивидуальные эквидистантные смещения. \en Indices of faces and their unique offset distances. + bool copyAttributes; ///< \ru Копировать атрибуты из исходных граней в эквидистантные. \en Copy attributes of initial faces to offset faces. \~ + +public : + /// \ru Конструктор с общим эквидистантным смещением граней. \en Constructor with the common offset distance of the faces. + MbShellSolid( const SweptValues & p, SArray & outInds, + const MbSNameMaker & n, bool copyFaceAttrs ); + /// \ru Конструктор с индивидуальными эквидистантными смещениям граней. \en Constructor with the unique offset distance of the faces. + MbShellSolid( const SweptValues & p, SArray & outInds, SArray & offIndPars, + const MbSNameMaker & n, bool copyFaceAttrs ); + /// \ru Деструктор. \en Destructor. + virtual ~MbShellSolid(); +private : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbShellSolid( const MbShellSolid &, MbRegDuplicate * ); +public : + // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + + // \ru Общие функции твердого тела \en Common functions of solid + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + /// \ru Дать параметры. \en Get the parameters. + void GetParameters( SweptValues & params ) const { params = parameters; } + /// \ru Установить параметры. \en Set the parameters. + void SetParameters( const SweptValues & params ) { parameters = params; } + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbShellSolid ) +OBVIOUS_PRIVATE_COPY( MbShellSolid ) +}; // MbShellSolid + +IMPL_PERSISTENT_OPS( MbShellSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную оболочку с общим эквидистантным смещением. + \en Create an offset shell with the common offset distance. \~ + \details \ru Для указанной оболочки построить эквидистантную оболочку (тонкостенное тело, придание толщины), + удалив указанные грани, построив эквидистантные грани для оставшихся граней, + и соединив две полученные незамкнутые оболочки частями удалённых граней или новыми гранями. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en For the given shell construct an offset shell (thin-walled solid, thickening) + by deletion the specified faces and construction the offset faces for the remained faces + and connecting two obtained open shells with parts of deleted faces or with new faces. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Общее эквидистантное смещение от исходной оболочки и замкнутость результирующей оболочки. + \en The common offset distance from the source shell and closedness of the resultant shell. \~ + \param[in] outFaces - \ru Вскрываемые грани. + \en Faces to open. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Результирующая оболочка. + \en The required shell. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateThinShelling( MbFaceShell * solid, + MbeCopyMode sameShell, + SweptValues & parameters, + RPArray & outFaces, + const MbSNameMaker & names, // \ru Используется только для главного имени \en Used for the main name only. + bool copyFaceAttrs, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать эквидистантную оболочку с индивидуальными эквидистантными смещениями. + \en Create an offset shell with unique offset distance. \~ + \details \ru Для указанной оболочки построить эквидистантную оболочку (тонкостенное тело, придание толщины), + удалив указанные грани, построив эквидистантные грани для оставшихся граней, + и соединив две полученные незамкнутые оболочки частями удалённых граней или новыми гранями. \n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en For the given shell construct an offset shell (thin-walled solid, thickening) + by deletion the specified faces and construction the offset faces for the remained faces + and connecting two obtained open shells with parts of deleted faces or with new faces. \n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Общее эквидистантное смещение от исходной оболочки и замкнутость результирующей оболочки. + \en The common offset distance from the source shell and closedness of the resultant shell. \~ + \param[in] outFaces - \ru Вскрываемые грани. + \en Faces to open. \~ + \param[in] offFaces - \ru Грани с индивидуальными эквидистантными смещениям. + \en Faces with unique offset distance. \~ + \param[in] offDists - \ru Индивидуальные эквидистантные смещения. + \en Unique offset distances. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Результирующая оболочка. + \en The required shell. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateThinShelling( MbFaceShell * solid, + MbeCopyMode sameShell, + SweptValues & parameters, + RPArray & outFaces, + RPArray & offFaces, + SArray & offDists, + const MbSNameMaker & names, // \ru Используется только для главного имени \en Used for the main name only. + bool copyFaceAttrs, + MbResultType & res, + MbFaceShell *& shell ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить эквидистантную оболочку. + \en Construct an offset shell. \~ + \details \ru Для указанной оболочки построить эквидистантную оболочку (тонкостенное тело, придание толщины), + удалив указанные грани, построив эквидистантные грани для оставшихся граней, + и соединив две полученные незамкнутые оболочки частями удалённых граней или новыми гранями. \n + \en For the given shell construct an offset shell (thin-walled solid, thickening) + by deletion the specified faces and construction the offset faces for the remained faces + and connecting two obtained open shells with parts of deleted faces or with new faces. \n \~ + \param[in] solid - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Общее эквидистантное смещение от исходной оболочки и замкнутость результирующей оболочки. + \en The common offset distance from the source shell and closedness of the resultant shell. \~ + \param[in] outInds - \ru Номера вскрываемых граней. + \en Indices of faces to open. \~ + \param[in] offIndPars - \ru Номера граней и их индивидуальные эквидистантные смещения. + \en Indices of faces and their unique offset distances. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] copyFaceAttrs - \ru Копировать атрибуты из исходных граней в эквидистантные. + \en Copy attributes of initial faces to offset faces. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \result \ru Возвращает построенную оболочку, если операция была выполнена успешно. + \en Returns the constructed shell if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbFaceShell *) MakeThinShell( MbFaceShell & solid, + MbeCopyMode sameShell, + const SweptValues & parameters, + SArray & outInds, + SArray & offIndPars, + const MbSNameMaker & names, + bool copyFaceAttrs, + MbResultType & res ); + + +#endif // __CR_THIN_SHELL_SOLID_H diff --git a/C3d/Include/cr_transformed_solid.h b/C3d/Include/cr_transformed_solid.h new file mode 100644 index 0000000..7863eb7 --- /dev/null +++ b/C3d/Include/cr_transformed_solid.h @@ -0,0 +1,114 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель трансформируемой оболочки. + \en Constructor of a transformed shell. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_TRANSFORMED_SOLID_H +#define __CR_TRANSFORMED_SOLID_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель трансформируемой оболочки. + \en Constructor of a transformed shell. \~ + \details \ru Строитель трансформируемой оболочки, матрица преобразования которой + получена по изменению положения контрольных точек габаритного куба. \n + \en Constructor of a transformed shell the transformation matrix of which + is obtained due to the change of bounding box control points positions. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbTransformedSolid : public MbCreator { +protected: + TransformValues parameters; ///< \ru Параметры преобразования оболочки. \en Parameters of a shell transformation. + MbCube cube; ///< \ru Габаритный куб. \en Bounding box. + SArray cubePoints; ///< \ru Контрольные точки куба. \en Control points of the bounding box. + +public: // \ru Конструктор по параметрам \en Constructor by parameters + MbTransformedSolid( const TransformValues &, const MbCube &, const MbSNameMaker & ); +private: // \ru Конструктор дублирующий \en Duplication constructor + MbTransformedSolid( const MbTransformedSolid &, MbRegDuplicate * ireg ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbTransformedSolid( const MbTransformedSolid & ); + +public: // \ru Деструктор \en Destructor + ~MbTransformedSolid(); + +public: // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + virtual bool IsSame( const MbCreator & other, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать по матрице \en Transform according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг по вектору \en Translation by a vector + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /// \ru Построение оболочки \en Creation of a shell + virtual bool CreateShell( MbFaceShell *&, MbeCopyMode sameShell, + RPArray * items = NULL ); + virtual void Refresh( MbFaceShell & ); ///< \ru Обновить форму оболочки \en Update shape of the shell + // \ru Добавить модификацию по матрице \en Add a modification by a matrix + void AddMatrix( MbFaceShell &, const MbMatrix3D & ); + + // \ru Дать параметры. \en Get the parameters. + void GetParameters( TransformValues & params ) const { params = parameters; } + // \ru Установить параметры. \en Set the parameters. + void SetParameters( const TransformValues & params ) { parameters = params; } + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbTransformedSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTransformedSolid ) +}; + +IMPL_PERSISTENT_OPS( MbTransformedSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создание строителя масштабированной оболочки. + \en Creation of constructor of a scaled shell. \~ + \details \ru Построить оболочку путём трансформации исходной оболочки по матрице преобразования, + полученной по изменению положения контрольных точек габаритного куба.\n + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Create a shell by transformation of the source shell according to the transformation matrix + obtained due to the change of the bounding box control points positions.\n + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] outer - \ru Исходная оболочка. + \en The source shell. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the source shell. \~ + \param[in] parameters - \ru Параметры модификации. + \en Parameters of the modification. \~ + \param[in] names - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции выдавливания. + \en The extrusion operation result code. \~ + \param[out] shell - \ru Построенная оболочка. + \en The resultant shell. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateTransformedSolid( MbFaceShell * outer, + MbeCopyMode sameShell, + const TransformValues & parameters, + const MbSNameMaker & names, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_TRANSFORMED_SOLID_H diff --git a/C3d/Include/cr_truncated_shell.h b/C3d/Include/cr_truncated_shell.h new file mode 100644 index 0000000..c40689e --- /dev/null +++ b/C3d/Include/cr_truncated_shell.h @@ -0,0 +1,156 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение усеченной оболочки. + \en Construction of a truncated shell. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TRUNCATED_SHELL_H +#define __TRUNCATED_SHELL_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbSpaceItem; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; +struct MATH_CLASS MbMergingFlags; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель усеченной оболочки. + \en Constructor of a truncated shell. \~ + \details \ru Строитель усеченной оболочки режет исходную оболочку на части указанными элементами, + которыми могут служить двумерные кривые в локальной системе координат, трёхмерные кривые, поверхности и оболочки. \n + \en Constructor of a truncated shell cuts the initial shell into parts by the specified elements + which can be two-dimensional curves in the local coordinate system, three-dimensional curves, surfaces and shells. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbTruncatedShell : public MbCreator { +private : + std::vector selIndices; ///< \ru Идентификаторы выбранных граней усекаемой оболочки. \en Identifiers of selected faces of the shell being truncated. + MbSplitData splitItems; ///< \ru Усекающие элементы c ориентациями. \en Truncating elements with orientations. + SArray orients; ///< \ru Ориентация усекающих элементов. \en Orientation of truncating elements. + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool mergeEdges; ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). + +public: + /// \ru Конструктор по двумерным кривым. \en Constructor by two-dimensional curves. + MbTruncatedShell( const MbPlacement3D &, const RPArray &, bool same, + const SArray & orients, const MbMergingFlags &, const MbSNameMaker & ); + /// \ru Конструктор по трехмерным кривым. \en Constructor by three-dimensional curves. + MbTruncatedShell( const RPArray &, bool same, + const SArray & orients, const MbMergingFlags &, const MbSNameMaker & ); + /// \ru Конструктор по поверхностям. \en Constructor by surfaces. + MbTruncatedShell( const RPArray &, bool same, + const SArray & orients, const MbMergingFlags &, const MbSNameMaker & ); + /// \ru Конструктор по строителям тела. \en Constructor by solid creators. + MbTruncatedShell( const MbSolid &, bool same, bool keepShell, + bool orient, const MbMergingFlags &, const MbSNameMaker & ); + + virtual ~MbTruncatedShell(); + +private: + MbTruncatedShell( const MbTruncatedShell &, MbRegDuplicate * ); + +public: + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en Type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию \en Create a copy + + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar ( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Построение оболочки по исходным данным \en Construction of a shell from the given data + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + + // \ru Установить номера выбраных граней усекаемого тела \en Set indices of selected faces of the solid being truncated. + void SetSelIndices( const std::vector & selInds ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTruncatedShell ) +OBVIOUS_PRIVATE_COPY( MbTruncatedShell ) +}; + +IMPL_PERSISTENT_OPS( MbTruncatedShell ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить усечённую оболочку. + \en Build a truncated shell. \~ + \details \ru Построить усечённую оболочку резкой исходного тела на части указанными элементами, + которыми могут служить двумерные кривые в локальной системе координат, трёхмерные кривые, поверхности и оболочки. + Одновременно с построением оболочки функция создаёт её строитель.\n + \en Construct a truncated shell by cutting the initial solid into parts by the specified elements + which can be two-dimensional curves in the local coordinate system, three-dimensional curves, surfaces and shells. + The function simultaneously creates the shell and its constructor.\n \~ + \param[in] initSolid - \ru Исходное тело. + \en The initial solid. \~ + \param[in] selIndices - \ru Идентификаторы выбранныых граней, приотсутствии - всё тело. + \en Identifiers of selected faces, if not specified - the whole solid. \~ + \param[in] sameShell - \ru Режим копирования исходной оболочки. + \en Mode of copying the initial shell. \~ + \param[in] operNames - \ru Именователь граней. + \en An object for naming faces. \~ + \param[in] items - \ru Усекающие объекты. + \en Truncating objects. \~ + \param[in] orients - \ru Ориентация усекающих объектов. + \en The truncating objects orientation. \~ + \param[in] curvesSplitMode - \ru Кривые используются как линии разъема. + \en The curves are used as parting lines. \~ + \param[in] solidsCopyMode - \ru Режим копирования усекающих объектов. + \en Mode of copying the truncating objects. \~ + \param[in] mergeFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] resShell - \ru Построенная усеченная оболочка. + \en Constructed truncated shell. \~ + \param[out] resDir - \ru Направление фантома усечения. + \en Direction of truncation phantom. \~ + \result \ru Возвращает строитель оболочки. + \en Returns the shell constructor. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) TruncateSurfacesSol( MbSolid & initSolid, + SArray & selIndices, + MbeCopyMode sameShell, + const MbSNameMaker & operNames, + RPArray & items, + SArray & orients, + bool curvesSplitMode, + MbeCopyMode solidsCopyMode, + const MbMergingFlags & mergeFlags, // флаги слияния граней и ребер + MbResultType & res, + MbFaceShell *& resShell, + MbPlacement3D *& resDir ); + + +#endif // __TRUNCATED_SHELL_H diff --git a/C3d/Include/cr_union_solid.h b/C3d/Include/cr_union_solid.h new file mode 100644 index 0000000..e25208b --- /dev/null +++ b/C3d/Include/cr_union_solid.h @@ -0,0 +1,200 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель объединения наборов граней в один набор граней. + \en Constructor of union of two face sets to one face set. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CR_UNION_SOLID_H +#define __CR_UNION_SOLID_H + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель объединения наборов граней в один набор граней. + \en Constructor of union of two face sets to one face set. \~ + \details \ru Строитель объединения выполняет объединение наборов граней в один набор граней, + при этом может быть выполнена обработка пересечений граней. \n + \en Constructor of union performs union of face sets into a single face set, + meanwhile the treatment of faces intersection can be performed. \n \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbUnionSolid : public MbCreator { +protected : + c3d::CreatorsSPtrVector creators; ///< \ru Набор данных для построения исходных оболочек. \en Data set for construction of the source shells. + c3d::IndicesVector countNumbers; ///< \ru Индекс начального строителя для следующей оболочки. \en Index of the source creator for the next shell. + c3d::IndicesVector sharedLinks; ///< \ru Номера общих наборов строителей для оболочек. \en Numbers of common creators sets for shells. + size_t sharedCount; ///< \ru Количество общих набор строителей. \en The number of common creators sets. + OperationType operation; ///< \ru Тип булевой операции над оболочками. \en Type of Boolean operation on shells. + bool checkIntersection; ///< \ru Проверять ли на пересечение тела. \en Whether to check the solids for intersection. + bool mergeFaces; ///< \ru Объединять подобные грани (true). \en Whether to union similar faces (true). + double buildSag; ///< \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + +public : + MbUnionSolid( const c3d::CreatorsSPtrVector & creators, + bool sameCreators, + const c3d::IndicesVector & countNumbers, + size_t sharedCnt, + const c3d::IndicesVector & sharedLinks, + OperationType operType, + bool checkIntersection, + bool mergeFaces, + const MbSNameMaker & nameMaker ); +private : + MbUnionSolid( const MbUnionSolid &, MbRegDuplicate * ); + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbUnionSolid( const MbUnionSolid & ); +public : + virtual ~MbUnionSolid(); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeCreatorType IsA() const; // \ru Тип элемента \en A type of element + virtual MbCreator & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию \en Create a copy + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual MbePrompt GetPropertyName(); // \ru Выдать заголовок свойства объекта \en Get a name of object property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual size_t GetCreatorsCount ( MbeCreatorType ) const; // \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const; // \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ); // \ru Получить внутренние построители по типу. \en Get internal creators by type. + + virtual bool IsSame( const MbCreator &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSimilar( const MbCreator & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual bool SetEqual ( const MbCreator & ); // \ru Сделать равным \en Make equal + + // \ru Общие функции твердого тела \en Common functions of solid + + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); // \ru Построение \en Construction + + virtual void SetYourVersion( VERSION version, bool forAll ); + +public: + /// \ru Тип булевой операции над телами. \en Type of Boolean operation on solids. + OperationType GetOperationType() const { return operation; } + /// \ru Угловое отклонение при движении по кривым и поверхностям. \en Angular deviation while moving along curves and surfaces. + double GetBuildSag() const { return buildSag; } + + /// \ru Общее количество строителей. \en Total count of creators. + size_t GetCreatorsCount() const { return creators.size(); } + /// \ru Дать строитель. \en Get the creator. + const MbCreator * GetCreator( size_t k ) const { return ((k < creators.size()) ? &(*creators[k]) : NULL); } + +public: + /// \ru Собрать группы общих строителей тел. \en Collect groups of shared creators. + static size_t CollectSharedCreators( c3d::CreatorsSPtrVector & creators, c3d::IndicesVector & countNumbers, c3d::IndicesVector & sharedLinks ); +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbUnionSolid & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbUnionSolid ) +}; // MbUnionSolid + +IMPL_PERSISTENT_OPS( MbUnionSolid ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку булевой операции множества оболочек. + \en Create a shell of Boolean operation of shell set. \~ + \details \ru Для указанной оболочки и множества оболочек построить оболочку как результат булевой операции над оболочкой и множеством оболочек. + Перед операцией множество оболочек объединяется в одну оболочку, в которой содержатся все грани множества оболочек. + При необходимости выполняется объединение пересекающихся оболочек.\n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en For a given shell and a shell set construct a shell as a result of Boolean operation on the shell and a shell set. + Before the operation a shell set is united into a single shell which contains all the faces of shell set. + Union of the intersected shells is performed if necessary. + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] solid - \ru Оболочка, с которой выполняется булева операция объединённого множества оболочек (может быть NULL). + \en The shell the Boolean operation of the united shell set is performed with (can be NULL). \~ + \param[in] sameShell - \ru Способ копирования граней оболочки. + \en Method of shell faces copying. \~ + \param[in] creators - \ru Строители набора оболочек. + \en Shell set creators. \~ + \param[in] countNumbers - \ru Номера крайних строителей для набора оболочек. + \en Indices of the last creators for a shell set. \~ + \param[in] shells - \ru Набор оболочек, подлежащих объединению. + \en Shell set to unite. \~ + \param[in] sameShells - \ru Способ копирования граней. + \en The method of copying faces. \~ + \param[in] oType - \ru Тип булевой операции. + \en A Boolean operation type. \~ + \param[in] checkIntersect - \ru Проверять ли пересечение оболочек. + \en Whether to check shells intersection. \~ + \param[in] mergeFaces - \ru Сливать подобные грани. + \en Whether to merge similar faces. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[in] isArray - \ru Являются ли оболочки размноженными по прямоугольной сетке копиями? + \en Are the shells copies duplicated over the rectangular mesh? \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \param[out] notGluedShells - \ru Множество оболочек, которые не получилось приклеить. + \en An array of shells which were not glued. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateUnion( MbFaceShell * solid, + MbeCopyMode sameShell, + const c3d::CreatorsSPtrVector & creators, + const c3d::IndicesVector & countNumbers, + const RPArray & shells, + MbeCopyMode sameShells, + OperationType oType, + bool checkIntersect, + bool mergeFaces, + const MbSNameMaker & operNames, + bool isArray, // \ru Флаг массива \en Flag of array + MbResultType & res, + MbFaceShell *& shell, + RPArray * notGluedShells = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Объединить множества граней оболочек в одну оболочку. + \en Unite a set of shells' faces into a single shell. \~ + \details \ru Множества граней указанных оболочек положить в одну оболочку. \n + Одновременно с построением оболочки функция создаёт её строитель. \n + \en Put sets of faces of the specified shells to a single shell.+ \n + The function simultaneously constructs the shell and creates its constructor. \n \~ + \param[in] creators - \ru Строители набора оболочек. + \en Shell set creators. \~ + \param[in] countNumbers - \ru Номера крайних строителей для набора оболочек. + \en Indices of the last creators for a shell set. \~ + \param[in] shells - \ru Набор оболочек, подлежащих объединению. + \en Shell set to unite. \~ + \param[in] operNames - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + \param[out] res - \ru Код результата операции. + \en Operation result code. \~ + \param[out] shell - \ru Построенный набор граней. + \en Constructed set of faces. \~ + \result \ru Возвращает строитель, если операция была выполнена успешно. + \en Returns the constructor if the operation has been successfully performed. \~ + \ingroup Model_Creators +*/ +// --- +MATH_FUNC (MbCreator *) CreateUnion( const c3d::CreatorsSPtrVector & creators, + const c3d::IndicesVector & countNumbers, + const RPArray & shells, + const MbSNameMaker & operNames, + MbResultType & res, + MbFaceShell *& shell ); + + +#endif // __CR_UNION_SOLID_H diff --git a/C3d/Include/creator.h b/C3d/Include/creator.h new file mode 100644 index 0000000..78c2f0d --- /dev/null +++ b/C3d/Include/creator.h @@ -0,0 +1,527 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строитель объекта геометрической модели. + \en Constructor of object of the geometric model. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CREATOR_H +#define __CREATOR_H + +#include +#include +#include +#include +#include + +class MATH_CLASS MbVertex; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbPointFrame; +class MATH_CLASS MbWireFrame; +class MATH_CLASS MbCreator; + + +namespace c3d // namespace C3D +{ +typedef SPtr CreatorSPtr; +typedef SPtr ConstCreatorSPtr; + +typedef std::vector CreatorsVector; +typedef std::vector ConstCreatorsVector; + +typedef std::vector CreatorsSPtrVector; +typedef std::vector ConstCreatorsSPtrVector; + +typedef std::set CreatorsSet; +typedef CreatorsSet::iterator CreatorsSetIt; +typedef CreatorsSet::const_iterator CreatorsSetConstIt; +typedef std::pair CreatorsSetRet; + +typedef std::set CreatorsSPtrSet; +typedef CreatorsSPtrSet::iterator CreatorsSPtrSetIt; +typedef CreatorsSPtrSet::const_iterator CreatorsSPtrSetConstIt; +typedef std::pair CreatorsSPtrSetRet; + +typedef std::set ConstCreatorsSet; +typedef ConstCreatorsSet::iterator ConstCreatorsSetIt; +typedef ConstCreatorsSet::const_iterator ConstCreatorsSetConstIt; +typedef std::pair ConstCreatorsSetRet; + +typedef std::set ConstCreatorsSPtrSet; +typedef ConstCreatorsSPtrSet::iterator ConstCreatorsSPtrSetIt; +typedef ConstCreatorsSPtrSet::const_iterator ConstCreatorsSPtrSetConstIt; +typedef std::pair ConstCreatorsSPtrSetRet; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы строителей. + \en Types of creators. \~ + \details \ru Типы строителей оболочек тел, точечных и проволочных каркасов геометрической модели. \n + \en Types of constructors of shells of solids, point-frames and wire-frames of the geometric model. \n \~ + \ingroup Model_Creators + */ +// --- +enum MbeCreatorType { + + ct_Undefined = 0, ///< \ru Неизвестный объект. \en Unknown object. + ct_Creator = 1, ///< \ru Строитель объекта. \en Constructor of object. \n + + // \ru Строители точек. \en Creators of points. + ct_PointsCreator = 101, ///< \ru Строитель точечного каркаса. \en Constructor of point-frame. \n + + // \ru Строители кривых. \en Creators of curves. + ct_Curve3DCreator = 201, ///< \ru Строитель кривой. \en Constructor of curve. + ct_Nurbs3DCreator = 202, ///< \ru Строитель сплайна с сопряжениями. \en Constructor of spline with tangents. + ct_SurfaceSplineCreator = 203, ///< \ru Строитель сплайна на поверхности с сопряжениями. \en Constructor of spline on a surface with tangents. + ct_ProjectionCurveCreator = 204, ///< \ru Строитель проекционной кривой. \en Constructor of the projection curve. + ct_OffsetCurveCreator = 205, ///< \ru Строитель эквидистантной кривой. \en Constructor of the offset curve. + ct_IntersectionCurveCreator = 206, ///< \ru Строитель кривой пересечения. \en Constructor of the intersection curve. + ct_ConnectingCurveCreator = 207, ///< \ru Строитель кривой скругления двух кривых. \en Constructor of the curve connecting two curves. \n + + // \ru Строители тел. \en Creators of solids. + ct_ShellCreator = 501, ///< \ru Строитель оболочки. \en Constructor of shell. + ct_SimpleCreator = 502, ///< \ru Строитель оболочки без истории. \en Constructor of a shell without history. + ct_ElementarySolid = 503, ///< \ru Строитель оболочки в форме: блока, клина, цилиндра, конуса, шара, тора. \en Constructor of a shell as: a block, a wedge, a cylinder, a cone, a sphere, a torus. + ct_CurveSweptSolid = 504, ///< \ru Строитель оболочки движения. \en Constructor of a swept shell. + ct_CurveExtrusionSolid = 505, ///< \ru Строитель оболочки выдавливания. \en Constructor of a shell of extrusion. + ct_CurveRevolutionSolid = 506, ///< \ru Строитель оболочки вращения. \en Constructor of a shell of revolution. + ct_CurveEvolutionSolid = 507, ///< \ru Строитель кинематической оболочки. \en Constructor of a shell of evolution. + ct_CurveLoftedSolid = 508, ///< \ru Строитель оболочки по плоским сечениям. \en Constructor of lofted shell. + ct_BooleanSolid = 509, ///< \ru Строитель оболочки булевой операции. \en Constructor of a shell of boolean operation. + ct_CuttingSolid = 510, ///< \ru Строитель разрезанной поверхностью оболочки. \en Constructor of a shell cut by surface. + ct_SymmetrySolid = 511, ///< \ru Строитель симметричной оболочки. \en Constructor of a symmetric shell. + ct_HoleSolid = 512, ///< \ru Строитель оболочки отверстия, кармана или фигурного паза. \en Constructor of a shell of a hole, a pocket or a groove. + ct_SmoothSolid = 513, ///< \ru Строитель оболочки с фаской или скруглением ребер. \en Constructor of a shell with a chamfer or with edges fillet. + ct_ChamferSolid = 514, ///< \ru Строитель оболочки с фаской ребер. \en Constructor of a shell with edges chamfer. + ct_FilletSolid = 515, ///< \ru Строитель оболочки со скруглением ребер. \en Constructor of a shell with edges fillet. + ct_FullFilletSolid = 516, ///< \ru Строитель оболочки со скруглением граней. \en Constructor of a shell with a faces fillet. + ct_ShellSolid = 517, ///< \ru Строитель тонкостенной оболочки, эквидистантной оболочки, придания толщины. \en Constructor of a thin-walled shell, an offset shell, thickening. + ct_DraftSolid = 518, ///< \ru Строитель оболочки с литейным уклоном. \en Constructor of a shell with a pattern taper. + ct_RibSolid = 519, ///< \ru Строитель оболочки с ребром жесткости. \en Constructor of a shell with a rib. + ct_SplitShell = 520, ///< \ru Строитель оболочки с подразбиением граней. \en Constructor of a shell with faces subdivision. + ct_NurbsBlockSolid = 521, ///< \ru Строитель оболочки в форме блока из nurbs-поверхностей. \en Constructor of a shell as a block from NURBS surfaces: + ct_FaceModifiedSolid = 522, ///< \ru Строитель модифицированной оболочки. \en Constructor of a modified shell. + ct_ModifiedNurbsItem = 523, ///< \ru Строитель модифицированной nurbs-поверхностями оболочки. \en Constructor of a shell with modified NURBS surfaces. + ct_NurbsModification = 524, ///< \ru Строитель модифицированной контрольными точками оболочки. \en Constructor of a shell modified by control points. + ct_TransformedSolid = 525, ///< \ru Строитель трансформированной оболочки. \en Constructor of a transformed shell. + ct_ThinShellCreator = 526, ///< \ru Строитель тонкой оболочки. \en Constructor of a thin shell. + ct_UnionSolid = 527, ///< \ru Строитель объединённой оболочки. \en Constructor of a united shell. + ct_DetachSolid = 528, ///< \ru Строитель оболочки из отделяемой части многосвязной оболочки. \en Constructor of a shell from the detached part of a multiply connected shell. + ct_DuplicationSolid = 529, ///< \ru Строитель множества тел, построенных из исходного. \en Constructor of set of solids built from the original. \n + ct_ReverseCreator = 530, ///< \ru Строитель вывернутого "наизнанку" тела. \en Constructor of a reversed solid. \n + ct_DividedShell = 531, ///< \ru Строитель разделенной на части оболочки \en Constructor of a divided shell. + + // \ru Строители листовых тел. \en Creators of sheet solids. + ct_SheetMetalSolid = 601, ///< \ru Строитель листовой оболочки. \en Constructor of a sheet shell. + ct_BendOverSegSolid = 602, ///< \ru Строитель оболочки со сгибом относительно отрезка. \en Constructor of a shell with a bend at the segment. + ct_JogSolid = 603, ///< \ru Строитель оболочки с подсечкой. \en Constructor of a shell with a jog. + ct_BendsByEdgesSolid = 604, ///< \ru Строитель оболочки со сгибом по ребру. \en Constructor of a shell with a bend at the edge. + ct_BendUnbendSolid = 605, ///< \ru Строитель оболочки с выполненным сгибом или разгибом. \en Constructor of a shell with bending or unbending. + ct_ClosedCornerSolid = 606, ///< \ru Строитель оболочки с замыканием угла. \en Constructor of a shell with corner enclosure. + ct_StampSolid = 607, ///< \ru Строитель оболочки с штамповкой. \en Constructor of a shell with stamping. + ct_SphericalStampSolid = 608, ///< \ru Строитель оболочки со сферической штамповкой. \en Constructor of a shell with spherical stamping. + ct_BeadSolid = 609, ///< \ru Строитель оболочки с буртиком. \en Constructor of a shell with a bead. + ct_JalousieSolid = 610, ///< \ru Строитель оболочки с жалюзи. \en Constructor of a shell with jalousie. + ct_JointBendSolid = 611, ///< \ru Строитель оболочки с комбинированным сгибом. \en Constructor of a shell with a composite bend. + ct_StitchedSolid = 612, ///< \ru Строитель оболочки, сшитой из нескольких граней или оболочек. \en Constructor of a shell stitched from several faces or shells. + ct_RuledSolid = 613, ///< \ru Строитель линейчатой оболочки (обечайки). \en Constructor of a ruled shell (shell ring). + ct_RestoredEdgesSolid = 614, ///< \ru Строитель листовой оболочки с восстановленными боковыми рёбрами. \en Constructor of a sheet shell with restored lateral edges. + ct_SheetUnionSolid = 615, ///< \ru Строитель объединения двух листовых тел по торцу. \en Constructor of two sheet solids union by the side. + ct_StampRibSolid = 616, ///< \ru Строитель ребра жесткости листового тела. \en Constructor of sheet solid rib. \n + ct_BendAnySolid = 617, ///< \ru Строитель оболочки с выполненным сгибом нелистового тела. \en Constructor of a shell with bending of non-sheet solid + ct_SimplifyFlatSolid = 618, ///< \ru Строитель упрощения развёртки листового тела. \en Constructor of the sheet solid flat pattern simplification. + ct_UserStampSolid = 619, ///< \ru Строитель оболочки с штамповкой телом. \en Constructor of a shell with stamping by solid. + ct_RemoveOperationSolid = 620, ///< \ru Строитель удаления операции листового тела. \en Constructor of removing of the sheet solid. + + // \ru Строители оболочек. \en Creators of shells. + ct_JoinShell = 701, ///< \ru Строитель оболочки соединения. \en Constructor of a joint shell. + ct_MeshShell = 702, ///< \ru Строитель оболочки по поверхностям на сетках кривых. \en Constructor of a shell by surfaces constructed by the grid curves. + ct_RuledShell = 703, ///< \ru Строитель оболочки по набору линейчатых поверхностей. \en Constructor of a shell by a set of ruled surfaces. + ct_NurbsSurfacesShell = 704, ///< \ru Строитель NURBS-оболочки на двумерном массиве точек. \en Constructor of a NURBS-shell on a two-dimensional array of points. + ct_TruncatedShell = 705, ///< \ru Строитель оболочки, усеченная геометрическими объектами. \en Constructor of a shell truncated by geometric objects. + ct_ExtensionShell = 706, ///< \ru Строитель продолженной оболочки. \en Constructor of an extended shell. + ct_PatchSetCreator = 707, ///< \ru Строитель заплатки по кривым на оболочке. \en Constructor of a patch by curves on the shell. + ct_FilletShell = 708, ///< \ru Строитель оболочки грани соединения. \en Constructor of a shell of a fillet face. + ct_MedianShell = 709, ///< \ru Строитель срединной оболочки тела. \en Constructor of a median shell of solid. \n + + // \ru Строители других объектов (вставлять новые типы перед этим типом). \en Creators of the other objects (insert new types before this type). + ct_AttributeProvider = 801, ///< \ru Поставщик атрибутов для примитивов оболочки. \en Attribute provider for the shell primitives. + + ct_FreeItem = 900, ///< \ru Тип для объектов, созданных пользователем. \en Type for the user-defined objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Строитель объекта геометрической модели. + \en Constructor of object of the geometric model. \~ + \details \ru Строитель выполняет одно действие при построении объекта геометрической модели и + содержит необходимую для этого информацию. \n + Множество строителей образует журнал построения геометрической модели.\n + Строители наиболее востребованы при создании оболочки тела MbSolid. + Изначально оболочки тела строятся на основе кривых или поверхностей. + Многие оболочки можно построить путем движения составной кривой, + называемой образующей по траектории, заданной направляющей кривой. + Можно построить оболочку, проходящую по заданному набору кривых. + На основе поверхности можно построить оболочку в форме листа конечной толщины. + Подобные оболочки назовём простыми. \n + Более сложные оболочки можно получить с помощью операций. + Операцией называется совокупность действий над оболочками, + которая приводит к рождению новой оболочки. \n + Примерами операций служат булевы операции, + построение тонкостенной оболочки, + построение скруглений или фасок рёбер. + \en The constructor performs one operation while creating the object of a geometric model and + contains the information necessary for this. \n + Array of constructors forms the history tree of geometric model.\n + Creators are mostly required while creating a shell of solid MbSolid. + Initially solid are created on the base of curves or surfaces. + Most shells can be created by moving the composite curve + which is called generatrix, along the trajectory specified by the guide curve. + A shell can be constructed passing through a given set of curves. + A shell in the form of a sheet of finite thickness can be constructed on the base of a surface. + Let's call such shells simple. \n + More complex shells can be obtained by operations. + Operation is a set of actions on the shells + which result in creation of a new shell. \n + Examples of operations are boolean operations, + thin-walled shell construction, + edges fillet or chamfers creation. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbCreator : public MbRefItem, public TapeBase { +protected : + MbSNameMaker names; ///< \ru Именователь создаваемых строителем элементов и объектов. \en An object defining the names of elements and objects created by the constructor. + mutable MbeProcessState status; ///< \ru Состояние строителя и результата выполнения операции. \en State of the constructor and of the operation result. + +protected : + /// \ru Конструктор по именователю. \en Constructor by name-maker. + MbCreator( MbSNameMaker * ); + /// \ru Конструктор по именователю. \en Constructor by name-maker. + MbCreator( const MbSNameMaker & ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbCreator( const MbCreator & ); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbCreator(); + + /** \ru \name Общие функции строителя оболочки. + \en \name Common functions of the shell creator. + \{ */ + /// \ru Получить регистрационный тип (для копирования, дублирования). \en Get the registration type (for copying, duplication). + virtual MbeRefType RefType() const; + /// \ru Получить тип объекта. \en Get the object type. + virtual MbeCreatorType IsA() const = 0; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual MbeCreatorType Type() const; + + /** \brief \ru Создать копию объекта. + \en Create a copy of the object. \~ + \details \ru Создать копию объекта с использованием регистратора. + Регистратор используется для предотвращения многократного копирования объекта. + Если объект содержит ссылки на другие объекты, то вложенные объекты так же копируются. + Допустимо не передавать регистратор в функцию. Тогда будет создана новая копия объекта. + При копировании одиночного объекта или набора не связанных между собой объектов допустимо не использовать регистратор. + Регистратор необходимо использовать, если надо последовательно копировать несколько взаимосвязанных объектов. + Возможно, что связь объектов обусловлена наличием в них ссылок на общие объекты. + Тогда, при копировании без использования регистратора, можно получить набор копий, + содержащих ссылки на разные копии одного и того же вложенного объекта, что ведет к потере связи между копиями. + \en Create a copy of the object using the registrator. + The registrator is used to prevent multiple copying of an object. + If the object contains references to other objects, then the included objects are copied too. + It is allowed not to pass the registrator to a function. Then the new copy of the object will be created. + It is allowed not to use the registrator while copying a single object or a set of disconnected objects. + The registrator must be used to copy several correlated objects successively. + It is possible that the relation between objects means that the objects contain references on the common objects. + Then, while copying without using the registrator, one can get a set of copies + which contain references to the different copies of a single embedded object, what leads to loss of relationship between the copies. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \return \ru Копия объекта. + \en The object copy. \~ + */ + virtual MbCreator & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; + + /** \brief \ru Преобразовать согласно матрице. + \en Transform according to the matrix. \~ + \details \ru Преобразовать исходный объект согласно матрице c использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то вложенные объекты так же преобразуются согласно матрице. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих трансформации. + \en Transform the initial object according to the matrix using the registrator. + If the object contains references to the other geometric objects, then the nested objects are transformed according to the matrix. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to transformation. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Сдвинуть вдоль вектора. + \en Translate along a vector. \~ + \details \ru Сдвинуть геометрический объект вдоль вектора с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция сдвига. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих сдвигу. + \en Move a geometric object along the vector using the registrator. + If the object contains references to the other objects, then the translation operation is applied to the nested objects. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to moving. \~ + \param[in] to - \ru Вектор сдвига. + \en Movement vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + virtual void Move ( const MbVector3D & to, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Повернуть объект вокруг оси. + \en Rotate an object about the axis. \~ + \details \ru Повернуть объект вокруг оси на заданный угол с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция поворота. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих повороту. + \en Rotate an object about the axis by the given angle using the registrator. + If the object contains references to the other geometric objects, then the rotation operation is applied to the nested objects too. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to rotation. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Являются ли объекты равными? + \en Determine whether an object is equal? \~ + \details \ru Равными считаются однотипные объекты, все данные которых одинаковы (равны). + \en Still considered objects of the same type, all data is the same (equal). \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. + */ + virtual bool IsSame( const MbCreator & other, double accuracy ) const = 0; + + /** \brief \ru Являются ли объекты подобными? + \en Determine whether an object is similar? \~ + \details \ru Подобными считаются однотипные объекты, данные которых можно приравнять или данные так же являются подобными (указатели). + Подобный объект можно инициализировать по данным подобного ему объекта (приравнять один другому без изменения адресов). + \en Such are considered the same objects whose data are similar. \~ + \param[in] item - \ru Объект для сравнения. + \en The object to compare. \~ + \return \ru Подобны ли объекты. + \en Whether the objects are similar. + */ + virtual bool IsSimilar( const MbCreator & item ) const; + + /// \ru Сделать объекты равными, если они подобны. \en Make the objects equal if they are similar. + virtual bool SetEqual( const MbCreator & ) = 0; + + /** \brief \ru Построить оболочку по исходным данным. + \en Create a shell from the initial data. \~ + \details \ru Построение новой или модификация присланной оболочки по исходным данным согласно строителю. + \en Construction of a new shell or modification of the given one from the source data according to the constructor. \~ + \param[in] shell - \ru Подлежащая модификации или новая оболочка. + \en A shell to be modified or a new shell. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \param[in] items - \ru Контейнер для складывания элементов невыполненных построений (может быть NULL). + \en Container for the elements of not performed constructions (can be NULL). \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + virtual bool CreateShell( MbFaceShell *& shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + + /** \brief \ru Построить оболочку по исходным данным. + \en Create a shell from the initial data. \~ + \details \ru Построение новой или модификация присланной оболочки по исходным данным согласно строителю. + \en Construction of a new shell or modification of the given one from the source data according to the constructor. \~ + \param[in] shell - \ru Подлежащая модификации или новая оболочка. + \en A shell to be modified or a new shell. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \param[in] items - \ru Контейнер для складывания элементов невыполненных построений (может быть NULL). + \en Container for the elements of not performed constructions (can be NULL). \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + bool CreateShell( SPtr & shell, MbeCopyMode sameShell, + RPArray * items = NULL ); + + /** \brief \ru Построить проволочный каркас по исходным данным. + \en Create a wire-frame from the source data. \~ + \details \ru Построение нового каркаса (кривых) или модификация присланного каркаса по исходным данным согласно строителю. + \en Construction of a new frame (of curves) or modification of the given one from the source data according to the constructor. \~ + \param[in] frame - \ru Подлежащий модификации или новый каркас. + \en A frame to be modified or a new frame. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \param[in] items - \ru Контейнер для складывания элементов невыполненных построений (может быть NULL). + \en Container for the elements of not performed constructions (can be NULL). \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + virtual bool CreateWireFrame( MbWireFrame *& frame, MbeCopyMode sameShell, + RPArray * items = NULL ); + + /** \brief \ru Построить проволочный каркас по исходным данным. + \en Create a wire-frame from the source data. \~ + \details \ru Построение нового каркаса (кривых) или модификация присланного каркаса по исходным данным согласно строителю. + \en Construction of a new frame (of curves) or modification of the given one from the source data according to the constructor. \~ + \param[in] frame - \ru Подлежащий модификации или новый каркас. + \en A frame to be modified or a new frame. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + bool CreateWireFrame( SPtr & frame, MbeCopyMode sameShell ); + + /** \brief \ru Построить точечный каркас по исходным данным. + \en Create a point-frame from the source data. \~ + \details \ru Построение нового каркаса (точек) или модификация присланного каркаса по исходным данным согласно строителю. + \en Creation of a new frame (of points) or modification of the given one from the given data according to the constructor. \~ + \param[in] frame - \ru Подлежащий модификации или новый каркас. + \en A frame to be modified or a new frame. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \param[in] items - \ru Контейнер для складывания элементов невыполненных построений (может быть NULL). + \en Container for the elements of not performed constructions (can be NULL). \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + virtual bool CreatePointFrame( MbPointFrame *& frame, MbeCopyMode sameShell, + RPArray * items = NULL ); + + /** \brief \ru Построить точечный каркас по исходным данным. + \en Create a point-frame from the source data. \~ + \details \ru Построение нового каркаса (точек) или модификация присланного каркаса по исходным данным согласно строителю. + \en Creation of a new frame (of points) or modification of the given one from the given data according to the constructor. \~ + \param[in] frame - \ru Подлежащий модификации или новый каркас. + \en A frame to be modified or a new frame. \~ + \param[in] sameShell - \ru Полнота копирования элементов при построении. + \en Whether to perform complete copying of elements while constructing. \~ + \return \ru Выполнено ли построение. + \en Whether the construction is performed. \~ + */ + bool CreatePointFrame( SPtr & frame, MbeCopyMode sameShell ); + + /// \ru Выдать свойства объекта. \en Get properties of the object. + virtual void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + virtual void SetProperties( const MbProperties & ); + /// \ru Выдать заголовок свойства объекта. \en Get a name of object property. + virtual MbePrompt GetPropertyName() = 0; + /// \ru Обновить форму оболочки. \en Update the shell shape. + virtual void Refresh( MbFaceShell & ); + /// \ru Обновить форму каркаса. \en Update the frame shape. + virtual void Refresh( MbWireFrame & ); + /// \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisItems ( RPArray & ); + /// \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void GetBasisPoints( MbControlData3D & ) const; + /// \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void SetBasisPoints( const MbControlData3D & ); + /// \ru Посчитать внутренние построители по типу. \en Count internal creators by type. + virtual size_t GetCreatorsCount( MbeCreatorType ct ) const { return (IsA() == ct) ? 1 : 0; } + /// \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool GetInternalCreators( MbeCreatorType, c3d::ConstCreatorsSPtrVector & ) const { return false; } + /// \ru Получить внутренние построители по типу. \en Get internal creators by type. + virtual bool SetInternalCreators( MbeCreatorType, c3d::CreatorsSPtrVector & ) { return false; } + + /// \ru Установить версию объектов. \en Set the objects version. + virtual void SetYourVersion( VERSION version, bool forAll ); + /// \ru Выдать версию объекта. \en Get the object version. + VERSION GetYourVersion() const { return names.GetMathVersion(); } + /// \ru Выдать именователь объекта. \en Get the name-maker. + const MbSNameMaker & GetYourName() const { return names; } + /// \ru Выдать именователь объекта для редактирования. \en Get the object's name-maker for editing. + MbSNameMaker & SetYourName() { return names; } + /// \ru Установить именователь объекта. \en Set the object's name-maker. + void SetName( const MbSNameMaker & n ) { names.SetName( n ); } + /// \ru Выдать главное имя объекта. \en Get the main name of the object. + SimpleName GetMainName() const { return names.GetMainName(); } + /// \ru Установить главное имя объекта. \en Set the main name of the object. + void SetMainName( SimpleName n ) { names.SetMainName(n); } + /// \ru Выдать флаг состояния. \en Get the flag of state. + MbeProcessState GetStatus() const { return status; } + /// \ru Установить флаг состояния. \en Set the flag of state. + void SetStatus( MbeProcessState l ) { status = l; } + + /** \brief \ru Регистрировать объект. + \en Register the object. \~ + \details \ru Регистрация объекта для предотвращения его многократной записи. + Другие объекты могут содержать указатель на данный объект. + Функция взводит флаг, который позволяет записывать объект один раз, а в остальных записях ссылаться на записанный экземпляр. + Чтение так же выполняется один раз, а в остальных случаях чтения подставляется адрес уже прочитанного объекта. + \en Object registration for preventing its multiple writing. + Other objects may contain a pointer to the given object. + The function sets a flag that allow to write the object once and to use the references to the recorded instance in the other records. + Reading is performed once too, in other cases of reading the address of the already read object is used. \~ + */ + void PrepareWrite() { SetRegistrable( (GetUseCount() > 1) ? registrable : noRegistrable ); } + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en Declaration without implementation of the assignment operator to prevent an assignment by default + MbCreator & operator = ( const MbCreator & ); + + DECLARE_PERSISTENT_CLASS( MbCreator ) +}; // MbCreator + +IMPL_PERSISTENT_OPS( MbCreator ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку по протоколу построения. + \en Create a shell by history tree. \~ + \details \ru Создать оболочку по протоколу построения.\n + \en Create a shell by history tree.\n \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (bool) CreateShell( MbFaceShell *& shell, const RPArray & creators, MbeCopyMode copyMode ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать оболочку по протоколу построения. + \en Create a shell by history tree. \~ + \details \ru Создать оболочку по протоколу построения.\n + \en Create a shell by history tree.\n \~ + \ingroup Solid_Modeling +*/ +// --- +MATH_FUNC (bool) CreateShell( MbFaceShell *& shell, const std::vector< SPtr > & creators, MbeCopyMode copyMode ); + + +#endif // __CREATOR_H diff --git a/C3d/Include/creator_transaction.h b/C3d/Include/creator_transaction.h new file mode 100644 index 0000000..6c5368f --- /dev/null +++ b/C3d/Include/creator_transaction.h @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Журнал построения объекта. + \en The history tree of object. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CREATOR_TRANSACTION_H +#define __CREATOR_TRANSACTION_H + + +#include +#include +#include +#include + + +class MATH_CLASS reader; +class MATH_CLASS writer; +class MATH_CLASS IProgressIndicator; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbSpaceItem; +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbWireFrame; +class MATH_CLASS MbPointFrame; +class MATH_CLASS MbProperties; +struct MATH_CLASS MbControlData3D; +class MbRegDuplicate; +class MbRegTransform; +enum MbeCopyMode; + + +//------------------------------------------------------------------------------ +/** \brief \ru Журнал построения объекта. + \en The history tree of object. \~ + \details \ru Журнал построения содержит упорядоченное множество строителей, + последовательная работа которых строит объект. \n + Неактивные строители (с состоянием mps_Skip) не принимают участия в построении объекта. + \en The history tree contains an ordered set of creators + whose successive work creates the objects. \n + Inactive creators (with state mps_Skip) are not used in the object construction. \~ + \ingroup Model_Creators +*/ +// --- +class MATH_CLASS MbTransactions +{ +private: + c3d::CreatorsVector transactions; ///< \ru Упорядоченное множество строителей. \en An ordered set of creators. + +protected: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with registrator. + MbTransactions( const MbTransactions &, MbRegDuplicate * iReg ); +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbTransactions(); + /// \ru Конструктор по строителям. \en Constructor by creators. + template + MbTransactions( const Creators & creators ) + : transactions() + { + size_t iCount = creators.size(); + if ( iCount > 0 ) { + transactions.reserve( iCount ); + for ( size_t i = 0; i < iCount; i++ ) { + MbCreator * creator = const_cast( creators[i] ); + if ( creator != NULL ) { + creator->AddRef(); + transactions.push_back( creator ); + } + } + } + } + + /// \ru Деструктор. \en Destructor. + virtual ~MbTransactions(); +public: + + /// \ru Перестроить объект по протоколу построения. \en Reconstruct object according to the history tree. + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + + /// \ru Очистить присланный журнал и скопировать в него строители. \en Clear the given history tree and copy the creators to it. + void CreatorsCopy ( MbTransactions & other, MbRegDuplicate * iReg = NULL ) const; + /// \ru Очистить журнал и скопировать в него строители из присланного журнала. \en Clear the history tree and copy the creators from the given history tree to it. + void CreatorsAssign ( const MbTransactions & other ); + /// \ru Сделать строители равными соответствующим строителям присланного журнала, если строители подобны. \en Make the creators equal to the creators from the given history tree if the creators are similar. + bool SetCreatorsEqual ( const MbTransactions & other ); + /// \ru Проверить, являются ли соответствующие строители присланного журнала подобными. \en Check whether the corresponding creators of the given history tree are similar. + bool IsCreatorsSimilar( const MbTransactions & other ) const; + /// \ru Преобразовать согласно матрице строители. \en Transform the creators according to the matrix. + void CreatorsTransform( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Сдвинуть вдоль вектора строители. \en Move creators along the vector. + void CreatorsMove ( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Повернуть вокруг оси строители на заданный угол. \en Rotate the creators about the axis by the given angle. + void CreatorsRotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + /// \ru Выдать количество строителей. \en Get the creators count. + size_t GetCreatorsCount() const { return transactions.size(); } + /// \ru Зарезервировать место для строителей. \en Reserve space for creators. + void Reserve( size_t count ) { transactions.reserve( transactions.size() + count ); } + /// \ru Выдать строитель по его индексу. \en Get constructor by its index. + const MbCreator * GetCreator( size_t ind ) const; + /// \ru Выдать строитель по его индексу с возможностью редактирования. \en Get constructor by its index with possibility of editing. + MbCreator * SetCreator( size_t ind ); + /// \ru Добавить свои строители в присланный массив. \en Add your own creators to the given array. + virtual bool GetCreators( RPArray & ) const; + /// \ru Добавить свои строители в присланный массив. \en Add your own creators to the given array. + virtual bool GetCreators( c3d::CreatorsSPtrVector & ) const; + /// \ru Добавить копии своих строителей в присланный массив. \en Add copies of your own creators to the given array. + bool GetCreatorsCopies( RPArray & ) const; + /// \ru Добавить копии своих строителей в присланный массив. \en Add copies of your own creators to the given array. + bool GetCreatorsCopies( c3d::CreatorsSPtrVector & ) const; + /// \ru Найти номер строителя в журнале или вернуть SYS_MAX_T в случае отсутствия. \en Find the number of creators in the history tree or return SYS_MAX_T if it is absent. + size_t FindCreator( const MbCreator * creator ); + /// \ru Добавить строитель (addSame = false) или его копию (addSame = true) в журнал. \en Add the constructor (addSame = false) or its copy (addSame = true) to the history tree. + bool AddCreator ( const MbCreator &, bool addSame = false ); + /// \ru Добавить строитель (addSame = false) или его копию (addSame = true) в журнал. \en Add the constructor (addSame = false) or its copy (addSame = true) to the history tree. + bool AddCreator ( const MbCreator *, bool addSame = false ); + /// \ru Добавить строители в журнал. \en Add creators to the history tree. + void AddCreators( const RPArray & ); + /// \ru Вытереть строитель с указанным номером из журнала и отдать его. \en Remove the constructor with the specified index from the history tree and return it. + MbCreator * DetachCreator ( size_t ind ); + /// \ru Удалить строитель с указанным номером и вытереть его из журнала. \en Delete the constructor with the specified index and remove it from the history tree. + bool DeleteCreator ( size_t ind ); + /// \ru Удалить все строители и очистить журнал. \en Delete all the creators and clear the history tree. + void DeleteCreators(); + /// \ru Дать статус строителя с указанным номером. \en Get the status of creator with the specified index. + int GetCreatorStatus( size_t ind ) const; + /// \ru Установить строителю с указанным номером статус. \en Set status to creator with the specified index. + bool SetCreatorStatus( size_t ind, MbeProcessState ); + /// \ru Дать количество активных строителей. \en Get the active creators count. + size_t GetActiveCreatorsCount() const; + /// \ru Установить количество активных строителей от начала до заданного номера. \en Set the count of active creators from the beginning to the given index. + bool SetActiveCreatorsCount( size_t activeCount ); + /// \ru Выдать создаваемый заданным числом строителей объект и базовые объекты остальных строителей. \en Get the object created by the specified number of creators and the basis items of the other creators. + void BreakCreatorsToBasisItem( size_t c, RPArray & ); + /// \ru Выдать базовые объекты строителей. \en Get the basis items of the creators. + void GetCreatorsBasisItems ( RPArray & ); + /// \ru Выдать базовые точки строителей. \en Get the basis points of the creators. + void GetCreatorsBasisPoints( MbControlData3D & ) const; + /// \ru Изменить объект по контрольным точкам. \en Change the object by control points. + void SetCreatorsBasisPoints( const MbControlData3D & ); + /// \ru Выдать свойства строителей (на копиях или на оригиналах строителей). \en Get properties of the creators (using original creators or their copies). + void GetProperties( MbProperties &, bool sameCreators = false ); + /// \ru Установить свойства строителей. \en Set properties of the creators. + void SetProperties( const MbProperties & ); + /// \ru Прочитать строители из потока. \en Read creators from the stream. + void CreatorsRead ( reader & in ); + /// \ru Записать строители в поток. \en Write creators to the stream. + void CreatorsWrite( writer & out ) const; + +OBVIOUS_PRIVATE_COPY( MbTransactions ) +}; + + +#endif // __CREATOR_TRANSACTION_H diff --git a/C3d/Include/cur_arc.h b/C3d/Include/cur_arc.h new file mode 100644 index 0000000..db401d9 --- /dev/null +++ b/C3d/Include/cur_arc.h @@ -0,0 +1,1559 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Окружность, эллипс или их дуга в двумерном пространстве. + \en Circle, ellipse or circular or elliptical arc in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_ARC_H +#define __CUR_ARC_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbLine; +class MATH_CLASS MbContour; +class MbTrimmedCurve; +class MbRect1D; +class DiskreteLengthData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Дуга эллипса в двумерном пространстве. + \en Elliptical arc in two-dimensional space. \~ + \details \ru Дуга эллипса описывается двумя радиусами a и b и двумя параметрами trim1 и trim2, заданными в локальной системе координат position. \n + Параметры trim1 и trim2 отсчитываются по дуге в направлении движения от оси position.axisX к оси position.axisY. + Параметры trim1 и trim2 будем называть параметрами усечения. + Значения параметров усечения, равные нулю и 2pi, соответствуют точке на оси position.axisX. \n + Параметр кривой t принимает значения на отрезке: 0<=t<=trim2–trim1. + Кривая может быть замкнутой. У замкнутой кривой trim2–trim1=2pi. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией\n + r(t) = position.origin + (a cos(trim1+(sense)t) position.axisX) + (b sin(trim1+(sense)t) position.axisY).\n + Радиусы кривой дожны быть больше нуля: a>0, b>0. \n + Для параметров усечения должны соблюдаться неравенства: trim1trim2 при sense==-1. \n + Локальная система координат position может быть как правой, так и левой. + Если локальная система координат правая и sense=+1 или локальная система координат левая и sense=–1, + то дуга направлена против движения часовой стрелки.\n + \en The elliptical arc is described by two radii a and b and two parameters trim1 and trim2 given in the local coordinate system 'position'. \n + Parameters 'trim1' and 'trim2' are measured along the arc in direction from position.axisX axis to position.axisY axis. + Parameters 'trim1' and 'trim2' will be called parameters of trimming. + Values of parameters of trimming equal to 0 and 2pi correspond to a point on position.axisX axis. \n + Parameter t of curve possesses the values in the range: 0<=t<=trim2-trim1. + The curve can be closed. For closed curve: trim2-trim1=2pi. \n + Radius-vector of the curve in the method PointOn(double&t,MbCartPoint3D&r) is described by the function\n + r(t) = position.origin + (a cos(trim1+(sense)t) position.axisX) + (b sin(trim1+(sense)t) position.axisY).\n + Radii of the curve must be positive: a>0, b>0. \n + The following inequalities must be satisfied for the parameters of trimming: trim1trim2 if sense==-1. \n + The local coordinate system 'position' can be both right and left. + If the local coordinate system is right and sense=+1 or the local coordinate system is left and sense=-1, + then the arc is oriented counterclockwise.\n \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbArc : public MbCurve, public MbSyncItem { +protected : + MbPlacement position; ///< \ru Локальная система координат. \en Local coordinate system. + double a; ///< \ru Радиус полуоси вдоль X. \en Radius of semiaxis along X. + double b; ///< \ru Радиус полуоси вдоль Y. \en Radius of semiaxis along Y. + double trim1; ///< \ru Параметры начальной точки. \en The start point parameters. + double trim2; ///< \ru Параметры конечной точки. \en The end point parameters. + int sense; ///< \ru Флаг совпадения с направлением от axisX к axisY (sense==0 не допускается). \en Flag of coincidence with direction from axisX to axisY (sense==0 is not allowed). + bool circle; ///< \ru Флаг, указывающий является объект окружностью (true) или эллипсом (false). \en Whether the object is a circle (true) or an ellipse (false). + bool closed; ///< \ru Флаг, указывающий является объект замкнутой кривой (true) или дугой (false). \en Whether the object is a closed curve (true) or an arc (false). + + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + mutable MbRect rect; ///< \ru Габаритный прямоугольник. \en Bounding rectangle. + mutable double metricLength; ///< \ru Метрическая длина кривой. \en Metric length of curve. + +public : + /** \brief \ru Конструктор окружности с параметрами по умолчанию. + \en Constructor of a circle with default parameters. \~ + \details \ru Создается окружность с центром в начале координат и с нулевым радиусом. + \en A circle is created with center in the origin and zero radius. \~ + */ + MbArc(); // \ru Конструктор по умолчанию. \en Default constructor. + + /** \brief \ru Конструктор окружности по радиусу. + \en Constructor of a circle by radius. \~ + \details \ru Создается окружность с центром в начале координат и с заданным радиусом. + \en A circle is created with center in the origin and the given radius. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + */ + MbArc( double rad ); // \ru Конструктор окружности по радиусу с центром в начале координат. \en Constructor of a circle by the given radius and centered in the origin. + + /** \brief \ru Конструктор окружности. + \en Constructor of a circle. \~ + \details \ru Создается окружность с центром в точке p и с заданным радиусом. + \en A circle is created with center in point 'p' and with the given radius. \~ + \param[in] p - \ru Центр окружности. + \en Center of circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + */ + MbArc( const MbCartPoint & p, double rad ); // \ru Конструктор окружности \en Constructor of a circle. + + /** \brief \ru Создать окружность. + \en Create a circle. \~ + \details \ru Создается окружность с центром в точке pc. + Радиус определяется как расстояние между точками pc и on . + \en A circle is created with center in point 'pc'. + The radius is determined as the distance between points 'pc' and 'on'. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] on - \ru Точка на окружности. + \en Point on circle. \~ + */ + MbArc( const MbCartPoint & pc, const MbCartPoint & on ); // \ru Конструктор окружности \en Constructor of a circle + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности с центром в точке p и с заданным радиусом. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en A circular arc is created with a center in point 'p' and with a given radius. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense cannot be equal to zero. \~ + */ + MbArc( const MbCartPoint & pc, double rad, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); // \ru Конструктор дуги \en The arc constructor + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности с центром в точке p и с заданным радиусом. + t1 и t2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en A circular arc is created with a center in point 'p' and with a given radius. + t1 and t2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] t1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] t2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( const MbCartPoint & pc, double rad, double t1, double t2, int initSense ); // \ru Конструктор дуги \en The arc constructor + + /** \brief \ru Конструктор дуги эллипса по образцу и концевым точкам. + \en Constructor of an elliptic arc based on a sample and bounding points. \~ + \details \ru Создается дуга на основе образца данного эллипса или окружности. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An arc based on the given sample of circle or ellipse is created. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] init - \ru Образец окружности или эллипса. + \en A sample circle or ellipse. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( const MbArc &init, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); // \ru Конструктор дуги \en The arc constructor + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности с центром в точке pc. + Радиус определяется как расстояние между точками pc и p1. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An arc of a circle centered in point 'pc'. + The radius is determined as the distance between points 'pc' and 'p1'. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги и радиус. + \en A point determining the beginning of the arc and the radius. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( const MbCartPoint & pc, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); // \ru Конструктор дуги \en The arc constructor + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности, проходящая через все 3 заданные точки. + Точки p1 и p3 - крайние. Направление движения по дуге определяется так, чтобы точка p2 лежала на дуге. + \en A circular arc is created passing through 3 given points. + Points p1 and p3 are the end points. Direction of moving along the arc is defined so as point p2 lay on the arc. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Точка, лежащая на дуге. + \en A point on the arc. \~ + \param[in] p3 - \ru Конец дуги. + \en End of the arc. \~ + */ + MbArc( const MbCartPoint & p1, const MbCartPoint & p2, const MbCartPoint & p3 ); // \ru Конструктор дуги по трем точкам \en Constructor of the arc by three points + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности с концами в заданных точках. + Радиус окружности определяется по заданному тангенсу 1/4 угла раствора дуги. + \en An arc is created with ends at the given points. + A circle radius is defined by the given tangent of 1/4 of arc opening angle. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Конец дуги. + \en End of the arc. \~ + \param[in] a4 - \ru Тангенс 1/4 угла раствора дуги. + \en Tangent of 1/4 of the arc opening angle. \~ + */ + MbArc( const MbCartPoint & p1, const MbCartPoint & p2, double a4 ); // \ru Конструктор дуги по начальной и конечной точкам и тангенса 1/4 угла раствора дуги \en Constructor of an arc from the start and end points and tangent of 1/4 of the arc opening angle + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с заданными полуосями и локальной системой координат. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An elliptical arc is created with the given semiaxes and the local coordinate system. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] place - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( double aa, double bb, const MbPlacement & place, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); // \ru Конструктор дуги эллипса \en Constructor of an elliptical arc + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с заданными полуосями и локальной системой координат. + t1 и t2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An elliptical arc is created with the given semiaxes and the local coordinate system. + t1 and t2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] place - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + \param[in] t1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] t2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( double aa, double bb, const MbPlacement & place, double t1, double t2, int initSense ); // \ru Конструктор дуги эллипса \en Constructor of an elliptical arc + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с локальной системой координат и полуосями заданного эллипса. + t1 и t2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An elliptical arc is constructed with the local coordinate system and semiaxes of the given ellipse. + t1 and t2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] ellipse - \ru Эллипс - образец. + \en A pattern ellipse. \~ + \param[in] t1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] t2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + MbArc( const MbArc & ellipse, double t1, double t2, int initSense ); + + /** \brief \ru Конструктор эллипса. + \en Constructor of an ellipse. \~ + \details \ru Создается эллипс с заданными локальной системой координат и полуосями. + \en An ellipse is created with the given local coordinate system and semiaxes. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] pos - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + */ + MbArc( double aa, double bb, const MbPlacement & pos ); // \ru Конструктор эллипса \en Constructor of an ellipse + + /** \brief \ru Конструктор эллипса. + \en Constructor of an ellipse. \~ + \details \ru Создается эллипс с заданными полуосями. + Локальная система координат эллипса имеет начало в точке c и + ось OX локальной системы координат составляет с осью OX текущей системы координат угол angle. + Направление поворота от оси текущей системы координат к оси новой системы координат. + \en An ellipse is created with the given semiaxes. + The local coordinate system of the ellipse has the origin in point 'c'; + OX axis of the local coordinate system forms angle 'angle' with the OX axis of the current coordinate system. + Direction of turning from the current coordinate system axis to the axis of the new coordinate system. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] c - \ru Начало локальной системы координат эллипса. + \en Origin of local coordinate system of ellipse. \~ + \param[in] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + MbArc( double aa, double bb, const MbCartPoint & c, double angle ); // \ru Конструктор эллипса \en Constructor of an ellipse +//protected : + /// \ru Конструктор копирования. \en Copy-constructor. + explicit MbArc( const MbArc & init ); +public : + /// \ru Деструктор \en Destructor + virtual ~MbArc(); + +public : + VISITING_CLASS( MbArc ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента \en A type of element + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать согласно матрице \en Transform according to the matrix + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual double DistanceToPoint( const MbCartPoint & ) const;// \ru Расстояние до точки \en Distance to a point + virtual bool DistanceToPointIfLess( const MbCartPoint & toP, double & d ) const; // \ru Расстояние до точки, если оно меньше d \en Distance to a point if it is less than 'd' + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавь свой габарит в прямой прям-к \en Add own bounding rectangle to an upright bounding rectangle + virtual void CalculateGabarit( MbRect & r ) const; + virtual bool IsInRectForDeform( const MbRect & r ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the given rectangle for deformation + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + virtual void Refresh(); // \ru Сбросить все временные данные \en Flush all the temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике \en Whether the object is visible in the given rectangle + using MbCurve::IsVisibleInRect; + virtual bool IsCompleteInRect( const MbRect & r ) const; // \ru Виден ли объект полностью в в заданном прямоугольнике \en Whether the object is completely visible in the given rectangle + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description + \{ */ + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Return the period + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the domain of a curve. + PointOn, FirstDer, SecondDer, ThirdDer,... functions correct parameter + when it runs out the domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void FirstDer ( double & t, MbVector & ) const; // \ru Первая производная. \en The first derivative. + virtual void SecondDer( double & t, MbVector & ) const; // \ru Вторая производная. \en The Second derivative. + virtual void ThirdDer ( double & t, MbVector & ) const; // \ru Третья производная. \en The third derivative with respect. + virtual void Normal ( double & t, MbVector & ) const;// \ru Вектор главной нормали. \en Vector of the principal normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. Ограниченная кривая продолжается в соответствии с уравнениями кривой. + \en \name Functions for working inside and outside of the curve domain. + _PointOn, _FirstDer, _SecondDer, _ThirdDer,... functions don't correct parameter + when it runs out the domain. The bounded curve is extended due to the equations of curve. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void _FirstDer ( double t, MbVector & ) const; // \ru Первая производная. \en The first derivative. + virtual void _SecondDer( double t, MbVector & ) const; // \ru Вторая производная. \en The Second derivative. + virtual void _ThirdDer ( double t, MbVector & ) const; // \ru Третья производная. \en The third derivative with respect. + virtual void _Normal ( double t, MbVector & ) const;// \ru Вектор главной нормали. \en Vector of the principal normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + /** \ru \name Функции движения по кривой + \en \name Functions of moving along the curve + \{ */ + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of the approximation step + virtual double DeviationStep( double t, double angle ) const; + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of the curve + \{ */ + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual double GetMetricLength() const; // \ru Выдать метрическую длину кривой \en Get the metric length of the curve + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate metric length + virtual double GetLengthEvaluation() const; + virtual double Curvature( double t ) const; // \ru Кривизна по t \en Curvature by t + // \ru Посчитать метрическую длину дуги от параметра t1 до t2. \en Calculate the metric length of the arc from parameter 't1' to 't2'. + virtual double CalculateLength( double t1, double t2 ) const; + // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на кривую \en Projection of a point onto the curve + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Projection of the point onto the curve or its extension in the projection region + // \ru Вычисление всех касательных к кривой из данной точки \en Calculation of all the tangents to the curve from a given point + virtual void TangentPoint( const MbCartPoint & pnt, SArray & tFind ) const; + // \ru Вычисление всех перпендикуляров к кривой из данной точки \en Calculation of all the perpendiculars to the curve from a given point + virtual void PerpendicularPoint( const MbCartPoint & pnt, SArray & tFind ) const; + // \ru Нахождение ближайшего перпендикуляра к кривой из данной точки \en Calculation of the closest perpendicular to the curve from the given point + virtual bool SmallestPerpendicular( const MbCartPoint & pnt, double & tProj ) const; + + virtual void IntersectHorizontal( double y, SArray & cross ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with a horizontal line + virtual void IntersectVertical ( double x, SArray & cross ) const; // \ru Пересечение с вертикальной прямой \en Intersection with a vertical line + + virtual bool GetCentre( MbCartPoint & c ) const; ///< \ru Вернуть центр эллипса или окружности. \en Return the center of an ellipse or a circle. + virtual const MbCartPoint & GetCentre() const; ///< \ru Вернуть центр эллипса или окружности. \en Return the center of an ellipse or a circle. + virtual bool GetMiddlePoint( MbCartPoint & p ) const; // \ru Выдать среднюю точку дуги окружности \en Get the middle point of a circular arc + virtual bool GetWeightCentre( MbCartPoint & p ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en Count of splittings for pass in operations + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curves equally spaced by the arc length + + virtual bool HasLength( double & length ) const; + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS-copy of the curve + virtual MbContour * NurbsContour() const; + + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + virtual MbCurve * Offset ( double rad ) const; // \ru Смещение дуги эллипса \en Elliptical arc offset + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru Возвращает результат: \en Returning result: + // \ru iloc_InItem = 1 - точка находится слева по направлению обхода, \en Iloc_InItem = 1 - the point is on the left, + // \ru iloc_OnItem = 0 - точка находится на окружности, \en Iloc_OnItem = 0 - the point is on the circle, + // \ru iloc_OutOfItem = -1 - точка находится справа по направлению обхода. \en Iloc_OutOfItem = -1 - the point is on the right. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть усеченной кривой между параметрами t1 и t2 \en Delete a part of a trimmed curve between parameters t1 and t2 + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть усеченной кривой между параметрами t1 и t2 \en Keep a part of a trimmed curve between parameters t1 and t2 + + /** \brief \ru Модифицировать эллипс по характерной точке. + \en Modify the ellipse by a characteristic point. \~ + \param[in] ind - \ru Номер характерной точки. Возможные значения:\n + 0 - Центр эллипса.\n + 1 - Точка на эллипсе, соответствующая 0 гр.\n + 2 - Точка на эллипсе, соответствующая 90 гр.\n + 3 - Точка на эллипсе, соответствующая 180 гр.\n + 4 - Точка на эллипсе, соответствующая 270 гр. + \en Index of a characteristic point. Possible values:\n + 0 - Ellipse center.\n + 1 - The point on ellipse corresponding to 0 degrees.\n + 2 - The point on ellipse corresponding to 90 degrees.\n + 3 - The point on ellipse corresponding to 180 degrees.\n + 4 - The point on ellipse corresponding to 270 degrees. \~ + \param[in] pnt - \ru Характерная точка. + \en Characteristic point. \~ + \return \ru true - если операция прошла успешно. Иначе возвращает false. + \en True - if the operation succeeded. Otherwise returns false. \~ + */ + bool ModifyByPoint( size_t ind, const MbCartPoint & pnt ); // \ru Модификация по характерным точкам \en Modification by the characteristic points + + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + virtual void Isoclinal( const MbVector & angle, SArray & tFind ) const; // \ru Прямые, проходящие под углом к оси 0X и касательные к кривой \en Lines passing angularly to the 0X axis and tangent to the curve + virtual bool GetAxisPoint( MbCartPoint & p ) const; // \ru Точка для построения оси \en A point for the axis construction + + /// \ru Проверить с заданной точностью, является ли эллипс окружностью. \en Check whether the ellipse is a circle with a given tolerance. + bool IsCircle( double eps = PARAM_EPSILON ) const; + /** \} */ + /** \ru \name Функции в локальной системе координат плейсмента объекта. + \en \name Functions in the local coordinate system of object placement. + \{ */ + /// \ru Выдать локальную систему координат объекта. \en Get the local coordinate system of an object. + const MbPlacement & GetPlacement() const { return position; } + /// \ru Изменить локальную систему координат объекта. \en Modify the local coordinate system of the object. + void SetPlacement( const MbPlacement & pl ) { position = pl; Refresh(); } + /// \ru Определить, является ли локальная система координат ортонормированной. \en Determine whether the local coordinate system is orthonormalized. + bool IsPositionNormal() const { return ( position.IsNormal() ); } + /// \ru Определить, является ли локальная система координат ортогональной с равными по длине осями X,Y. \en Determine whether the local coordinate system is orthogonal with X and Y axes equal by length. + bool IsPositionCircular() const { return ( position.IsCircular() ); } + /// \ru Определить, является ли локальная система координат ортогональной и изотропной по осям. \en Determine whether the local coordinate system is orthogonal and isotropic by the axes. + bool IsPositionIsotropic() const { return ( position.IsIsotropic()); } + + /** \brief \ru Вычислить угол в локальной системе координат. + \en Calculate the angle in the local coordinate system. \~ + \details \ru Вычислить угол между осью OX локальной системы координат и + лучом, выходящим из начала локальной системы координат и проходящим через точку p. + \en Calculate the angle between OX axis of the local coordinate system and + the ray starting from the origin of local coordinate system and passing through point p. \~ + \param[in] p - \ru Заданная точка. + \en A given point. \~ + \return \ru Значение угла. + \en Value of angle. \~ + */ + double GetPositionAngle( const MbCartPoint & p ) const; // \ru Вычисление угла в локальной системе \en Calculation of angle in the local system + + /** \brief \ru Инициализация параметров эллипса. + \en Initialization of the ellipse parameters. \~ + \details \ru Параметры вычисляются в соответствии с направлением и углами, + соответствующими началу и концу дуги, вычисленными в локальной системе координат. + \en Parameters are calculated subject to the directions and angles + corresponding to the beginning and the end of the arc calculated in the local coordinate system. \~ + \param[in] a1 - \ru Угол, соответствующий началу дуги. + \en The angle corresponding to the beginning of the arc. \~ + \param[in] a2 - \ru Угол, соответствующий концу дуги. + \en The angle corresponding to the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + \return \ru Значение угла. + \en Value of angle. \~ + */ + void InitByPositionAngles( double a1, double a2, int initSense ); // \ru Инициализация параметров по значениям углов в локальной системе \en Initialization of the parameters by values of angles in the local system + /** \} */ + /** \ru \name Функции для работы с данными. + \en \name Functions for working with data. + \{ */ + double GetR() const { return a; } ///< \ru Вернуть радиус или длину полуоси вдоль X для эллипса. \en Return the radius and the length of semiaxis along X for the ellipse + double GetRadiusA() const { return a; } ///< \ru Вернуть длину полуоси вдоль X. \en Return the length of semiaxis along X. + double GetRadiusB() const { return b; } ///< \ru Вернуть длину полуоси вдоль Y. \en Return the length of semiaxis along Y. + void SetRadiusA( double aa ) { a = aa; Refresh(); } ///< \ru Установить длину полуоси вдоль X. \en Set the length of semiaxis along X. + void SetRadiusB( double bb ) { b = bb; Refresh(); } ///< \ru Установить длину полуоси вдоль Y. \en Set the length of semiaxis along Y. + double GetAngle() const { return (trim2 - trim1); } ///< \ru Вернуть угол раствора дуги. \en Return the arc opening angle. + /// \ru Установить угол раствора дуги. Начальная точка дуги остается неизменной. \en Set the arc opening angle. The start point of the arc remains unchanged. + void SetAngle ( double ang ) { InitByPositionAngles( trim1, sense ? (trim1+ang) : (trim1-ang), sense ); } + + /// \ru Вычислить угол между осями OX локальной и глобальной системой координат. \en Calculate the angle between OX axes of the local and the global coordinate systems. + double GetMajorAxisAngle() const { return position.GetAxisX().DirectionAngle(); } + + double GetTrim1() const { return trim1; } ///< \ru Вернуть параметр начальной точки. \en Return the parameter of the start point. + double GetTrim2() const { return trim2; } ///< \ru Вернуть параметр конечной точки. \en Return the parameter of the end point. + int GetSense() const { return trim2 > trim1 ? 1 : -1; } ///< \ru Определить флаг совпадения направления с направлением базовой кривой. \en Determine the flag of coincidence of the direction with the base curve direction. + void SetTrim1( double t ) { trim1 = t; InitByPositionAngles( trim1, trim2, sense ); } ///< \ru Установить параметр начальной точки. \en Set the parameter of the start point. + void SetTrim2( double t ) { trim2 = t; InitByPositionAngles( trim1, trim2, sense ); } ///< \ru Установить параметр конечной точки. \en Set the parameter of the end point. + + /// \ru Установить радиус дуги окружности. \en Set the radius of the circular arc. + void SetRadius( double rad ) { + a = rad; + b = rad; + Refresh(); + } + /// \ru Установить центр. \en Set the center. + void SetCentre( const MbCartPoint & c ) { + position.SetOrigin( c ); // \ru Установить центр \en Set the center + Refresh(); + } + /// \ru Установить направление дуги. \en Set the arc orientation. + void SetDirection( bool clockwise ) { + int newSense = clockwise ? - 1 : + 1; + if ( newSense != GetSense() ) { + InitByPositionAngles( trim1, trim2, newSense ); + } + } + /// \ru Инициализировать дуги эллипса заданной дугой. \en Initialize elliptical arcs with the given arc. + void Init( const MbArc & ); + /// \ru Инициализировать окружность по центру и радиусу \en Initialize a circle by the center and the radius + void Init( const MbCartPoint & pc, double rad ); + /// \ru Инициализировать дугу по начальному и конечному параметрам. \en Initialize arc by parameters for begin point and end point. + void Init( double t1, double t2 ); + + /** \brief \ru Инициализировать дугу окружности. + \en Initialize a circular arc. \~ + \details \ru Инициализировать дугу окружности, проходящую через все 3 заданные точки. + Точки p1 и p3 - крайние. Если дуга не замкнута, то направление движения по дуге определяется так, + чтобы точка p2 лежала на дуге. + \en Initialize a circular arc passing through all 3 given points. + Points p1 and p3 are the end points. If the arc is not closed, then the direction of moving along the arc is defined so as + the point p2 lies on the arc. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Точка, лежащая на дуге. + \en A point on the arc. \~ + \param[in] p3 - \ru Конец дуги. + \en End of the arc. \~ + \param[in] cl - \ru Признак замкнутости. + \en Closedness attribute. \~ + */ + void Init3Points( const MbCartPoint & p1, const MbCartPoint & p2, const MbCartPoint & p3, bool cl ); + + /** \brief \ru Инициализировать дугу окружности. + \en Initialize a circular arc. \~ + \details \ru Инициализировать дугу окружности, проходящую через все 3 заданные точки. + Точки p1 и p3 - крайние. Направление движения по дуге определяется так, + чтобы точка p2 лежала на дуге. + \en Initialize a circular arc passing through all 3 given points. + Points p1 and p3 are the end points. The direction of moving along the arc is defined so as + the point p2 lies on the arc. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Точка, лежащая на дуге. + \en A point on the arc. \~ + \param[in] p3 - \ru Конец дуги. + \en End of the arc. \~ + */ + void InitCircle( const MbCartPoint & p1, const MbCartPoint & p2, const MbCartPoint & p3 ); + + /** \brief \ru Инициализировать дугу окружности. + \en Initialize a circular arc. \~ + \details \ru Задается новое положение центра дуги, центр дуги будет расположен на биссектрисе угла раствора. + \en A new position of the arc center is specified, the arc center will be located on the bisector of the opening angle. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Конец дуги. + \en End of the arc. \~ + */ + void InitArc( MbCartPoint & pc, const MbCartPoint & p1, const MbCartPoint & p2 ); + + /** \brief \ru Инициализировать дугу окружности. + \en Initialize a circular arc. \~ + \details \ru Изменяется центр и радиус окружности. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en The center and the radius of the circle is being modified. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( const MbCartPoint & pc, double rad, + const MbCartPoint & p1, const MbCartPoint & p2, bool clockwise ); + + // \ru Инициализация по центру и точке на дуге ( 360 градусов ) \en Initialization by the center and a point on the arc (360 degrees) + /** \brief \ru Инициализировать окружность. + \en Initialize a circle. \~ + \details \ru Исходный объект изменяется на окружность с центром в точке pc. + Радиус определяется как расстояние между точками pc и p . + \en The source object is changed to a circle with center in point 'pc'. + The radius is determined as a distance between points pc and p. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] p - \ru Точка на окружности. + \en Point on circle. \~ + */ + void Init( const MbCartPoint & pc, const MbCartPoint & p ); + + // \ru Первая точка, угол, радиус ( 360 градусов ) \en The first point, angle and radius (360 degrees) + /** \brief \ru Инициализировать окружность. + \en Initialize a circle. \~ + \details \ru Исходный объект изменяется на окружность, проходящую через точку p1 с заданным радиусом. + Угол angle определяет прямую, на которой лежит центр окружности. Это угол между лучем, + выходящим из точки p1 в сторону центра окружности и осью OX. + \en The source object is changed to a circle passing through point p1 with the given radius. + Angle 'angle' specifies a line the circle's center lies on. It is the angle between a ray + starting from point p1 and directed to the circle's center and OX axis. \~ + \param[in] p1 - \ru Точка на окружности. + \en Point on circle. \~ + \param[in] angle - \ru Угол, определяющий положение центра окружности. + \en An angle specifying the position of the center on the circle. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + */ + void Init( const MbCartPoint & p1, double angle, double rad ); + + // \ru центр, точка на окружности, начальный угол ( 360 градусов ) \en Center, a point on the circle, initial angle (360 degrees) + /** \brief \ru Инициализировать окружность. + \en Initialize a circle. \~ + \details \ru Исходный объект изменяется на окружность с заданным центром, проходящую через точку pnt. + Радиус определяется как расстояние между точками pc и pnt. + \en The source object is changed to a circle with the given center and passing through point pnt. + The radius is determined as the distance between points pc and pnt. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] pnt - \ru Точка на окружности. + \en Point on circle. \~ + \param[in] angle - \ru Начальный параметр. + \en Get the start parameter. \~ + */ + void Init( const MbCartPoint & pc, const MbCartPoint & pnt, double angle ); + + // \ru Центр, угол первой точки, угол второй точки, радиус, направление \en Centre, angle of the first point, angle of the second point, radius, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Исходный объект изменяется на дугу окружности с заданным центром и радиусом. + angle1 и angle2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en The source object is changed to a circular arc with the given center and radius. + angle1 and angle2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] angle1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] angle2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( const MbCartPoint & pc, double angle1, double angle2, double rad, bool clockwise ); + + // \ru центр, точка, номер точки, угол другой точки, направление \en Center, point, index of point, angle of another point, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Исходный объект изменяется на дугу окружности с заданным и проходящую через точку pnt. + Радиус определяется как расстояние между точками pc и pnt. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en The source object is changed to a circular arc with the given center and passing through point pnt. + The radius is determined as the distance between points pc and pnt. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] pnt - \ru Крайняя точка дуги окружности. + \en End point of the circular arc. \~ + \param[in] firstPoint - \ru Флаг, определяющий, является точка pnt начальной. + \en Flag determining whether the point pnt is the start point. \~ + \param[in] angle - \ru Угол между радиусом, идущим ко второй точки и осью OX. + \en The angle between the radius to the second point and the OX axis. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( const MbCartPoint & pc, const MbCartPoint & pnt, bool firstPoint, double angle, bool clockwise ); + + // \ru центр, угол первой точки, вторая точка, радиус, направление \en Center, angle of the first point, the second point, radius, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Исходный объект изменяется на дугу окружности с заданным центром и радиусом. + Конечная точка дуги определяется как пересечение луча (pc, p2) и окружности. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en The source object is changed to a circular arc with the given center and radius. + The end point of the arc is determined as intersection of ray (pc, p2) and the circle. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] angle1 - \ru Начальный параметр дуги. + \en The start parameter of the circle. \~ + \param[in] p2 - \ru Точка, определяющая угол конца дуги окружности. + \en A point specifying the angle of the circular arc end. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + void Init( const MbCartPoint & pc, double angle1, const MbCartPoint & p2, double rad, bool clockwise ); + + // \ru Окружность, первая точка, вторая точка, направление \en Circle, the first point, the second point, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Исходный объект изменяется на дугу окружности, соответствующей заданному объекту. + Начальная и конечная точки дуги определяются как пересечения лучей, направленных из центра к точкам p1 и p2 c окружностью. + Конечная точка дуги определяется как пересечение луча (pc, p2) и окружности. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en The source object is changed to a circular arc corresponding to a given object. + The start and the end point of the arc is determined as intersection of rays passing from the center to points p1 and p2 with the circle. + The end point of the arc is determined as intersection of ray (pc, p2) and the circle. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] obj - \ru Объект-образец. + \en A pattern object. \~ + \param[in] p1 - \ru Точка, определяющая угол начала дуги окружности. + \en A point determining the angle of the beginning of the circular arc. \~ + \param[in] p2 - \ru Точка, определяющая угол конца дуги окружности. + \en A point specifying the angle of the circular arc end. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + void Init( MbArc * obj, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); + + // \ru Первая точка, вторая точка, угол, номер угла, направление \en The first point, the second point, angle, index of angle, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru В результате операции получаем дугу окружности, которая начинается в точке p1 и заканчивается в точке p2. + Для одной из точек задан угол между направлением от нее до центра окружности и осью OX. + Параметр firstAngle определяет, для какой точке задан угол. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en In the result of the operation the circular arc is obtained which starts at point p1 and ends at point p2. + For one of points the angle between the direction from the point to the circle center and the OX axis is specified. + Parameter firstAngle determines for which of points the angle is specified. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] p1 - \ru Начальная точка дуги окружности. + \en The start point of the circular arc. \~ + \param[in] p2 - \ru Конечная точка дуги окружности. + \en The end point of the circular arc. \~ + \param[in] angle - \ru Угол между направлением из точки на центр окружности осью OX. + \en The angle between the direction from the point to the circle center and OX axis. \~ + \param[in] firstAngle - \ru Флаг, определяющий для какой точки задан угол. firstAngle == true - для первой. + \en Flag determining for which point the angle is specified. firstAngle == true - for the first one. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( const MbCartPoint & p1, const MbCartPoint & p2, double angle, bool firstAngle, bool clockwise ); + + // \ru Плавающий центр, угол первой точки, угол второй точки, точка, номер точки, направление \en Variable center, angle of the first point, angle of the second point, index of the point, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru В результате операции получаем дугу окружности, одним из концов которой является точка pnt. + Для этой точки задан угол между прямой - направлением от точки к центру окружности и осью OX. + Для определения центра окружности находим проекцию pc на эту прямую. + Второй угол определяет второй конец дуги. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en In the result of the operation a circular arc is obtained one of ends of which is point pnt. + For this point the angle between the line directed from the point to the circle center and OX axis is specified. + Find projection pc onto this line to determine the circle center. + The second angle specifies the second end of the arc. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in, out] pc - \ru На входе - заданная точка, на выходе - центр окружности. + \en On input - the given point, on output - the circle center. \~ + \param[in] angle1 - \ru Угол между направлением от начальной точки дуги на центр окружности и осью OX. + \en Angle between the direction from the starting point of the arc to the circle center and OX axis. \~ + \param[in] angle2 - \ru Угол между направлением от конечной точки дуги на центр окружности и осью OX. + \en Angle between the direction from the end point of the arc to the circle center and OX axis. \~ + \param[in] pnt - \ru Крайняя точка дуги окружности. + \en End point of the circular arc. \~ + \param[in] firstPoint - \ru Флаг, определяющий, является ли точка pnt начальной. + \en Flag determining whether the point pnt is a starting point. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( MbCartPoint & pc, double angle1, double angle2, + const MbCartPoint & pnt, bool firstPoint, bool clockwise ); + + // \ru Плавающий центр, точка, номер точки, угол противоположной точки, радиус, направление \en Variable center, point, index of the point, angle of the opposite point, radius, direction + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Исходный объект изменяется на дугу окружности с заданным радиусом и проходящую через точку p. + Надо определить центр окружности так, чтобы он был как можно ближе к заданной точке pc. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en The source object is changed to the circular arc with the given radius and passing through point p. + The circle center should be defined so as it is as close to the given point pc as possible. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in, out] pc - \ru На входе - заданная точка, на выходе - центр окружности. + \en On input - the given point, on output - the circle center. \~ + \param[in] p - \ru Крайняя точка дуги окружности. + \en End point of the circular arc. \~ + \param[in] firstPoint - \ru Флаг, определяющий, является ли точка pnt начальной. + \en Flag determining whether the point pnt is a starting point. \~ + \param[in] angle - \ru Угол между радиусом, идущим ко второй точки и осью OX. + \en The angle between the radius to the second point and the OX axis. \~ + \param[in] rad - \ru Радиус. + \en Radius. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( MbCartPoint & pc, const MbCartPoint & p, bool firstPoint, + double angle, double rad, bool clockwise ); + + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru В результате операции получаем дугу окружности с центром в точке pc. + Радиус определяется как расстояние между точками pc и p1. + Направления от центра к точкам p1 и p2 задают углы, определяющие начало и конец дуги. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en In the result of the operation the circular arc is obtained with the center in point pc. + The radius is determined as the distance between points 'pc' and 'p1'. + Directions from the center to points p1 and p2 specify the angles determining the start and the end of the circle. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] p1 - \ru Точка, определяющая направление на начало дуги окружности. + \en A point specifying the direction to the beginning of the circular arc. \~ + \param[in] p2 - \ru Точка, определяющая направление на конец дуги окружности. + \en A point specifying the direction to the end of the circular arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + void Init( const MbCartPoint & pc, const MbCartPoint & p1, const MbCartPoint & p2, int initSense ); + + // \ru NES 9.12.2011 не нашла реализации этой функции. \en NES 9.12.2011 didn't find the implementation of this function. + // void Init( double t1, double t2, int initSense ); + + // \ru Инициализация по начальной и конечной точкам и 1/2 угла раствора дуги \en Initialization by the starting and end points and 1/2 of the arc opening angle + // \ru Если diskrData != NULL, то округлить радиус и скорректировать первую \en If diskrData != NULL, then round the radius and correct the first + // \ru Или вторую точку (зависит от correctFirstPnt) \en Or the second point (depends on correctFirstPnt) + /** \brief \ru Инициализировать дугу окружность. + \en Initialize a circular arc. \~ + \details \ru Инициализация происходит по начальной и конечной точкам и 1/2 угла раствора дуги. + Если diskrData != NULL, радиус округляется и корректируется первая + или вторая точка (зависит от correctFirstPnt). + \en The initialization is performed by the starting and end points and 1/2 of the arc opening angle. + If diskrData != NULL, the radius is rounded and the first + or the second point is corrected (depends on correctFirstPnt). \~ + \param[in] a2 - \ru 1/2 угла раствора дуги окружности. + \en 1/2 of the circular arc opening angle. \~ + \param[in, out] p1 - \ru Начальная точка дуги. Может быть скорректирована после округления радиуса. + \en The starting point of the arc. Can be corrected after rounding the radius. \~ + \param[in, out] p2 - \ru Конечная точка дуги. Может быть скорректирована после округления радиуса. + \en The end point of the arc. Can be corrected after rounding the radius. \~ + \param[in] diskrData - \ru Структура для округления радиуса. + \en The structure for rounding the radius. \~ + \param[in] correctFirstPnt - \ru Определяет, какую точку корректировать после округления. + correctFirstPnt == true - корректируется первая точка. + \en Determines which point to be corrected after the rounding. + correctFirstPnt == true - the first point is to be corrected. \~ + */ + void Init( double a2, MbCartPoint & p1, MbCartPoint & p2, + const DiskreteLengthData * diskrData = NULL, + bool correctFirstPnt = true ); + // \ru Инициализация эллипса \en Ellipse initialization + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс с заданными локальной системой координат и полуосями. + \en In the result of the operation the ellipse is obtained with the given local coordinate system and semiaxes. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] place - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + */ + void Init( double aa, double bb, const MbPlacement & place ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс с заданными полуосями. + Локальная система координат эллипса имеет начало в точке pc и + ось OX локальной системы координат составляет с осью OX текущей системы координат угол ang. + Направление поворота - от оси текущей системы координат к оси новой системы координат. + \en In the result of the operation the ellipse is obtained with the specified semiaxes. + The ellipse local coordinate system has origin in point pc; + OX axis of the local coordinate system forms angle ang with OX axis of the current coordinate system. + The turning direction - from the axis of the current coordinate system to the axis of the new coordinate system. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] pc - \ru Начало локальной системы координат эллипса. + \en Origin of local coordinate system of ellipse. \~ + \param[in] ang - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init( double aa, double bb, const MbCartPoint & pc, double ang ); + + // \ru Различные варианты построения эллипса \en Different variants of ellipse construction + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс с центром в точке c. + Длина полуоси эллипса, идущая вдоль оси X, определяется как расстояние между точками c и p1. + Длина второй полуоси 0. + Определяются угол между осями OX локальной системы координат эллипса и текущей системы координат. + \en In the result of the operation an ellipse is obtained with center in point c. + The length of ellipse semiaxis along X-axis is determined as the distance between points c and p1. + The length of the second semiaxis is 0. + The angle between OX axes of the ellipse's local coordinate system and the current coordinate system. \~ + \param[in] c - \ru Центр эллипса. + \en The ellipse center. \~ + \param[in] p1 - \ru Точка, лежащая на эллипсе. + \en A point on ellipse. \~ + \param[out] len - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init1( const MbCartPoint & c, const MbCartPoint & p1, + double & len, double & angle ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс с центром в точке c. + Точка p1 определяет направление оси OX локальной системы координат эллипса и длину полуоси вдоль X. + Точка p2 - длину полуоси вдоль Y, как расстояние от точки до оси OX локальной системы координат. + Точка p2 изменяется так, чтобы она лежала на пересечении эллипса с осью OY локальной системы координат. + \en In the result of the operation an ellipse is obtained with center in point c. + Point p1 determines the direction of OX axis of ellipse's local coordinate system and the length of semiaxis along X. + Point p2 determines the length of semiaxis along Y as the distance from the point to the OX axis of the local coordinate system. + Point p2 is changed so as it lies on intersection of the ellipse with OY axis of the local coordinate system. \~ + \param[in] c - \ru Центр эллипса. + \en The ellipse center. \~ + \param[in] p1 - \ru Точка, лежащая на эллипсе, определяет ось OX. + \en A point on ellipse specifies OX axis. \~ + \param[in, out] p2 - \ru Определяет длину полуоси вдоль Y. На выходе - точка, лежащая на пересечении эллипса с осью OY локальной системы координат. + \en Specifies the length of semiaxis along Y. On output - point on intersection of ellipse with OY axis of the local coordinate system. \~ + \param[out] lenB - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + */ + void Init2( const MbCartPoint & c, const MbCartPoint & p1, + MbCartPoint & p2, double & lenB ); + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс, вписанный в повернутый прямоугольник, + заданный точкой центра c, вершиной p1 и углом наклона angle. + Ось OX локальной системы координат эллипса будет направлена в соответствии с углом angle. + \en In the result of the operation an ellipse is obtained inscribed into the rotated rectangle + specified by the point of center c, the vertex p1 and the slope angle 'angle'. + OX-axis of the local coordinate system of the ellipse will be oriented according to the angle 'angle'. \~ + \param[in] c0 - \ru Центр прямоугольника. + \en The center of the rectangle. \~ + \param[in] p1 - \ru Вершина прямоугольника. + \en The rectangle vertex. \~ + \param[in] angle - \ru Угол наклона прямоугольника. + \en Slope angle of the rectangle. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + */ + void Init3( const MbCartPoint & c0, const MbCartPoint & p1, + double angle, double & aa, double & bb ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс, вписанный в повернутый прямоугольник, + заданный двумя диагональными точками p1, p2 и углом наклона angle. + Ось OX локальной системы координат эллипса будет направлена в соответствии с углом angle. + \en In the result of the operation an ellipse is obtained inscribed into the rotated rectangle + specified by two diagonal points p1 and p2 and the slope angle 'angle'. + OX-axis of the local coordinate system of the ellipse will be oriented according to the angle 'angle'. \~ + \param[in] p1 - \ru Вершина прямоугольника. + \en The rectangle vertex. \~ + \param[in] p2 - \ru Вершина прямоугольника. + \en The rectangle vertex. \~ + \param[in] angle - \ru Угол наклона прямоугольника. + \en Slope angle of the rectangle. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + */ + void Init4( const MbCartPoint & p1, const MbCartPoint & p2, + double angle, double & aa, double & bb ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс, вписанный в параллелограмм, + заданный тремя точками: центром параллелограмма (c), серединой одной из его сторон (p1) + и одной вершин этой стороны (p2). + Ось OX локальной системы координат эллипса будет проходить через точку p2. + \en In the result of the operation an ellipse is obtained inscribed into the parallelogram + given by three points: center of parallelogram (c), middle of one of its sides (p1) + and one of vertices of this side (p2). + OX-axis of the local coordinate system of the ellipse will pass through the point p2. \~ + \param[in] c - \ru Центр параллелограмма. + \en The center of parallelogram. \~ + \param[in] p1 - \ru Середина стороны параллелограмма. + \en The middle of a side of the parallelogram. \~ + \param[in] p2 - \ru Вершина параллелограмма. + \en A vertex of the parallelogram. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + \param[out] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init5( const MbCartPoint & c, const MbCartPoint & p1, const MbCartPoint & p2, + double & aa, double & bb, double & angle ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс, вписанный в параллелограмм, + заданный тремя вершинами. + Ось OX локальной системы координат эллипса будет параллельна отрезку [p1 p2]. + \en In the result of the operation an ellipse is obtained inscribed into the parallelogram + given by three vertices. + OX-axis of the local coordinate system of the ellipse will be parallel to the segment [p1 p2]. \~ + \param[in] p1 - \ru Вершина параллелограмма. + \en A vertex of the parallelogram. \~ + \param[in] p2 - \ru Вершина параллелограмма. + \en A vertex of the parallelogram. \~ + \param[in] p3 - \ru Вершина параллелограмма. + \en A vertex of the parallelogram. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + \param[out] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init6( const MbCartPoint & p1, const MbCartPoint & p2, const MbCartPoint & p3, + double & aa, double & bb, double & angle ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru В результате операции получаем эллипс, построенный + по центру pc и трем точкам на нем p1, p2, p3 + \en In the result of the operation an ellipse is obtained constructed + by the center pc and three points on it p1, p2, p3 \~ + \param[in] pc - \ru Центр эллипса. + \en The ellipse center. \~ + \param[in] p1 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[in] p2 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[in] p3 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + \param[out] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init7( const MbCartPoint & pc, + MbCartPoint p1, MbCartPoint p2, MbCartPoint p3, + double & aa, double & bb, double & angle ); + + /** \brief \ru Инициализировать эллипс. + \en Initialize an ellipse. \~ + \details \ru Для построения эллипса имеем две точки на эллипсе и касательные в этих точках + и третью точку, лежащую на эллипсе. + \en For ellipse construction we have two points on ellipse and tangent lines at these points + and the third point on the ellipse. \~ + \param[in] p1 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[in] dir1 - \ru Направление касательной к эллипсу в точке p1. + \en The direction of tangent line to ellipse at point p1. \~ + \param[in] p2 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[in] dir2 - \ru Направление касательной к эллипсу в точке p2. + \en The direction of tangent line to ellipse at point p2. \~ + \param[in] p3 - \ru Точка на эллипсе. + \en A point on ellipse. \~ + \param[out] aa - \ru Длина полуоси вдоль X. + \en The length of semiaxis along X. \~ + \param[out] bb - \ru Длина полуоси вдоль Y. + \en The length of semiaxis along Y. \~ + \param[out] angle - \ru Угол между осями OX локальной и текущей системами координат. + \en An angle between OX axes of the local and the current coordinate systems. \~ + */ + void Init8( const MbCartPoint & p1, const MbDirection & dir1, + const MbCartPoint & p2, const MbDirection & dir2, + const MbCartPoint & p3, + double & aa, double & bb, double & angle ); + // \ru Различные варианты построения дуги эллипса \en Different variants of elliptical arc construction + /** \brief \ru Инициализировать дугу эллипса. + \en Initialize an elliptical arc. \~ + \details \ru В результате операции получаем дугу эллипса с заданными полуосями и локальной системой координат. + t1 и t2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en In the result of the operation an elliptical arc is obtained with the specified semiaxes and the local coordinate system. + t1 and t2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the orientation is counterclockwise. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] place - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + \param[in] t1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] t2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - counterclockwise, initSense < 0 - clockwise. + initSense can't be equal to zero. \~ + */ + void Init( double aa, double bb, const MbPlacement & place, + double t1, double t2, int initSense ); + + /** \brief \ru Инициализировать дугу эллипса. + \en Initialize an elliptical arc. \~ + \details \ru В результате операции получаем дугу эллипса с заданными полуосями и локальной системой координат. + Точки p1 и p2 определяют границы дуги. + Начальная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p1. + Конечная точка - на луче, проходящем через точку p2. + Параметр clockwise определяет направление дуги. Если clockwise > 0, то направление движения против часовой стрелки. + \en In the result of the operation an elliptical arc is obtained with the specified semiaxes and the local coordinate system. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'clockwise' specifies the direction of the arc. If clockwise > 0, then the direction of moving is counterclockwise. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] place - \ru Локальная система координат эллипса. + \en The local coordinate system of the ellipse. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init( double aa, double bb, const MbPlacement & place, + const MbCartPoint & p1, const MbCartPoint & p2, bool clockwise ); + + // \ru Эллипс вписан в прямоугольник, заданный двумя диагональными точками p1, p2, \en Ellipse is inscribed into the rectangle given by two diagonal points p1, p2, + // \ru проекции точек pB и pE на эллипс определяют начало и конец дуги, \en The projections of points pB and pE onto ellipse determine the start and the end of the arc, + // \ru clockwise определяет движение от начальноц точки к конечной по часовой стрелке или против \en 'clockwise' determines moving from the starting point to the end point clockwise or counterclockwise + /** \brief \ru Инициализировать дугу эллипса. + \en Initialize an elliptical arc. \~ + \details \ru Эллипс вписан в прямоугольник, заданный двумя диагональными точками p1, p2. + Стороны прямоугольника параллельны осям текущей системы координат. + Проекции точек pB и pE на эллипс определяют начало и конец дуги. + clockwise определяет движение от начальноц точки к конечной по часовой стрелке или против. + \en Ellipse is inscribed into the rectangle given by two diagonal points p1 and p2. + Sides of the rectangle are parallel to the axes of the current coordinate system. + The projections of points pB and pE onto ellipse determine the start and the end of the arc. + 'clockwise' determines moving form the start point to the end point clockwise or counterclockwise. \~ + \param[in] p1 - \ru Вершина прямоугольника. + \en The rectangle vertex. \~ + \param[in] p2 - \ru Вершина прямоугольника. + \en The rectangle vertex. \~ + \param[in] pB - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] pE - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] clockwise - \ru Направление. clockwise > 0 - движение против часовой стрелки, clockwise < 0 - по часовой стрелке. + clockwise не должно быть равным нулю. + \en Direction. clockwise > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'clockwise' can't be equal to zero. \~ + */ + void Init4( const MbCartPoint & p1, const MbCartPoint & p2, + const MbCartPoint & pB, const MbCartPoint & pE, bool clockwise = false ); + + bool OnSector( const MbCartPoint & pnt ) const; ///< \ru Определить, находится ли луч от центра до точки в секторе дуги. \en Determine whether the ray from the center to the point is in the arc's sector. + + /** \brief \ru Определить попадание в сектор дуги. + \en Determine whether the ray hits the arc's sector. \~ + \details \ru Анализируется попадание в сектор дуги луча, выходящего из центра + и имеющего с осью OX текущей системы координат угол angle. + \en It is analyzed if the ray starting from the center and forming + the angle 'angle' with OX-axis of the current coordinate system hits the arc's sector. \~ + \param[in] angle - \ru Угол между анализируемым направлением и осью OX текущей системы координат. + \en The angle between the direction being analyzed and the OX-axis of the current coordinate system. \~ + \result \ru true, если направление попадает в сектор дуги. + \en True if the direction hits the arc's sector. \~ + */ + bool OnSector( double angle ) const; // \ru Находится угол в секторе дуги ? \en Is the angle in the arc's sector? + + /** \brief \ru Заменить точку дуги. + \en Replace the arc's point. \~ + \details \ru Происходит построение дуги эллипса по крайним точкам с сохранением угла раствора дуги. + \en The reconstruction of the elliptical arc by the end points is performed keeping the arc opening angle. \~ + \param[in] number - \ru Номер крайней точки дуги. 1 - начало дуги, 2 - конец дуги. + \en The index of end point of the arc. 1 - start of arc, 2 - end of arc. \~ + \param[in] pnt - \ru Новая точка. + \en A new point. \~ + */ + void SetLimitPoint( ptrdiff_t number, const MbCartPoint & pnt ); // \ru Заменить точку дуги \en Replace the arc point + /// \ru Вернуть направление дуги: true - по часовой стрелке; false - против часовой стрелки. \en Return the arc direction: true - clockwise, false - counterclockwise. + bool IsClockwise() const { return ( position.IsLeft() == (GetSense() > 0) ); } + + /** \brief \ru Вернуть угол крайней точки дуги. + \en Return the angle of the end point. \~ + \details \ru Угол крайней точки дуги считается относительно оси OX текущей системы координат. + \en The angle of the end point of the arc is measured relative to the OX-axis of the current coordinate system. \~ + \param[in] number - \ru Номер крайней точки дуги. 1 - начало дуги, 2 - конец дуги. + \en The index of end point of the arc. 1 - start of arc, 2 - end of arc. \~ + \result \ru Угол между направлением от центра к крайней точке и осью OX текущей системы координат. + \en The angle between the direction from the center to the end point and OX-axis of the current coordinate system. \~ + */ + double GetLimitAngle( ptrdiff_t number ) const { + double ang = ( number == 1 ) ? trim1 : trim2; + if ( position.IsLeft() ) + ang = -ang; + ang += GetMajorAxisAngle(); // \ru Угол с осью X \en Angle with X axis + c3d::NormalizeAngle( ang); + return ang; + } + + /** \brief \ru Изменить граничный угол дуги. + \en Modify the end angle of the arc. \~ + \param[in] number - \ru Номер крайней точки дуги. 1 - начало дуги, 2 - конец дуги. + \en The index of end point of the arc. 1 - start of arc, 2 - end of arc. \~ + \param[in] pnt - \ru Точка, определяющая направление на новый конец дуги. + \en The point specifying the direction to the new end of the arc. \~ + \result \ru Угол между направлением от центра к крайней точке и осью OX текущей системы координат. + \en The angle between the direction from the center to the end point and OX-axis of the current coordinate system. \~ + */ + void SetLimitAngle( ptrdiff_t number, const MbCartPoint & pnt ) { + if ( number == 1 ) + InitByPositionAngles( GetPositionAngle(pnt), trim2, GetSense() ); + else + InitByPositionAngles( trim1, GetPositionAngle(pnt), GetSense() ); + Refresh(); + } + + inline double CheckParam( double & t ) const; ///< \ru Установить параметр в область допустимых значений. \en Set the parameter to the range of the allowable values. + inline void ParamToAngle( double & t ) const; ///< \ru Перевести параметр кривой в угол. \en Convert the parameter of the curve to the angle. + inline void AngleToParam( double & t ) const; ///< \ru Перевести угол кривой в параметр кривой. \en Convert the curve angle to the curve parameter. + + + void ParameterInto( double &t ) const { AngleToParam( t ); } ///< \ru Перевести параметр базовой кривой в локальный параметр. \en Convert parameter of the base curve to the local parameter. + void ParameterFrom( double &t ) const { ParamToAngle( t ); } ///< \ru Перевести локальный параметр в параметр базовой кривой. \en Convert the local parameter to the parameter of the base curve. + bool IsBaseParamOn( double t, double eps = Math::paramEpsilon ) const; ///< \ru Определить, находится ли параметр базовой кривой в диапазоне усеченной кривой. \en Determine whether the parameter of the base curve is in range of the trimmed curve. + + // \ru Работа с базовым эллипсом \en Work with the basic ellipse + /** \brief \ru Вычислить точку на эллипсе. + \en Evaluate a point on ellipse. \~ + \details \ru Точка вычисляется на замкнутом эллипсе, независимо от того, является объект эллипсом или дугой эллипса. + \en The point is evaluated on a closed ellipse regardless of whether the object is an ellipse or is an elliptical arc. \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[out] pnt - \ru Искомая точка. + \en The required point. \~ + */ + void PointOnBaseEllipse( double & t, MbCartPoint & pnt ) const; // \ru Точка на базовом эллипсе \en A point on the base ellipse + + /** \brief \ru Найти проекцию точки на эллипс. + \en Find the projection of a point onto the ellipse. \~ + \details \ru Точка проецируется на замкнутый эллипсе, независимо от того, является объект эллипсом или дугой эллипса. + \en A point is projected onto the closed ellipse regardless of whether the object is an ellipse or an elliptical arc. \~ + \param[in] pnt - \ru Проецируемая точка. + \en A point to project. \~ + \result \ru Параметр, соответствующий точке проекции. + \en Parameter corresponding to the projected point. \~ + */ + double PointProjectionOnBaseEllipse( const MbCartPoint & pnt ) const; // \ru Проекция на базовом эллипсе \en Projection onto the base ellipse + + void MakeAsBaseEllipse(); ///< \ru Инициализировать как полный эллипс. \en Initialize as complete ellipse. + void CopyBaseEllipse( const MbArc & init ); ///< \ru Cкопировать базовый эллипс. \en Copy the base ellipse. + + /** \brief \ru Определить, самопересекается ли эквидистанта от эллипса. + \en Determine whether the ellipse offset has self-intersections. \~ + \param[in] d - \ru Расстояние эквидистанты. + \en Offset distance. \~ + \result \ru true, если самопересекается. + \en True if it has self-intersections. \~ + */ + bool IsSelfIntersectOffset( double d ) const; // \ru Есть ли самопересечения \en Whether there are self-intersections + // \ru Рассчитать коэффициенты неявного представления эллипса для IGES: Ax2 + Bxy + Cy2 + Dx + Ey + F = 0 \en Calculate coefficients of ellipse's implicit representation for IGES: Ax2 + Bxy + Cy2 + Dx + Ey + F = 0 + bool ParametricToCanonicConic( double & A, double & B, double & C, + double & D, double & E, double & F, + double & X1, double & Y1, double & X2, double & Y2 ) const; + bool Normalize(); ///< \ru Ортонормировать локальную систему координат. \en Orthonormalize the local coordinate system. + void GetControlPoints( SArray & points ); ///< \ru Заполнить массив контрольными точками. \en Fill the array with the control points. + void NormalizeTransform( const MbMatrix & mt ); ///< \ru Ортонормировать плейсмент при трансформировании. \en Orthonormalize the placement when transforming. + + /** \brief \ru Определить параметры пересечения прямой с эллипсом. + \en Determine the parameters of intersection of a line with an ellipse. \~ + \param[in] pLine - \ru Прямая. + \en Line. \~ + \param[out] cross - \ru Массив с параметрами эллипса в точках пересечения. + \en Array with parameters of ellipse at intersection points. \~ + \result \ru Количество точек пересечения. + \en Count of intersection points. \~ + */ + ptrdiff_t EllipticIntersect( const MbLine & pLine, double cross[2], double eps0 = PARAM_PRECISION ) const; + const MbArc & operator = ( const MbArc & init ) { Init( init ); return *this; } ///< \ru Переопределяет оператор присваивания. \en Overrides the assignment operator. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + void ReadAsCircle( reader & in ); // \ru Чтение. + void ReadAsEllipse( reader & in ); // \ru Чтение. + void ReadAsEllipseArc( reader & in ); // \ru Чтение. + void WriteAsCircle( writer & out ) const; // \ru Запись. + void WriteAsEllipse( writer & out ) const; // \ru Запись. + void WriteAsEllipseArc( writer & out ) const; // \ru Запись. + +protected : + // \ru Инициализация параметров по значениям углов эллипса \en Initialization of parameters by values of ellipse angles. + inline double GetParamEpsilon( double eps = Math::LengthEps ) const; ///< \ru Получить погрешность параметра. \en Get the parameter accuracy + inline void SetClosed(); ///< \ru Сделать замкнутым. \en Make closed. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbArc ) +}; + +IMPL_PERSISTENT_OPS( MbArc ) + + +//------------------------------------------------------------------------------ +// \ru Установить параметр в область допустимых значений \en Set the parameter into the region of the legal values +// --- +inline double MbArc::CheckParam( double & t ) const +{ + double tMax = ::fabs( trim2 - trim1 ); + if ( (t < 0.0) || (t > tMax) ) { + if ( closed ) + t -= ::floor( t * Math::invPI2 ) * M_PI2; + else if ( t < 0.0 ) + t = 0.0; + else if ( t > tMax ) + t = tMax; + } + double w = t; + ParamToAngle( w ); + return w; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра кривой в угол \en Convert parameter of curve to the angle +// --- +inline void MbArc::ParamToAngle( double & t ) const +{ + if ( trim2 < trim1 ) + t = -t; + if ( ::fabs(trim1) > NULL_EPSILON ) + t += trim1; + if ( (t < 0.0) || (t > M_PI2) ) + t -= ::floor( t * Math::invPI2 ) * M_PI2; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод угла кривой в параметр кривой \en Convert an angle of curve to a parameter of curve +// --- +inline void MbArc::AngleToParam( double & t ) const +{ + double dtr = ( trim2 + trim1 - M_PI2 ) * 0.5; + t -= ::floor( (t - dtr) * Math::invPI2 ) * M_PI2; + t = ( trim2 > trim1 ) ? ( t - trim1 ) : ( trim1 - t ); +} + + +//------------------------------------------------------------------------------ +// \ru Погрешность параметра \en Parameter accuracy +// --- +inline double MbArc::GetParamEpsilon( double eps ) const +{ + double r = ::fabs( a + b ) * 0.5; + return ( (r > eps) ? (eps / r) : 1.0 ); +} + + +//------------------------------------------------------------------------------ +// \ru Сделать замкнутым \en Make closed +// --- +inline void MbArc::SetClosed() +{ + trim2 = ( sense > 0 ) ? ( trim1 + M_PI2 ) : ( trim1 - M_PI2 ); + closed = true; + rect.SetEmpty(); + metricLength = -1.0; +} + + +//------------------------------------------------------------------------------ +// \ru Находится ли параметр базовой кривой в диапазоне \en Whether the parameter of the base curve is in the range +// \ru Усеченной кривой \en Of the trimmed curve +// --- +inline bool MbArc::IsBaseParamOn( double t, double eps ) const +{ + AngleToParam( t ); + return IsParamOn( t, eps ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание эквидистантной кривой (дуги) эллипса c разными полуосями с учетом самопересечений. + \en Creation of the offset curve (arc) of ellipse with different semiaxes subject to self-intersections. \~ + \details \ru Создание эквидистантной кривой (дуги) эллипса c разными полуосями с учетом самопересечений. \n + Для (дуги) окружности не предназначена - выходит с флагом true, ничего не создавая. \n + \en Creation of the offset curve (arc) of ellipse with different semiaxes subject to self-intersections. \n + Not for (arc of) a circle - exits with flag true but constructs nothing. \n \~ + \ingroup Curves_2D +*/ +// --- +MATH_FUNC (bool) CreateOffsetElliptic( const MbArc & curve, double rad, RPArray & segments, size_t & count, + bool setArcLimits = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Запись в поток для старых версий. + \en Writes to the stream for older versions. \~ + \details \ru Запись в поток для старых версий. \n + \en Writes to the stream for older versions. \n \~ + \ingroup Curves_2D +*/ +// --- +MATH_FUNC (void) EllipticWrite( writer & out, const MbArc * curve ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Запись в поток для старых версий. + \en Writes to the stream for older versions. \~ + \details \ru Запись в поток для старых версий. \n + \en Writes to the stream for older versions. \n \~ + \ingroup Curves_2D +*/ +// --- +MATH_FUNC (void) TrimmedWrite( writer & out, const MbTrimmedCurve * curve ); + + +#endif // __CUR_ARC_H + diff --git a/C3d/Include/cur_arc3d.h b/C3d/Include/cur_arc3d.h new file mode 100644 index 0000000..1ceceeb --- /dev/null +++ b/C3d/Include/cur_arc3d.h @@ -0,0 +1,494 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Эллипс в трёхмерном пространстве. + \en Ellipse in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_ARC3D_H +#define __CUR_ARC3D_H + + +#include +#include + + +#define CONIC_COUNT 32 +#define LINES_COUNT 10 + + +class MATH_CLASS MbArc; + + +//------------------------------------------------------------------------------ +/** \brief \ru Дуга эллипса в трёхмерном пространстве. + \en Elliptical arc in three-dimensional space. \~ + \details \ru Дуга эллипса описывается двумя радиусами a и b и двумя параметрами trim1 и trim2, заданными в локальной системе координат position. \n + Параметры trim1 и trim2 отсчитываются по дуге в направлении движения от оси position.axisX к оси position.axisY. + Параметры trim1 и trim2 будем называть параметрами усечения. + Значения параметров усечения, равные нулю и 2pi, соответствуют точке на оси position.axisX. \n + Параметр кривой t принимает значения на отрезке: 0<=t<=trim2–trim1. + Кривая может быть замкнутой. У замкнутой кривой trim2–trim1=2pi. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией\n + r(t) = position.origin + (a cos(trim1+t) position.axisX) + (b sin(trim1+t) position.axisY).\n + Радиусы кривой дожны быть больше нуля: a>0, b>0. \n + Для параметров усечения должны соблюдаться неравенства: trim10, b>0. \n + The following inequalities must be satisfied for the parameters of trimming: trim1 0, то направление движения против часовой стрелки, если смотреть навстречу векторному произведению (p1 - pc) и (p2 - pc). \n + Если initSense < 0, то направление движения против часовой стрелки, если смотреть навстречу векторному произведению (p1 - pc) и (p2 - pc). \n + \en An arc centered in point 'pc' is created. \n + The first semiaxis is determines as the distance between points pc and p1. + The second semiaxis is determined as the length of projection of the vector from pc to p2 onto the perpendicular to (p1 - pc). + The start point of the arc lies on the ray starting from the circle center and passing through point 'p1'. + The end point is on the ray from the center passing through the point 'p2'. \n + Parameter 'initSense' specifies completeness and the arc direction. + If initSense == 0, then the complete ellipse or circle is constructed. \n + If initSense > 0, then the direction of moving is counterclockwise if seeing against the vector product (p1 - pc) and (p2 - pc). \n + If initSense < 0, , then the direction of moving is counterclockwise if seeing against the vector product (p1 - pc) and(p2 - pc). \n \~ + \param[in] pc - \ru Центр эллипса или окружности. + \en Center of the ellipse or the circle. \~ + \param[in] p1 - \ru Точка, определяющая начало кривой и первую полуось. + \en A point determining the beginning of the curve and the first semiaxis. \~ + \param[in] p2 - \ru Точка, определяющая конец кривой и вторую полуось. + \en A point determining the end of the curve and the second semiaxis. \~ + \param[in] initSense - \ru Определяет цельность и направление. initSense == 0 - замкнутая кривая initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + \en Determines the completeness and the direction. initSense == 0 - closed curve initSense > 0 - moving counterclockwise, initSense < 0 - clockwise. \~ + */ + MbArc3D( const MbCartPoint3D & pc, const MbCartPoint3D & p1, const MbCartPoint3D & p2, int initSense = 0 ); + + /** \brief \ru Конструктор окружности или дуги окружности. + \en Constructor of a circle or a circular arc. \~ + \details \ru Конструктор окружности или дуга окружности одним из двух способов. + \en Constructor of a circle or a circular arc by one of two methods. + \param[in] p0 - \ru Центр (n == 0) или начальная точка (n != 0). + \en Center (n == 0) or starting point (n != 0). \~ + \param[in] p1 - \ru Начальная точка (n == 0) или точка, через которую проходит окружность (n != 0). + \en Starting point (n == 0) or point the circle passes through (n == 1). \~ + \param[in] p2 - \ru Точка, определяющая конец кривой и вторую полуось. + \en A point determining the end of the curve and the second semiaxis. \~ + \param[in] n - \ru Определяет способ построения окружности. + Если n == 0, то окружность или дуга имеют центр в точке p0. + Если n == 1, то окружность или дуга проходят по трем заданным точкам. \n + Если |n| == 2 и closed == false, то дуга будет дополнять до полной окружности дугу, проходящую по трем заданным точкам. \n + \en The parameter defines the method of arc construction. \~ + If n == 0, then a circle or a circular arc have the center in point p0. + If n == 1, then a circle or an arc passes through the specified three points. \n + If |n| == 2 & closed == false, then an arc passes through p0 and p2 but not p1. \n \~ + \param[in] closed - \ru Определяет окружность (true) или дугу (false). + \en Specifies a circle (true) or an arc (false). \~ + */ + MbArc3D( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, int n, bool closed ); + + /** \brief \ru Конструктор окружности или дуги окружности. + \en Constructor of a circle or a circular arc. \~ + \details \ru Создается дуга окружности с центром в точке pc и с заданным радиусом. + Радиус окружности или ее дуги определяется как расстояние между точками pc и p1. + Точки pc, p1 и p2 определяют плоскость дуги. + Точки p1 и p2 определяют границы дуги. + Вектор aZ определяет направление оси Z локальной системы координат дуги окружности. + Начальная точка дуги лежит в точке p1. + Конечная точка дуги лежит на луче, выходящем из центра окружности и проходящем через точку p2. + Параметр initSense определяет направление дуги. + \en A circular arc is created with a center in point 'pc'. + Points 'p1' and 'p2' specify the bounds of arc. + The start point of the arc lies on point 'p1'. + The end point is on the ray passing through the point 'p2'. + Parameter 'initSense' specifies the arc direction. \~ + \param[in] pc - \ru Центр окружности. + \en Center of circle. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] aZ - \ru Направление оси Z локальной системы координат дуги окружности. + \en A direction of axis Z local coordinate system of the arc. \~ + \param[in] initSense - \ru Направление дуги. + Если initSense > 0, то направление движения дуги против часовой стрелки, если cмотреть навстречу вектору aZ. + Если initSense < 0, то направление движения дуги по часовой стрелке, если cмотреть навстречу вектору aZ. + Если initSense == 0, то будет построена полная окружность. + \en Arc direction. + If initSense > 0, then the orientation is counterclockwise if you look towards the vector aZ. + If initSense < 0, then the orientation is clockwise if you look towards the vector aZ. + If initSense = 0, then the circle is building. \~ + */ + MbArc3D( const MbCartPoint3D & pc, const MbCartPoint3D & p1, const MbCartPoint3D & p2, + const MbVector3D & aZ, int initSense ); + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с заданными полуосями и локальной системой координат. + angle определяет угол дуги. Угол отсчитываются от оси OX против часовой стрелки. + Угол задан в радианах. + \en An elliptical arc is created with the given semiaxes and the local coordinate system. + 'angle' determines the arc angle. The angle is measured from the OX axis counterclockwise. + The angle is given in radians. \~ + \param[in] p0 - \ru Центр локальной системы координат эллипса. + \en The ellipse local coordinate system center. \~ + \param[in] vZ - \ru Ось Z локальной системы координат эллипса. + \en Z-axis of the local coordinate system of the ellipse. \~ + \param[in] vX - \ru Ось X локальной системы координат эллипса. + \en X-axis of the local coordinate system of the ellipse. \~ + \param[in] aa - \ru Радиус полуоси вдоль X. + \en Radius of semiaxis along X. \~ + \param[in] bb - \ru Радиус полуоси вдоль Y. + \en Radius of semiaxis along Y. \~ + \param[in] angle - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + */ + MbArc3D( const MbCartPoint3D & p0, const MbVector3D & vZ, const MbVector3D & vX, double aa, double bb, double angle ); + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с локальной системой координат и полуосями заданного эллипса. + t1 и t2 определяют начальный и конечный углы дуги. Углы отсчитываются от оси OX против часовой стрелки. + Углы заданы в радианах. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An elliptical arc is constructed with the local coordinate system and semiaxes of the given ellipse. + t1 and t2 specify the start and the end angles of the arc. The angles are measured from the OX axis counterclockwise. + The angles are given in radians. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the direction of moving is counterclockwise. \~ + \param[in] init - \ru Эллипс - образец. + \en A pattern ellipse. \~ + \param[in] t1 - \ru Угол, определяющий начало дуги. + \en An angle specifying the beginning of the arc. \~ + \param[in] t2 - \ru Угол, определяющий конец дуги. + \en An angle specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'initSense' can't be equal to zero. \~ + */ + MbArc3D( const MbArc3D & init, double t1, double t2, int initSense ); + + /** \brief \ru Конструктор дуги эллипса. + \en Constructor of an elliptical arc. \~ + \details \ru Создается дуга эллипса с локальной системой координат и полуосями заданного эллипса. + Проекции p1 и p2 на init определяют начальный и конечный углы дуги. + Параметр initSense определяет направление дуги. Если initSense > 0, то направление движения против часовой стрелки. + \en An elliptical arc is constructed with the local coordinate system and semiaxes of the given ellipse. + Projections of p1 and p2 onto 'init' determines the starting and the end angles of the arc. + Parameter 'initSense' specifies the arc direction. If initSense > 0, then the direction of moving is counterclockwise. \~ + \param[in] init - \ru Эллипс - образец. + \en A pattern ellipse. \~ + \param[in] p1 - \ru Точка, определяющая начало дуги. + \en A point specifying the beginning of the arc. \~ + \param[in] p2 - \ru Точка, определяющая конец дуги. + \en A point specifying the end of the arc. \~ + \param[in] initSense - \ru Направление. initSense > 0 - движение против часовой стрелки, initSense < 0 - по часовой стрелке. + initSense не должно быть равным нулю. + \en Direction. initSense > 0 - moving counterclockwise, clockwise < 0 - clockwise. + 'initSense' can't be equal to zero. \~ + */ + MbArc3D( const MbArc3D & init, MbCartPoint3D p1, MbCartPoint3D p2, int initSense ); + + /** \brief \ru Конструктор дуги окружности. + \en Constructor of a circular arc. \~ + \details \ru Создается дуга окружности с концами в заданных точках. + Радиус окружности определяется по заданному тангенсу 1/4 угла раствора дуги. + \en An arc is created with ends at the given points. + A circle radius is defined by the given tangent of 1/4 of arc opening angle. \~ + \param[in] p1 - \ru Начало дуги. + \en Beginning of the arc. \~ + \param[in] p2 - \ru Конец дуги. + \en End of the arc. \~ + \param[in] a4 - \ru Тангенс 1/4 угла раствора дуги. + \en Tangent of 1/4 of the arc opening angle. \~ + \param[in] vZ - \ru Ось дуги. + \en Axis of the arc. \~ + */ + MbArc3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2, double a_4, MbVector3D & vZ ); + + /** \brief \ru Конструктор по локальной системе и двумерной дуге эллипса. + \en Constructor by a local system and two-dimensional elliptical arc. \~ + \details \ru Конструктор по локальной системе координат и двумерной дуге эллипса. + \en Constructor by a local coordinate system and two-dimensional elliptical arc. \~ + \param[in] ellipse - \ru Двумерная дуга эллипса. + \en Two-dimensional elliptical arc. \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + */ + MbArc3D( const MbArc & ellipse, const MbPlacement3D & place ); + + /** \brief \ru Конструктор окружности по двум точкам и направлению к центру в одной из них. + \en Constructor of a circle by two points and direction to the center from one of them. \~ + \details \ru Создается окружность по двум точкам и направлению в одной из них. + \en A circle is created by two points and direction at one of them. \~ + \param[in] p1 - \ru Начальная точка. + \en The starting point. \~ + \param[in] p2 - \ru Конечная точка. + \en The end point. \~ + \param[in] dirInPoint - \ru Направление из одной из точек (p1 или p2) к центру окружности. + \en Direction at one of points (p1 or p2) to the center of the circle. \~ + \param[in] insecond - \ru Направление из первой точки (insecond == true) к центру окружности. + \en Direction from the first point (insecond == true) to the circle center. \~ + */ + MbArc3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2, const MbVector3D & dirInPoint, bool insecond ); + +//protected: + explicit MbArc3D( const MbArc3D & init ); +public : + virtual ~MbArc3D(); + + VISITING_CLASS( MbArc3D ); + + void Init( const MbArc3D & ); + void Init( const MbPlacement3D &, double aa, double bb, double angle ); + void Init( const MbArc3D & init, double t1, double t2, int initSense ); + /// \ru Инициализация окружности или дуги окружности по трем точкам, (n == 0) - окружность или дуга по центру и двум точкам, (n == 1) - окружность или дуга по трем точкам \en Initialization of a circular arc by three points; (n == 0) - a circle or an arc by the center and two points, (n == 1) - a circle or an arc by three points. + void Init( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, int n, bool closed ); + /// \ru Инициализация дуги окружности по начальной и конечной точкам и 1/2 угла раствора дуги. \en Initialization of a circular arc by the starting and the end points and 1/2 of the arc opening angle. + void Init( double a_2, const MbCartPoint3D & p1, const MbCartPoint3D & p2, MbVector3D & vZ ); + /// \ru Инициализация дуги окружности по 2D-дуге и локальной системе координат. \en Initialization of an arc by 2D-arc and local coordinate system. + void Init( const MbArc & ellipse, const MbPlacement3D & pos ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual double DistanceToPoint( const MbCartPoint3D & ) const;// \ru Расстояние до точки \en Distance to a point + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; // \ru Являются ли объекты идентичными в пространстве \en Whether the objects are identical in the space + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + // \ru Общие функции кривой \en Common functions of the curve + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description + \{ */ + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Return the period + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the domain of a curve. + PointOn, FirstDer, SecondDer, ThirdDer,... functions correct parameter + when it runs out the domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void Normal ( double & t, MbVector3D & ) const; // \ru Вектор главной нормали \en Vector of the principal normal + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. Ограниченная кривая продолжается в соответствии с уравнениями кривой. + \en \name Functions for working inside and outside of the curve domain. + _PointOn, _FirstDer, _SecondDer, _ThirdDer,... functions don't correct parameter + when it runs out the domain. The bounded curve is extended due to the equations of curve. + \{ */ + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void _Normal ( double t, MbVector3D & ) const;// \ru Вектор главной нормали \en Vector of the principal normal + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + /** \} */ + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + // \ru Все проекции точки на кривую \en All the projections of a point onto the curve + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The closest projection of a point onto the curve + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS-copy of the curve + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of the trimmed curve + + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate metric length + virtual double GetLengthEvaluation() const; + virtual double Curvature( double t ) const; // \ru Кривизна по t \en Curvature by t + // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + virtual size_t GetCount() const; + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curves equally spaced by the arc length + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of a curve + virtual MbCurve * GetMapPsp( const MbMatrix3D &, double zNear, + MbRect1D * pRgn = NULL ) const; + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой \en Get the axis of the curve + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called on a three-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой \en Calculate bounding box of curve + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to local coordinate system + /// \ru Является ли объект смещением \en Whether the object is a shift + virtual bool IsShift ( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + + void SetRadiusA( double aa ) { a = aa; Refresh(); } // \ru Установить большую полуось \en Set the major semiaxis + void SetRadiusB( double bb ) { b = bb; Refresh(); } // \ru Установить малую полуось \en Set the minor semiaxis + void SetRadius( double r ) { a = r; b = r; Refresh(); } // \ru Установить радиус окружности \en Set circle radius + double GetRadiusA() const { return a; } + double GetRadiusB() const { return b; } + void SetLimitPoint( ptrdiff_t number, const MbCartPoint3D & ); // \ru Заменить точку отрезка \en Replace a point of the segment + double GetAngle() const { return (trim2 - trim1); } // \ru Выдать граничный угол дуги \en Get the end angle of the arc + void SetAngle ( double ang ) { trim2 = trim1 + ang; CheckClosed(); Refresh(); } // \ru Изменить граничный угол дуги \en Change the end angle of the arc + + bool IsCircle( double eps = Math::metricRegion ) const; + + inline double CheckParam( double & t ) const; + inline void ParamToAngle( double & t ) const; // \ru Перевод параметра кривой в угол \en Convert parameter of curve to the angle + inline void AngleToParam( double & t ) const; // \ru Перевод угла кривой в параметр кривой \en Convert an angle of curve to a parameter of curve + inline double GetTrim1() const { return trim1; } ///< \ru Параметры начальной точки \en Parameters of start point + inline double GetTrim2() const { return trim2; } ///< \ru Параметры конечной точки \en Parameters of end point + bool MakeTrimmed( double t1, double t2 ); ///< \ru Установка параметров усечения с сохранением направления кривой. \en Setting of the parameters of trimming with keeping the curve direction. + void AlignXAxis(); ///< \ru Повернуть плейсмент круговой дуги так, чтобы ось ox указывала в начальную точку дуги. \en Rotate the placement of a circular arc so as the ox-axis points to the start point of the arc. + + /// \ru Является ли кривая плоской? \en Whether the curve is planar? + virtual bool IsPlanar() const; + /// \ru Заполнить плейсемент, если кривая плоская. \en Fill the placement if a curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + const MbPlacement3D & GetPlacement() const { return position; } + MbPlacement3D & SetPlacement() { return position; } + void SetPlacement( const MbPlacement3D & pl ) { position = pl; } + virtual void GetCentre( MbCartPoint3D & wc ) const; + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; + + bool Normalize(); ///< \ru Ортонормировать локальную систему координат. \en Orthonormalize the local coordinate system. + bool IsPositionNormal() const { return ( !position.IsAffine() ); } + bool IsPositionCircular() const { return ( position.IsCircular() ); } + bool IsPositionIsotropic() const { return ( position.IsIsotropic()); } + + const MbCartPoint3D & GetCentre() const { return position.GetOrigin(); } + +private: + void CheckClosed(); // \ru Проверить и установить признак замкнутости кривой. \en Check and set attribute of curve closedness. + +private: + void operator = ( const MbArc3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbArc3D ) +}; + +IMPL_PERSISTENT_OPS( MbArc3D ) + +//------------------------------------------------------------------------------ +// \ru Установить параметр в область допустимых значений \en Set the parameter into the region of the legal values +// --- +inline double MbArc3D::CheckParam( double & t ) const +{ + double tMax = trim2 - trim1; + if ( (t < 0.0) || (t > tMax) ) { + if ( closed ) + t -= ::floor( t * Math::invPI2 ) * M_PI2; + else if ( t < 0.0 ) + t = 0.0; + else if ( t > tMax ) + t = tMax; + } + double w = t; + if ( ::fabs(trim1) > NULL_EPSILON ) { + w = trim1 + w; + if ( (w < 0.0) || (w > M_PI2) ) + w -= ::floor( w * Math::invPI2 ) * M_PI2; + } + return w; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра кривой в угол \en Convert parameter of curve to the angle +// --- +inline void MbArc3D::ParamToAngle( double & t ) const +{ + if ( ::fabs(trim1) > NULL_EPSILON ) { + t = trim1 + t; + if ( (t < 0.0) || (t > M_PI2) ) + t -= ::floor( t * Math::invPI2 ) * M_PI2; + } +} + + +//------------------------------------------------------------------------------ +// \ru Перевод угла кривой в параметр кривой \en Convert an angle of curve to a parameter of curve +// --- +inline void MbArc3D::AngleToParam( double & t ) const +{ + if ( ::fabs(trim1) > NULL_EPSILON ) { + double dtr = ( trim2 + trim1 - M_PI2 ) * 0.5; + t -= ::floor( (t - dtr) * Math::invPI2 ) * M_PI2; + t = t - trim1; + } +} + + +#endif // __CUR_ARC3D_H diff --git a/C3d/Include/cur_b_spline.h b/C3d/Include/cur_b_spline.h new file mode 100644 index 0000000..b4f1622 --- /dev/null +++ b/C3d/Include/cur_b_spline.h @@ -0,0 +1,108 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Набор В-сплайнов NURBS кривой. + \en B-spline set of NURBS-curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_B_SPLINE_H +#define __CUR_B_SPLINE_H + + +#include +#include + + +class MATH_CLASS MbNurbs3D; +class MATH_CLASS MbNurbs; + + +//------------------------------------------------------------------------------ +/** \brief \ru Набор В-сплайнов NURBS кривой. + \en B-spline set of NURBS-curve. \~ + \details \ru Объект со свойствами кривой служит для визуализации набора В-сплайнов некоторой NURBS кривой. \n + В-сплайны NURBS кривой располагаются в плоскости XY локальной системы координат position. + Длина рисунка всех В-сплайнов равна параметру a, высота рисунка всех В-сплайнов равна параметру h. + \en Object with curve properties is used to visualize B-spline set of some NURBS-curve. \n + B-splines of NURBS-curve are located in the XY plane of the local coordinate system. + Picture length of all B-splines is equal to the parameter a, the height of all B-splines is the parameter h. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbBSpline : public MbCurve3D { +private: + ptrdiff_t degree; ///< \ru Степень В-сплайнов. \en Degree of B-splines. + SArray knots; ///< \ru Узловой вектор. \en Knot vector. + ptrdiff_t pCount; ///< \ru Число точек. \en Number of points. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + MbPlacement3D position; ///< \ru Плоскость для отрисовки. \en A plane for drawing. + double a; ///< \ru Горизонтальный размер (длина рисунка). \en Horizontal size (picture length). + double h; ///< \ru Вертикальный размер (высота рисунка). \en Vertical size (picture height). + +public: + MbBSpline( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, const MbNurbs & nurbs ); + MbBSpline( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, const MbNurbs3D & nurbs ); + MbBSpline( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, const SArray & t ); +private: + MbBSpline( const MbBSpline & init ); +public: + virtual ~MbBSpline(); + +public: + VISITING_CLASS( MbBSpline ); + + // \ru Общие функции математического объекта \en The common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double &t, MbCartPoint3D &pnt ) const; // \ru Точка на кривой \en The point on the curve + virtual void FirstDer ( double &t, MbVector3D &fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double &t, MbVector3D &sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double &t, MbVector3D &td ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculate step of approximation + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + void CalculateOnePolygon( size_t i, const MbStepData & stepData, MbPolygon3D * polygon ) const; // \ru Pассчитать полигон по параметру T \en Calculate polygon of the parameter T + // \ru Расчет весовых функций и их первых, вторых и третьих производных \en Calculation of the weight functions and their first, second and third derivatives + ptrdiff_t CalculateFunctions( double x, double * m, + double * mm0, double * mm1, double * mm2, double * mm3 ) const; + ptrdiff_t CalculateParam( double & t, double & x ) const; // \ru Расчет параметра и номера сплайна \en Calculation of the parameter and spline number + void GetWeightFunctions( double t, double * m, + double * mm0, double * mm1, double * mm2, double * mm3 ) const; // \ru Определение В-сплайнов \en Definition of B-splines + +private: + void operator = ( const MbBSpline & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBSpline ) +}; // MbBSpline + +IMPL_PERSISTENT_OPS( MbBSpline ) + +#endif // __CUR_B_SPLINE_H diff --git a/C3d/Include/cur_bezier.h b/C3d/Include/cur_bezier.h new file mode 100644 index 0000000..9dda0c1 --- /dev/null +++ b/C3d/Include/cur_bezier.h @@ -0,0 +1,485 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сплайн Безье в двумерном пространстве. + \en Bezier spline in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_BEZIER_H +#define __CUR_BEZIER_H + + +#include +#include + + +class MATH_CLASS MbArc; +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сплайн Безье в двумерном пространстве. + \en Bezier spline in two-dimensional space. \~ + \details \ru Сплайн Безье в двумерном пространстве определяется контрольными точками pointList. \n + Сплайн Безье является составной кривой, образованной стыкующимися между собой кривыми Безье третьей степени. + Каждая кривая Безье третьей степени построена по четырём соседним контрольным точкам множества pointList. + Для незамкнутого сплайна Безье первая и последняя контрольная точка множества pointList не используются. + Таким образом, сплайн Безье проходит через каждую контрольную точку множества pointList с индексом 3n+1, где n - целое число. + Значение параметра вдоль каждой кривой Безье третьей степени увеличивается на единицу. + Параметр сплайна Безье изменяется от нуля до k, где k - количество кривых Безье третьей степени, образующих сплайн. + В общем случае первая производная сплайна Безье может быть разрывной как по длине, так и по направлению. + \en Bezier spline in two-dimensional space is defined by control points pointList. \n + Bezier spline is composite curve formed by connected among themselves Bezier curves with third degree. + Each third-degree Bezier curve is constructed by four adjacent control points pointList. + First and last control point from pointList for unclosed Bezier spline are not used + Thus Bezier spline passes through each control point with index 3n+1, where n is integer. + The value of parameter along each third-degree Bezier curve is incremented. + The parameter of Bezier spline changes from zero to k, where k is the number of tree-degree Bezier curves which form spline. + In general case the first derivative of Bezier spline can be discontinuous by length and direction. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbBezier : public MbPolyCurve { +private : + ptrdiff_t splinesCount; ///< \ru Количество сплайнов. \en The number of splines. + int form; ///< \ru Форма сплайна. \en The shape of spline. + +public : + /** \brief \ru Конструктор по массиву всех точек. + \en Constructor by array of all points. \~ + \details \ru Конструктор по массиву всех точек(полюсов и коромысел), + для создания из трехмерной кривой MbBezier3D. + \en Constructor by array of all points(poles and rockers), + for creation from three-dimensional curve MbBezier3D. \~ + \param[in] closed - \ru Замкнута ли кривая. + \en Is curve closed? \~ + \param[in] points - \ru Массив точек. + Должен быть получен из массива точек трехмерной кривой MbBezier3D, которая является + плоской, путем проецирования их на плоскость кривой. + Количество точек должно быть кратно трем. Минимальное количество точек - шесть. + \en An array of points. + It must be obtained from point array of three-dimensional curve MbBezier3D which is + planar, by projecting them onto the plane of the curve. + The number of points must be multiple of three. The minimal number of points is six. \~ + */ + DEPRECATE_DECLARE MbBezier( bool closed, const SArray & points ); + /** \brief \ru Конструктор по полюсам. + \en Constructor by poles. \~ + \details \ru Конструктор по полюсам. В массиве initList заданы только полюса. + \en Constructor by poles. initList array contains only poles. \~ + \param[in] initList - \ru Массив полюсов кривой. + Минимальное количество точек в массиве равно двум. + \en An array of curve poles. + Minimal number of points in array equals two. \~ + \param[in] cls - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[in] initForm - \ru Форма сплайна. Возможные значения:\n + 0 - Стандартная форма. + 1 - Более выпуклая форма кривой. + \en The shape of spline. Possible values:\n + 0 - The standard form. + 1 - More convex form of curve. \~ + */ + DEPRECATE_DECLARE MbBezier( const SArray & initList, bool cls, int initForm = 0 ); + +protected : + MbBezier( const MbBezier & pCurve ); ///< \ru Конструктор копирования. \en Copy-constructor. + /** \brief \ru Конструктор по четырем точкам. + \en Constructor by four points. \~ + \details \ru Конструктор по четырем точкам. + \en Constructor by four points. \~ + \param[in] initList - \ru Массив точек. Количество точек должно быть равно четырем. + Если точек больше четырех, то на каждых последовательных четырех + точках строится классический кубический сплайн Безье. + Гладкость полученной кривой в точках стыка сегментов может нарушаться. + \en An array of points. Number of points must be equal to four. + When number of points is more then four classical cubic bezier is + created for each sequential four points. The smoothness of result curve + can be broken. \~ + */ + MbBezier( const SArray & initList ); + + /** \brief \ru Конструктор по сегменту Bezier-кривой. + \en Constructor by segment of Bezier curve. \~ + \details \ru Конструктор по сегменту заданной Bezier-кривой. + \en Constructor by segment of a given Bezier curve. \~ + \param[in] pCurve - \ru Заданная кривая. + \en A given curve. \~ + \param[in] iseg - \ru Номер сегмента кривой. + \en A number of curve segment. \~ + */ + MbBezier( const MbBezier & pCurve, ptrdiff_t iseg ); + /** \brief \ru Конструктор по дуге окружности. + \en Constructor by circle arc. \~ + \details \ru Построена кривая Безье, точно аппроксимирующая заданную дугу окружности. + \en There was constructed a Bezier curve which approximates a given arc of a circle. \~ + \param[in] arc - \ru Дуга окружности. + \en Circle arc. \~ + */ + MbBezier( const MbArc & arc ); // \ru Инициализация по дуге окружности \en Initialization by a circle arc +public : + virtual ~MbBezier(); ///< \ru Деструктор. \en Destructor. + +public : + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbBezier * Create( const MbBezier & other ); + /** \brief \ru Создать сплайн по четырем точкам. + \en Create spline by four points. \~ + \details \ru Создать сплайн по четырем точкам. + \en Create spline by four points. \~ + \param[in] initList - \ru Массив точек. Количество точек должно быть равно четырем. + Если точек больше четырех, то на каждых последовательных четырех + точках строится классический кубический сплайн Безье. + Гладкость полученной кривой в точках стыка сегментов может нарушаться. + \en An array of points. Number of points must be equal to four. + When number of points is more then four classical cubic bezier is + created for each sequential four points. The smoothness of result curve + can be broken. \~ + */ + static MbBezier * Create( const SArray & initList ); + /** \brief \ru Создать сплайн по массиву всех точек. + \en Create spline by array of all points. \~ + \details \ru Создать сплайн по массиву всех точек(полюсов и коромысел), + для создания из трехмерной кривой MbBezier3D. + \en Create spline by array of all points(poles and rockers), + for creation from three-dimensional curve MbBezier3D. \~ + \param[in] closed - \ru Замкнута ли кривая. + \en Is curve closed? \~ + \param[in] points - \ru Массив точек. + Должен быть получен из массива точек трехмерной кривой MbBezier3D, которая является + плоской, путем проецирования их на плоскость кривой. + Количество точек должно быть кратно трем. Минимальное количество точек - шесть. + \en An array of points. + It must be obtained from point array of three-dimensional curve MbBezier3D which is + planar, by projecting them onto the plane of the curve. + The number of points must be multiple of three. The minimal number of points is six. \~ + */ + static MbBezier * Create( bool closed, const SArray & points ); + /** \brief \ru Создать сплайн по сегменту Bezier-кривой. + \en Create spline by segment of Bezier curve. \~ + \details \ru Создать сплайн по сегменту заданной Bezier-кривой. + \en Create spline by segment of a given Bezier curve. \~ + \param[in] pCurve - \ru Заданная кривая. + \en A given curve. \~ + \param[in] iseg - \ru Номер сегмента кривой. + \en A number of curve segment. \~ + */ + static MbBezier * Create( const MbBezier & pCurve, ptrdiff_t iseg ); + /** \brief \ru Создать сплайн по полюсам. + \en Create spline by poles. \~ + \details \ru Создать сплайн по полюсам. В массиве initList заданы только полюса. + \en Create spline by poles. initList array contains only poles. \~ + \param[in] initList - \ru Массив полюсов кривой. + Минимальное количество точек в массиве равно двум. + \en An array of curve poles. + Minimal number of points in array equals two. \~ + \param[in] cls - \ru Замкнутость кривой. + \en A curve closedness. \~ + \param[in] initForm - \ru Форма сплайна. Возможные значения:\n + 0 - Стандартная форма. + 1 - Более выпуклая форма кривой. + \en The shape of spline. Possible values:\n + 0 - The standard form. + 1 - More convex form of curve. \~ + */ + static MbBezier * Create( const SArray & initList, bool cls, int initForm = 0 ); + /** \brief \ru Создать сплайн по дуге окружности. + \en Create spline by circle arc. \~ + \details \ru Построена кривая Безье, точно аппроксимирующая заданную дугу окружности. + \en There was constructed a Bezier curve which approximates a given arc of a circle. \~ + \param[in] arc - \ru Дуга окружности. + \en Circle arc. \~ + */ + static MbBezier * Create( const MbArc & arc ); // \ru Инициализация по дуге окружности \en Initialization by a circle arc + +public : + VISITING_CLASS( MbBezier ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента \en A type of element + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the 'curve' curve is duplicate of current curve. + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element +/** \} */ + /** \ru \name Функции инициализации сплайна. + \en \name Spline initialization functions. + \{ */ + + /** \brief \ru Инициировать кривую по полюсам и замкнутости. + \en Initialize a curve by poles and closedness. \~ + \details \ru Инициировать кривую по полюсам и замкнутости. В массиве initList заданы только полюса. + \en Initialize a curve by poles and closedness. initList array contains only poles. \~ + \param[in] initList - \ru Массив полюсов кривой. + \en An array of curve poles. \~ + \param[in] cls - \ru Замкнутость кривой. + \en A curve closedness. \~ + */ + void Init( const SArray & initList, bool cls ); + + /** \brief \ru Инициировать кривую по заданной кривой Безье. + \en Initialize a curve by a given Bezier curve. \~ + \details \ru Инициировать кривую по заданной кривой Безье. \n + \en Initialize a curve by a given Bezier curve. \n \~ + \param[in] initCurve - \ru Заданная кривая. + \en A given curve. \~ + */ + void Init( const MbBezier & initCurve ); + + /** \brief \ru Инициировать кривую по дуге окружности. + \en Initialize a curve by a circle arc. \~ + \details \ru Построена кривая Безье, точно аппроксимирующая заданную дугу окружности. + \en There was constructed a Bezier curve which approximates a given arc of a circle. \~ + \param[in] arc - \ru Дуга окружности. + \en Circle arc. \~ + */ + void Init( const MbArc & arc ); // \ru Инициализация по дуге окружности \en Initialization by a circle arc + + /** \brief \ru Инициировать кривую по контрольным точкам. + \en Initialize a curve by control points. \~ + \details \ru Инициировать кривую по контрольным точкам. + В массиве initList входят и полюса и коромысла. + \en Initialize a curve by control points. + The array initList contains poles and "rocker arms". \~ + \param[in] initList - \ru Массив контрольных точек кривой. + \en An array of control points of curve. \~ + */ + void InitCtrlPoints( const SArray & initList ); +/** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the domain of a curve. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en The point on the curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en Third derivative + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + /** \ru \name Функции движения по кривой + \en \name Functions of the motion along the curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of the approximation step with consideration of the curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности \en Calculation of the approximation step by angular tolerance + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + virtual MbContour * NurbsContour() const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change to the opposite direction of a curve + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + + /** \} */ + /** \ru \name Общие функции полигональной кривой + \en \name Common functions of a polygonal curve + \{ */ + virtual size_t GetPointsCount() const; ///< \ru Вернуть количество несовпадающих контрольных точек. \en Return the number of non-coincedent control points. + virtual void GetPoint( ptrdiff_t index, MbCartPoint & pnt ) const; // \ru Выдать точку \en Get point + + virtual ptrdiff_t GetNearPointIndex( const MbCartPoint & pnt ) const; ///< \ru Выдать индекс точки, ближайшей к заданной. \en Get the point index which is nearest to the given. + + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки \en Get the interval of point influence + + virtual void Rebuild(); // \ru Пересчитать Безье кривую \en Recalculate Bezier curve + virtual void SetClosed( bool cls ); + + // \ru BEG: для библиотеки (хорошо бы избавиться) \en BEG: for the library (it would be good to get rid of this) + void LtSetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set the closedness attribute. + // \ru END: для библиотеки (хорошо бы избавиться) \en END: for the library (it would be good to get rid of this) + + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку \en Remove the point. + virtual void RemovePoints(); // \ru Удалить все точки \en Remove all points + + virtual void AddPoint( const MbCartPoint & pnt ); // \ru Добавить точку в конец массива \en Add a point to the end of array + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Вставить точку по индексу \en Insert a point by index + virtual void InsertPoint( double t, const MbCartPoint & pnt, double xEps, double yEps ); // \ru Вставить точку по индексу \en Insert a point by index + + /** \brief \ru Заменить полюс. + \en Replace the pole. \~ + \details \ru Заменяет характерную точку с указанным индексом. + \en Replaces characteristic point with a given index. \~ + \param[in] index - \ru Индекс изменяемой точки. + \en An index of changed point. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + */ + virtual void ChangePole ( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить полюс \en Replace the pole + virtual void ChangePoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить точку или производную \en Replace a point or derivative + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Загнать параметр получить локальный индексы и параметры \en Move parameter, get local indices and parameters + virtual double GetParam( ptrdiff_t i ) const; + virtual size_t GetParamsCount() const; + virtual void GetTList( SArray & params ) const; + + // \ru Функции только 2D кривой \en Functions for 2D-curve + + virtual void CalculateGabarit ( MbRect & ) const; // \ru Определить габариты кривой \en Determine the bounding box of the curve + + virtual MbeState DeletePart( double t1, double t2, MbCurve *&part2 ); // \ru Удалить часть поликривой между параметрами t1 и t2 \en Remove a part of the polyline between t1 and t2 parameters + virtual MbeState TrimmPart( double t1, double t2, MbCurve *&part2 ); // \ru Оставить часть поликривой между параметрами t1 и t2 \en Save a part of the polyline between t1 and t2 parameters + + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + virtual bool IsInRectForDeform( const MbRect & r ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the specified rectangle for the deformation + virtual void TangentPoint( const MbCartPoint & pnt, SArray & tFind ) const; // \ru Вычисление всех касательных к кривой из данной точки \en Calculation of all tangents to the curve from a given point + + /** \brief \ru Добавить точку и производные в конец массива. + \en Add point and derivatives to the end of array. \~ + \details \ru Добавить полюс в конец кривой и перемещением соседних точек (не полюсов), обеспечить + направление касательной к кривой в точке полюса и длины производных в полюсе. + \en Add pole to the end of curve, and the movement of neighboring points (no poles), to ensure + the direction of the tangent to the curve at the pole and derivatives lengths in the pole. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] dl - \ru Длина производной в полюсе слева. + \en Derivative length in pole on the left. \~ + \param[in] dr - \ru Длина производной в полюсе справа. + \en Derivative length in pole on the right. \~ + \param[in] angle - \ru Угол между направлением касательной и осью OX текущей системы координат. + \en The angle between the direction of the tangent and the OX-axis of the current coordinate system. \~ + */ + void AddPoint( MbCartPoint & pnt, double dl, double dr, double angle ); + + /** \brief \ru Определить выпуклую оболочку сегмента кривой. + \en Determine the convex hull of the curve segment. \~ + \details \ru Определить выпуклую оболочку сегмента кривой.\n + \en Determine the convex hull of the curve segment.\n \~ + \param[in] seg - \ru Номер сегмента кривой. + \en A number of curve segment. \~ + \param[out] poly - \ru Массив точек, составляющих выпуклую оболочку сегмента. + \en Array of points which constitute the convex hull of the segment. \~ + */ + void ConvexHull( ptrdiff_t seg, SArray & poly ) const; + // \ru Определение особых точек офсетной кривой \en Determination of singular points of the offset curve + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; + /// \ru Вернуть массив отдельных сегментов Bezier-кривой. \en Return an array of separate segments of the Bezier-curve. + void GetSegments( RPArray & segments ) const; + /// \ru Удалить совпадающие точки. \en Delete coincident points. + void ExeptEqualPoints(); + + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + /// \ru Сделать контур из NURBS-кривой. \en Create a contour from the NURBS curve. + MbContour * CreateContour() const; + + // \ru Функции только Bezier кривой \en Functions for Bezier curve + + /** \brief \ru Выделить часть кривой Безье. + \en Allocate a part of the Bezier curve. \~ + \details \ru Создается новая кривая - часть кривой Безье между параметрами t1 и t2. + \en The new curve is created - a part of the Bezier curve between t1 and t2 parameters. \~ + \param[out] trimPart - \ru Созданная кривая. + \en Created curve. \~ + \param[in] t1 - \ru Параметр начала выделенной части. + \en A beginning parameter. \~ + \param[in] t2 - \ru Параметр конца выделенной части. + \en An end parameter. \~ + \result \ru true - если построение прошло успешно. + \en True - if construction has been successfully. \~ + */ + bool Break( MbBezier & trimPart, double t1, double t2 ) const; // \ru Выделить часть \en Break a part + void SetBezierSplines(); ///< \ru Вычислить параметры кривой-Bezier. \en > Calculate parameters of the Bezier curve. + int GetFormType() const { return form; } ///< \ru Вернуть форму сплайна. \en Return the spline shape. + void SetFormType( int newForm ); ///< \ru Установить форму сплайна. \en Set the spline shape. + ptrdiff_t GetSplinesCount() const { return splinesCount; } ///< \ru Количество сплайнов \en The number of splines + + /** \brief \ru Выделить часть кривой Безье. + \en Break a part of the Bezier curve. \~ + \details \ru Создается новая кривая - часть кривой Безье между параметрами t1 и t2. + \en The new curve is created - a part of the Bezier curve between t1 and t2 parameters. \~ + \param[out] trimm - \ru Созданная кривая. + \en Created curve. \~ + \param[in] t1 - \ru Параметр начала выделенной части. + \en A beginning parameter. \~ + \param[in] t2 - \ru Параметр конца выделенной части. + \en An end parameter. \~ + \param[in] sense - \ru Совпадает ли направление полученной кривой с направлением исходной кривой. + \en Whether the direction of the resulting curve coincides with the direction of the original curve. \~ + */ + void Trimm( MbBezier & trimm, double t1, double t2, int sense ) const; + + virtual bool DistanceToPointIfLess( const MbCartPoint & to, double &d ) const; // \ru Расстояние до точки, если оно меньше d \en Distance to the point if it is less than d + + /** \brief \ru Вычислить все базовые функции в точке. + \en Calculate all base functions in the point. \~ + \details \ru При заданном параметре вычисляются все базовые функции сплайна и + индекс первой характерной точки, от которой зависит поведение сплайна + при заданном параметре. + \en For a given parameter, are calculated all base functions of the spline and + the index of the first characteristic point which determines the behavior of the spline + at a given parameter. \~ + \param[in] t - \ru Параметр. + \en A parameter. \~ + \param[out] values - \ru Массив со значениями базовых функций в точке. + \en An array with values of base functions in the point. \~ + \param[in] left - \ru Индекс характерной точки - начала интервала влияния. + \en An index of characteristic point. \~ + \result \ru true - если операция прошла успешно. + \en True - if operation has been successfully. \~ + */ + bool BasicFunctions( double & t, CcArray & values, ptrdiff_t & left ) const; + + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + /** \} */ + +protected: + virtual bool CanChangeClosed() const; // \ru Можно ли поменять признак замкнутости \en Whether it is possible to change the attribute of closedness +private : + void CheckData( double & t ) const; + void EvaluateSlope ( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index \en Calculate derivatives at the pole "index" + void EvaluateSlope0 ( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index для 0-ой формы \en Calculate derivatives at the pole "index" for 0-th form + void EvaluateSlope1 ( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index для 1-ой формы \en Calculate derivatives at the pole "index" for 1-th form + void SetDerives(); // \ru Рассчитать все производные \en Calculate all derivatives + void SetDerives ( ptrdiff_t index ); // \ru Рассчитать производные в полюсах при изменении полюса index. \en Calculate derivatives at poles when changing the pole "index". + + void operator = ( const MbBezier & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBezier ) +}; + +IMPL_PERSISTENT_OPS( MbBezier ) + +#endif // __CUR_BEZIER_H diff --git a/C3d/Include/cur_bezier3d.h b/C3d/Include/cur_bezier3d.h new file mode 100644 index 0000000..4fd36d0 --- /dev/null +++ b/C3d/Include/cur_bezier3d.h @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сплайн Безье в трёхмерном пространстве. + \en Bezier spline in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_BEZIER3D_H +#define __CUR_BEZIER3D_H + + +#include + + +class MATH_CLASS MbBezier; +class MATH_CLASS MbArc3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сплайн Безье в трёхмерном пространстве. + \en Bezier spline in three-dimensional space. \~ + \details \ru Сплайн Безье в трёхмерном пространстве определяется контрольными точками pointList. \n + Сплайн Безье является составной кривой, образованной стыкующимися между собой кривыми Безье третьей степени. + Каждая кривая Безье третьей степени построена по четырём соседним контрольным точкам множества pointList. + Для незамкнутого сплайна Безье первая и последняя контрольная точка множества pointList не используются. + Таким образом, сплайн Безье проходит через каждую контрольную точку множества pointList с индексом 3n+1, где n - целое число. + Значение параметра вдоль каждой кривой Безье третьей степени увеличивается на единицу. + Параметр сплайна Безье изменяется от нуля до k, где k - количество кривых Безье третьей степени, образующих сплайн. + В общем случае первая производная сплайна Безье может быть разрывной как по длине, так и по направлению. + \en Bezier spline in three-dimensional space is defined by control points pointList. \n + Bezier spline is composite curve formed by connected among themselves Bezier curves with third degree. + Each third-degree Bezier curve is constructed by four adjacent control points pointList. + First and last control point from pointList for unclosed Bezier spline are not used + Thus Bezier spline passes through each control point with index 3n+1, where n is integer. + The value of parameter along each third-degree Bezier curve is incremented. + The parameter of Bezier spline changes from zero to k, where k is the number of tree-degree Bezier curves which form spline. + In general case the first derivative of Bezier spline can be discontinuous by length and direction. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbBezier3D : public MbPolyCurve3D { +private : + ptrdiff_t splinesCount; ///< \ru Количество кривых Безье третьей степени. \en The number of third-degree Bezier curves. + int form; ///< \ru Форма кривой. \en Form of curve. + +protected : + MbBezier3D( const SArray & initList, bool cls, int initForm = 0 ); + MbBezier3D( const MbBezier &, const MbPlacement3D & ); + MbBezier3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + MbBezier3D( const MbBezier3D & ); ///< \ru Конструктор копирования. \en Copy constructor. +public : + virtual ~MbBezier3D(); + +public : + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbBezier3D * Create( const MbBezier3D & other ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initList - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] initForm - \ru Форма кривой. + \en Form of curve. \~ + */ + static MbBezier3D * Create( const SArray & initList, bool cls, int initForm = 0 ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] bezier - \ru Двумерный сплайн. + \en The two-dimensional spline. \~ + \param[in] place - \ru Локальная система координат сплайна. + \en Local coordinate system of spline. \~ + */ + static MbBezier3D * Create( const MbBezier & bezier, const MbPlacement3D & place ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create a spline and set parameters of spline.\n \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + */ + static MbBezier3D * Create( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + +public : + VISITING_CLASS( MbBezier3D ); + + void Init( const SArray & initList, bool cls ); + void Init( const MbBezier3D & ); + void Init( const MbBezier &, const MbPlacement3D & ); + void Init( MbArc3D & ); + + // \ru Общие функции математического объекта \en The common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Поворот \en Rotation + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en The point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная \en Third derivative + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculate step of approximation + virtual double DeviationStep( double t, double angle ) const; + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual bool Break( MbBezier3D &, double t1, double t2 ) const; // \ru Разбить на две части \en Split into two parts + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; + + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const; + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) + // \en Give a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called for a two-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + // \ru Общие функции полигональной кривой \en Common functions of a polygonal curve + + virtual void Rebuild(); // \ru Пересчитать Безье кривую \en Recalculate Bezier curve + virtual void SetClosed ( bool cls ); // \ru Установить признак замкнутости \en Set the closedness attribute. + virtual void AddPoint ( const MbCartPoint3D & ); // \ru Добавить точку в конец массива \en Add a point to the end of array + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D &, double ); // \ru Добавить точку \en Add a point + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку \en Remove a point + virtual bool ChangePoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Заменить точку \en Replace a point + virtual void ChangePole ( ptrdiff_t index, const MbCartPoint3D & ); // \ru Заменить полюс \en Replace a pole + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Загнать параметр получить локальный индексы и параметры \en Move parameter, get local indices and parameters + virtual double GetParam( ptrdiff_t i ) const; // \ru Выдать параметр для точки с номером \en Get a parameter for point with number + virtual size_t GetPointsCount() const; // \ru Выдать количество точек \en Get the number of points + virtual void GetPoint ( ptrdiff_t index, MbCartPoint3D & ) const; // \ru Выдать точку \en Get a point + virtual ptrdiff_t GetNearPointIndex ( const MbCartPoint3D & ) const; // \ru Выдать индекс точки, ближайшей к заданной \en Get the point index which is nearest to the given + virtual void GetRuleInterval ( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки \en Get the interval of point influence + + MbNurbs3D * Trimm( double t1, double t2, int sense ) const; + void Trimm( MbBezier3D &, double t1, double t2, int sense ) const; + + void InitCtrlPoints( const SArray & ); + void SetBezierSplines(); // \ru Вычислить параметры кривой-Bezier \en Calculate parameters of the Bezier curve + int GetFormType() const { return form; } // \ru Форма сплайна \en The spline form + void SetFormType( int newForm ); + ptrdiff_t GetSplinesCount() const { return splinesCount; } // \ru Количество сплайнов \en The number of splines + + // \ru Функции только 3D кривой \en Function for 3D-curve + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + + virtual size_t GetCount() const; + + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + +private : + void CheckBezierClosed(); // \ru Проверка признака замкнутости. \en Check closed. + void EvaluateSlope ( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index \en Calculate derivatives at the pole "index" + void EvaluateSlope0( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index для 0-ой формы \en Calculate derivatives at the pole "index" for 0-th form + void EvaluateSlope1( ptrdiff_t index ); // \ru Рассчитать производные в полюсе index для 1-ой формы \en Calculate derivatives at the pole "index" for 1-th form + void SetDerives (); // \ru Рассчитать все производные \en Calculate all derivatives + void SetDerives ( ptrdiff_t index ); // \ru Рассчитать производные в полюсах при изменении полюса index \en Calculate derivatives at poles when changing the pole "index" + +private: + void operator = ( const MbBezier3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBezier3D ) +}; + +IMPL_PERSISTENT_OPS( MbBezier3D ) + +#endif // __CUR_BEZIER3D_H diff --git a/C3d/Include/cur_bridge3d.h b/C3d/Include/cur_bridge3d.h new file mode 100644 index 0000000..358d30b --- /dev/null +++ b/C3d/Include/cur_bridge3d.h @@ -0,0 +1,142 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая-мостик, соединяющая концы двух кривых. + \en Bridge curve connecting ends of two curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_BRIDGE3D_H +#define __CUR_BRIDGE3D_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая-мостик, соединяющая концы двух кривых. + \en Bridge curve connecting ends of two curves. \~ + \details \ru Кривая-мостик соединяет точки двух кривых кривой третьей степени, + построенной по конечным точкам и производным в конечных точках. + Конечные точки и производные в конечных точках вычисляются в соединяемых точках соединяемых кривых. \n + \en The bridge curve connects points of two curves with a curve of the third degree + constructed by the end points and derivatives at the end points. + The end points and derivatives at the end points are calculated for curves' points being connected. \n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbBridgeCurve3D : public MbCurve3D { +protected: + MbCurve3D * curve1; ///< \ru Первая соединяемая кривая. \en The first curve to connect. + MbCurve3D * curve2; ///< \ru Вторая соединяемая кривая. \en The second curve to connect. + double param1; ///< \ru Параметр точки соединения первой кривой. \en Parameter of the first curve's connection point. + double param2; ///< \ru Параметр точки соединения второй кривой. \en Parameter of the second curve's connection point. + bool sense1; ///< \ru Совпадение (true) направления производных кривой и первой кривой. \en The coincidence(true) of directions this curve and the first curve in connection points. + bool sense2; ///< \ru Совпадение (true) направления производных кривой и второй кривой. \en The coincidence(true) of directions this curve and the second curve in connection points. + double tmin; ///< \ru Начальный параметр кривой. \en The starting parameter of the curve. + double tmax; ///< \ru Конечный параметр кривой. \en The end parameter of the curve. + // \ru Насчитанные по кривым данные. \en Data calculated for the curves. + MbCartPoint3D point1; ///< \ru Точка на первой кривой. \en Point on the first curve. + MbCartPoint3D point2; ///< \ru Точка на второй кривой. \en Point on the second curve. + MbVector3D derive1;///< \ru Производная в начальной точке. \en Derivative at the starting point. + MbVector3D derive2;///< \ru Рроизводная в конечной точке. \en Derivative at the end point. + // \ru Временные данные. \en Temporary data. + mutable MbCube cube; ///< \ru Габаритный куб. \en Bounding box. + +public : + MbBridgeCurve3D( MbCurve3D & c1, double t1, bool s1, + MbCurve3D & c2, double t2, bool s2, + double _tmin = 0.0, double _tmax = 1.0 ); +protected: + MbBridgeCurve3D( const MbBridgeCurve3D & ); // \ru НЕЛЬЗЯ \en NOT ALLOWED + MbBridgeCurve3D( const MbBridgeCurve3D &, MbRegDuplicate * ireg ); + +public: + virtual ~MbBridgeCurve3D(); + +public: + VISITING_CLASS( MbBridgeCurve3D ); + + void Init( MbCurve3D & c1, double t1, bool s1, + MbCurve3D & c2, double t2, bool s2, + double _tmin, double _tmax ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией \en Whether the object is a copy + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Сделать элементы равными \en Make the elements equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб \en Add own bounding box into a bounding box + virtual void Refresh(); // \ru Сбросить все временные данные \en Flush all the temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of the curve + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed () const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const;// \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of the approximation step + virtual double DeviationStep( double t, double angle ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + const MbCube &GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } // \ru Выдать габарит кривой \en Get the bounding box of a curve + +private: + inline void CheckParam ( double & t ) const; // \ru Проверка параметра \en Check parameter + inline void LocalParams ( const double & t, double & quota1, double & quota2 ) const; // \ru Вычисление локальных данных по параметру \en Calculation of local data by the parameter + void LocalData (); // \ru Определение значений точек и производных на концах \en Determination of values of points and derivatives at the ends + void ChangeCurves( MbCurve3D & c1, MbCurve3D & c2 ); + void operator = ( const MbBridgeCurve3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBridgeCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbBridgeCurve3D ) + +//------------------------------------------------------------------------------ +/// \ru Проверка параметра. \en Check parameter. +// --- +inline void MbBridgeCurve3D::CheckParam( double & t ) const { + if ( t < tmin ) + t = tmin; + else + if ( t > tmax ) + t = tmax; +} + + +//------------------------------------------------------------------------------ +/// \ru Определение необходимых локальных параметров. \en Determination of the necessary local parameters. +// --- +inline void MbBridgeCurve3D::LocalParams( const double & t, double & quota1, double & quota2 ) const { + double paramW = 1 / ( tmax - tmin ); + quota1 = ( tmax - t ) * paramW; + quota2 = ( t - tmin ) * paramW; +} + + +#endif // __CUR_BRIDGE3D_H diff --git a/C3d/Include/cur_character_curve.h b/C3d/Include/cur_character_curve.h new file mode 100644 index 0000000..eb22602 --- /dev/null +++ b/C3d/Include/cur_character_curve.h @@ -0,0 +1,151 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерная кривая, координатные функции которой заданы в символьном виде. + \en Functionally defined two-dimensional curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CHARACTER_CURVE_H +#define __CUR_CHARACTER_CURVE_H + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbFunction; + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерная кривая, координатные функции которой заданы в символьном виде. + \en Functionally defined two-dimensional curve. \~ + \details \ru Координатные функции кривой заданы в виде пользовательских функций общего параметра t. + Каждая координата кривой описана своей функцией в виде строкового выражения. + Параметр кривой, он же параметр координатных функций, изменяется на отрезке [tmin tmax]. \n + Все пользовательские функции заданы в локальной системе координат position. + Система координат может быть декартовой или полярной. + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + r(t) = position.origin + (position.axisX xFunction(t)) + (position.axisY yFunction(t)). + \en Functions of coordinates of curve are given as custom functions of common parameter t. + Each coordinate of the curve is described by its own function in form of string expression. + Parameter of the curve, which is also the parameter of functions of coordinates, varies in range [tmin tmax]. \n + All the custom functions are given in the local coordinate system position. + The coordinate system can be Cartesian or polar. + The radius-vector of the curve in method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + r(t) = position.origin + (position.axisX xFunction(t)) + (position.axisY yFunction(t)). \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbCharacterCurve : public MbCurve { +private: + MbFunction * xFunction; ///< \ru Функция координаты x. \en Function of x-coordinate. + MbFunction * yFunction; ///< \ru Функция координаты y. \en Function of y-coordinate. + MbPlacement position; ///< \ru Локальная система координат, в которой заданы координатные функции. \en The local coordinate system the functions of coordinates are specified in. + MbMatrix transform; ///< \ru Матрица трансформации кривой. \en Transformation matrix of the curve. + double tmin; ///< \ru Минимальное значение параметра кривой. \en The minimal value of a curve parameter. + double tmax; ///< \ru Максимальное значение параметра кривой. \en The maximal value of the curve parameter. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + MbeLocalSystemType coordinateType; ///< \ru Тип системы координат, в которой заданы координатные функции \en Type of coordinate system the functions of coordinates are specified in + c3d::DoubleVector specialParams; ///< \ru Перечень параметров особых точек кривой \en List of parameters of curve's singular points + // \ru Буферные данные для ускорения вычислений. \en Buffer data to speed up computations. + mutable double metricLength; + mutable MbRect rect; + +public: + MbCharacterCurve( MbFunction & x, MbFunction & y, + MbeLocalSystemType cs, + const MbPlacement & place, + double tmin_, double tmax_ ); +protected: + MbCharacterCurve( const MbCharacterCurve & ); +public: + virtual ~MbCharacterCurve(); + +public: + VISITING_CLASS( MbCharacterCurve ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en A type of element + virtual MbPlaneItem & Duplicate ( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Кривая есть копия этой кривой ? \en Is a curve a copy of this curve? + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void AddYourGabaritTo( MbRect & ) const; // \ru Добавь в прям-к свой габарит \en Add own bounding rectangle to the bounding rectangle + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + // \ru Общие функции кривой. \en Common functions of the curve. + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer( double & t, MbVector & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer( double & t, MbVector & ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага параметра по величине прогиба кривой \en Calculation of parameter step by value of sag of the curve + virtual double DeviationStep ( double t, double ang ) const; // \ru Вычисление шага параметра по углу отклонения касательной \en Calculation of parameter by the angle of tangent deviation + + virtual bool HasLength ( double & length ) const; // \ru Метрическая длина кривой \en Metric length of a curve + + virtual double GetMetricLength () const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Metric length evaluation of a curve + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual size_t GetCount () const; // \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual MbNurbs * NurbsCurve ( const MbCurveIntoNurbsInfo & ) const; + + virtual MbCurve * Trimmed ( double t1, double t2, int sense ) const; + virtual MbeState DeletePart ( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть кривой между параметрами t1 и t2 \en Remove a piece of curve between t1 and t2 parameters + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть кривой между параметрами t1 и t2 \en Keep a piece of curve between t1 and t2 parameters + + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void GetProperties ( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + void CheckParam ( double & t ) const; + void CalculateParam( double t, MbCartPoint & point, + MbVector & firstDer, MbVector & secondDer, MbVector & thirdDer ) const; + + const MbFunction * GetX() const { return xFunction; } + const MbFunction * GetY() const { return yFunction; } + const MbMatrix & GetMatrix() const { return transform; } + const MbPlacement & GetPlacement() const { return position; } + MbeLocalSystemType GetCoordinateType() const { return coordinateType; } + void GetSpecialParams( std::vector & params ) const; + +protected: + double ApproximationStep( double t, bool isAngle, double sag ) const; + void ConvertParamsInd( size_t componentIndex, + const std::vector & tComponent, + std::vector & tCrv ) const; + void ConvertParams( const double tCrv, + double (&tComponents) [2], + double (&proportionFactors)[2]) const; + +private: + // \ru Проверить и установить признак замкнутости. \en Check and set the flag of closedness. + void CheckClosed(); + +private: + void operator = ( const MbCharacterCurve & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCharacterCurve ) +}; + +IMPL_PERSISTENT_OPS( MbCharacterCurve ) + +#endif // __CUR_CHARACTER_CURVE_H diff --git a/C3d/Include/cur_character_curve3d.h b/C3d/Include/cur_character_curve3d.h new file mode 100644 index 0000000..213d8b6 --- /dev/null +++ b/C3d/Include/cur_character_curve3d.h @@ -0,0 +1,153 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая, координатные функции которой заданы в символьном виде. + \en Functionally defined curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CHARCTER_CURVE3D_H +#define __CUR_CHARCTER_CURVE3D_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbFunction; +class MATH_CLASS MbCharacterCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая, координатные функции которой заданы в символьном виде. + \en Functionally defined curve. \~ + \details \ru Координатные функции кривой заданы в виде пользовательских функций общего параметра t. + Каждая координата кривой описана своей функцией в виде строкового выражения. + Параметр кривой, он же параметр координатных функций, изменяется на отрезке [tmin tmax]. \n + Все пользовательские функции заданы в локальной системе координат position. + Система координат может быть декартовой, цилиндрической или сферической. + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + r(t) = position.origin + (position.axisX xFunction(t)) + (position.axisY yFunction(t)) + (position.axisZ zFunction(t)). + \en Functions of coordinates of the curve are given as custom functions of common parameter t. + Each coordinate of the curve is described by its own function in form of string expression. + Parameter of the curve, which is also the parameter of functions of coordinates, varies in range [tmin tmax]. \n + All the custom functions are given in the local coordinate system position. + The coordinate system can be Cartesian, cylindrical or spherical. + The radius-vector of the curve in method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + r(t) = position.origin + (position.axisX xFunction(t)) + (position.axisY yFunction(t)) + (position.axisZ zFunction(t)). \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbCharacterCurve3D : public MbCurve3D { +private: + MbFunction * xFunction; ///< \ru Функция координаты x. \en Function of x-coordinate. + MbFunction * yFunction; ///< \ru Функция координаты y. \en Function of y-coordinate. + MbFunction * zFunction; ///< \ru Функция координаты z. \en Function of z-coordinate + MbPlacement3D position; ///< \ru Локальная система координат, в которой заданы координатные функции. \en The local coordinate system the functions of coordinates are specified in. + MbMatrix3D transform; ///< \ru Матрица трансформации кривой. \en Transformation matrix of the curve. + double tmin; ///< \ru Минимальное значение параметра кривой. \en The minimal value of a curve parameter. + double tmax; ///< \ru Максимальное значение параметра кривой. \en The maximal value of the curve parameter. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + MbeLocalSystemType3D coordinateType; ///< \ru Тип системы координат, в которой заданы координатные функции. \en Type of coordinate system the functions of coordinates are specified in. + c3d::DoubleVector specialParams; ///< \ru Множество параметров особых точек кривой. \en Set of parameters of curve's singular points. + // \ru Буферные данные для ускорения вычислений. \en Buffer data to speed up computations. + mutable double metricLength; + mutable MbCube cube; + +public: + MbCharacterCurve3D( MbFunction & x, MbFunction & y, MbFunction & z, + MbeLocalSystemType3D cs, const MbPlacement3D & place, + double tmin_, double tmax_ ); + MbCharacterCurve3D( const MbCharacterCurve & init, const MbPlacement3D & place ); // \ru Конструктор по двумерной кривой \en Constructor by two-dimensional curve +protected: + MbCharacterCurve3D( const MbCharacterCurve3D & ); +public: + virtual ~MbCharacterCurve3D(); + +public: + VISITING_CLASS( MbCharacterCurve3D ) + + virtual MbeSpaceType IsA () const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Кривая есть копия этой кривой ? \en Is a curve a copy of this curve? + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform ( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void AddYourGabaritTo( MbCube & ) const; + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties ( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties ( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой. \en Common functions of the curve. + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer( double & t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer( double & t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Step ( double t, double sag ) const; ///< \ru Вычисление шага параметра по величине прогиба кривой \en Calculation of parameter step by value of sag of the curve + virtual double DeviationStep( double t, double ang ) const; ///< \ru Вычисление шага параметра по углу отклонения касательной \en Calculation of parameter by the angle of tangent deviation + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; + + virtual bool IsPlanar() const; // \ru Является ли кривая плоской \en Whether the curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, если кривая плоская \en Fill the placement if curve is planar + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called on a three-dimensional curve) + virtual bool GetPlaneCurve ( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + virtual MbCurve * GetMap( const MbMatrix3D & into, MbRect1D * pRegion = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + // \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual size_t GetCount() const; + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + void CheckParam ( double & t ) const; + void CalculateParam( double t, MbCartPoint3D & point, + MbVector3D & firstDer, MbVector3D & secondDer, MbVector3D & thirdDer ) const; + + const MbFunction * GetX() const { return xFunction; } + const MbFunction * GetY() const { return yFunction; } + const MbFunction * GetZ() const { return zFunction; } + const MbMatrix3D & GetMatrix() const { return transform; } + const MbPlacement3D & GetPlacement() const { return position; } + MbeLocalSystemType3D GetCoordinateType() const { return coordinateType; } + +protected: +// void GetSpecialParams( std::vector & params ) const; + double ApproximationStep( double t, bool isAngle, double constraint ) const; + void ConvertParamsInd( size_t componentIndex, + const std::vector & tComponent, + std::vector & tCrv ) const; + void ConvertParams( const double tCrv, + double (&tComponents)[3], + double (&proportionFactors)[3]) const; + +private: + // \ru Проверить и установить признак замкнутости. \en Check and set the flag of closedness. + void CheckClosed(); + +private: + void operator = ( const MbCharacterCurve3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCharacterCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbCharacterCurve3D ) + +#endif // __CUR_CHARCTER_CURVE3D_H diff --git a/C3d/Include/cur_cone_spiral.h b/C3d/Include/cur_cone_spiral.h new file mode 100644 index 0000000..cc48305 --- /dev/null +++ b/C3d/Include/cur_cone_spiral.h @@ -0,0 +1,220 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Коническая спираль. + \en Conical spiral. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONE_SPIRAL_H +#define __CUR_CONE_SPIRAL_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Коническая спираль. + \en Conical spiral. \~ + \details \ru Плоская, коническая или цилиндрическая спираль. + Ось спирали направлена вдоль оси Z локальной системы координат. \n + Параметр кривой отсчитывается от оси position.axisX локальной системы координат. + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + для плоской спирали: \n + r(t) = position.origin + (position.axisX rad cos(t)) + (position.axisY rad sin(t)), + где rad = radius + (stepd2pi t), если tgAlpha = pi/2 или rad = radius - (stepd2pi t), если tgAlpha = -pi/2; + для цилиндрической спирали: \n + r(t) = position.origin + (position.axisZ stepd2pi t) + (position.axisX radius cos(t)) + (position.axisY radius sin(t)); + для конической спирали: \n + r(t) = position.origin + (position.axisZ stepd2pi t) + (position.axisX rad cos(t)) + (position.axisY rad sin(t)), + где rad = radius + (tgAlpha stepd2pi t). \n + \en Planar, Conical or cylindrical spiral. + A spiral axis is directed along the Z-axis of the local coordinate system. \n + The curve parameter is measured from the axis "position.axisX" of the local coordinate system. + The radius-vector of curve in the method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + for planar spiral: \n + r(t) = position.origin + (position.axisX rad cos(t)) + (position.axisY rad sin(t)), + where rad = radius + (stepd2pi t), if tgAlpha = pi/2 or rad = radius - (stepd2pi t), if tgAlpha = -pi/2; + for cylindrical spiral: \n + r(t) = position.origin + (position.axisZ stepd2pi t) + (position.axisX radius cos(t)) + (position.axisY radius sin(t)); + for conical spiral: \n + r(t) = position.origin + (position.axisZ stepd2pi t) + (position.axisX radius cos(t)) + (position.axisY radius sin(t)); + where rad = radius + (tgAlpha stepd2pi t). \n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbConeSpiral: public MbSpiral +{ +public: + enum ConeSpiralType { + cst_Plane, ///< \ru Плоская спираль. \en Planar spiral. + cst_Cylindrical, ///< \ru Цилиндрическая спираль. \en Cylindrical spiral. + cst_Conical, ///< \ru Коническая спираль. \en Conical spiral. + }; +private: + ConeSpiralType type; ///< \ru Тип спирали. \en A spiral type. +protected: + double radius; ///< \ru Радиус основания. \en Bottom radius. + double tgAlpha; ///< \ru Тангенс угла полуконуса. \en Tangent of the semicone angle. + double stepd2pi; ///< \ru Шаг спирали, деленный на 2*pi. \en Spiral step divided by 2*pi. + +public: + /// \ru Цилиндрическая спираль по трем точкам и шагу. \en Cylindrical spiral by three points and step. + MbConeSpiral( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, double st, bool left = false ); + /// \ru Коническая спираль по основанию, радиусам двух оснований, и высоте с шагом. \en Conical spiral by the base, radii of the two bases and height with step. + MbConeSpiral( const MbPlacement3D & pl, double radius1, double radius2, double height, double st ); + /// \ru Коническая спираль , радиусу, углу уклона, высоте с шагом, и основанию. \en Conical spiral by radius, inclination angle, height with step and base. + MbConeSpiral( double radius, double angle, double height, double st, const MbPlacement3D & pl ); + /// \ru Цилиндрическая спираль по радиусу основания, шагу, основанию, и двум параметрам. \en Cylindrical spiral by bottom radius, step, base and two parameters. + MbConeSpiral( double radius, double st, const MbPlacement3D & pl, double t1, double t2 ); + /// \ru Коническая спираль по радиусу основания, высоте, тангенсу угла наклона, основанию, и параметрам. \en Conical spiral by bottom radius, height, tangent of inclination angle, base and parameters. + MbConeSpiral( double r0, double h, double tgAH, const MbPlacement3D & pl, double u1, double v1, double u2, double v2 ); + +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbConeSpiral( const MbConeSpiral & init ); + +public: + /// \ru Деструктор. \en Destructor. + virtual ~MbConeSpiral(); + +public: + VISITING_CLASS( MbConeSpiral ); + + /// \ru Инициализация конической спирали по конической спирали. \en Initialization of conical spiral by conical spiral. + void Init( const MbConeSpiral & init ); + /// \ru Инициализация цилиндрической спирали по основанию. \en Initialization of cylindrical spiral by base. + void Init( const MbPlacement3D & place ); + /// \ru Инициализация конической спирали по радиусам оснований, высоте и шагу. \en Initialization of conical spiral by bottom radii, height and step. + void Init( double radius1, double radius2, double height, double st ); + /// \ru Инициализация конической спирали по основанию, радиусам оснований, и высоте с шагом. \en Initialization of conical spiral by the base, radii of bases and height with step. + void Init( const MbPlacement3D & place, double radius1, double radius2, double height, double st ); + +public: + // \ru Общие функции математического объекта. \en The common functions of the mathematical object. + virtual MbeSpaceType IsA() const; // \ru Получить тип. \en Get a type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru Общие функции кривой. \en Common functions of curve. + + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & pnt ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void FirstDer ( double & t, MbVector3D & fd ) const; // \ru Первая производная. \en First derivative. + virtual void SecondDer( double & t, MbVector3D & sd ) const; // \ru Вторая производная. \en Second derivative. + virtual void ThirdDer ( double & t, MbVector3D & td ) const; // \ru Третья производная по t. \en The third derivative with respect to t. + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint3D & pnt ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void _FirstDer ( double t, MbVector3D & fd ) const; // \ru Первая производная. \en First derivative. + virtual void _SecondDer( double t, MbVector3D & sd ) const; // \ru Вторая производная. \en Second derivative. + virtual void _ThirdDer ( double t, MbVector3D & td ) const; // \ru Третья производная по t. \en The third derivative with respect to t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой. \en Creation of a trimmed curve. + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual double CalculateLength( double t1, double t2 ) const; + + // \ru Ближайшая проекция точки на спираль. \en The nearest point projection on the spiral. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & t, bool ext, MbRect1D * tRange = NULL ) const; + + // \ru Частные функции спирали. \en Special functions for spiral. + virtual void SetStep( double s ); // \ru Изменить шаг. \en Change the step. + virtual double GetSpiralRadius( double t ) const; // \ru Выдать радиус физический спирали. \en Get a radius of the physical spiral. + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of curve with equal intervals along the length of the arc. + + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы) \en Get a surface curve if spatial curve is lying on the surface (after the using call DeleteItem for arguments) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + + double GetAlpha() const { return ::atan( tgAlpha ); } + double GetTgAlpha() const { return tgAlpha; } + void SetAlpha( double a ) { tgAlpha = ::tan( a ); Refresh(); } + + double GetR() const { return radius; } + void FastInverse(); + double GetStepD2PI() const { return stepd2pi; } + void GetSpiralDir( MbVector3D & dir ) const; + + /// \ru Узнать тип конической спирали \en Learn the type of conical spiral. + ConeSpiralType GetType() const { return type; } +private: + bool IsConeType() const { return ::fabs( tgAlpha ) > LENGTH_EPSILON; } + void CalConeTMax(); // \ru Усеченное значение tmax для случая закручивающихся в точку плоской или конической спиралей. \en Trimmed value tmax for the case of planar or conical spirals trailing to the point. + double GetR( double t ) const; // \ru Текущий радиус. \en The current radius. + double GetRDerive( double t ) const; // \ru Производная текущего радиуса. \en The derivative of the current radius. + // \ru Ближайшая проекция точки на плоскую спираль. \en The nearest point projection on the planar spiral. + bool PlaneProjection( const MbCartPoint3D & pSpace, double & tProj, bool ext, MbRect1D * tRange ) const; + // \ru Ближайшая проекция точки на цилиндрическую спираль. \en The nearest point projection on the cylindrical spiral. + bool CylindricalProjection( const MbCartPoint3D & pSpace, double & tProj, bool ext, MbRect1D * tRange ) const; + +private: + // \ru Объявление (перегрузка) оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en Declaration (overload) of the assignment operator without its implementation, to prevent the default assignment. + MbConeSpiral & operator = ( const MbConeSpiral & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbConeSpiral ) +}; + +IMPL_PERSISTENT_OPS( MbConeSpiral ) + +//------------------------------------------------------------------------------ +// \ru Дать направление движения по спирали \en Give the direction of motion on a spiral +// --- +inline void MbConeSpiral::GetSpiralDir( MbVector3D & dir ) const +{ + dir.Init( position.GetAxisZ() ); + + MbCartPoint3D pnt1, pnt2; + double t = GetTMin(); + _PointOn( t, pnt1 ); + t += M_PI2; + _PointOn( t, pnt2 ); + MbVector3D spiralV( pnt1, pnt2 ); + + if ( spiralV * dir < -ANGLE_EPSILON ) + dir.Invert(); +} + + +//------------------------------------------------------------------------------ +// \ru Внутренний радиус \en Inner radius +// --- +inline double MbConeSpiral::GetR( double t ) const +{ + //C3D_ASSERT( position.IsIsotropic() || ::fabs(tgAlpha) < LENGTH_EPSILON ); // \ru Проверить корректность работы \en Check the correctness of working + switch ( type ) { // t = [0; 2*pi] + case cst_Plane : return tgAlpha > 0.0 ? ( radius + stepd2pi * t ) : ( radius - stepd2pi * t ); + case cst_Cylindrical : return radius; + default : return radius + tgAlpha * stepd2pi * t; + } +} + + +//------------------------------------------------------------------------------ +// \ru Производная внутреннего радиуса \en Derivative of inner radius +// --- +inline double MbConeSpiral::GetRDerive( double /*t */) const +{ + switch ( type ) { // t = [0; 2*pi] + case cst_Plane : return tgAlpha > 0.0 ? stepd2pi : -stepd2pi; + case cst_Cylindrical : return 0.0; + default : return tgAlpha * stepd2pi; + } +} + + +#endif // __CUR_CONE_SPIRAL_H diff --git a/C3d/Include/cur_contour.h b/C3d/Include/cur_contour.h new file mode 100644 index 0000000..41b5a99 --- /dev/null +++ b/C3d/Include/cur_contour.h @@ -0,0 +1,705 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контур в двумерном пространстве. + \en Contour in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONTOUR_H +#define __CUR_CONTOUR_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbArc; +class SimpleNameArray; +class MbCurveIntoNurbsInfo; + + +class MATH_CLASS MbContour; +namespace c3d // namespace C3D +{ +typedef SPtr PlaneContourSPtr; +typedef SPtr ConstPlaneContourSPtr; + +typedef std::vector PlaneContoursVector; +typedef std::vector ConstPlaneContoursVector; + +typedef std::vector PlaneContoursSPtrVector; +typedef std::vector ConstPlaneContoursSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Контур в двумерном пространстве. + \en Contour in two-dimensional space. \~ + \details \ru Контур представляет собой составную кривую, в которой начало каждого последующего сегмента стыкуется с концом предыдущего. + Контур является замкнутым, если конец последнего сегмента стыкуется с началом первого сегмента.\n + Если сегменты составной кривой стыкуются не гладко, то составная кривая будет иметь изломы. + В общем случае в местах стыковки сегментов производные составной кривой терпят разрыв по длине и направлению. \n + Начальное значение параметра составной кривой равно нулю. + Параметрическая длина составной кривой равна сумме параметрических длин составляющих её сегментов. \n + При вычислении радиуса-вектора составной кривой сначала определяется сегмент, + которому соответствует значение параметра составной кривой, и соответствующее значение собственного параметра этого сегмента. + Далее вычисляется радиус-вектор сегмента, который и будет радиусом-вектором составной кривой. \n + В качестве сегментов составной кривой не используются другие составные кривые. + Если составную кривую нужно построить на основе других составных кривых, + то последние должны рассматриваться как совокупность составляющих их кривых, а не как единые кривые.\n + Двумерный контур используется для плоского моделирования, а также для описания двумерных связных областей, например, для описания области определения параметров поверхности.\n + \en Contour is a composite curve in which the beginning of each subsequent segment is joined to the end of the previous one. + Contour is closed if the end of last segment is joined to the beginning of the first segment.\n + If the segments of a composite curve are not smoothly joined then the composite curve will have breaks. + In general case in places of joining segments derivatives of a composite curve have discontinuity along the length and direction. \n + The initial value of the composite curve is equal to zero. + The parametric length of a composite curve is equal to the sum of the parametric lengths of components of its segments. \n + When the calculation of the radius-vector of a composite curve segment is determined at first, + the value of composite curve parameter and the corresponding value of the own parameters of this segment corresponds to this segment. + Then computes the radius-vector of the segment which will be the radius-vector of the composite curve. \n + Other composite curves are not used as segments of the composite curve. + If it is required to create a composite curve based on other composite curves, + then the latter must be regarded as a set of their curves, and not as single curves. \n + The two-dimensional contour is used for planar modeling and also for describing of two-dimensional areas, for example for determining of the domain of surface.\n \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbContour : public MbCurve, public MbNestSyncItem { +protected : + RPArray segments; ///< \ru Множество сегментов контура. \en An array of contour segments. + bool closed; ///< \ru Признак замкнутости кривой. \en An Attribute of curve closedness. + double paramLength; ///< \ru Параметрическая длина контура. \en Parametric length of a contour. +protected: + mutable double metricLength; ///< \ru Метрическая длина контура. \en Metric length of a contour. + mutable MbRect rect; ///< \ru Габаритный прямоугольник. \en Bounding box. + mutable c3d::DoublePair areaSign; ///< \ru Площадь контура со знаком. \en Contour area with a sign. + +public : + /// \ru Пустой контур. \en Empty contour. + MbContour(); + /// \ru Конструктор по набору кривых. \en Constructor by curves vector. + template + MbContour( const Curves &, bool same ); +protected : + explicit MbContour( const MbContour *, MbRegDuplicate * ); ///< \ru Конструктор копирования. \en Copy constructor. +public : + virtual ~MbContour(); + +public: + VISITING_CLASS( MbContour ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en A type of element + virtual MbePlaneType Type() const; // \ru Тип элемента \en A type of element + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element. + virtual bool IsSimilar ( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar. + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements. + virtual bool IsSame( const MbPlaneItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the curve "curve" is a copy of a given curve? + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix. + virtual void Move( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation. + virtual void Rotate( const MbCartPoint &, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation. + + /** \brief \ru Построить эквидистантную кривую, смещённую на заданное расстояние. + \en Construct the equidistant curve which is shifted by the given value. \~ + \details \ru Построить эквидистантную кривую, смещённую на заданное расстояние. + Функция вставляет в копии контура дуги нулевого радиуса между стыками сегментов. + Это нужно для обеспечения непрерывности контура для обоих направлений смещения. + Но это может приводить к появлению самопересечений контура. + Затем выполняет эквидистантное смещение всех сегментов. + Данная функция имеет ограниченную область применения. + В качестве альтернативы можно использовать функцию OffsetContour. + \en Construct the equidistant curve which is shifted by the given value. + The function inserts (in a contour's copy) the arcs of zero radius between neighbor segments. + This is necessary to provide continuity of the contour for both directions of displacement. + But it can lead to the appearance of self-intersections of an contour. + Then the function performs an equidistant offset of all segments. + This function has a limited scope of using. + You can use the OffsetContour function instead this function. \~ + \param[in] rad - \ru Величина эквидистантного смещения. + \en Equidistant offset. \~ + \return \ru Возвращает эквидистантный контур, если получилось его построить, иначе - NULL. + \en Returns the equidistant curve if it's possible to build it, otherwise - NULL. \~ + */ + virtual MbCurve * Offset( double rad ) const; // \ru Смещение контура. \en Shift of a contour + + virtual void AddYourGabaritTo ( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к. \en Add bounding box into a straight box. + virtual void CalculateGabarit ( MbRect & ) const; // \ru Определить габариты кривой. \en Determine the bounding box of the curve. + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const; // \ru Добавь в прям-к свой габарит с учетом матрицы \en Add bounding box into a box with consideration of the matrix. + + const MbRect & GetGabarit() const { if ( rect.IsEmpty() ) CalculateGabarit( rect ); return rect; } + const MbRect & GetCube() const { if ( rect.IsEmpty() ) CalculateGabarit( rect ); return rect; } + void SetDirtyGabarit() const { rect.SetEmpty(); } + void CopyGabarit( const MbContour & c ) { rect = c.rect; } + bool IsGabaritEmpty() const { return rect.IsEmpty(); } + + virtual double DistanceToPoint( const MbCartPoint & ) const; // \ru Расстояние до точки \en Distance to a point. + + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation. + virtual bool IsInRectForDeform( const MbRect & ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the specified rectangle for the deformation. + + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data. + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + // \ru Удалить часть контура между параметрами t1 и t2 \en Remove a part of the contour between t1 and t2 parameters. + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть контура между параметрами t1 и t2 \en Save a part of the contour between t1 and t2 parameters. + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой. \en Check for curve closedness. + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой. \en An attribute of curve straightness. + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of contour\curve are smooth. + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the domain of a curve. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double &, MbCartPoint & ) const; // \ru Точка на кривой \en The point on the curve + virtual void FirstDer ( double &, MbVector & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double &, MbVector & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double &, MbVector & ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Function for working inside and outside of the curve domain. + Function _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct a parameter + when it is outside domain. If non-closed curve is outside of the domain + in the general case it continues along a tangent, which it has at the respective end. + \{ */ + virtual void _PointOn ( double, MbCartPoint & ) const; // \ru Точка на кривой. \en The point on the curve. + virtual void _FirstDer ( double, MbVector & ) const; // \ru Первая производная. \en First derivative. + virtual void _SecondDer( double, MbVector & ) const; // \ru Вторая производная. \en Second derivative. + virtual void _ThirdDer ( double, MbVector & ) const; // \ru Третья производная. \en Third derivative. + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Functions of the motion along the curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculate step of approximation. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of step approximation with consideration of the deviation angle. + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual bool HasLength( double & ) const; + virtual double GetMetricLength() const; // \ru Метрическая длина контура \en Metric length of a contour. + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Evaluation of the metric length of the curve. + + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + double GetParamLength() const { return paramLength; } + double CalculateParamLength(); // \ru Посчитать параметрическую длину \en Calculate the parametric length + + double GetArea( double sag = Math::deviateSag ) const + { + sag = ::fabs(sag); + if ( ::fabs( areaSign.first - sag ) > EXTENT_EPSILON ) + return CalculateArea( sag ); + return areaSign.second; + } + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbContour * NurbsContour() const; + + void SetClosed(); ///< \ru Установить признак замкнутости контура. \en Set the closedness attribute of contour. + void CheckClosed( double eps ); ///< \ru Установить признак замкнутости контура. \en Set the closedness attribute of contour. + void InitClosed( bool c ) { closed = c; } ///< \ru Установить признак замкнутости контура. \en Set the closedness attribute of contour. + + /** \brief \ru Проверить замкнутость и непрерывность точек контура. + \en Check for closedness and continuity of contour points. \~ + \details \ru Проверить замкнутость и непрерывность точек контура. + Проверяется совпадение первой и последней точки контура, + совпадение последней точки каждого сегмента с первой точкой следующего сегмента. + Равенство точек проверяется по умолчанию грубо - с точностью, равной 5 * PARAM_NEAR. + \en Check for closedness and continuity of contour points. + Checking for coincidence of first and last points of the contour, + coincidence of the last point of each segment with the first point of the next segment. + Equality of points is checked roughly by default - with tolerance is equal to 5* PARAM_NEAR. \~ + \return \ru true, если контур замкнутый и непрерывный. + \en true, if contour is closed and continuous. \~ + */ + bool IsClosedContinuousC0( double eps = 5.0 * PARAM_NEAR ) const; + + void CloseByLineSeg( bool calcData ); ///< \ru Замкнуть контур отрезком. \en Close the contour by segment. + + // \ru Посчитать метрическую длину разомкнутой кривой с заданной точностью \en Calculate the metric length of unclosed curve within the given tolerance + virtual double CalculateLength( double t1, double t2 ) const; + // \ru Сдвинуть параметр t на расстояние len \en Move parameter t on the distance len + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Cбросить переменные кэширования. \en Reset variables caching. + void Clear( bool calculateParamLength = true ) + { + if ( calculateParamLength ) + CalculateParamLength(); // \ru Параметрическая длина контура \en Parametric length of a contour + metricLength = -1; // \ru Метрическая длина кривой \en Metric length of a curve + rect.SetEmpty(); + areaSign.first = -1.0; + } + ptrdiff_t FindSegment( double & t, double & tSeg ) const; ///< \ru Нахождение сегмента контура. \en Finding of a contour segment. + size_t GetSegmentsCount() const { return segments.size(); } ///< \ru Выдать количество сегментов контура. \en Get the number of contour segments. + const MbCurve * GetSegment( size_t ind ) const { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index. + MbCurve * SetSegment( size_t ind ) { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index. + + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru iloc_InItem = 1 - точка находится слева от контура, \en Iloc_InItem = 1 - point is located to the left of the contour, + // \ru iloc_OnItem = 0 - точка находится на контуре, \en Iloc_OnItem = 0 - point is located on the contour, + // \ru iloc_OutOfItem = -1 - точка находится справа от контура. \en Iloc_OutOfItem = -1 - point is located to the right of the contour. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + virtual MbeLocation PointLocation( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + + virtual double PointProjection( const MbCartPoint & ) const; // \ru Проекция точки на кривую \en Point projection on the curve + virtual bool NearPointProjection( const MbCartPoint &, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + double DistanceToBorder( const MbCartPoint & ) const; ///< \ru Параметрическое расстояние до ближайшей границы \en Parametric distance to the nearest boundary + + void Trimm( double t1, double t2 ); ///< \ru Выделить часть контура. \en Trim a part of the contour. + + // \ru Вычисление всех перпендикуляров к кривой из данной точки \en Calculation of all perpendiculars to the curve from a given point + virtual void PerpendicularPoint( const MbCartPoint &, SArray & tFind ) const; + // \ru Вычисление всех касательных к кривой из данной точки \en Calculation of all tangents to the curve from a given point + + virtual void TangentPoint( const MbCartPoint &, SArray & tFind ) const; + + virtual void IntersectHorizontal( double y, SArray & ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with the horizontal line + virtual void IntersectVertical ( double x, SArray & ) const; // \ru Пересечение с вертикальной прямой \en Intersection with the vertical line + virtual void SelfIntersect( SArray &, double metricEps = Math::LengthEps ) const; // \ru Самопересечение контура \en Self-intersection of the contour + + /** \brief \ru Есть ли самопересечения контура? + \en Is it a contour with self-intersections? \~ + \details \ru Есть ли самопересечения контура? + \en Is it a contour with self-intersections? \~ + \param[in] metricEps - \ru Точность (по умолчанию рекомендуется использовать Math::LengthEps). + \en Accuracy (it's recommended to use Math::LengthEps). \~ + \param[in] considerPartialCoincidence - \ru Считать частичное совпадение соседних сегментов самопересечением (true - по умолчанию). + \en Consider partial coincidence of neighboring segments as self-intersection (true - by default). \~ + */ + bool IsSelfIntersect( double metricEps, bool considerPartialCoincidence ) const; + + // \ru Функции находятся в файле equcntr.cpp \en Functions are in the file equcntr.cpp + + /// \ru Скругление двух соседних элементов с информацией об удалении \en Fillet of two neighboring elements with information about removal + bool FilletTwoSegments( ptrdiff_t & index, double rad, bool & del1, bool & del2 ); + /// \ru Скругление двух соседних элементов \en Fillet of two neighboring elements + bool FilletTwoSegments( ptrdiff_t & index, double rad ); + /// \ru Вставка фаски между двумя соседними элементами с информацией об удалении \en Insertion of chamfer between two neighboring elements with information about removal + bool ChamferTwoSegments( ptrdiff_t & index, double len, double angle, + bool type, bool firstSeg, bool & del1, bool & del2 ); + /// \ru Вставка фаски между двумя соседними элементами \en Insertion of chamfer between two neighboring elements + bool ChamferTwoSegments( ptrdiff_t & index, double len, double angle, + bool type, bool firstSeg = true ); + bool Fillet( double rad ); ///< \ru Скругление контура \en Fillet of contour + bool Chamfer( double len, double angle, bool type ); ///< \ru Вставка фаски \en Insertion of the chamfer + MbeState RemoveFilletOrChamfer( const MbCartPoint & pnt ); ///< \ru Удалить скругление или фаску контура \en Remove fillet or contour chamfer + /// \ru Разбить контур на непересекающиеся сегменты. \en Split contour into non-overlapping segments. + bool InsertCrossPoints(); + /// \ru Разбиение сегментов контура в точках пересечения. \en Splitting of contour segments at the points of intersection. + void BreakSegment( ptrdiff_t & index, ptrdiff_t firtsIdx, + SArray & cross, bool firstCurve = true ); + + bool CheckConnection( double eps = Math::LengthEps ) const; ///< \ru Проверка непрерывности контура \en Check for contour continuity. + bool CheckConnection( double xEps, double yEps ) const; ///< \ru Проверка непрерывности контура \en Check for contour continuity. + + /// \ru Скругление двух соседних элементов дугой нулевого радиуса. \en Rounding two neighboring elements by arc of zero radius. + void FilletTwoSegmentsZero( ptrdiff_t & index, int defaultSense, bool fullInsert ); + /// \ru Скругление контура дугой нулевого радиуса. \en Rounding contour by arc of zero radius. + void FilletZero( int defaultSense, bool fullInsert = false ); + /// \ru Вставка фаски между двумя соседними элементами для построения эквидистанты. \en Insertion of chamfer between two neighboring elements for construction of the offset. + void ChamferTwoSegmentsZero( ptrdiff_t & index, double rad ); + /// \ru Вставка фаски для построения эквидистанты. \en Insertion of chamfer for construction of the offset. + void ChamferZero( double rad ); + /// \ru Удаление вырожденных сегментов контура. \en Removal of degenerate contour segments. + void DeleteDegenerateSegments( double radius, MbCurve * curve, bool mode ); + + /** \brief \ru Построение эквидистанты к контуру. + \en Construction of offset to contour. \~ + \details \ru Построение эквидистанты к контуру справа и слева. + Имя каждого эквидистантного контура совпадает с именем исходного. + \en Construction of offset to contour of the left and right. + A name of every offset contour matches with the name of the initial one. \~ + \param[in] radLeft - \ru Радиус эквидистанты слева по направлению. + \en The equidistance radius on the left by direction. \~ + \param[in] radRight - \ru Радиус эквидистанты справа по направлению. + \en The equidistance radius on the right by direction. \~ + \param[in] side - \ru Признак, с какой стороны строить:\n + 0 - слева по направлению,\n + 1 - справа по направлению,\n + 2 - с двух сторон. + \en Attribute defining the side to construct:\n + 0 - on the left by direction,\n + 1 - on the right by direction,\n + 2 - on the both sides. \~ + \param[in] mode - \ru Cпособ обхода углов:\n + true - дугой, + false - срезом. + \en The way of traverse of angles:\n + true - by arc, + false - by section. \~ + \param[out] equLeft - \ru Массив контуров слева. + \en The array of contours on the left side. \~ + \param[out] equRight - \ru Массив контуров справа. + \en The array of contours on the right side. \~ + */ + void Equid( double radLeft, double radRight, int side, bool mode, + PArray & equLeft, PArray & equRight ); + + /// \ru Построение новых контуров из эквидистанты. \en Construction of new contours from equidistance. + void CreateNewContours( RPArray & ); + + /// \ru Вычисление площади контура, если контур замкнут. \en Calculation of contour area if contour is closed. + double CalculateArea( double sag = Math::deviateSag ) const; + /// \ru Определение направления обхода контура, если контур замкнут. \en Determination of traverse direction if contour is closed. + int GetSense() const; + /// \ru Установить направление обхода контура. \en Set the traverse direction of the contour. + void SetSense( int sense ); + + // \ru Изменить направление обхода контура \en Change the traverse direction of the contour + virtual void Inverse( MbRegTransform * = NULL ); + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en The number of partitions for passage in the operations + // \ru Выдать характерную точку ограниченной кривой если она ближе чем dmax \en Get characteristic point of bounded curve if it is closer than dmax + virtual bool DistanceToPointIfLess( const MbCartPoint & toP, double & d ) const; // \ru Расстояние до точки, если оно меньше d \en Distance to the point if it is less than d + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + /// \ru Выдать среднюю точку сегмента контура. \en Get a mid-point of the contour segment. + bool GetSegmentMiddlePoint( const MbCartPoint & from, MbCartPoint & midPoint ) const; + /// \ru Выдать линейный сегмент контура. \en Get the linear segment of contour. + bool GetLinearSegment( const MbCartPoint & from, double maxDist, MbCartPoint & p1, MbCartPoint & p2, double & d ) const; + /// \ru Выдать дуговой сегмент контура. \en Get the arc segment of contour. + MbArc * GetArcSegment( const MbCartPoint & from, double maxDist, double & d ) const; + /// \ru Выдать длину сегмента контура. \en Get the contour segment length. + bool GetSegmentLength( const MbCartPoint & from, double & length ) const; + + virtual bool GetWeightCentre( MbCartPoint & ) const; // \ru Выдать центр тяжести контура \en Get gravity center of contour + virtual bool GetCentre ( MbCartPoint & ) const; // \ru Выдать центр кривой \en Get the center of curve + + /// \ru Найти ближайший к точке узел контура \en Find the nearest node of contour to point + ptrdiff_t FindNearestNode( const MbCartPoint & to ) const; + /// \ru Найти ближайший к точке сегмент контура \en Find the nearest segment of contour to point + ptrdiff_t FindNearestSegment( const MbCartPoint & to ) const; + + // \ru Определение особых точек офсетной кривой \en Determination of singular points of the offset curve + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetAxisPoint( MbCartPoint & ) const; // \ru Выдать центр оси кривой. \en Give the curve axis center. + + void CombineNurbsSegments(); ///< \ru Объединить NURBS кривые в контуре. \en Unite NURBS curves into the contour. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \brief \ru Непрерывна ли первая производная кривой по длине и направлению? + \en Have the first derivative of the curve the continuous length and direction? + \details \ru Отсутствуют ли разрывы производной по длине и направлению в стыках сегментов контура? \n + \en Are absent any discontinuities of the derivative at length or at direction in the junction of path segments? \n \~ + \param[out] contLength - \ru Непрерывность длины (да/нет). + \en The length is continuous (true/false). \~ + \param[out] contDirect - \ru Непрерывность направления (да/нет). + \en The direction of the first derivative is continuous (true/false). \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; + + /** \brief \ru Устранить разрывы производных по длине в стыках сегментов. + \en Eliminate the discontinuities of the derivatives of the length of the joints of the segments. + \details \ru Устранить разрывы производных по длине в стыках сегментов. \n + \en Eliminate the discontinuities of the derivatives of the length of the joints of the segments. \n \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + /** \} */ + /** \ru \name Функции работы с сегментами контура + \en \name Function for working with segments of contour + \{ */ + + bool Init( List & curves ); ///< \ru Инициализация по списку кривых. \en Initialization by list of curves. + void Init( const MbContour & other ); ///< \ru Инициализация по контуру. \en Initialization by a contour. + template + bool Init( Curves & curves, bool same ); ///< \ru Инициализация по массиву кривых. \en Initialization by array of curves. + template + bool InitByPoints( const Points & ); ///< \ru Инициализация по массиву точек (замкнутый контур). \en Initialization by array of points (closed contour). + bool InitAsRectangle( const MbCartPoint * ); ///< \ru Инициализация как прямоугольника ( приходит 4 точки ) \en Initialization as rectangle (4 points are given). + bool InitByRectangle( const MbRect & ); ///< \ru Инициализация по прямоугольнику габарита. \en Initialization by rectangle of bounding box. + + bool AddSegment ( MbCurve * ); ///< \ru Добавить сегмент в контур. \en Add a segment to the contour. + bool AddSegmentOrDeleteCurve( MbCurve * ); ///< \ru Добавить кривую как сегмент или удалить ее. \en Add a curve as segment or remove its. + MbCurve * AddSegment( const MbCurve * pBasis, double t1, double t2, int sense = 1 ); + bool AddAtSegment ( MbCurve * newSegment, size_t index ); ///< \ru Вставить сегмент перед сегментом контура с индексом index. \en Insert a segment before the contour segment with the index "index". + bool AddAfterSegment( MbCurve * newSegment, size_t index ); ///< \ru Вставить сегмент после сегмента контура с индексом index. \en Insert a segment after the contour segment with the index "index". + /// \ru Функция добавления новой кривой с управляемой проверкой. \en Function for addition of a new curve with checking. + bool AddCurveWithRuledCheck( MbCurve & newCur, double absEps, bool toEndOnly = false, bool checkSame = true, + VERSION version = Math::DefaultMathVersion() ); + + void DeleteSegments(); ///< \ru Удалить все сегменты в контуре. \en Remove all segments from contour. + void DeleteSegment( size_t ind ); ///< \ru Удалить сегмент в контуре. \en Remove a segment from contour. + void DetachSegments(); ///< \ru Отцепить все сегменты от контура без удаления. \en Detach all segments from the contour without removing. + MbCurve * DetachSegment( size_t ind ); ///< \ru Отцепить сегмент от контура и вернуть его. \en Detach a segment from contour return it. + + void SetSegment( MbCurve & newSegment, size_t ind ); ///< \ru Заменить сегмент в контуре. \en Replace a segment in the contour. + void SegmentsAdd( MbCurve & newSegment, bool calculateParamLength = true ); ///< \ru Добавить сегмент в контур без проверки. \en Add a segment to the contour without checking. + void SegmentsInsert( size_t ind, MbCurve & newSegment ); ///< \ru Вставить сегмент в контур перед индексом без проверки. \en Insert a segment into contour before an index without checking. + void SegmentsRemove( size_t ind ); ///< \ru Удалить сегмент без проверки. \en Remove a segment without checking. + void SegmentsDetach( size_t ind ); ///< \ru Отцепить сегмент без проверки. \en Detach a segment without checking. + + void Calculate( bool calcArea = false ); ///< \ru Рассчитать параметры: rect, paramLength, metricLength, closed. \en Calculate parameters: rect, paramLength, metricLength, closed. + + // \ru Управление распределением памяти в массиве segments \en Control of memory allocation in the array "segments" + void SegmentsReserve( size_t additionalSpace ) { segments.Reserve( additionalSpace ); } ///< \ru Зарезервировать место под столько элементов. \en Reserve memory for this number of elements. + void SegmentsAdjust () { segments.Adjust(); } ///< \ru Удалить лишнюю память. \en Free the unnecessary memory. + + template + bool GetSegments( Curves & segms ) const; ///< \ru Получить сегменты контура. \en Get contour segments. + + void SetMetricLength( double len ) const { metricLength = len; } + /// \ru Установить начальную (конечную) точку для замкнутого контура. \en Set the start (end) point for closed contour. + bool SetBegEndPoint( double t ); + /// \ru Заменить сегменты контуры и сегменты полилинии. \en Replace segments of contour and segments of polyline. + void ReplaceContoursAndPolylines(); + void GetPolygon( double sag, SArray & poly, double eps ) const; ///< \ru Дать точки полигона. \en Get points of polygon. + + bool IsAnyCurvilinear() const; ///< \ru Есть ли в контуре криволинейный сегмент. \en Whether the contour has a curved segment. + bool IsSameSegments( const MbContour & cntr ) const; ///< \ru Содержат ли контура идентичные сегменты. \en Whether contours contains identical segments. + bool GetBegSegmentPoint( size_t i, MbCartPoint & ) const; ///< \ru Дать начальную точку i-го сегмента. \en Get the start point of i-th segment. + bool GetEndSegmentPoint( size_t i, MbCartPoint & ) const; ///< \ru Дать конечную точку i-го сегмента. \en Get the end point of i-th segment. + + /** \brief \ru Нормаль по параметру, учитывая стыки сегментов. + \en Normal by parameter with consideration of segments joints \~ + \details \ru Нормаль по параметру, учитывая стыки сегментов.\n + \en Normal by parameter with consideration of segments joints \n \~ + \param[in] t - \ru Параметр на контуре + \en Parameter on the contour \~ + \param[out] norm - \ru Единичный вектор нормали, если не попали на стык сегментов\n + если попали на стык сегментов - вектор, направленный, + как сумма двух нормалей на сегментах в точке стыка, + с длиной, равной 1, деленной на синус половинного угла между сегментами + \en Unit vector of normal if not hit on the joint of segments \n + if we got on the joint of segments then the vector is directed, + as the sum of two normals on segments in joint, + with length which is equal to 1 divided by the sine of half angle between the segments \~ + \return \ru true, если попали на стык сегментов + \en true, if got on the joint of segments \~ + */ + bool CornerNormal( double t, MbVector & norm ) const; + + /** \brief \ru Параметры стыков сегментов. + \en Parameters of segments joints. \~ + \details \ru Параметры стыков сегментов кроме минимального + и максимального параметров контура. + \en Parameters of segments joints without minimal + and maximal contour parameter. \~ + \param[out] params - \ru Набор параметров. + \en Set of parameters. \~ + */ + template + void GetCornerParams( Params & params ) const; + // \ru Вычисление всех касательных к кривой из данной точки \en Calculation of all tangents to the curve from a given point + + /** \brief \ru Вычисление двух касательных (для параметров стыков). + \en Calculation of two tangents (for parameters of joints). \~ + \details \ru Вычисление двух касательных для параметра стыка по соответствующим сегментам. + Если параметр не стыковой, то касательные равны. + \en Calculation of two tangents for parameter of segments joint corresponding to the segments. + If parameter is not one of parameters of segments joints tangents are equal. + and maximal contour parameter. \~ + \param[in] t - \ru Параметр. + \en A parameter. \~ + \param[out] tan1 - \ru Первая касательная. + \en First tangent. \~ + \param[out] tan2 - \ru Вторая касательная. + \en Second tangent. \~ + */ + bool GetTwoTangents( double t, MbVector & tan1, MbVector & tan2 ) const; + + /** \} */ + /** \ru \name Функции работы с именами контура. + \en \name Functions for working with names of contours. + \{ */ + + /** \brief \ru Дать имена сегментов. + \en Get names of segments. \~ + \details \ru Дать имена сегментов контура.\n + \en Get names of contour segments. \n \~ + \param[out] names - \ru Имена сегментов. + \en Names of segments \~ + */ + void GetSegmentsNames( SimpleNameArray & names ) const; + + /** \brief \ru Установить имена сегментов. + \en Set names of segments. \~ + \details \ru Установить имена сегментов контура по массиву имен.\n + \en Set names of contour segments by array of names. \n \~ + \param[in] names - \ru Набор имен. + \en A set of names. \~ + */ + void SetSegmentsNames( const SimpleNameArray & names ); + + /** \} */ + +private: + ptrdiff_t _FindSegment( double & t, double & tSeg ) const; // \ru Нахождение сегмента контура \en Finding of a contour segment + MbContour & operator = ( const MbContour & initContour ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbContour ) +}; // MbContour + + +IMPL_PERSISTENT_OPS( MbContour ) + + +//------------------------------------------------------------------------------ +// \ru Конструктор по набору кривых. \en Constructor by curves vector. +// --- +template +MbContour::MbContour( const Curves & initCurves, bool same ) + : MbCurve ( ) + , segments ( 0, 1 ) + , closed ( false ) + , paramLength ( 0.0 ) + , metricLength( -1.0 ) + , rect ( ) + , areaSign ( c3d::DoublePair( -1.0, 0.0 ) ) +{ + size_t count = initCurves.size(); + segments.reserve( count ); + SPtr segment; + for ( size_t i = 0; i < count; ++i ) { + segment = same ? &const_cast( *initCurves[i] ) : &static_cast( initCurves[i]->Duplicate() ); + SegmentsAdd( *segment ); + } + + CalculateGabarit( rect ); // посчитать габарит + CalculateParamLength(); + CalculateMetricLength(); + SetClosed(); // установить признак замкнутости контура +} + +//------------------------------------------------------------------------------ +// \ru Инициализация по массиву точек (замкнутый контур). \en Initialization by array of points (closed contour). +// --- +template +bool MbContour::InitByPoints( const Points & points ) +{ + size_t count = points.size(); + + if ( count > 1 ) { + DeleteSegments(); + segments.reserve( count ); + for ( size_t i = 0; i < count; ++i ) { + MbLineSegment * seg = new MbLineSegment( points[i], points[ (i + 1) % count ] ); + segments.push_back( seg ); + seg->AddRef(); + } + closed = true; + Clear(); + return true; + } + return false; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация по массиву кривых. \en Initialization by array of curves. +// --- +template +bool MbContour::Init( Curves & curves, bool same ) +{ + bool res = false; + + if ( !curves.empty() ) { + DeleteSegments(); + + size_t count = curves.size(); + segments.reserve( count ); + for ( size_t i = 0; i < count; i++ ) { + MbCurve * segm = same ? &const_cast(*curves[i]) : static_cast( &curves[i]->Duplicate() ); + SegmentsAdd( *segm ); + } + + CalculateGabarit( rect ); // посчитать габарит + CalculateParamLength(); + CalculateMetricLength(); + SetClosed(); // установить признак замкнутости контура + res = true; + } + + return res; +} + +//------------------------------------------------------------------------------ +// \ru Получить сегменты контура. \en Get contour segments. +// --- +template +bool MbContour::GetSegments( Curves & segms ) const +{ + bool res = false; + SPtr segm; + segms.reserve( segms.size() + segments.size() ); + for ( size_t k = 0, segCount = segments.size(); k < segCount; ++k ) { + segm = segments[k]; + segms.push_back( segm ); + res = true; + } + return res; +} + +//------------------------------------------------------------------------------ +// \ru Параметры стыков сегментов. \en Parameters of segments joints. +// --- +template +void MbContour::GetCornerParams( Params & params ) const +{ + size_t segCount = GetSegmentsCount(); + if ( segCount > 1 ) { + double pLength = 0.0; + + const MbCurve * segment = GetSegment( 0 ); + if ( segment != NULL ) + pLength = segment->GetParamLength(); + + for ( size_t segInd = 1; segInd < segCount; ++segInd ) { + params.push_back( pLength ); + segment = GetSegment( segInd ); + if ( segment != NULL ) + pLength += segment->GetParamLength(); + } + } +} + + +#endif // __CUR_CONTOUR_H diff --git a/C3d/Include/cur_contour3d.h b/C3d/Include/cur_contour3d.h new file mode 100644 index 0000000..a271260 --- /dev/null +++ b/C3d/Include/cur_contour3d.h @@ -0,0 +1,450 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контур в трёхмерном пространстве. + \en Contour in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONTOUR3D_H +#define __CUR_CONTOUR3D_H + + +#include +#include +#include +#include +#include + + +class SimpleNameArray; + + +class MATH_CLASS MbContour3D; +namespace c3d // namespace C3D +{ +typedef SPtr SpaceContourSPtr; +typedef SPtr ConstSpaceContourSPtr; + +typedef std::vector SpaceContoursVector; +typedef std::vector ConstSpaceContoursVector; + +typedef std::vector SpaceContoursSPtrVector; +typedef std::vector ConstSpaceContoursSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Контур в трёхмерном пространстве. + \en Contour in three-dimensional space. \~ + \details \ru Контур представляет собой составную кривую, в которой начало каждого последующего сегмента стыкуется с концом предыдущего. + Контур является замкнутым, если конец последнего сегмента стыкуется с началом первого сегмента.\n + Если сегменты составной кривой стыкуются не гладко, то составная кривая будет иметь изломы. + В общем случае в местах стыковки сегментов производные составной кривой терпят разрыв по длине и направлению. \n + Начальное значение параметра составной кривой равно нулю. + Параметрическая длина составной кривой равна сумме параметрических длин составляющих её сегментов. \n + При вычислении радиуса-вектора составной кривой сначала определяется сегмент, + которому соответствует значение параметра составной кривой, и соответствующее значение собственного параметра этого сегмента. + Далее вычисляется радиус-вектор сегмента, который и будет радиусом-вектором составной кривой. \n + В качестве сегментов составной кривой не используются другие составные кривые. + Если составную кривую нужно построить на основе других составных кривых, + то последние должны рассматриваться как совокупность составляющих их кривых, а не как единые кривые.\n + Трёхмерный контур используется для пространственного моделирования, например, для описания траекторий движения.\n + \en Contour is a composite curve in which the beginning of each subsequent segment is joined to the end of the previous one. + Contour is closed if the end of last segment is joined to the beginning of the first segment.\n + If the segments of a composite curve are not smoothly joined then the composite curve will have breaks. + In general case in places of joining segments derivatives of a composite curve have discontinuity along the length and direction. \n + The initial value of the composite curve is equal to zero. + The parametric length of a composite curve is equal to the sum of the parametric lengths of components of its segments. \n + When the calculation of the radius-vector of a composite curve segment is determined at first, + the value of composite curve parameter and the corresponding value of the own parameters of this segment corresponds to this segment. + Then computes the radius-vector of the segment which will be the radius-vector of the composite curve. \n + Other composite curves are not used as segments of the composite curve. + If it is required to create a composite curve based on other composite curves, + then the latter must be regarded as a set of their curves, and not as single curves. \n + The three-dimensional contour is used for space modeling e.g. for describing trajectories. \n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbContour3D : public MbCurve3D { +protected : + RPArray segments; ///< \ru Множество сегментов контура. \en A set of contour segments. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + double paramLength; ///< \ru Параметрическая длина контура. \en Parametric length of a contour. + +public : + MbContour3D(); ///< \ru Пустой контур. \en Empty contour. + /// \ru Конструктор по набору кривых. \en Constructor by curves. + template + MbContour3D( const CurvesVector & initSegments, bool sameCurves ); // \ru sameCurves - кривые или их копии \en SameCurves - curves or their copies +protected: + MbContour3D( const MbContour3D &, MbRegDuplicate * ); ///< \ru Конструктор копирования. \en Copy constructor. +public : + virtual ~MbContour3D(); + +public: + VISITING_CLASS( MbContour3D ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbeSpaceType Type() const; // \ru Групповой тип элемента \en Group element type + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией \en Whether the object is a copy + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Расстояние до точки \en Distance to a point + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; // \ru Являются ли объекты идентичными в пространстве \en Are the objects identical in space? + + // \ru Общие функции кривой \en Common functions of curve + + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions describing the domain of a curve. + \{ */ + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of contour\curve are smooth. + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the domain of a curve. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct the parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + virtual void Normal( double & t, MbVector3D & ) const; // \ru Вычислить вектор главной нормали. \en Calculate main normal vector. + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Function for working inside and outside of the curve domain. + Function _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct a parameter + when it is outside domain. When parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + \{ */ + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + virtual void _Normal( double t, MbVector3D & ) const; // \ru Вычислить вектор главной нормали. \en Calculate main normal vector. + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Functions of the motion along the curve + \{ */ + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + + /// \ru Вычислить кривизну кривой. \en Calculate curvature of curve. + virtual double Curvature( double t ) const; + // \ru Преобразование в NURBS кривую \en Transform to NURBS-curve + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + /// \ru Подобные ли кривые для объединения (слива). \en Whether the curves to union (joining) are similar. + virtual bool IsSimilarToCurve( const MbCurve3D & other, double precision = METRIC_PRECISION ) const; + + // \ru Все проекции точки на кривую \en All point projections on the curve + // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; + + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateLength( double t1, double t2 ) const; + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой \en Calculate the bounding box of curve + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + virtual size_t GetCount() const; + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether the curve is planar? + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if curve is planar + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Give a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called on a three-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get surface curve if the space curve is surface (after the using call DeleteItem for arguments) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + virtual void GetWeightCentre( MbCartPoint3D & ) const; + virtual void GetCentre ( MbCartPoint3D & ) const; + + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \brief \ru Непрерывна ли первая производная кривой по длине и направлению? + \en Have the first derivative of the curve the continuous length and direction? + \details \ru Отсутствуют ли разрывы производной по длине и направлению в стыках сегментов контура? \n + \en Are absent any discontinuities of the derivative at length or at direction in the junction of path segments? \n \~ + \param[out] contLength - \ru Непрерывность длины (да/нет). + \en The length is continuous (true/false). \~ + \param[out] contDirect - \ru Непрерывность направления (да/нет). + \en The direction of the first derivative is continuous (true/false). \~ + \param[out] params - \ru Параметры точек, в которых происходит разрыв направления. + \en The parameters of the points at which the direction break occurs. \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; + + /** \brief \ru Устранить разрывы производных по длине в стыках сегментов. + \en Eliminate the discontinuities of the derivatives of the length of the joints of the segments. + \details \ru Устранить разрывы производных по длине в стыках сегментов. \n + \en Eliminate the discontinuities of the derivatives of the length of the joints of the segments. \n \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); + + /// \ru Найти все особые точки функции кривизны кривой. \en Find all the special points of the curvature function of the curve. + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + + /** \} */ + /** \ru \name Функции работы с сегментами контура + \en \name Function for working with segments of contour + \{ */ + + /// \ru Инициализация по набору кривых (sameCurves - кривые или их копии). \en Initialize by curves (sameCurves - curves or their copies). + template + bool Init( const CurvesVector & initSegments, bool sameCurves, bool cls ); + /// \ru Инициализация по набору кривых (замкнутый контур). \en Initialize by curves (closed contour). + template + bool Init( const PointsVector & points ); + + ptrdiff_t FindSegment( double & t, double & tSeg ) const; ///< \ru Нахождение сегмента контура. \en Finding of a contour segment. + size_t GetSegmentsCount() const { return segments.size(); } ///< \ru Выдать количество сегментов контура. \en Get the number of contour segments. + template + void GetSegments( CurvesVector & curves ) const; ///< \ru Получить кривые контура. \en Get contour segments. + void DetachSegments(); ///< \ru Отцепить все сегменты контура. \en Detach all segments of contour. + void DeleteSegments(); ///< \ru Отсоединить используемые сегменты и удалить остальные. \en Delete used segments and remove other segments. + void DeleteSegment( size_t ind ); ///< \ru Удалить сегмент контура. \en Delete the segment of contour. + MbCurve3D * DetachSegment( size_t ind ); ///< \ru Отцепить сегмент контура. \en Detach the segment of contour. + const MbCurve3D * GetSegment( size_t ind ) const { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index. + MbCurve3D * SetSegment( size_t ind ) { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index. + void SetSegment ( MbCurve3D & newSegment, size_t ind, bool same ); ///< \ru Заменить сегмент в контуре. \en Replace a segment in the contour. + void AddSegment ( MbCurve3D & newSegment, bool same ); ///< \ru Добавить сегмент в контур. \en Add a segment to the contour. + void AddAtSegment ( MbCurve3D & newSegment, size_t ind, bool same ); ///< \ru Добавить сегмент в контур перед сегментом с индексом ind. \en Add a segment to the contour before the segment with index ind. + void AddAfterSegment( MbCurve3D & newSegment, size_t ind, bool same ); ///< \ru Добавить сегмент в контур после сегмента с индексом ind. \en Add a segment to the contour after the segment with index ind. + MbCurve3D * AddSegment( MbCurve3D & pBasis, double t1, double t2, int sense ); + void SegmentsAdd( MbCurve3D & newSegment, bool calculateParamLength = true ); ///< \ru Добавить сегмент в контур без проверки. \en Add a segment to the contour without checking. + bool GetCornerAngle( size_t index, MbCartPoint3D & origin, MbVector3D & axis, MbVector3D & tau, double & angle, + double angleEps ) const; + /// \ru Cбросить переменные кэширования. \en Reset variables caching. + void Clear() { + CalculateParamLengthAndClosed(); // \ru Параметрическая длина контура. \en Parametric length of a contour. + } + bool IsSimple() const; ///< \ru Состоит ли контур из отрезков и дуг? \en Whether the contour consists of the segments and arcs? + /// \ru Управление распределением памяти в массиве segments. \en Control of memory allocation in the array "segments". + void SegmentsReserve( size_t additionalSpace ) { segments.Reserve( additionalSpace ); } ///< \ru Зарезервировать место. \en Reserve space. + void SegmentsAdjust () { segments.Adjust(); } ///< \ru Удалить лишнюю память. \en Free the unnecessary memory. + /// \ru Добавить новый элемент в начало или конец контура. \en Add the new element to the beginning or end of contour. + bool AddCurveWithRuledCheck( MbCurve3D &, double absEps, bool toEndOnly = false, bool checkSame = true, + VERSION version = Math::DefaultMathVersion() ); + /// \ru Проверка непрерывности контура. \en Check for contour continuity. + bool CheckConnection( double eps = METRIC_PRECISION ) const; + void CalculateParamLength(); ///< \ru Рассчитать параметрическую длину. \en Calculate parametric length. + void CheckClosed( double eps ); ///< \ru Установить признак замкнутости контура. \en Set the closedness attribute of contour. + /// \ru Содержат ли контура идентичные сегменты \en Whether contours contains identical segments. + bool IsSameSegments( const MbContour3D & ) const; + void FindCorner( size_t index, MbCartPoint3D & ) const; + + /** \} */ + /** \ru \name Функции работы с именами контура. + \en \name Functions for working with names of contours. + \{ */ + + /** \brief \ru Дать имена сегментов. + \en Get names of segments. \~ + \details \ru Дать имена сегментов контура.\n + \en Get names of contour segments. \n \~ + \param[out] names - \ru Имена сегментов. + \en Names of segments \~ + */ + void GetSegmentsNames( SimpleNameArray & names ) const; + + /** \brief \ru Установить имена сегментов. + \en Set names of segments. \~ + \details \ru Установить имена сегментов контура по массиву имен.\n + \en Set names of contour segments by array of names. \n \~ + \param[in] names - \ru Набор имен. + \en A set of names. \~ + */ + void SetSegmentsNames( const SimpleNameArray & names ); + + /** \} */ + +private: + void SetClosed(); // \ru Проверить и установить признак замкнутости контура. \en Check and set closedness attribute of contour. + void CalculateParamLengthAndClosed(); // \ru Посчитать параметрическую длину и признак замкнутости \en Calculate parametric length and closedness attribute + ptrdiff_t _FindSegment( double & t, double & tSeg ) const; // \ru Нахождение сегмента контура \en Finding of a contour segment + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbContour3D ) +OBVIOUS_PRIVATE_COPY( MbContour3D ) +}; + +IMPL_PERSISTENT_OPS( MbContour3D ) + + +//------------------------------------------------------------------------------ +// \ru Конструктор по набору кривых. \en Constructor by curves. +// --- +template +MbContour3D::MbContour3D( const CurvesVector & initSegments, bool sameCurves ) + : MbCurve3D ( ) + , segments ( initSegments.size(), 1 ) + , closed ( false ) + , paramLength( 0.0 ) // параметрическая длина контура не рассчитана +{ + const size_t count = initSegments.size(); + + if ( count > 0 ) { + MbRegDuplicate * ireg = NULL; + MbAutoRegDuplicate autoreg( ireg ); + for ( size_t i = 0; i < count; ++i ) { + const MbCurve3D * initSegment = initSegments[i]; + if ( initSegment != NULL ) { + C3D_ASSERT( initSegment->GetSubstrate().Type() != st_Contour3D ); // \ru Использование контура не по назначению. \en Wrong contour use as contours container. + MbCurve3D * segment = sameCurves ? const_cast(initSegment) : static_cast(&initSegment->Duplicate( ireg )); + segments.push_back( segment ); + segment->AddRef(); + } + } + CalculateParamLengthAndClosed(); + } +} + +//------------------------------------------------------------------------------ +// \ru Инициализация по набору кривых. \en Initialize by curves. +// --- +template +bool MbContour3D::Init( const CurvesVector & initSegments, bool sameCurves, bool cls ) +{ + size_t count = initSegments.size(); + + if ( count > 0 ) { + ::AddRefItems( initSegments ); + DeleteSegments(); + for ( size_t i = 0; i < count; ++i ) { + if ( initSegments[i] != NULL ) { + C3D_ASSERT( initSegments[i]->GetSubstrate().Type() != st_Contour3D ); // \ru Использование контура не по назначению. \en Wrong contour use as contours container. + MbCurve3D * initSegment = &const_cast( *initSegments[i] ); + MbCurve3D * segment = sameCurves ? initSegment : static_cast(&initSegment->Duplicate()); + segments.push_back( segment ); + segment->AddRef(); + } + } + ::DecRefItems( initSegments ); + CalculateParamLength(); + closed = cls; + return true; + } + return false; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация по набору точек. \en Initialize by points. +// --- +template +bool MbContour3D::Init( const PointsVector & points ) +{ + size_t count = points.size(); + + if ( count > 1 ) { + DeleteSegments(); + segments.reserve( count ); + for ( size_t i = 0; i < count; ++i ) { + MbLineSegment3D * seg = new MbLineSegment3D( points[i], points[ (i + 1) % count ] ); + segments.push_back( seg ); + seg->AddRef(); + } + CalculateParamLength(); + closed = true; + return true; + } + + return false; +} + +//------------------------------------------------------------------------------ +// \ru Получить кривые контура. \en Get contour segments. +// --- +template +void MbContour3D::GetSegments( CurvesVector & curves ) const +{ + size_t segmentsCnt = segments.size(); + curves.reserve( curves.size() + segmentsCnt ); + SPtr curve; + for ( size_t k = 0; k < segmentsCnt; ++k ) { + curve = const_cast(segments[k]); + if ( curve != NULL ) { + curves.push_back( curve ); + ::DetachItem( curve ); + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Усечь контур. + \en Trim a contour. \~ + \details \ru Усечь контур. Расширенная версия функции контура Trimmed + \en Trim a contour. This function is extended version of contour's function Trimmed. \~ + \param[in] t1 - \ru Параметр, соответствующий началу усеченной кривой. + \en Parameter corresponding to start of a trimmed curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу усеченной кривой. + \en Parameter corresponding to end of a trimmed curve. \~ + \param[in] sense - \ru Направление усеченной кривой относительно исходной.\n + sense = 1 - направление кривой сохраняется. + sense = -1 - направление кривой меняется на обратное. + \en Direction of a trimmed curve in relation to an initial curve. + sense = 1 - direction does not change. + sense = -1 - direction changes to the opposite value. \~ + \param[in] useTrimmedOnly - \ru При усечении создавать кривые MbTrimmedCurve3D. + \en A truncated segment is always curve MbTrimmedCurve3D. \~ + \result \ru Построенная усеченная кривая. + \en A constructed trimmed curve. \~ + \ingroup Curves_3D + */ +// --- +MATH_FUNC (MbCurve3D *) TrimContour( const MbContour3D & cntr, double t1, double t2, int sense, + bool useTrimmedOnly ); + +#endif // __CUR_CONTOUR3D_H diff --git a/C3d/Include/cur_contour_on_plane.h b/C3d/Include/cur_contour_on_plane.h new file mode 100644 index 0000000..2a6ef58 --- /dev/null +++ b/C3d/Include/cur_contour_on_plane.h @@ -0,0 +1,142 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контур на плоскости. + \en Contour on plane. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONTOUR_ON_PLANE_H +#define __CUR_CONTOUR_ON_PLANE_H + + +#include + + +class MATH_CLASS MbPlane; +class MATH_CLASS MbAxis3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Контур на плоскости. + \en Contour on plane. \~ + \details \ru Контур на плоскости представляет собой трёхмерную составную кривую, + полученную движением вдоль двумерного контура MbContour, + расположенного в пространстве параметров некоторой плоскости MbPlane. \n + Контур на плоскости используется: + для описания области определения параметров поверхности, + для описания плоского эскиза в операции. + \en Contour on the plane a is three-dimensional composite curve, + obtained by the motion along the two-dimensional contour MbContour, + located in the parameters space of a plane MbPlane. \n + Contour on the plane is used: + for description of surface domain, + for description of planar sketch in the operation. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbContourOnPlane : public MbContourOnSurface { + +public : + /// \ru Конструктор по плоскости, контуру и флагу использования оригинала контура. \en Constructor by plane, contour and flag of using original contour. + MbContourOnPlane( const MbPlane &, const MbContour &, bool same ); + /// \ru Конструктор по плоскости и направлению обхода поверхности. \en Constructor by plane and traverse direction of surface. + MbContourOnPlane( const MbPlane &, int sense ); + /// \ru Конструктор по плоскости. \en Constructor by plane. + MbContourOnPlane( const MbPlane & ); + +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbContourOnPlane( const MbContourOnPlane &, MbRegDuplicate * ); + /// \ru Конструктор копирования контура с той же поверхностью для CurvesDuplicate(). \en Constructor to copy contour with the same surface for CurvesDuplicate(). + explicit MbContourOnPlane( const MbContourOnPlane * ); +private: + MbContourOnPlane( const MbContourOnPlane & ); // \ru Не реализовано !!! \en Not implemented !!! + +public : + virtual ~MbContourOnPlane(); + +public : + VISITING_CLASS( MbContourOnPlane ); + + // \ru Общие функции математического объекта. \en The common functions of the mathematical object. + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get a type of the element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual MbContourOnSurface & CurvesDuplicate() const; // \ru Сделать копию со старой подложкой. \en Make a copy with old substrate. + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, является ли копией данного объекта? \en Determine whether the object is copy of a given object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru Общие функции кривой. \en Common functions of curve. + + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Curvature ( double t ) const; // \ru Вычислить кривизну кривой. \en Calculate the curve curvature. + virtual double Step ( double t, double sag ) const; // \ru Вычислить шаг аппроксимации. \en Calculate the approximation step. + virtual double DeviationStep( double t, double sag ) const; // \ru Вычислить шаг аппроксимации. \en Calculate the approximation step. + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создать усеченную кривую. \en Create the trimmed curve. + + virtual double GetMetricLength() const; // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of curve. + virtual double GetLengthEvaluation() const; // \ru Оценить метрическую длину кривой. \en Evaluate the metric length of curve. + virtual double CalculateMetricLength() const; // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of curve. + + virtual bool ChangeSurface( MbSurface & newsurf ); // \ru Заменить поверхность контура. \en Replace the surface of contour. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменить носителя. \en Change the carrier. + virtual bool IsPlanar() const; // \ru Является ли кривая плоской? \en Whether the curve is planar? + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get planar curve and placement if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place3d, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Заполнить плейсмент, если кривая плоская. \en Fill the placement if curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis( MbAxis3D & ) const; // \ru Дать ось кривой. \en Get the curve axis. + virtual void GetCentre( MbCartPoint3D & wc ) const; // \ru Дать центр тяжести. \en Get the center of gravity. + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; // \ru Дать центр тяжести. \en Get the center of gravity. + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой. \en Calculate the bounding box of curve. + + virtual bool IsStraight() const; // \ru Определить, является ли линия прямолинейной? \en Wetermine whether the line is straight. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D *pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of curve. + + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of curve with equal intervals along the length of the arc. + + /// \ru Получить локальную систему координат плоскости. \en Get the local coordinate system of a plane. + const MbPlacement3D & GetPlacement() const; + /// \ru Получить плоскость. \en Get the plane. + const MbPlane & GetPlane() const { return (const MbPlane &)GetSurface(); } + + /// \ru Сделать правой локальную систему координат плоскости. \en Make the local coordinate system of plane right. + void SetRightPlacement(); + /// \ru Адаптировать локальную систему координат плоскости. \en Adapt the local coordinate system of a plane. + void AdaptToPlace( const MbPlacement3D & ); + /// \ru Заменить локальную систему координат плоскости. \en Replace the local coordinate system of a plane. + void SetPlacement( const MbPlacement3D & ); + /// \ru Инвертировать нормаль плоскости. \en Invert the normal of plane. + void InvertNormal( MbRegTransform * ireg = NULL ); + +private: + void operator = ( const MbContourOnPlane & ); // \ru Не реализовано !!! \en Not implemented !!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbContourOnPlane ) +}; + +IMPL_PERSISTENT_OPS( MbContourOnPlane ) + +#endif // __CUR_CONTOUR_ON_PLANE_H diff --git a/C3d/Include/cur_contour_on_surface.h b/C3d/Include/cur_contour_on_surface.h new file mode 100644 index 0000000..639e7e1 --- /dev/null +++ b/C3d/Include/cur_contour_on_surface.h @@ -0,0 +1,334 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контур на поверхности. + \en Contour on surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONTOUR_ON_SURFACE_H +#define __CUR_CONTOUR_ON_SURFACE_H + +#include +#include +#include +#include + + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbContour; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbCurveTessellation; +class MbCurveIntoNurbsInfo; +class MbSegmentsSearchTree; + + +//------------------------------------------------------------------------------ +/** \brief \ru Контур на поверхности. + \en Contour on surface. \~ + \details \ru Контур на поверхности представляет собой трёхмерную составную кривую, + полученную движением вдоль двумерного контура MbContour, + расположенного в пространстве параметров некоторой поверхности MbSurface. \n + Контур на поверхности используется: + для описания области определения параметров поверхности. + \en The contour on surface is a three-dimensional composite curve, + obtained by the motion along the two-dimensional contour MbContour, + located in the parameters space of the surface MbSurface. \n + The contour on a surface is used: + to describe the domain of the surface parameters. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbContourOnSurface : public MbCurve3D, public MbSyncItem { + +protected : + MbSurface * surface; ///< \ru Указатель на базовую поверхность (всегда не NULL). \en The pointer to the base surface (this value is never NULL). + MbContour * contour; ///< \ru Указатель на 2D-контур в плоскости параметров поверхности (всегда не NULL). \en The pointer to 2D-contour in the plane of the surface parameters (this value is never NULL). + mutable double area; ///< \ru Площадь 2D-контура со знаком. \en The area of 2D-contour with sign. + mutable MbCube cube; ///< \ru Габаритный куб. \en Bounding box. + mutable double metricLength; ///< \ru Метрическая длина. \en The metric length. + mutable MbSegmentsSearchTree * searchTree; ///< \ru Дерево габаритов для ускорения поиска сегментов. \en A tree of bounding boxes for segment search acceleration. + +private: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbContourOnSurfaceAuxiliaryData : public AuxiliaryData { + public: + std::vector< SPtr > tessellation; ///< \ru Разбивка кривой. \en Curve tessellation.. + + MbContourOnSurfaceAuxiliaryData(); + + MbContourOnSurfaceAuxiliaryData( const MbContourOnSurfaceAuxiliaryData & init ); + + virtual ~MbContourOnSurfaceAuxiliaryData() {} + }; + + mutable CacheManager cache; + +public : + /// \ru Конструктор по поверхности, контуру и флагу использования оригинала контура. \en Constructor by surface, contour and flag of using original contour. + MbContourOnSurface( const MbSurface &, const MbContour &, bool same ); + /// \ru Конструктор по поверхности и направлению обхода поверхности. \en Constructor by a surface and the traverse direction of surface + MbContourOnSurface( const MbSurface &, int sense ); + +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbContourOnSurface( const MbContourOnSurface & init, MbRegDuplicate * ); + /// \ru Конструктор копирования контура с той же поверхностью для CurvesDuplicate(). \en Constructor to copy contour with the same surface for CurvesDuplicate(). + explicit MbContourOnSurface( const MbContourOnSurface * ); + /// \ru Конструктор по поверхности. \en Constructor by a surface. + MbContourOnSurface( const MbSurface & surf ); + +private: + MbContourOnSurface( const MbContourOnSurface & ); // \ru Не реализовано !!! \en Not implemented !!! + +public : + virtual ~MbContourOnSurface(); + +public : + VISITING_CLASS( MbContourOnSurface ); + + // \ru Общие функции математического объекта. \en The common functions of the mathematical object. + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get a type of the element. + virtual MbeSpaceType Type() const; // \ru Дать тип элемента. \en Get a type of the element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + /// \ru Сделать копию на той же поверхности. \en Create a copy on the same surface. + virtual MbContourOnSurface & CurvesDuplicate() const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, является ли копией данного объекта? \en Determine whether the object is copy of a given object. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube &r ) const; // \ru Добавить габарит в куб. \en Add bounding box into a cube. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые поверхности. \en Get base surfaces. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой. \en Common functions of curve. + + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual bool IsClosed() const; // \ru Проверить замкнутость кривой. \en Check for curve closedness. + // \ru Функции для работы в области определения. \en Functions for working in the definition domain. + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Функции для работы вне области определения. \en Functions for working outside of definition domain. + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную \en Calculate the second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + /// \ru Изменить ориентацию контура относительно поверхности. \en Change the contour orientation relative to a surface. + virtual void Inverse( MbRegTransform * iReg = NULL ); + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; // \ru Установить параметры NURBS. \en Set the NURBS parameters. + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создать усеченную кривую. \en Create the trimmed curve. + + virtual double Step( double t, double sag ) const; // \ru Вычислить шаг аппроксимации. \en Calculate the approximation step. + virtual double DeviationStep( double t, double angle ) const; // \ru Определить шаг по заданному углу отклонения касательной. \en Determine the step by a given angle of tangent deviation. + void GetTessellation( double angle, std::vector< SPtr > & tessellation ) const; // \ru Создать кэшированное разбиение контура. \en Create a cached contour tessellation. + virtual double GetMetricLength() const; // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of curve. + virtual double GetLengthEvaluation() const; // \ru Оценить метрическую длину кривой. \en Evaluate the metric length of curve. + virtual double CalculateMetricLength() const; // \ru Вычислить метрическую длину. \en Calculate the metric length. + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой. \en Calculate the bounding box of curve. + + /// \ru Сбросить рассчитанный габарит. \en Reset the calculated bounding box. + void SetDirtyGabarit() const { cube.SetEmpty(); } + /// \ru Выдать габарит кривой. \en Get the bounding box of curve. + const MbCube & GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } + + /// \ru Вычислить параметрический габарит контура. \en Calculate the parametric bounding box of the contour. + virtual void CalculateUVLimits( MbRect & uvRect ); + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменить носителя. \en Change the carrier. + virtual bool ChangeCarrierBorne( const MbSpaceItem & item, MbSpaceItem & init, const MbMatrix & matr ); // \ru Изменить носимые элементы. \en Change carrier elements. + /// \ru Заменить поверхность контура. \en Replace the surface of contour. + virtual bool ChangeSurface( MbSurface & ); + /// \ru Заменить двумерный контур. \en Replace the two-dimensional contour. + void ChangeContour( MbContour & ); + virtual bool IsPlanar() const; // \ru Определить, является ли кривая плоской. \en Determine whether the curve is planar. + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Определить, является ли контур гладким. \en Define whether the contour is smooth. + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get planar curve and placement if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place3d, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get surface curve if the space curve is surface (after the using call DeleteItem for arguments) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Заполнить плейсмент, если кривая плоская. \en Fill the placement if curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Вычислить ближайшую проекцию точки на кривую. \en Calculate the nearest projection of the point on the curve. + + virtual bool IsStraight() const; // \ru Определить, является ли линия прямолинейной. \en Determine whether the line is straight. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of curve. + /// \ru Найти все особые точки функции кривизны кривой. + /// \en Find all the special points of the curvature function of the curve. + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + // \ru Доступ к полям класса. \en Access to the fields of a class. + + /// \ru Выдать базовую поверхность. \en Get the base surface. + const MbSurface & GetSurface() const { return *surface; } + /// \ru Выдать двумерный контур. \en Get the two-dimensional contour. + const MbContour & GetContour() const { return *contour; } + /// \ru Получить сегмент двумерного контура. \en Get the segment of the two-dimensional contour. + const MbCurve * GetSegment( size_t index ) const; + /// \ru Выдать базовую поверхность для редактирования. \en Get the base surface for editing. + MbSurface & SetSurface() { return *surface; } + /// \ru Выдать двумерный контур для редактирования. \en Get the two-dimensional contour for editing. + MbContour & SetContour() { return *contour; } + /// \ru Получить сегмент двумерного контура для редактирования. \en Get the segment of the two-dimensional contour for editing. + MbCurve * SetSegment( size_t index ); + + /// \ru Выдать количество сегментов контура. \en Get the number of contour segments + size_t GetSegmentsCount() const; + /// \ru Выдать копию двумерного контура. \en Get a copy of the two-dimensional contour. + MbContour & ContourDuplicate() const; + + /// \ru Вычислить нормали к поверхности по параметру кривой. \en Calculate normals to the surface in the curve parameter. + void SurfaceNormal( double t, MbVector3D & n ) const; + /// \ru Найти сегмент контура по параметру на контуре. \en Find a segment of contour in the contour parameter. + ptrdiff_t FindSegment ( double & t, double & tSeg ) const; + /// \ru Найти точку сегмента контура по индексу. \en Find a point of the contour segment by the index. + void FindCorner ( ptrdiff_t index, MbCartPoint & ) const; + /// \ru Найти точку сегмента контура по индексу. \en Find a point of the contour segment by the index. + void FindCorner ( ptrdiff_t index, MbCartPoint3D & ) const; + /// \ru Добавить сегмент в контур. \en Add a segment to the contour. + void AddSegment( MbCurve & newSegment ); + /// \ru Добавить сегмент в контур. \en Add a segment to the contour. + void AddSegment( MbCurve & pBasis, double t1, double t2, int sense ); + /// \ru Добавить сегмент в контур. \en Add a segment to the contour. + void AddSegment( MbSurfaceCurve & newSegment ); + /// \ru Добавить сегмент в контур. \en Add a segment to the contour. + void AddSegment( MbSurfaceCurve & pBasis, double t1, double t2, int sense ); + /// \ru Получить параметры поверхности по параметру на контуре. \en Get surface parameters by the parameter on the contour. + void GetSurfacePar( double & t, double & u, double & v ) const; + /// \ru Вычислить U-пары от V. \en Calculate U-pairs from V. + void GetUPairs ( double v, SArray & u ) const; + /// \ru Вычислить V-пары от U. \en Calculate V-pairs from U. + void GetVPairs ( double u, SArray & v ) const; + + /// \ru Вычислить площадь и ориентация контура относительно поверхности. \en Calculate the area and the contour orientation relative to the surface. + double Area() const; + /// \ru Ориентировать контур против часовой стрелки. \en Orient the contour counterclockwise. + bool NormalizeOrientation(); + + /// \ru Классифицировать положение точки относительно контура. \en Classify the position of the point relative to the contour. + MbeItemLocation PointClassification ( const MbCartPoint & ) const; + /// \ru Вычислить параметрическое расстояние до ближайшей границы. \en Calculate the parametric distance to the nearest boundary. + double DistanceToBorder( const MbCartPoint & pnt, double & eps ) const; + /// \ru Определить, находится ли контур cntr в области контура (известно, что контуры не пересекаются). \en Determine whether the contour "cntr" is inside the region of the contour (contours do not intersect). + MbeItemLocation ContourClassification( const MbContourOnSurface & cntr, double precision = Math::metricPrecision ) const; + + /** \brief \ru Определить точки пересечения с двумерной кривой. + \en Determine points of intersection with two-dimensional uv-curve. \~ + \details \ru Определить точки пересечения плоской кривой и контура. \n + \en Determine intersection points of a planar curve and the contour. \n \~ + \param[in] pCurve - \ru Кривая. + \en A curve. \~ + \param[out] tcontour - \ru Массив параметров на контуре. + \en An array of parameters on the contour. \~ + \param[out] tcurv - \ru Массив параметров на кривой. + \en An array of parameters on the curve. \~ + \return \ru Количество точек пересечения. + \en The number of points. \~ + */ + size_t SegmentIntersection( const MbCurve & pCurve, SArray & tcontour, SArray & tcurv, double epsilon = Math::metricEpsilon ) const; + /** \brief \ru Определить точки пересечения с поверхностной кривой. + \en Determine points of intersection with a spatial curve. \~ + \details \ru Определить точки пересечения кривой на поверхности и контура. \n + \en Determine intersection points of curve on the surface and contour. \n \~ + \param[in] curv - \ru Кривая. + \en A curve. \~ + \param[out] tcontour - \ru Массив параметров на контуре. + \en An array of parameters on the contour. \~ + \param[out] tcurv - \ru Массив параметров на кривой. + \en An array of parameters on the curve. \~ + \return \ru Количество точек пересечения. + \en The number of points. \~ + */ + size_t SurfaceCurveIntersection( const MbSurfaceCurve & curv, SArray & tcontour, SArray & tcurv, double epsilon = Math::metricEpsilon ) const; + /** \brief \ru Определить точки пересечения с контуром на поверхности. + \en Determine intersection points with the contour on the surface. \~ + \details \ru Определить точки пересечения кривой с контуром на поверхности. \n + \en Determine intersection points of a curve with the contour on the surface. \n \~ + \param[in] cntr - \ru Кривая. + \en A curve. \~ + \param[out] tcontour - \ru Массив параметров на контуре. + \en An array of parameters on the contour. \~ + \param[out] tcntr - \ru Массив параметров на кривой. + \en An array of parameters on the curve. \~ + \return \ru Количество точек пересечения. + \en The number of points. \~ + */ + size_t ContourOnSurfaceIntersection( const MbContourOnSurface & cntr, SArray & tcontour, SArray & tcntr, double epsilon = Math::metricEpsilon ) const; + + /// \ru Сделать равным контур. \en Make the contour equal. + bool SetCurveEqual( const MbSpaceItem & ); + /// \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + bool IsCurveEqual ( const MbSpaceItem & ) const; + + /** \brief \ru Создать и инициализировать дерево габаритных кубов сегментов контура. + \en Create and initialize the segments bounding box tree. \~ + \details \ru Создать и инициализировать дерево габаритов сегментов контура по требованию. + Инициирует поиск ближайших к точке сегментов по дереву габаритов для пространственного контура, + что целесообразно при выполнении многократного поиска сегментов. \n + \en Create and initialize the segments bounding box tree by request. + Initiate nearest segment to given point search by bounding boxes tree in case 3D contour, + that is appropriate for multiple segment search.\n \~ + \param[in] indSegmMin - \ru Минимальный индекс сегмента в наборе для построения дерева габаритов. + \en Minimum segment index in set for bounding box tree creation. \~ + \param[in] indSegmMax - \ru Максимальный индекс сегмента в наборе для построения дерева габаритов. + \en Maximum segment index in set for bounding box tree creation. \~ + \return \ru Результат создания и инициализации дерева. + \en The result of bounding boxes tree creation. \~ + */ + bool CreateCubeTree( const size_t & indSegmMin, const size_t & indSegmMax ) const; + +protected: + /// \ru Посчитать параметрический габарит, сбросить временные данные, проверить замкнутость контура. \en Calculate parametric bounding box, reset temporary data, check for contour closedness. + void CalculateIncludePoints(); + + void DeleteCubeTree() const; // \ru Удаление дерева габаритных кубов. \en Delete bounding boxes tree. + void DeleteSearchTree() const; // \ru Удалить деревья габаритных кубов и прямоугольников. \en Delete bounding boxes and bounding rectangles trees. + +private: + void operator = ( const MbContourOnSurface & ); // \ru Не реализовано !!! \en Not implemented !!! + bool CreateRectTree() const; // \ru Создать и инициализировать дерево габаритных прямоугольников сегментов контура. \en Create and initialize the segments bounding rectangles tree. + bool FindNearestSegmentsByTree( const MbCartPoint & point, std::vector & indFound ) const; /// \ru Поиск ближайших к точке сегментов с помощью дерева габаритов на плоскости. \en Nearest to point segment search with bounding box tree in 2D space. + bool FindNearestSegmentsByTree3D( const MbCartPoint3D & point, const size_t & indStart, const size_t & indEnd, std::vector & indFound ) const; /// \ru Поиск ближайших к точке сегментов с помощью дерева габаритов в пространстве. \en Nearest to point segment search with bounding box tree in 3D space. + + void CacheReset() const; // \ru Удалить кэши. \en Delete caches. + + friend void MbSurfaceCurve::SetTesselation( const MbContourOnSurface & contour, size_t indSegment ); // \ru Установить разбиение из контура. \en Set tessellation from contour. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbContourOnSurface ) +}; + +IMPL_PERSISTENT_OPS( MbContourOnSurface ) + + +#endif // __CUR_CONTOUR_ON_SURFACE_H diff --git a/C3d/Include/cur_contour_with_breaks.h b/C3d/Include/cur_contour_with_breaks.h new file mode 100644 index 0000000..094d086 --- /dev/null +++ b/C3d/Include/cur_contour_with_breaks.h @@ -0,0 +1,982 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контур с разрывами. + \en Contour with breaks. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CONTOUR_WITH_BREAKS_H +#define __CUR_CONTOUR_WITH_BREAKS_H + + +#include +#include +#include + + +class MATH_CLASS MbBreaksPart; +class MATH_CLASS MbBreak; + + +//------------------------------------------------------------------------------ +/** \brief \ru Контур c разрывами. + \en Contour with breaks. \~ + \details \ru Контур c разрывами.\n + Для использования в мультилинии MbMultiline.\n + Содержит разрывы MbBreak, видимые части - контуры MbContour.\n + При использовании в мультилинии каждуй раз при перестроении контура в нем обновляется + список номеров по количеству сегментов контура. + Каждый номер показывает номер сегмента базовой кривой мультилинии, + которому соответствует этот сегмент контура.\n + Если сегмент контура является эквидистантой сегмента базовой кривой, + то ему соответствует номер этого сегмента.\n + Если контур является сегментом обхода вершины мультилинии, + то ему соответствует номер, соответствующий предыдущему сегменту контура.\n + Разрывы в контуре не могут накладываться друг на друга. + Если в результате перестроения один разрыв наложился на другой, то они объединяются. + \en Contour with breaks.\n + For using in the multiline MbMultiline.\n + Contains breaks MbBreak, visible parts - contours MbContour.\n + When using in a multiline every time when contour is rebuilding in it are updated + list of numbers by the number of contour segments + Each number indicates the segment number of base curve of multiline. + which corresponds to this segment of contour.\n + If segment of contour is equidistant of base curve segment, + then it corresponds to the number of this segment.\n + If contour is segment of multiline vertices traverse. + then it corresponds to the number corresponding the previous segment of the contour.\n + Breaks in the contour can not be overlapped each other. + If in the result of rebuilding a break overlapped on the other break then they are combined. \~ + \ingroup Curves_2D +*/ // --- +class MATH_CLASS MbContourWithBreaks : public MbContour +{ +private: + RPArray breaks; // \ru Разрывы. \en Breaks. + RPArray visibleContours; // \ru Видимые контуры \en Visible contours. + SArray baseSegNumbers; // \ru Номера сегментов базового контура \en Numbers of segments of base contour + // \ru для задания неподвижных точек разрыва \en to define the fixed points of break + // \ru заполняется при использовании контура в мультилинии. \en filled when using the contour in the multiline. +public: + + /** \brief \ru Создание пустого контура. + \en Creation of empty contour. \~ + \details \ru Создание пустого контура без сегментов.\n + \en Creation of empty contour without segments. \n \~ + */ + MbContourWithBreaks(); + + MbContourWithBreaks( const MbContour & cnt ); ///< \ru Копирующий конструктор. \en Copy-constructor. + +private: + MbContourWithBreaks( const MbContourWithBreaks & ); // \ru не реализовано \en not implemented +protected : + MbContourWithBreaks( const MbContourWithBreaks &, MbRegDuplicate * ); +public: + virtual ~MbContourWithBreaks(); + +public : + VISITING_CLASS( MbContourWithBreaks ); + + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента. \en A type of element. + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот. \en Rotation. + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + /** \} */ + /**\ru \name Функции доступа к данным: разрывы. + \en \name Functions for access to data: breaks. + \{ */ + size_t GetBreaksCount () const { return breaks.Count(); } ///< \ru Число разрывов. \en The number of breaks. + + /** \brief \ru Разрыв по номеру. + \en A break by the number. \~ + \details \ru Разрыв по номеру.\n + Номер не проверяется на корректность. + \en A break by the number. \n + A number isn't checked for correctness. \~ + \param[in] i - \ru Номер разрыва, должен быть меньше количества разрывов. + \en The number of break must be less than the number of breaks. \~ + \return \ru Указатель на разрыв. + \en Pointer to break. \~ + */ + MbBreak * GetBreak ( size_t i ) const { return breaks[i]; } + + /** \brief \ru Разрыв по номеру в параметрах контура. + \en A break by the number in contour parameters. \~ + \details \ru Разрыв по номеру в параметрах контура.\n + Номер проверяется на корректность. + В случае, если номер больше числа сегментов результат - вывернутая область. + \en A break by the number in contour parameters. \n + A number Is checked for correctness. + If number is more than numbers of segments then result is everted region. \~ + \param[in] i - \ru Номер разрыва, должен быть меньше количества разрывов. + \en The break number must be less than the number of all breaks. \~ + \return \ru Интервал разрыва в параметрах контура. + \en Break interval in contour parameters. \~ + */ + MbRect1D GetBreaksRange ( size_t i ) const; + + /** \} */ + /**\ru \name Функции доступа к данным: видимые участки. + \en \name Functions for access to data: visible regions. + \{ */ + + /** \brief \ru Количество видимых частей. + \en The number of visible parts. \~ + \details \ru Количество видимых частей.\n + Если в контуре нет разрывов, то возвращает 0. + \en The number of visible parts. \n + If contour does not contain breaks, then returns 0. \~ + \return \ru Число видимых частей. + \en The number of visible parts. \~ + */ + size_t GetVisibleCount () const { return visibleContours.Count(); } + + /** \brief \ru Видимая часть по номеру. + \en A visible part by the number. \~ + \details \ru Видимая часть по номеру.\n + Номер не проверяется на корректность. + \en A visible part by the number. \n + A number isn't checked for correctness. \~ + \param[in] i - \ru Номер видимой части, должен быть меньше количества видимых частей. + \en The number of visible part must be less than the number of visible parts. \~ + \return \ru Указатель не контур - видимую часть. + \en A pointer to visible part of the contour. \~ + */ + const MbContour * GetVisibleContour ( size_t i ) const { return visibleContours[i]; } + + /** \} */ + /**\ru \name Функции доступа к данным: невидимые участки. + \en \name Functions for access to data: Invisible regions. + \{ */ + + /** \brief \ru Невидимая часть по номеру разрыва. + \en Invisible part by the number of break. \~ + \details \ru Невидимая часть по номеру разрыва.\n + Номер проверяется на корректность. + В случае, если номер не меньше числа разрывов, функция вернет NULL.\n + После использования полученный контур нужно удалить. + \en Invisible part by the number of break. \n + A number Is checked for correctness. + If the number is not less than the number of breaks, the function returns NULL. \n + The resulting contour is to be deleted after use. \~ + \param[in] i - \ru Номер разрыва, должен быть меньше количества видимых частей. + \en The number of break must be less than the number of visible parts. \~ + \return \ru Указатель не контур - видимую часть. + \en A pointer to visible part of the contour. \~ + */ + MbContour * GetInvisibleContour ( size_t i ) const; + + /** \} */ + /**\ru \name Работа с разрывами: добавление. + \en \name Working with breaks: addition. + \{ */ + + /** \brief \ru Добавить разрыв между точками. + \en Add a break between points. \~ + \details \ru Добавить разрыв между точками.\n + \en Add a break between points. \n \~ + \param[in] point1 - \ru Первая граница разрыва. + \en The first boundary of break. \~ + \param[in] point2 - \ru Вторая граница разрыва. + \en The second boundary of break. \~ + \param[in] point3 - \ru Точка, которая показывает удаляемую часть замкнутого контура,\n + в случае разомкнутого контура она игнорируется. + \en A point which indicates a removable part of the closed contour, \n + in the case of open contour it is ignored. \~ + \param[in] invertBreak - \ru Признак добавления разрыва на противоположную часть контура. + \en addition attribute of break on the opposite part of contour. \~ + \return \ru true, если разрыв был добавлен. + \en true if break has been added. \~ + */ + bool AddBreak ( const MbCartPoint & point1, const MbCartPoint & point2, + const MbCartPoint & point3, bool invertBreak = false ); + + /** \brief \ru Добавить разрыв между параметрами контура. + \en Add a break between contour parameters. \~ + \details \ru Добавить разрыв между параметрами контура.\n + \en Add a break between contour parameters. \n \~ + \param[in] t1 - \ru Первая граница разрыва. + \en The first boundary of break. \~ + \param[in] t2 - \ru Вторая граница разрыва. + \en The second boundary of break. \~ + \param[in] t3 - \ru Параметр, который показывает удаляемую часть замкнутого контура,\n + в случае разомкнутого контура он игнорируется. + \en A parameter which indicates a removable part of the closed contour, \n + in the case if contour is open it is ignored. \~ + \param[in] invertBreak - \ru Признак добавления разрыва на противоположную часть контура. + \en addition attribute of break on the opposite part of contour. \~ + \return \ru true, если разрыв был добавлен. + \en true if break has been added. \~ + */ + bool AddBreak ( double t1, double t2, double t3, bool invertBreak = false ); + + /** \brief \ru Добавить разрыв по интервалу параметров контура. + \en Add a break by interval of contour parameters. \~ + \details \ru Добавить разрыв по интервалу параметров контура.\n + \en Add a break by interval of contour parameters. \n \~ + \param[in] range - \ru Интервал параметров контура,\n + если range.zmin больше range.zmax, то результат работы функции + будет корректным только в случае замкнутого контура - + добавится разрыв, проходящий через начало контура. + \en An interval of contour parameters. \n + if range.zmin is greater than range.zmax then the function result + is correct only in the case of closed contour - + added a break passing through the origin of the contour. \~ + \return \ru true, если разрыв был добавлен. + \en true if break has been added. \~ + */ + bool AddBreak ( const MbRect1D & range ); + + /** \} */ + /**\ru \name Работа с разрывами: удаление. + \en \name Working with breaks: removing. + \{ */ + + /** \brief \ru Удалить разрывы. + \en Remove breaks. \~ + \details \ru Удалить все разрывы.\n + \en Remove all breaks. \n \~ + \return \ru true, если хотя бы один разрыв был удален. + \en true, if at least one break has been removed. \~ + */ + bool DeleteBreaks (); ///< \ru Удалить разрывы. \en Remove breaks. + + /** \brief \ru Удалить разрыв по номеру разрыва. + \en Remove a break by the number. \~ + \details \ru Удалить разрыв по номеру разрыва.\n + \en Remove a break by the number. \n \~ + \param[in] breakIndex - \ru Номер разрыва,\n + проверяется на корректность.\n + \en The number of break. \n + checked for correctness. \n \~ + \param[in] rebuild - \ru Нужно ли перестроить контур после удаления разрыва.\n + Если контур не перестраивать, видимые части контура не будут соответствовать разрывам.\n + Перестроить контур можно отдельно вызовом RebuildBreaks. + \en Is the contour to be rebuilt after removing break. \n + If don't rebuild contour then the visible parts of contour do not match breaks. \n + Rebuild contour you can be separately by call RebuildBreaks. \~ + \return \ru true, если разрыв был удален. + \en true if break has been removed. \~ + */ + bool DeleteBreakAtNumber ( size_t breakIndex, bool rebuild = false); + + /** \brief \ru Удалить разрыв по параметру на контуре. + \en Remove a break by parameter on the contour. \~ + \details \ru Удалить разрыв по параметру на контуре.\n + \en Remove a break by parameter on the contour. \n \~ + \return \ru true, если разрыв был удален + \en true if break has been removed \~ + */ + bool DeleteBreakAtParam ( double t ); + + /** \brief \ru Удалить разрывы на сегментах с соответствующим базовым номером. + \en Remove breaks on the segments with the corresponding base number. \~ + \details \ru Удалить разрывы на сегментах с соответствующим базовым номером.\n + Разрывы удаляться, если в контуре заполнены базовые номера сегментов. + Номера заполняются при перестроении мультилинии, содержащей контур.\n + Если сегменту контура соответствует одна из частей разрыва, то весь разрыв будет удален. + \en Remove breaks on the segments with the corresponding base number. \n + Break are removed if base numbers of segments are filled in contour. + The number are filled when multiline is rebuilt which contrains contour. \n + If segment of contour corresponds to one of break parts then entire break is removed. \~ + \param[in] baseNumber - \ru Номер сегмента базовой кривой. + \en A segment number of base curve. \~ + \param[in] delTracingBreaks - \ru Нужно ли удалять разрывы с сегментоа, соответствующих обходу вершины мультилинии. + \en Is it necessary for breaks to be removed from segments which correspond to multiline vertices traverse. \~ + \param[in] delEquidBreaks - \ru Нужно ли удалять разрывы с сегментов, соответствующих эквидистантам. + \en breaks to be removed from segments which correspond to equidistants. \~ + \param[in] delInLineSeg - \ru Удалять ли разрывы с прямолинейных сегментов. + \en Is it necessary to remode breaks from straight segments. \~ + */ + void DeleteBreaksAtBaseNumber ( size_t baseNumber, bool delTracingBreaks, + bool delEquidBreaks, bool delInLineSeg = true ); + /** \} */ + /**\ru \name Удаление разрывов и видимых частей малой метрической длины. + \en \name Removing of breaks and visible parts of the small metric length. + \{ */ + + /** \brief \ru Удалить разрывы малой метрической длины. + \en Remove breaks of the small metric length. \~ + \details \ru Удалить разрывы малой метрической длины.\n + В случае успеха видимые контуры перестраиваются соответственно разрывам. + \en Remove breaks of the small metric length. \n + In case of success the visible contours are rebuilt by breaks. \~ + \param[in] length - \ru Минимальная длина невидимой части. + \en Minimal length of invisible part. \~ + \return \ru true, если хотя бы один разрыв был удален. + \en true, if at least one break has been removed. \~ + */ + bool DeleteSmallBreaks ( double length ); + + /** \brief \ru Удалить видимые части малой метрической длины. + \en Remove visible parts of the small metric length. \~ + \details \ru Удалить видимые части малой метрической длины.\n + Соответствует объединению близких разрывов в один. + В случае успеха видимые контуры перестраиваются соответственно разрывам. + \en Remove visible parts of the small metric length. \n + Corresponds to union of close discontinuities into one. + In case of success the visible contours are rebuilt by breaks. \~ + \param[in] length - \ru Минимальная длина видимой части. + \en Minimal length of visible part. \~ + \return \ru true, если разрывы были изменены. + \en true if breaks have been changed. \~ + */ + bool DeleteSmallVisContours ( double length ); + + /** \} */ + /**\ru \name Работа с разрывами + \en \name Working with breaks + \{ */ + + /** \brief \ru Номер разрыва, край которого попал в окрестность точки. + \en The number of break the edge of which is into point neighbourhood. \~ + \details \ru Номер разрыва, край которого попал в окрестность точки.\n + \en The number of break the edge of which is into point neighbourhood. \n \~ + \param[in] p - \ru Точка. + \en Point. \~ + \param[in] rad - \ru Радиус окрестности точки для поиска разрыва. + \en Radius of point neighborhood to search the break. \~ + \param[out] index - \ru Номер разрыва. + \en The number of break. \~ + \return \ru true, если разрыв найден. + \en true if the break is found. \~ + */ + bool GetBreakAtPoint ( const MbCartPoint & p, double rad, + size_t & index ) const; + + /** \brief \ru Номера разрывов, которые хотя бы одним краем попадают в область. + \en Numbers of breaks which at least one edge fall into the region. \~ + \details \ru Номера разрывов, которые хотя бы одним краем попадают в область.\n + \en Numbers of breaks which at least one edge fall into the region. \n \~ + \param[in] rect - \ru Область поиска. + \en Region of search. \~ + \param[out] breaksNumbers - \ru Номера разрывов. + \en Numbers of breaks. \~ + \return \ru true, если хотя бы один разрыв найден. + \en true, if at least one break has been found. \~ + */ + bool GetBreaksInRect ( const MbRect & rect, + SArray & breaksNumbers ) const; + + /** \brief \ru Номера разрывов, которые хотя бы одним краем попадают в область. + \en Numbers of breaks which at least one edge fall into the region. \~ + \details \ru Номера разрывов, которые хотя бы одним краем попадают в область, заданную контуром.\n + \en Numbers of breaks which at least one edge fall into the region given contour. \n \~ + \param[in] contour - \ru Контур должен быть замкнутым и иметь правильное направление. + \en Contour must be closed and have the right direction. \~ + \param[out] breaksNumbers - \ru Номера разрывов. + \en Numbers of breaks. \~ + \return \ru true, если хотя бы один разрыв найден. + \en true, if at least one break has been found. \~ + */ + bool GetBreaksInRect ( const MbContour & contour, + SArray & breaksNumbers ) const; + + /** \brief \ru Определить попадает ли точка в любой из разрывов. + \en Determine whether a point it inside a break. \~ + \details \ru Определить попадает ли точка в любой из разрывов.\n + \en Determine whether a point it inside a break. \n \~ + \param[in] p - \ru Точка для проверки. + \en A point for the check. \~ + \return \ru true, если точка попадает в любой из разрывов. + \en true, if point falls into any break. \~ + */ + bool HitToBreaks ( const MbCartPoint & p ) const; + + /** \brief \ru Находится ли интервал параметров на разрыве. + \en Whether the interval of parameters is on break. \~ + \details \ru Находится ли интервал параметров на разрыве.\n + \en Whether the interval of parameters is on break. \n \~ + \param[in] rect - \ru Интервал для проверки. + \en Interval to check. \~ + \return \ru true, если интервал полностью находится на разрыве или совпадает с ним. + \en true if interval entirely is on the break or coincides with it. \~ + */ + bool IsRectInBreak ( const MbRect1D & rect ); + + /** \brief \ru Обновить невидимые и видимые контуры. + \en Update visible and invisible contours. \~ + \details \ru Обновить невидимые и видимые контуры соответственно базовой кривой мультилинии.\n + После перестроения разрывы должны соответствовать сегментам базовой кривой мультилинии. + \en Update visible and invisible contours by base curve of multiline respectively. \n + After rebuilding the breaks must correspond to segments of base multiline curve. \~ + \param[in] oldBaseNumbers - \ru Старые номера базовых сегментов,\n + должны быть запомнены до изменения мультилинии. + \en Old numbers of base segments, \n + must be saved before multiline is changed. \~ + */ + void RebuildBreaks ( SArray & oldBaseNumbers ); + + /** \brief \ru Обновить невидимые и видимые контуры. + \en Update visible and invisible contours. \~ + \details \ru Обновить невидимые и видимые контуры соответственно разрывам. + \en Update visible and invisible contours according to breaks. \~ + */ + void RebuildBreaks ( ); + + /** \brief \ru Преобразование в соответствии с матрицей. + \en Transform according to matrix. \~ + \details \ru Преобразование в соответствии с матрицей.\n + Используется для преобразования мультилинии. + Преобразует длину и расстояние от фиксированной точки прямолинейного разрыва, + а так же фиксированную точку. + \en Transform according to matrix.\n + Used to transform multiline. + Transforms length and distance from fixed point of straight break, + and fixed point. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + */ + void TransformMultlinesBreaks ( const MbMatrix & matr ); + + /** \brief \ru Параметр привязки части разрыва. + \en A binding parameter of a break part. \~ + \details \ru Посчитать параметр привязки части разрыва в зависимости от типа сегмента контура.\n + \en Calculate binding parameter of a break part according to the type of contour segment. \n \~ + \param[in] brPart - \ru Часть разрыва этого контура. + \en A break part of this contour. \~ + \param[out] segNumber - \ru Номер сегмента контура. + \en A number of the contour segment. \~ + \return \ru Параметр центра разрыва на сегменте контура. + \en A parameter of the break center on the contour segment. \~ + */ + double GetLocalBreaksParam ( const MbBreaksPart & brPart, + size_t & segNumber ) const; + + /** \} */ + /**\ru \name Работа с разрывами: изменение разрыва. + \en \name Working with breaks: changing a break. + \{ */ + + /** \brief \ru Фиксировать точку. + \en Fix the point. \~ + \details \ru Поставить фиксированную точку части разрыва.\n + \en Set the fixed point of a break part. \n \~ + \param[in] newPoint - \ru Новая фиксированная точка. + \en A new fixed point. \~ + \param[out] part - \ru Часть разрыва контура для изменения. + \en A part of contour break to change. \~ + */ + void SetBreakFixedPoint ( const MbCartPoint & newPoint, + MbBreaksPart & part ); + + /** \brief \ru Фиксировать переменную. + \en Fix the variable. \~ + \details \ru Поставить фиксированную переменную части разрыва.\n + \en Set the fixed variable of a break part. \n \~ + \param[in] newFixedVar - \ru Новая фиксированная переменная. + \en New fixed variable. \~ + \param[out] part - \ru Часть разрыва контура для изменения. + \en A part of contour break to change. \~ + */ + void SetBreakFixedVar ( double newFixedVar, MbBreaksPart & part); + + /** \} */ + /**\ru \name Работа с разрывами: отслеживание разрыва + \en \name Working with breaks: tracking a break + \{ */ + /// \ru Количество номеров сегментов базового контура \en Count of segments numbers of the base contour + // \ru (должно соответствовать количеству сегментов контура) \en (must be equal to count of contour segments) + size_t GetBaseNumbersCount () const { return baseSegNumbers.Count(); } + + /// \ru Номера сегментов базового контура. \en Numbers of segments of base contour. + void GetBaseNumbers ( SArray & baseNumbers ) const; + + /** \brief \ru Номер сегмента базового контура. + \en Segment number of the base contour. \~ + \details \ru Номер сегмента базового контура.\n + Номер сегмента будет найден, если массив номеров не пуст и + корректно насчитан, то есть число номеров совпадает с числом сегментов контура + \en Segment number of the base contour. \n + Segment number will be found if the array of numbers is not empty and + it was numbered correctly, ie count of numbers is equal to count of contour segments \~ + \param[in] i - \ru Индекс номера. + \en Index of number. \~ + \return \ru Номер сегмента из массива номеров. + \en Number of segment from the array of numbers. \~ + */ + size_t GetBaseNumber ( size_t i ) const; + + /** \brief \ru Добавить номер базового сегмента. + \en Add number of the base segment. \~ + \details \ru Добавить номер сегмента базового контура в конец массива.\n + \en Add segment number of base contour to the end of array. \n \~ + \param[in] number - \ru Номер для добавления. + \en Number to add. \~ + */ + void AddBaseSegNumber ( size_t number ); + + /** \brief \ru Добавить номер базового сегмента. + \en Add number of the base segment. \~ + \details \ru Добавить номер сегмента базового контура в начало массива.\n + \en Add segment number of base contour to the beginning of array. \n \~ + \param[in] number - \ru Номер для добавления. + \en Number to add. \~ + */ + void AddBaseSegNumberAtBegin ( size_t number ); + + /** \brief \ru Вставить номер после lastInd. + \en Insert number after the lastInd. \~ + \details \ru Вставить после элемента номер lastInd номер, соответствующий lastInd.\n + \en Insert number corresponding lastInd after element lastInd. \n \~ + \param[in] lastInd - \ru Индекс номера. + \en Index of number. \~ + */ + void InsertLastSegNumber ( size_t lastInd ); + + /** \brief \ru Удалить элемент по индексу. + \en Delete element by an index. \~ + \details \ru Удалить номер базового сегмента по индексу.\n + \en Remove number of the base segment by an index. \n \~ + \param[in] ind - \ru Индекс номера. + \en Index of number. \~ + */ + void DeleteBaseSegNumber ( size_t ind ); + + /// \ru Очистить массив с номерами базовых сегментов. \en Clear the array with numbers of base segments. + void ClearBaseSegNumbers () { baseSegNumbers.HardFlush(); } + + /** \brief \ru Изменить номера сегментов в разрывах. + \en Change numbers of segments in the breaks. \~ + \details \ru Изменить номера сегментов в разрывах.\n + Заданному номеру базового сегмента соответствует сегмент - эквидистанта на контуре. + Для всех разрывов: + если хотя бы часть разрыва находится на этом сегменте, + у всех его частей номер сегмента будет изменен. + \en Change numbers of segments in the breaks. \n + A given number of the base segments corresponds to the segment - equidistant on the contour. + For all breaks: + if at least one part of break is in this segment, + the segment number of all of its parts will be changed. \~ + \param[in] begBaseNumber - \ru Номер базового сегмента. + \en An index of the base segment. \~ + \param[in] deltaN - \ru Величина изменение номера сегмента частей разрывов. + \en The change value of segment number of breaks parts. \~ + */ + void ChangeBreaksSegNumbers ( size_t begBaseNumber, ptrdiff_t deltaN ); + + /** \brief \ru Изменить разрывы соотвестсвенно замкнутости. + \en Change breaks of closedness respectively. \~ + \details \ru Изменить разрывы соотвестсвенно замкнутости.\n + При изменении признака замкнутости контура нужно изменить разрывы + соответственно новому значению замкнутости.\n + Если контур стал разомкнутым - разрыв, находящийся на первом и последнем + сегменте одновременно, делится на 2 части.\n + Если контур стал замкнутым - разрывы, первый из который примыкает к левому краю + первого сегмента контура, а второй из которых примыкает к правому краю последнего + сегмента контура, объединяется в один. + \en Change breaks of closedness respectively. \n + When changing attribute of contour closedness breaks need to change + respectively to the new value of closedness. \n + If contour has become open - the break located on the first and last + segment is divided into 2 parts at the same time. \n + If contour has become closed - breaks, the first of which is adjacent to the left boundary + of the first contour segment and the second of which is adjacent to the right boundary of the last + contour segment are united into one. \~ + \param[in] newClosed - \ru Новый признак замкнутости контура. + \en The new closedness attribute of contour. \~ + */ + void ChangeBreaksAtClosed ( bool newClosed ); + + /** \brief \ru Изменить номера сегментов частей разрывов. + \en Change segments numbers of breaks parts. \~ + \details \ru Изменить номера сегментов частей разрывов.\n + \en Change segments numbers of breaks parts. \n \~ + \param[in] deltaN - \ru Величина изменения. + \en A change value. \~ + */ + void MoveBreaksSegNumbers ( ptrdiff_t deltaN ); + + /** \brief \ru Находится ли часть разрыва этого контура на сегменте обхода вершин. + \en Is the break part of this contour located on the segment of vertices traverse. \~ + \details \ru Находится ли часть разрыва этого контура на сегменте обхода вершин.\n + \en Is the break part of this contour located on the segment of vertices traverse. \n \~ + \param[in] part - \ru Часть разрыва этого контура. + \en A break part of this contour. \~ + \param[out] vertNumber - \ru В случае успеха вернет номер вершины. + \en In the case of success returns the vertex number. \~ + \return \ru true, если часть разрыва находится на сегменте обхода вершины. + \en true, if the break part is located on the segment of vertices traverse. \~ + */ + bool IsTrasingBreaksPart ( const MbBreaksPart & part, + size_t & vertNumber ) const; + + /** \brief \ru Поменяться разрывами. + \en Swap breaks. \~ + \details \ru Поменяться разрывами.\n + \en Swap breaks. \n \~ + \param[in] other - \ru Контур с разрывами для обмена. + \en A contour with breaks to swap. \~ + */ + void SwapBreaksAndBaseNumbers ( MbContourWithBreaks & other ); + + /** \brief \ru Добавить разрывы контура. + \en Add contour breaks. \~ + \details \ru Добавить разрывы контура.\n + \en Add contour breaks. \n \~ + \param[in] other - \ru Контур с разрывами для добавления разрывов. + \en A contour with breaks for adding breaks. \~ + */ + void AddContoursBreaks ( const MbContourWithBreaks & other ); + + /** \brief \ru Заменить номера базовых сегментов. + \en Replace the numbers of base segments. \~ + \details \ru Заменить номера базовых сегментов.\n + \en Replace the numbers of base segments. \n \~ + \param[in] other - \ru Контур с новыми номерами. + \en A contour with new numbers. \~ + */ + void ChangeBaseNumbers ( const MbContourWithBreaks & other ); + /** \} */ + +private: + void DeleteBreaks ( size_t segmentIndex, + bool delInLineSeg = true ); // \ru удалить разрывы на сегменте с номером index \en remove breaks from segment with number "index" + void DeleteBreaksPartAtSegNum ( size_t segNumber, size_t oldSegCount ); // \ru часть разрыва по номеру сегмента \en part of break by the segment number + bool DeleteBreaksPartOrBreak ( size_t breakIndex, size_t partIndex, + size_t oldSegCount ); // \ru часть разрыва или разрыв \en part of break or break +private: + void CalculateVisibleContours ( ); // \ru посчитать видимые части \en calculate visible parts + void CalculateInvisibleContours( RPArray & invisibleContours ); // \ru посчитать невидимые части \en calculate invisible parts + void CalculateContours ( const CSSArray & ranges, // \ru посчитать контуры по интервалам \en calculate contours by intervals + RPArray & contours, + bool visible ) const; // \ru для видимых частей вызывать AddRef() \en call AddRef() for visible parts + void CalculateInVisibleRanges ( CSSArray & breaksRanges ); // \ru посчитать невидимые интервалы \en calculate invisible intervals + void CalculateVisibleRanges ( CSSArray & breaksRanges, + CSSArray & visibleRanges ) const; // \ru посчитать видимые интервалы \en Calculate visible intervals + void CalculateRanges ( const CSSArray & startingInt, // \ru посчитать противоположные интервалы \en Calculate opposite intervals + CSSArray & resultInt ) const; // \ru второй массив по первому \en the second array by the first + void CalculateBreaksPart ( const MbRect1D & segParams, + size_t segNumber, MbBreak & brRange ) const; // \ru посчитать часть разрыва \en Calculate a part of the break + void CalculateBreak ( const MbRect1D & range, + MbBreak & brRange ) const; // \ru посчитать разрыв по интервалу \en Calculate the break by interval + MbRect1D GetLocalBreaksRange ( const MbBreaksPart & part, + double brParam, size_t segNumber ) const; // \ru интервал по параметру привязки \en interval by the binding parameter + void AddCalcBreak ( const MbRect1D & range ); + void ChangeBreaksSegNumbers ( const SArray & oldBaseNumbers, + SArray & oldEqCounts, + SArray & newEqCounts ); // \ru изменить номера сегментов у разрывов \en change segments numbers of breaks + void RedefineBreaksParts (); // \ru доопределить неопределенные части разрыва \en complete the definition of indefinite parts of the break + + // \ru для преобразования контуров \en for transformation of contours + void TransformBreaks ( const MbMatrix & matr ); // \ru преобразование в соответствии с матрицей \en transform according to the matrix + + size_t GetLocalBreaksRange ( const MbBreaksPart & part, + MbRect1D & localRect ) const; // \ru разрыв по номеру в параметрах сегмента \en a break by the number in segment parameters + + + void operator = ( const MbContourWithBreaks & ); // \ru не реализован \en not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbContourWithBreaks ) + +}; // MbContourWithBreaks + +IMPL_PERSISTENT_OPS( MbContourWithBreaks ) + +//------------------------------------------------------------------------------ +/** \brief \ru Часть разрыва. + \en Part of break. \~ + \details \ru Часть разрыва контура мультилинии. Относится к одному сегменту контура.\n + Для использования в разрыве MbBreak. + \en Part of multiline contour break. Applicable to one segment of the contour.\n + For using in the break MbBreak. \~ + \ingroup Algorithms_2D +*/ // --- +class MATH_CLASS MbBreaksPart { + +private : + size_t segNumber; // \ru Номер сегмента \en Number of the segment. + double fixedVar; // \ru Фиксированная переменная \en Fixed variable + // \ru ( tMax - tCentre ) / ( tCentre - tMin ), tCentre - параметр центра разрыва \en ( tMax - tCentre ) / ( tCentre - tMin ), tCentre - center of the break + // \ru для отрезка - расстояние до проекции неподвижной точки \en for segment - distance to projection of the fixed point + double length; // \ru Длина части разрыва (для отрезка) \en Length of the break part (for segment) + // \ru для дуг и по умолчанию сохраняем параметрическую длину \en For arcs and save parametric length by default. + // \ru (для дуги - угол) \en (for arc - angle) + MbCartPoint fixedPoint; // \ru неподвижная точка ( корректное значение для отрезка ) \en fixed point (correct value for segment) + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по номеру сегмента, фиксированной переменной, длине, неподвижной точке. + \en Constructor by a number of segment, fixed variable, length, fixed point. \~ + \param[in] sNumber - \ru Номер сегмента контура, на котором находится часть разрыва. + \en Number of contour segment where a part of break is located. \~ + \param[in] fixVar - \ru Фиксированная переменная:\n + для отрезка - расстояние до проекции неподвижной точки,\n + в общем случае - величина, равная ( tMax - tCentre ) / ( tCentre - tMin ), где\n + tMin - минимальный параметр сегмента,\n + tMax - максимальный параметр сегмента,\n + tCentre - параметр центра части разрыва. + \en Fixed variable:\n + for segment - distance to projection of the fixed point,\n + In general case - a value which is equal to ( tMax - tCentre ) / ( tCentre - tMin ), where \n + tMin - minimal parameter of the segment,\n + tMax - maximal parameter of the segment,\n + tCentre - parameter of the break part center. \~ + \param[in] len - \ru Длина части разрыва:\n + для отрезка - метрическая длина,\n + в общем случае - параметрическая длина. + \en Length of the break part:\n + for segment - metric length, \n + In the general case - parametric length. \~ + \param[in] p - \ru Неподвижная точка:\n + для отрезка - используется для привязки части разрыва,\n + в общем случае - не имеет смысла. + \en Fixed point:\n + for segment - used to bind part of the break,\n + in general case - it is useless. \~ + */ + MbBreaksPart( size_t sNumber, double fixVar, double len, const MbCartPoint & p ) + : segNumber ( sNumber ), + fixedVar ( fixVar ), + length ( len ), + fixedPoint( p ) + { + } + + /// \ru Копирующий конструктор. \en Copy-constructor. + MbBreaksPart( const MbBreaksPart & other ) + : segNumber ( other.GetSegmentNumber() ), + fixedVar ( other.GetFixedVar() ), + length ( other.GetLength() ), + fixedPoint( other.GetFixedPoint() ) + { + } + + ~MbBreaksPart(){}; + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + size_t GetSegmentNumber() const { return segNumber; } ///< \ru Номер сегмента контура. \en A number of the contour segment. + double GetFixedVar() const { return fixedVar; } ///< \ru Фиксированная переменная. \en fixed variable + double GetLength() const { return length; } ///< \ru Длина части разрыва. \en Length of the break part. + const MbCartPoint & GetFixedPoint() const { return fixedPoint; } ///< \ru Фиксированная точка. \en Fixed point. + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Изменить номер сегмента контура. \en Change a number of the contour segment. + void SetSegmentNumber( size_t newNumber ) { segNumber = newNumber; } + /// \ru Изменить фиксированную переменную. \en Change a fixed variable. + void SetFixedFar ( double newFixedVar ) { fixedVar = newFixedVar; } + /// \ru Изменить длину части разрыва. \en Change the length of the break part. + void SetLength ( double newLength ) { length = newLength; } + /// \ru Изменить фиксированную точку. \en Change a fixed point. + void SetFixedPoint ( const MbCartPoint & point ) { fixedPoint.Init( point ); } + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move ( const MbVector & to ) { fixedPoint.Move( to ); } + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector which defines a rotation angle. \~ + */ + void Rotate ( const MbCartPoint & pnt, const MbDirection & angle ) { fixedPoint.Rotate( pnt, angle ); } + + /** \brief \ru Преобразование. + \en Transformation. \~ + \details \ru Преобразование в соответствии с матрицей.\n + \en Transform according to matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform ( const MbMatrix & matr ) { fixedPoint.Transform( matr ); } + + /** \brief \ru Изменить номер сегмента. + \en Change a number of the segment. \~ + \details \ru Изменить номер сегмента на заданную величину.\n + Номер сегмента не изменится, если величина изменения будет отрицательной и большей по модулю, чем номер. + \en Change a number of the segment by a given value. \n + The number of the segment does not change if the amount of change is negative and greater in absolute value than the number. \~ + \param[in] deltaN - \ru Величина увеличения номера сегмента. + \en Increase value of the segment number. \~ + */ + void ChangeSegNumber ( ptrdiff_t deltaN ) { if( deltaN >= 0 || (ptrdiff_t)segNumber >= -deltaN ) segNumber += deltaN; } + /** \} */ +private: + void operator = ( const MbBreaksPart & ); // \ru не реализован \en not implemented +}; // MbBreaksPart + + +//------------------------------------------------------------------------------ +/** \brief \ru Разрыв. + \en Break. \~ + \details \ru Разрыв контура.\n + Для использования в контуре с разрывом MbContourWithBreaks.\n + Разрыв состоит из частей MbBreaksPart, каждая из которых находится на одном сегменте контура.\n + В разрыве может быть 1 или 2 части. + Если разрыв должен располагаться более чем на трех сегментах, то он имеет 2 части, + соответствующие первому и последнему сегментам. + \en Contour break.\n + For using in the contour with break MbContourWithBreaks.\n + The break consists of parts MbBreaksPart all of which are on the same segment of the contour. \n + The break can have 1 or 2 parts. + If the break must be located more than three segments it has two parts, + corresponding to the first and the last segments. \~ + \ingroup Algorithms_2D +*/ // --- +class MATH_CLASS MbBreak { + +private: + SArray parts; // \ru части разрыва: \en part of break: + // \ru одна, если разрыв на одном сегменте, \en one if the break is on the one segment, + // \ru две, если на нескольких сегментах - первая и последняя \en two if break is on the several segments - the first and the last + +public: + + /** \brief \ru Конструктор пустого разрыва. + \en Constructor of an empty break. \~ + \details \ru Конструктор пустого разрыва.\n + Такой разрыв не может находиться в контуре с разрывом MbContourWithBreaks. + Он будет удален при перестроении. + \en Constructor of an empty break. \n + Such break can not be in the contour with break MbContourWithBreaks. + It will be removed when rebuilding. \~ + */ + MbBreak(): parts () { } + + /// \ru Копирующий конструктор. \en Copy-constructor. + MbBreak( const MbBreak & other ): parts ( other.parts ) {} + + ~MbBreak() {} + +public: + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + ///< \ru Количество частей. \en The number of parts. + size_t PartsCount () const { return parts.Count(); } + + /** \brief \ru Часть по номеру. + \en A part by the number. \~ + \details \ru Часть по номеру части разрыва.\n + Номер не проверяется на корректность. + \en A part by the number of the break part. \n + A number isn't checked for correctness. \~ + \param[in] number - \ru Номер части разрыва, должен быть меньше количества частей. + \en The number of break part must be less than the number of parts. \~ + \return \ru Ссылку на часть разрыва. + \en Reference to part of break. \~ + */ + MbBreaksPart & GetPart ( size_t number ) const { return parts[number]; } + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Добавить часть разрыва. \en Add a part of break. + void AddPart ( MbBreaksPart part ) { parts.Add( part ); } + /// \ru Удалить все части разрыва. \en Remove all parts of break. + void DeleteParts () { parts.HardFlush(); } + + /** \brief \ru Удалить часть. + \en Remove a part. \~ + \details \ru Удалить часть разрыва по номеру.\n + Номер проверяется на корректность. + Если номер не меньше количества частей, то разрыв не изменится. + \en Remove a part of break by the number. \n + A number Is checked for correctness. + If the number isn't less than the number of parts the break doesn't change. \~ + \param[in] number - \ru Номер части разрыва, должен быть меньше количества частей. + \en The number of break part must be less than the number of parts. \~ + */ + void DeletePart ( size_t number ) { if( number < PartsCount() ) parts.RemoveInd( number ); } + + /** \brief \ru Переместить. + \en Move. \~ + \details \ru Переместить на вектор.\n + \en Move by vector.\n \~ + \param[in] to - \ru Вектор перемещения. + \en Movement vector. \~ + */ + void Move( const MbVector & to ) + { + for( size_t i = 0, count = parts.Count(); i < count; ++i ) + parts[i].Move( to ); + } + + /** \brief \ru Повернуть. + \en Rotate. \~ + \details \ru Повернуть на угол вокруг точки.\n + \en Rotate at angle around a point.\n \~ + \param[in] pnt - \ru Точка - центр поворота. + \en A point is a rotation center. \~ + \param[in] angle - \ru Двумерный нормализованный вектор, задающий угол вращения. + \en A two-dimensional normalized vector which defines a rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ) + { + for( size_t i = 0, count = parts.Count(); i < count; ++i ) + parts[i].Rotate( pnt, angle ); + } + + /** \brief \ru Преобразовать. + \en Transform. \~ + \details \ru Преобразовать в соответствии с матрицей.\n + \en Transform according to matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ) + { + for( size_t i = 0, count = parts.Count(); i < count; ++i ) + parts[i].Transform( matr ); + } + /** \} */ +private: + void operator =( const MbBreak & ); // \ru не реализован \en not implemented + +}; // MbBreak + + +//------------------------------------------------------------------------------ +/** \brief \ru Ближайшие проекции на контур. + \en Nearest projections on the contour. \~ + \details \ru Ближайшие проекции точки на контур.\n + \en Nearest projections of point on the contour. \n \~ + \param[in] contour - \ru Контур. + \en A contour. \~ + \param[in] pnt - \ru Проецируемая точка. + \en Projecting point. \~ + \param[out] tProjs - \ru Параметры ближайших проекций. + \en Parameters of nearest projections. \~ + \param[in] isNear - \ru Выбрать только проекции, + находящиеся от проецируемой точки не дальше заданной точности. + \en Select only the projections + which are located from projecting point within a given tolerance. \~ + \param[in] mEps - \ru Точность выбора ближайших точек. + \en A tolerance of nearest points selection. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) NearPointProjections( const MbContour & contour, const MbCartPoint & pnt, + SArray & tProjs, bool isNear, double mEps = METRIC_REGION ); + + + +#endif // __CUR_CONTOUR_WITH_BREAKS_H diff --git a/C3d/Include/cur_cosinusoid.h b/C3d/Include/cur_cosinusoid.h new file mode 100644 index 0000000..e331252 --- /dev/null +++ b/C3d/Include/cur_cosinusoid.h @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Косинусоида в двумерном пространстве. + \en Cosinusoid in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_COSINUSOID_H +#define __CUR_COSINUSOID_H + + +#include +#include +#include +#include +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Косинусоида в двумерном пространстве. + \en Cosinusoid in two-dimensional space. \~ + \details \ru Косинусоида расположена вдоль оси X локальной системы координат. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией\n + r(t) = position.origin + (position.axisX ((tmin + t) - phase) / frequency) + (amplitude cos(tmin + t) position.axisY).\n + Косинусоида приведена на рисунке ниже. + t = 0 + amplitude | /\ /\ + |/ \ / \ + t = -phase | \ tmin t/ \ tmax + ______/|_____\|_____/______\|_____________________________ + / | \ / \ + / | \ / + / | \/ + y = amplitude cos(frequency x + phase) + \en Cosinusoid located along the X-axis of the local coordinate system. \n + Radius-vector of the curve in the method PointOn(double&t,MbCartPoint3D&r) is described by the vector function\n + r(t) = position.origin + (position.axisX ((tmin + t) - phase) / frequency) + (amplitude cos(tmin + t) position.axisY).\n + Cosinusoid is shown in the figure below. + t = 0 + amplitude | /\ /\ + |/ \ / \ + t = -phase | \ tmin t/ \ tmax + ______/|_____\|_____/______\|_____________________________ + / | \ / \ + / | \ / + / | \/ + y = amplitude cos(frequency x + phase) \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbCosinusoid: public MbCurve, public MbNestSyncItem { +private : + MbPlacement position; ///< \ru Локальная система координат. \en Local coordinate system. + double frequency; ///< \ru Циклическая частота (angular frequency). \en Angular frequency. + double phase; ///< \ru Начальная фаза в радианах. \en Initial phase in radians. + double amplitude; ///< \ru Амплитуда. \en Amplitude. + double tmin, tmax; ///< \ru Область определения (по умолчанию - один период). \en Domain (one period by default). + mutable MbRect rect; ///< \ru Габаритный прямоугольник. \en Bounding box. + mutable double metricLength; ///< \ru Метрическая длина. \en The metric length. + +public : + // \ru Конструктор по амплитуде, начальной фазе и круговой частоте \en Constructor by amplitude, initial phase and angular frequency + MbCosinusoid( const double & am , const double & phase, const double & anf ); + // \ru Конструктор по амплитуде, начальной фазе и признаку начала параметра \en Constructor by amplitude, initial phase and attribute of the beginning of the parameter + // \ru ( от максимума косинуса ( x(0) = -фаза ) или от начала координат( x(0) = 0 ) ) \en ( from the maximum cosine ( x(0) = -phase ) or from the origin( x(0) = 0 ) ) + MbCosinusoid( const double & am , const double & phase = 0.0, bool maxBegin = true ); + // \ru Конструктор по расположению, амплитуде, начальной фазе и круговой частоте \en Constructor by location, amplitude, initial phase and angular frequency + MbCosinusoid( const MbPlacement & pos, + const double & am = 0.0, + const double & phase = 0.0, + const double & anf = 0.0 ); + // \ru Конструктор по расположению, амплитуде, начальной фазе и предельным параметрам \en Constructor by location, amplitude, initial phase and limit parameters + MbCosinusoid( const MbPlacement & pos, double am, double ph, double af, double t1, double t2 ); +protected : + MbCosinusoid( const MbCosinusoid & ); // \ru Конструктор копирования \en Copy-constructor +public : + virtual ~MbCosinusoid(); + +public: + VISITING_CLASS( MbCosinusoid ); + + // \ru \name Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsBounded () const { return true; } // \ru Ограниченность кривой \en Bounded curve + virtual void Transform ( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual MbPlaneItem & Duplicate ( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавь свой габарит в прямой прям-к \en Add bounding box into a straight box + virtual void CalculateGabarit( MbRect & r ) const; // \ru Определить габариты кривой \en Determine the bounding box of the curve + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике \en Whether the object is visible in the given rectangle + using MbCurve::IsVisibleInRect; + + // \ru \name Общие функции кривой. \en Common functions of curve. + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости \en Check for closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & v ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & v ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & v ) const; // \ru Третья производная \en Third derivative + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + + virtual bool HasLength ( double & length ) const; + virtual double GetMetricLength() const; // \ru Метрическая длина \en The metric length + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change to the opposite direction of a curve + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть кривой между параметрами t1 и t2 \en Delete a part of a curve between parameters t1 and t2 + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть кривой между параметрами t1 и t2 \en Save a curve part between t1 and t2 parameters + + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + + virtual void IntersectHorizontal( double y, SArray & cross ) const; // \ru Пересечение кривой с горизонтальной прямой \en Intersection of curve with the horizontal line + virtual void IntersectVertical ( double x, SArray & cross ) const; // \ru Пересечение с вертикальной прямой \en Intersection with the vertical line + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of approximation step with consideration of deviation angle + + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на кривую \en Point projection on the curve + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + // \ru Подобные ли кривые для объединения? \en Are the curves similar to merge? + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; + + const MbPlacement & GetPlacement() const { return position; } + MbPlacement & SetPlacement() { return position; } + double GetFrequency() const { return frequency; } + double GetPhase() const { return phase; } + double GetAmplitude() const { return amplitude; } + double GetOwnTMin() const { return tmin; } + double GetOwnTMax() const { return tmax; } + void SetPlacement( const MbPlacement &pos ); + void SetFrequency( double f ); + void SetPhase ( double p ); + void SetAmplitude( double a ); + void SetOwnTMin ( double t ); + void SetOwnTMax ( double t ); + inline void CheckParam( double & t ) const; + + bool IsHorizontal( double eps = Math::AngleEps ) const; // \ru Проверка горизонтальности \en Check for horizontality + bool IsVertical ( double eps = Math::AngleEps ) const; // \ru Проверка вертикальности \en Check for verticality + + void Init ( const MbCosinusoid & ); + void Init ( double t1, double t2 ); + void Init ( const MbPlacement & pos, double am, double ph, double af ); + void Init1( CosinusoidPar & par, MbCartPoint & p1, MbCartPoint & p2, double & len, double & angle ); + void Init2( CosinusoidPar & par, const MbCartPoint & p1, MbCartPoint & p2, const double & len, double & angle ); + void Init3( CosinusoidPar & par, const MbCartPoint & p1, MbCartPoint & p2, double & len, const double & angle, + const DiskreteLengthData * = NULL ); + void Init4( CosinusoidPar & par, MbCartPoint & p1, const MbCartPoint & p2, const double & len, double & angle ); + void Init5( CosinusoidPar & par, MbCartPoint & p1, const MbCartPoint & p2, double & len, const double & angle, + const DiskreteLengthData * = NULL ); + void Init6( CosinusoidPar & par, const MbCartPoint & p1, MbCartPoint & p2, const double & len, const double & angle ); + void Init7( CosinusoidPar & par, MbCartPoint & p1, const MbCartPoint & p2, const double & len, const double & angle ); + void Init8( CosinusoidPar & par, MbCartPoint & p1, MbCartPoint & p2, double & len, double & angle, + const DiskreteLengthData & diskrData, bool correctP1 ); + void SpecInit( const CosinusoidPar &, const MbCartPoint & p1, double angle, double len ); + +private: + void operator = ( const MbCosinusoid & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCosinusoid ) +}; // MbCosinusoid + +IMPL_PERSISTENT_OPS( MbCosinusoid ) + +//------------------------------------------------------------------------------- +// \ru Проверка параметра \en Check parameter +// --- +inline void MbCosinusoid::CheckParam( double & t ) const { + if ( t < 0 ) + t = 0; + else if ( t > ( tmax - tmin ) ) + t = ( tmax - tmin ); +} + + +#endif // __CUR_COSINUSOID_H diff --git a/C3d/Include/cur_crooked_spiral.h b/C3d/Include/cur_crooked_spiral.h new file mode 100644 index 0000000..8ed8ae9 --- /dev/null +++ b/C3d/Include/cur_crooked_spiral.h @@ -0,0 +1,149 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Спираль постоянного радиуса и осью, заданной произвольной кривой на плоскости XZ position. + \en Spiral with constant radius and axis defined by an arbitrary curve on the XZ plane "position". \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CROOKET_SPIRAL_H +#define __CUR_CROOKET_SPIRAL_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Спираль с криволинейной осью. + \en Spiral with a curvilinear axis. \~ + \details \ru Спираль постоянного радиуса и осью, заданной произвольной плоской кривой. + Ось спирали определяется кривой curve, располагающейся в плоскости ZX локальной системы координат спирали. + При этом ось Z локальной системы координат спирали служит осью X системы координат двумерной кривой curve, + а ось X локальной системы координат спирали служит осью Y системы координат двумерной кривой curve, + что приведено на рис. 1 ниже. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + r(t) = position.origin + + (position.axisX (point.y + (radius cos(t) normal.ay)) + + (position.axisY radius sin(t)) + + (position.axisZ (point.x + (radius cos(t) normal.ax)), + где point - точка кривой curve, normal - нормаль кривой curve. + Рис. 1. + ^ Ось X локальной системы координат спирали является осью Y системы координат curve. + | + | curve(w) + | + +----> Ось Z локальной системы координат спирали является осью X системы координат curve. + \en Spiral with a constant radius and axis defined by an arbitrary plane curve. + Spiral axis is determined by the curve "curve" based in the ZX plane of the local coordinate system of spiral. + The Z-axis of the local coordinate system is the X-axis of coordinate system of two-dimensional uv-curve "curve", + and the X-axis of the local coordinate system is the Y-axis of the coordinate system of two-dimensional uv-curve "curve", + that is shown in fig. 1 below. \n + The radius-vector of curve in the method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + r(t) = position.origin + + (position.axisX (point.y + (radius cos(t) normal.ay)) + + (position.axisY radius sin(t)) + + (position.axisZ (point.x + (radius cos(t) normal.ax)), + where "point" is point of the curve "curve", "normal" is normal of the curve "curve". + Fig. 1 1. + ^ X-axis of the local coordinate system of the spiral is Y-axis of the coordinate system of the curve "curve". + | + | curve(w) + | + +----> Z-axis of the local coordinate system of the spiral is X-axis of the coordinate system of the curve "curve". \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbCrookedSpiral : public MbSpiral { + typedef std::vector CurveParams; +protected: + MbCurve * curve; ///< \ru Кривая, задающая ось спирали, (не может быть NULL). \en The curve which determines the axis of the spiral, (can not be NULL). + double radius; ///< \ru Радиус спирали. \en A spiral radius. + double wMin; ///< \ru Минимальное значение параметра curve. \en Minimal value of parameter "curve". + double wMax; ///< \ru Максимальное значение параметра curve. \en Maximal value of parameter "curve". + double t0; ///< \ru Начальный угол спирали. \en The initial angle of the spiral. + bool curveSense; ///< \ru Совпадение направления оси спирали с направлением кривой curve. \en The coincidence of the direction of the spiral axis with the direction of the curve "curve". + CurveParams curveParams; ///< \ru Параметры спирали (параметрические сдвиги от начала кривой) и параметры двумерной кривой. \en Parameters of spiral (parametric shifts from the beginning of the curve) and parameters of "curve". + +protected: + MbCrookedSpiral( const MbCrookedSpiral & init ); // \ru Не реализовано \en Not implemented + MbCrookedSpiral( const MbCrookedSpiral & init, MbRegDuplicate * iReg ); +public : + MbCrookedSpiral( const MbPlacement3D & pos, MbCurve & axisCurve, double radius, double step, bool same ); // \ru Спираль с кривой осью \en Spiral with a curvilinear axis + virtual ~MbCrookedSpiral(); + +public : + VISITING_CLASS( MbCrookedSpiral ); + + void Init( const MbCrookedSpiral & init ); + void Init( const MbPlacement3D & place ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Общие функции кривой \en Common functions of curve + + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & pnt ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & td ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint3D & pnt ) const; // \ru Точка на кривой \en Point on the curve + virtual void _FirstDer ( double t, MbVector3D & fd ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & sd ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & td ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + virtual double CalculateLength( double t1, double t2 ) const; + virtual void GetBasisItems( RPArray & ); + + // \ru Функции спирали \en Functions of spiral + + virtual void SetStep( double s ); // \ru Изменить шаг \en Change step + virtual double GetSpiralRadius( double t ) const; // \ru Выдать физический радиус спирали \en Get physical radius of spiral + const MbCurve & GetAxisCurve() const { return *curve; }; // \ru Выдать осевую кривую \en Get axial curve + double GetSpiralRadius() const { return radius; }; // \ru Выдать радиус \en Get radius + void SetSpiralRadius( double r ) { radius = r; }; // \ru Изменить радиус \en Change radius + bool GetCurveSense () const { return curveSense;};// \ru Выдать признак совпадения направления на спирали и оси (кривой) \en Get attribute of coincidence of the direction on the spiral and axis (curve) + +private: + void GetFirstDerNormW ( const MbVector & fDerW, const MbVector & sDerW, MbVector & fdNormW ) const; // \ru Выдать первую производную нормали по параметру кривой оси \en Get the first derivative of normal vector with respect to parameter of axis curve + void GetSecondDerNormW ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW, MbVector & sdNormW ) const; // \ru Выдать вторую производную нормали по параметру кривой оси \en Get the second derivative of normal vector with respect to parameter of axis curve + void GetThirdDerNormW ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW, MbVector & tdNormW ) const; // \ru Выдать третью производную нормали по параметру кривой оси \en Get the third derivative of normal vector with respect to parameter of axis curve + void GetFirstDerNormT ( const MbVector & fDerW, const MbVector & sDerW, MbVector & fdNorm ) const; // \ru Выдать первую производную нормали по параметру спирали \en Get the first derivative of normal vector with respect to parameter of the spiral + void GetSecondDerNormT ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW, MbVector & sdNorm ) const; // \ru Выдать вторую производную нормали по параметру спирали \en Get the second derivative of normal vector with respect to parameter of the spiral + void GetThirdDerNormT ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW, MbVector & tdNorm ) const; // \ru Выдать третью производную нормали по параметру спирали \en Get the third derivative of normal vector with respect to parameter of the spiral + void GetFirstDerT ( const MbVector & fDerW, MbVector & fd ) const; // \ru Выдать первую производную кривой оси по параметру спирали \en Get the first derivative of axis curve with respect to parameter of the spiral + void GetSecondDerT ( const MbVector & fDerW, const MbVector & sDerW, MbVector & sd ) const; // \ru Выдать вторую производную кривой оси по параметру спирали \en Get the second derivative of axis curve with respect to parameter of the spiral + void GetThirdDerT ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW, MbVector & td ) const; // \ru Выдать третью производную кривой оси по параметру спирали \en Get the third derivative of axis curve with respect to parameter of the spiral + double GetFirstDerParamT ( const MbVector & fDerW ) const; // \ru Выдать первую производную параметра кривой оси по параметру спирали \en Get the first derivative of axis curve parameter with respect to parameter of the spiral + double GetSecondDerParamT( const MbVector & fDerW, const MbVector & sDerW ) const; // \ru Выдать вторую производную параметра кривой оси по параметру спирали \en Get the second derivative of axis curve parameter with respect to parameter of the spiral + double GetThirdDerParamT ( const MbVector & fDerW, const MbVector & sDerW, const MbVector & tDerW ) const; // \ru Выдать третью производную параметра кривой оси по параметру спирали \en Get the third derivative of axis curve parameter with respect to parameter of the spiral + void GetCurveParams ( double tSense, MbCartPoint & point, MbDirection & normal, + MbVector & fDerW, MbVector & sDerW, MbVector & tDerW ) const; // \ru Параметры кривой оси, соответствующие параметру спирали t \en Parameters of axis curve corresponding to the parameter t of the spiral + void CalculateParams (); // \ru Посчитать параметры спирали (параметрические сдвиги от начала кривой) и параметры кривой. \en Calculate parameters of spiral (parametric shifts from the beginning of the curve) and parameters of "curve". + bool NearestLeftParams ( double tSense, c3d::DoublePair & paramPair ) const; // \ru Ближайшая слева пара параметров спирали и кривой. \en Nearest left parameters pair of spiral and "curve". + +private: + void operator = ( const MbCrookedSpiral & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCrookedSpiral ) +}; // MbCrookedSpiral + +IMPL_PERSISTENT_OPS( MbCrookedSpiral ) + +#endif // __CUR_CROOKET_SPIRAL_H diff --git a/C3d/Include/cur_cubic_spline.h b/C3d/Include/cur_cubic_spline.h new file mode 100644 index 0000000..36054e6 --- /dev/null +++ b/C3d/Include/cur_cubic_spline.h @@ -0,0 +1,394 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кубический сплайн в двумерном пространстве. + \en Cubic spline in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CUBIC_SPLINE_H +#define __CUR_CUBIC_SPLINE_H + + +#include + + +class MbCurveIntoNurbsInfo; +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кубический сплайн в двумерном пространстве. + \en Cubic spline in two-dimensional space. \~ + \details \ru Кубический сплайн определяется контрольными точками pointList и значениями параметра сплайна tList в контрольных точках. + По контрольным точкам сплайна и значениям параметра в контрольных точках рассчитываются + вторые производные сплайна vectorList в контрольных точках. + Для не замкнутой кривой множества pointList, vectorList и tList должны содержать одинаковое количество элементов. + Для замкнутой кривой количество элементов tList должно быть на единицу больше, чем количество элементов pointList и vectorList. + Кубический сплайн проходит через свои контрольные точки при значениях параметра из множества tList. + На каждом участке между двумя соседними контрольными точками сплайн описывается кубическим полиномом. + Кубические полиномы гладко стыкуются в контрольных точках и имеют в них непрерывные вторые производные. + Вторые производные между двумя соседними контрольными точками сплайна изменяются по линейному закону. + \en Cubic spline is defined by control points "pointList" and spline parameter values in the control points. + By control points of the spline and parameter values in the control points there are calculated + second derivatives of the spline vectorList in the control points. + For unclosed curve the sets pointList, vectorList and tList must contain the same number of elements. + For closed curve the number of elements tList must be one greater than the number of elements of pointList and vectorList. + Cubic spline passes through its control points for parameter values from the set tList. + On each region between two neighboring control points the spline is described by the cubic polynomial. + Cubic polynomials are smoothly connected at the control points and they have continuous second derivatives at these points. + The second derivatives between the two neighboring control points of spline are changed linearly. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbCubicSpline : public MbPolyCurve { +protected : + SArray vectorList; ///< \ru Множество вторых производных в контрольных точках. \en Set of second derivatives at the control points. + SArray tList; ///< \ru Множество параметров в контрольных точках. \en Set of parameters at the control points. + ptrdiff_t splinesCount; ///< \ru Максимальное значение индекса в множестве параметров tList. \en Maximal value of index in the parameters tList. + +protected : + MbCubicSpline(); ///< \ru Конструктор по умолчанию. \en Constructor by default. + MbCubicSpline( const MbCubicSpline & other ); ///< \ru Дублирующий конструктор. \en Duplicating constructor. + /// \ru Конструктор по заданной кривой. \en Constructor by a given curve. + MbCubicSpline( const MbCurve & ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по точкам и признаку замкнутости. + \en Constructor by points and an attribute of closedness. \~ + \param[in] points - \ru Набор узловых точек. + В случае незамкнутой кривой количество точек должно быть не меньше двух, + в случае замкнутой кривой - не меньше трех. + Если количество точек не соответствует требованиям - поведение кривой неопределено. + \en A knot set. + In the case of unclosed curve the number of points must be not less than two, + in the case of closed curve - not less than three. + If the number of points does not comply with the requirements - curve behavior is undefined. \~ + \param[in] cls - \ru Признак замкнутости кривой. + \en An attribute of curve closedness. \~ + */ + MbCubicSpline( const SArray & points, bool cls ); + + /// \ru Конструктор по точкам, вторым производным и признаку замкнутости. \en Constructor by points, second derivatives and closedness attribute. + MbCubicSpline( const SArray & points, + const SArray & seconds, bool cls ); + /// \ru Конструктор по точкам, параметрам и признаку замкнутости. \en Constructor by points, parameters and closedness attribute. + MbCubicSpline( const SArray & points, + const SArray & params, bool cls ); + /// \ru Конструктор по точкам, вторым производным, параметрам и признаку замкнутости. \en Constructor by points, second derivatives, parameters and closedness attribute. + MbCubicSpline( const SArray & points, + const SArray & seconds, + const SArray & params, bool cls ); +public : + virtual ~MbCubicSpline(); ///< \ru Деструктор. \en Destructor. + +public : + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbCubicSpline * Create( const MbCubicSpline & other ); + /** \brief \ru Создать сплайн gj rhb. + \en Create spline. \~ + \details \ru Создать сплайн по заданной кривой и установить параметры сплайна.\n + \en Create spline by a given curve and set parameters of spline.\n \~ + \param[in] curve - \ru Заданная кривая. + \en Given curve. \~ + */ + static MbCubicSpline * Create( const MbCurve & curve ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline * Create( const SArray & points, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] seconds - \ru Набор вторых производных в контрольных точках. + \en Set of second derivatives at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline * Create( const SArray & points, + const SArray & seconds, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] params - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline * Create( const SArray & points, + const SArray & params, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] seconds - \ru Набор вторых производных в контрольных точках. + \en Set of second derivatives at the control points. \~ + \param[in] params - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline * Create( const SArray & points, + const SArray & seconds, + const SArray & params, bool cls ); + +public : + VISITING_CLASS( MbCubicSpline ); + + /** \ru \name Функции инициализации сплайна. + \en \name Spline initialization functions. + \{ */ + /// \ru Инициализатор по заданной кривой. \en Initializer by a given curve. + bool Init( const MbCurve & ); + /// \ru Инициализатор по точкам и признаку замкнутости. \en Initializer by points and an attribute of closedness. + bool Init( const SArray &, bool ); + /// \ru Инициализатор по точкам, вторым производным и признаку замкнутости. \en Initializer by points, second derivatives and closedness attribute. + bool Init( const SArray &, + const SArray &, bool ); + /// \ru Инициализатор по точкам, параметрам и признаку замкнутости. \en Initializer by points, parameters and closedness attribute. + bool Init( const SArray &, + const SArray &, bool ); + /// \ru Инициализатор по точкам, вторым производным, параметрам и признаку замкнутости. \en Initializer by points, second derivatives, parameters and closedness attribute. + bool Init( const SArray &, + const SArray &, + const SArray &, bool ); + /// \ru Дублирующий инициализатор. \en Duplicating initializer. + void InitC( const MbCubicSpline & ); + /** \} */ + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA () const; // \ru Тип элемента \en Type of element + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements + virtual bool IsSame ( const MbPlaneItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой \en Whether the curve "curve" is a copy of a given curve + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbCartPoint &, const MbDirection &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions describing the domain of a curve. + \{ */ + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + Исключение составляет MbLine (прямая). + \en \name Functions for working in the domain of a curve. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct the parameter + when it is out of domain bounds. + The exception is MbLine (line). + \{ */ + virtual void PointOn ( double &, MbCartPoint & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double &, MbVector & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double &, MbVector & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double &, MbVector & ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + + // \ru четвертая производная \en Fourth derivative + void FourDer ( double &, MbVector & ) const; ///< \ru Вычислить четвертую производную. \en Calculate the fourth derivative. + void PointOnLine ( double &, MbCartPoint & ); ///< \ru Вычислить точку на кривой при линейной аппроксимации. \en Calculate a point on the curve with a linear approximation. + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Functions of the motion along the curve + \{ */ + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of approximation step with consideration of curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of approximation step with consideration of deviation angle + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual void Rebuild (); // \ru Пересчитать Безье кривую \en Recalculate Bezier curve + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change to the opposite direction of a curve + + /** \brief \ru Построить усеченную кривую. + \en Construct a trimmed curve. \~ + \details \ru Строит усеченную кривую, начало которой соответствует точке с параметром t1 и конец - точке с параметром t2. + Можно изменить направление полученной кривой относительно исходной с помощью параметра sense. + \en Constructs a trimmed curve, a start point of which corresponds to a point with parameter t1 and an end point corresponds to a point with parameter t2. + Direction of the constructed curve relative to the initial curve may be changed by the parameter 'sense'. \~ + \param[in] t1 - \ru Параметр, соответствующий началу усеченной кривой. + \en Parameter corresponding to start of a trimmed curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу усеченной кривой. + \en Parameter corresponding to end of a trimmed curve. \~ + \param[in] sense - \ru Направление усеченной кривой относительно исходной.\n + sense = 1 - направление кривой сохраняется. + sense = -1 - направление кривой меняется на обратное. + \en Direction of a trimmed curve in relation to an initial curve. + sense = 1 - direction does not change. + sense = -1 - direction changes to the opposite value. \~ + \result \ru Построенная усеченная кривая. + \en A constructed trimmed curve. \~ + */ + virtual MbCurve * Trimmed ( double t1, double t2, int sense ) const; // \ru Усечь кривую \en Trim a curve + MbCurve * TrimmedBreak( double t1, double t2, int sense ) const; // \ru Усечь кривую с разрывом \en Trim a curve with a break + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; + + // \ru Удалить часть поликривой между параметрами t1 и t2 \en Remove a part of the polyline between t1 and t2 parameters + virtual MbeState DeletePart( double, double, MbCurve *& ); + + // \ru Оставить часть поликривой между параметрами t1 и t2 \en Save a part of the polyline between t1 and t2 parameters + virtual MbeState TrimmPart( double, double, MbCurve *& ); + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + /** \} */ + /** \ru \name Общие функции полигональной кривой + \en \name Common functions of a polygonal curve + \{ */ + + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint &, double xEps, double yEps ); // \ru Добавить точку \en Add a point + virtual void ChangePoint( ptrdiff_t index, const MbCartPoint & ); // \ru Заменить точку \en Replace a point + virtual void RemovePoints(); // \ru Удалить все точки \en Remove all points + + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки кривой \en Get interval of influence of a curve point + + virtual double PointProjection( const MbCartPoint & to ) const; // \ru Проекция точки на полилинию \en Point projection on the polyline + virtual void IntersectHorizontal( double y, SArray & ) const; // \ru Пересечение кривой с горизонтальной прямой \en Intersection of a curve with a horizontal line + virtual void IntersectVertical ( double x, SArray & ) const; // \ru Пересечение с вертикальной прямой \en Intersection with a vertical line + // \ru Загнать параметр получить локальный индексы и параметры \en Drive parameter into domain, get local indices and parameters + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; + virtual double GetParam( ptrdiff_t i ) const; + virtual size_t GetParamsCount() const; + + /** \brief \ru Создание копии кривой. + \en Creation of a curve copy. \~ + \details \ru Создание копии кривой циклическим перебросом части кривой + с началом в t1 или t2 для замкнутой пространственной кривой на поверхности. + \en Creation of a curve copy by cyclic flip of a curve part + starting at t1 or t2 for a closed spatial curve on the surface. \~ + \param[in] t1 - \ru Крайний параметр с копируемой части кривой. + \en The first parameter of copied part of the curve. \~ + \param[in] t2 - \ru Крайний параметр с копируемой части кривой. + \en The second parameter of copied part of the curve. \~ + \return \ru Копия части кривой. + \en A copy of the curve part. \~ + */ + virtual MbCurve * CicleCopy( double t1, double t2 ) const; + + /** \brief \ru Подготовить вычисление сплайна. + \en Prepare the calculation of the spline. \~ + \details \ru Подготовить параметры для вычисления кубического сплайна. + Если кривая не замкнута и black = true, система решается + при условии отсутствия узла. + \en Prepare parameters for calculation of a cubic spline. + If a curve is not closed and "black" is true then the system has a solution + when knot is absent. \~ + */ + void InitCreate ( MbVector &, MbVector &, SArray &, double &, + double &, double &, double &, bool black = false ); + /// \ru Решить систему методом исключения Гаусса. \en Solve the system by Gaussian elimination method. + void Create ( MbVector &, MbVector &, bool black = false ); + /// \ru Вычислить производные на концах в случае незамкнутости сплайна. \en Calculate derivatives at the ends if the spline is not closed. + void CreateEndS ( MbVector &, MbVector & ); + /// \ru Построить сплайн если необходимо. \en Create a spline if necessary. + void Create (); + /// \ru Очистить кривую. \en Clear the curve. + void Delete (); + /// \ru Установить область изменения параметра: первый - минимальный, второй - максимальный. \en Set the range of parameter: the first is minimum, the second is maximum. + bool SetLimitParam( double newTMin, double newTMax ); + /// \ru Преобразовать в замкнутую кривую, если кривая разомкнута но концы кривой гладко стыкуются. \en Convert to a closed curve if the curve is unclosed but the ends of the curve are connected smoothly. + bool ConvertToClosed(); + virtual void SetBegEndDerivesEqual(); // \ru Установить равные производные на краях \en Set equal derivatives at the edges + virtual void ClosedBreak(); // \ru Сделать незамкнутой, оставив совпадающими начало и конец \en Make unclosed, leave coinciding start and end + /// \ru Вычисление шага аппроксимации. \en Calculation of a step of approximation. + double StepD( double &t, double sag, bool bfirst, double ang = 0.35 ) const; + + /// \ru Вернуть количество элементов в массиве векторов производных. \en Get the number of elements in array of derivative vectors. + ptrdiff_t GetVectorListCount() const { return (ptrdiff_t)/*OV_x64 (int)*/vectorList.Count(); } + /// \ru Вернуть массив вторых призводных в контрольных точках. \en Get the array of second derivatives at the control points. + void GetVectorList( SArray & vectors ) const { vectors = vectorList; } + /// \ru Выдать вектор второй производной с индексов i. \en Get the vector of the second derivative with index i. + const MbVector & GetVectorList( size_t i ) const { return vectorList[i]; } + /// \ru Выдать вектор второй производной с индексов i. \en Get the vector of the second derivative with index i. + MbVector & SetVectorList( size_t i ) { return vectorList[i]; } + + /// \ru Вернуть количество параметров в узлах. \en Get the number of parameters in knots. + ptrdiff_t GetTListCount() const { return tList.Count(); } + /// \ru Вернуть массив параметров в узлах. \en Get the array of parameters in knots. + virtual void GetTList( SArray & params ) const { params = tList; } + /// \ru Вернуть значение параметра для точки с индексом i. \en Get the value of parameter for the point with index i. + const double & GetTList( size_t i ) const { return tList[i]; } + /// \ru Вернуть число сегментов сплайна. \en Get the number of spline segments. + ptrdiff_t GetUppParam() const { return splinesCount; } + /// \ru Определение максимального индекса массива параметров слева. \en Determination of the maximum index of parameter array on the left. + ptrdiff_t GetIndex( double t ) const; + /** \} */ +private: + // \ru Найти узел в положительном направлении \en Find a knot in the positive direction + void AddKnot( ptrdiff_t &, double &, ptrdiff_t &, double &, ptrdiff_t &, double & ) const; + void CheckSpline(); // \ru Проверить корректность расчета сплайна \en Check correctness of the spline calculation + void operator = ( const MbCubicSpline & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCubicSpline ) +}; + +IMPL_PERSISTENT_OPS( MbCubicSpline ) + +//------------------------------------------------------------------------------ +/// \ru Используется в трехмерном кубическом сплайне \en It is used in the three-dimensional cubic spline +// --- +int SurStepCS( double & t, double & step, const SArray & knots, ptrdiff_t idCs, bool bplus, bool bfirst, + double & alp, double & qd, double df, double ds, double qds, double dt, + double epsAL, double epsQD ); + + +//------------------------------------------------------------------------------ +/// \ru Используется в трехмерном кубическом сплайне \en It is used in the three-dimensional cubic spline +// --- +int SurAngularStepCS( double & t, double & step, const SArray & knots, ptrdiff_t idCs, bool bplus, + double & alf, double & alt, double df, double ds, double dt, + double epsAF, double epsAT ); + + +#endif // __CUR_CUBIC_SPLINE_H diff --git a/C3d/Include/cur_cubic_spline3d.h b/C3d/Include/cur_cubic_spline3d.h new file mode 100644 index 0000000..ab23832 --- /dev/null +++ b/C3d/Include/cur_cubic_spline3d.h @@ -0,0 +1,325 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кубический сплайн. + \en Cubic spline. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_CUBIC_SPLINE3D_H +#define __CUR_CUBIC_SPLINE3D_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Кубический сплайн. + \en Cubic spline. \~ + \details \ru Кубический сплайн определяется контрольными точками pointList и значениями параметра сплайна tList в контрольных точках. + По контрольным точкам сплайна и значениям параметра в контрольных точках рассчитываются + вторые производные сплайна vectorList в контрольных точках. + Для не замкнутой кривой множества pointList, vectorList и tList должны содержать одинаковое количество элементов. + Для замкнутой кривой количество элементов tList должно быть на единицу больше, чем количество элементов pointList и vectorList. + Кубический сплайн проходит через свои контрольные точки при значениях параметра из множества tList. + На каждом участке между двумя соседними контрольными точками сплайн описывается кубическим полиномом. + Кубические полиномы гладко стыкуются в контрольных точках и имеют в них непрерывные вторые производные. + Вторые производные между двумя соседними контрольными точками сплайна изменяются по линейному закону. + \en Cubic spline is defined by control points "pointList" and spline parameter values in the control points. + By control points of the spline and parameter values in the control points there are calculated + second derivatives of the spline vectorList at the control points. + For unclosed curve the sets pointList, vectorList and tList must contain the same number of elements. + For closed curve the number of elements tList must be one greater than the number of elements of pointList and vectorList. + Cubic spline passes through its control points for parameter values from the set tList. + On each region between two neighboring control points the spline is described by the cubic polynomial. + Cubic polynomials are smoothly connected at the control points and they have continuous second derivatives at these points. + The second derivatives between the two neighboring control points of spline are changed linearly. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbCubicSpline3D : public MbPolyCurve3D { +protected : + SArray vectorList; ///< \ru Множество вторых производных в контрольных точках. \en Set of second derivatives at the control points. + SArray tList; ///< \ru Множество параметров в контрольных точках. \en Set of parameters at the control points. + ptrdiff_t splinesCount; ///< \ru Максимальное значение индекса в множестве параметров tList. \en Maximal value of index in the parameters tList. + +protected: + MbCubicSpline3D(); ///< \ru Конструктор по умолчанию. \en Constructor by default. + MbCubicSpline3D( const MbCubicSpline3D & other ); // \ru Дублирующий конструктор. \en Duplicating constructor. + // \ru Конструктор по точкам и признаку замкнутости \en Constructor by points and an attribute of closedness + MbCubicSpline3D( const SArray & points, bool cls, VERSION version = Math::DefaultMathVersion() ); + // \ru Конструктор по точкам параметрам и признаку замкнутости \en Constructor by points, parameters and an attribute of closedness + MbCubicSpline3D( const SArray & points, + const SArray & params, bool cls ); + // \ru Конструктор по точкам вторым производным и признаку замкнутости \en Constructor by points, second derivatives and closedness attribute + MbCubicSpline3D( const SArray & points, + const SArray & seconds, bool cls, VERSION version = Math::DefaultMathVersion() ); + // \ru Конструктор по точкам вторым производным параметрам и признаку замкнутости \en Constructor by points, second derivatives, parameters and an attribute of closedness + MbCubicSpline3D( const SArray & points, + const SArray & seconds, + const SArray & params, bool cls ); + // \ru Конструктор по точкам, первым производным на краях (если их надо учитывать) \en Constructor by points, first derivatives at the edges (if they should be considered) + MbCubicSpline3D( const SArray & points, + const MbVector3D & vectS, + const MbVector3D & vectE, + bool sInit, + bool eInit ); + MbCubicSpline3D( const MbCurve3D & curve ); // \ru Конструктор по другой кривой \en Constructor by another curve + // \ru Конструктор по двумерному сплайну на плоскости \en Constructor by a two-dimensional spline on the plane + MbCubicSpline3D( const MbCubicSpline & initFlat, const MbPlacement3D & plane ); +public: + virtual ~MbCubicSpline3D(); +public : + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbCubicSpline3D * Create( const MbCubicSpline3D & other ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн по заданной кривой и установить параметры сплайна.\n + \en Create spline by a given curve and set parameters of spline.\n \~ + \param[in] curve - \ru Заданная кривая. + \en Given curve. \~ + */ + static MbCubicSpline3D * Create( const MbCurve3D & curve ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] version - \ru Версия. + \en Version. \~ + */ + static MbCubicSpline3D * Create( const SArray & points, + bool cls, + VERSION version = Math::DefaultMathVersion() ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] seconds - \ru Набор вторых производных в контрольных точках. + \en Set of second derivatives at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] version - \ru Версия. + \en Version. \~ + */ + static MbCubicSpline3D * Create( const SArray & points, + const SArray & seconds, + bool cls, + VERSION version = Math::DefaultMathVersion() ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] params - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline3D * Create( const SArray & points, + const SArray & params, + bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] seconds - \ru Набор вторых производных в контрольных точках. + \en Set of second derivatives at the control points. \~ + \param[in] params - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbCubicSpline3D * Create( const SArray & points, + const SArray & seconds, + const SArray & params, + bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initFlat - \ru Плоский сплайн. + \en Plane spline. \~ + \param[in] plane - \ru Плоскость кривой. + \en Plane of curve. \~ + */ + static MbCubicSpline3D * Create( const MbCubicSpline & initFlat, const MbPlacement3D & plane ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] vectS - \ru Первая производная в начале. + \en First derivative at the begin. \~ + \param[in] vectE - \ru Первая производная в конце. + \en First derivative at the end. \~ + \param[in] sInit - \ru Учитывать ли производную в начале. + \en Use or not first derivative at the begin. \~ + \param[in] eInit - \ru Учитывать ли производную в конце. + \en Use or not first derivative at the end. \~ + */ + // \ru Конструктор по точкам, первым производным на краях (если их надо учитывать) \en Constructor by points, first derivatives at the edges (if they should be considered) + static MbCubicSpline3D * Create( const SArray & points, + const MbVector3D & vectS, + const MbVector3D & vectE, + bool sInit, + bool eInit ); +public: + VISITING_CLASS( MbCubicSpline3D ); + + // \ru Инициализатор по точкам и признаку замкнутости \en Initializer by points and an attribute of closedness + bool Init( const SArray &, bool cls, VERSION version = Math::DefaultMathVersion() ); + // \ru Инициализатор по точкам вторым производным и признаку замкнутости \en Initializer by points, second derivatives and closedness attribute + bool Init( const SArray &, const SArray &, bool cls, VERSION version = Math::DefaultMathVersion() ); + // \ru Инициализатор по точкам параметрам и признаку замкнутости \en Initializer by points, parameters and an attribute of closedness + bool Init( const SArray &, const SArray &, bool ); + // \ru Инициализатор по точкам вторым производным параметрам и признаку замкнутости \en Initializer by points, second derivatives, parameters and an attribute of closedness + bool Init( const SArray &, const SArray &, + const SArray &, bool ); + // \ru Инициализация по точкам и краевым производным \en Initialization by points and boundary derivatives + bool Init( const SArray &, const MbVector3D &, const MbVector3D &, bool, bool ); + // \ru Инициализация по точкам, параметрам и краевым производным \en Initialization by points, parameters and boundary derivatives + bool Init( const SArray &, const SArray &, + const MbVector3D &, const MbVector3D &, bool, bool ); + bool Init( const MbCurve3D & ); // \ru Инициализатор по другой кривой \en Initializer by another curve + void InitC( const MbCubicSpline3D & ); // \ru Дублирующий инициализатор \en Duplicating initializer + // \ru Инициализатор по двумерному сплайну на плоскости \en Initializer by a two-dimensional spline on the plane + void Init( const MbCubicSpline &, const MbPlacement3D & ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double &, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double &, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double &, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double &, MbVector3D & ) const; // \ru Третья производная \en Third derivative + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + void FourDer ( double &, MbVector3D & ) const; // \ru четвертая производная \en Fourth derivative + + // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual size_t GetCount() const; + virtual void Rebuild (); // \ru Перестроить кривую \en Rebuild the curve + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + virtual bool IsDegenerate( double eps = METRIC_PRECISION ) const; + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const; // \ru Создать усеченную кривую \en Create the trimmed curve + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether a curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if curve is planar + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Give a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called for a two-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + // \ru Общие функции полигональной кривой \en Common functions of a polygonal curve + + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D &, double eps ); // \ru Добавить точку \en Add a point + virtual bool ChangePoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Заменить точку \en Replace a point + virtual void RemovePoints(); // \ru Удалить все точки \en Remove all points + // \ru Загнать параметр получить локальный индексы и параметры \en Move parameter, get local indices and parameters + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; + virtual double GetParam( ptrdiff_t i ) const; // \ru Выдать параметр для точки с номером \en Get a parameter for point with number + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки кривой \en Get interval of influence of a curve point + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; + // \ru Периодичность \en Periodicity + virtual bool IsPointsPeriodic( ptrdiff_t & begPointNumber, // \ru Номер первой точки \en Number of the first point + ptrdiff_t & endPointNumber, // \ru Номер последней точки \en Number of the last point + ptrdiff_t & period ) const; // \ru Количество точек в периоде \en The number of points in the period + + void Delete(); // \ru Очистить данные \en Clear data + // \ru Подготовить вычисление сплайна \en Prepare the calculation of the spline + void InitCreate( MbVector3D &, MbVector3D &, SArray &, + double &, double &, double &, double &, bool black = false ); + + // \ru Решить систему методом исключения гауса \en Solve the system by Gaussian elimination method + // \ru Если кривая не замкнута и black = true система решается \en If a curve is non-closed and black is true then the system is solved + // \ru При условии отсутствия узла Де Бор К. "Практическое руководство по сплайнам" \en If knot is not (Carl de Boor - "A Practical Guide to Splines") + // \ru 1985, М.: Радио и связь, стр. 52. \en 2001, Springer 52. + void Create ( MbVector3D &, MbVector3D &, bool black = false ); + void CreateEndS( MbVector3D &, MbVector3D & ) const; + void Create (); // \ru Построить сплайн \en Create a spline + + void Create ( const MbVector3D &, const MbVector3D &, bool , bool ); + // \ru Вычислить параметры сплайна \en Calculate parameters of the spline + void CreateVects( const MbVector3D & startS, bool startFirst, + const MbVector3D & endS, bool endFirst ); + // \ru Установить область изменения параметра первый минимальный второй максимальный \en Set the range of the parameter: first minimum and second maximum + bool SetLimitParam( double, double ); + bool ConvertToClosed(); // \ru Преобразовать в замкнутую кривую если кривая разомкнута \en Convert to a closed curve if the curve is open + // \ru Но концы кривой гладко стыкуются \en But the ends of the curve are connected smoothly + double StepD( double t, double sag, bool bfirst, double angle = Math::lowRenderAng ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + + ptrdiff_t GetVectorListCount() const { return (ptrdiff_t)vectorList.Count(); } + void GetVectorList( SArray & vectors ) const { vectors = vectorList; } ///< \ru Вторые призводные в хар. точках \en Second derivatives at control points. + const MbVector3D & GetVectorList( size_t i ) const { return vectorList[i]; } // \ru Вторые призводные в характеристических точках \en Second derivatives at control points. + MbVector3D & SetVectorList( size_t i ) { return vectorList[i]; } // \ru Вторые призводные в характеристических точках \en Second derivatives at control points. + + ptrdiff_t GetTListCount() const { return tList.Count(); } ///< \ru Количество параметров в узлах \en The number of parameters in knots. + void GetTList( SArray & params ) const { params = tList; } ///< \ru Параметры в узлах \en Parameters in knots + const double & GetTList( size_t i ) const { return tList[i]; } + + ptrdiff_t GetUppParam() const { return splinesCount; } ///< \ru число сегментов \en The number of segments + + +private: + // \ru Найти узел в положительном направлении \en Find a knot in the positive direction + void AddKnot( ptrdiff_t &, double &, ptrdiff_t &, double &, ptrdiff_t &, double & ) const; + void CheckSpline() const; // \ru Проверить корректность расчета сплайна \en Check correctness of the spline calculation + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbCubicSpline3D & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCubicSpline3D ) +}; + +IMPL_PERSISTENT_OPS( MbCubicSpline3D ) + +#endif // __CUR_CUBIC_SPLINE3D_H diff --git a/C3d/Include/cur_curve_spiral.h b/C3d/Include/cur_curve_spiral.h new file mode 100644 index 0000000..ee06016 --- /dev/null +++ b/C3d/Include/cur_curve_spiral.h @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Спираль переменного радиуса, именяющегося в соответствии с образующей кривой. + \en Spiral with a variable radius which changes according to the generating curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUC_CURVE_SPIRAL_H +#define __CUC_CURVE_SPIRAL_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Спираль переменного радиуса. + \en Spiral with a variable radius. \~ + \details \ru Спираль переменного радиуса, именяющегося в соответствии с образующей кривой curve. \n + Образующая кривая является двумерной и располагается в плоскости ZX локальной системы координат спирали. + Радиус спирали равен второй координате точки образующей кривой. + Ось спирали направлена вдоль оси Z локальной системы координат. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + r(t) = position.origin + (position.axisZ step t / 2pi) + (position.axisX radius cos(t)) + (position.axisY radius sin(t)), + где radius = curve(w).y; + \en Spiral with a variable radius which are changed according to the generating curve "curve". \n + Generating curve is two-dimensional and located in the ZX plane of the local coordinate system. + A spiral radius is equal to the second point coordinate of generating curve. + A spiral axis is directed along the Z-axis of the local coordinate system. \n + The radius-vector of curve in the method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + r(t) = position.origin + (position.axisZ step t / 2pi) + (position.axisX radius cos(t)) + (position.axisY radius sin(t)), + where radius = curve(w).y; \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbCurveSpiral : public MbSpiral { +protected: + MbCurve * curve; ///< \ru Кривая, задающая закон изменения радиуса. \en Curve which determines the rule of radius changing. + double wMin; ///< \ru Минимальное значение параметра кривой curve. \en Minimal parameter value of curve "curve". + double wMax; ///< \ru Максимальное значение параметра кривой curve. \en Maximal parameter value of curve "curve". + bool curveSense; ///< \ru Совпадение направления оси спирали с направлением кривой curve. \en The coincidence of the direction of the spiral axis with the direction of the curve "curve". + +public: + MbCurveSpiral( const MbPlacement3D & pl, double rad, double s, double t1, double t2 ); // \ru Цилиндрическая спираль \en Cylindrical spiral + MbCurveSpiral( const MbPlacement3D & pos, MbCurve & lawCurve, double s, bool same ); // \ru Спираль с образующей кривой \en Spiral with a generating curve + +protected: + MbCurveSpiral( const MbCurveSpiral & init ); + +public : + virtual ~MbCurveSpiral(); + +public: + VISITING_CLASS( MbCurveSpiral ); + + void Init( const MbCurveSpiral & init ); + void Init( const MbPlacement3D & place ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems( RPArray & ); + + // \ru Общие функции кривой \en Common functions of curve + + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & pnt ) const ; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector3D & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & td ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint3D & pnt ) const ; // \ru Точка на кривой \en Point on curve + virtual void _FirstDer ( double t, MbVector3D & fd ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & sd ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & td ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + + // \ru Функции спирали \en Functions of spiral + + virtual void SetStep( double s ); // \ru Изменить шаг \en Change step + virtual double GetSpiralRadius ( double t ) const; // \ru Выдать физический радиус спирали \en Get physical radius of spiral + +protected: + void Init( bool setLimits ); + double GetRadiusValue( double t, double & r0, MbVector & derive ) const; // \ru Выдать радиус спирали \en Get the spiral radius + void GetRadiusDerivative( MbVector & derive, double & r1 ) const; // \ru Выдать первую производную радиуса \en Get the first derivative of the radius + void GetRadiusDerivatives( double wPar, MbVector & derive, double & r1, double & r2, double & r3 ) const; // \ru Выдать первую, вторую и третью производные радиуса \en Get the first, second and third derivatives of the radius + +private: + void operator = ( const MbCurveSpiral & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveSpiral ) +}; // MbCurveSpiral + +IMPL_PERSISTENT_OPS( MbCurveSpiral ) + +#endif // __CUC_CURVE_SPIRAL_H diff --git a/C3d/Include/cur_hermit.h b/C3d/Include/cur_hermit.h new file mode 100644 index 0000000..1196811 --- /dev/null +++ b/C3d/Include/cur_hermit.h @@ -0,0 +1,491 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cоставной кубический сплайн Эрмитa в двумерном пространстве. + \en Composite Hermite cubic spline in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_HERMIT_H +#define __CUR_HERMIT_H + + +#include +#include +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Составной кубический сплайн Эрмитa в двумерном пространстве. + \en Composite Hermite cubic spline in two-dimensional space. \~ + \details \ru Составной кубический сплайн Эрмитa определяется контрольными точками pointList, первыми производными + сплайна vectorList в контрольных точках и значениями параметра сплайна tList в контрольных точках. + Для не замкнутой кривой множества pointList, vectorList и tList должны содержать одинаковое количество элементов. + Для замкнутой кривой количество элементов tList должно быть на единицу больше, чем количество элементов pointList и vectorList. + Сплайн Эрмитa является составной кубический кривой. + На каждом участке между двумя соседними контрольными точками сплайн описывается кубическим полиномом + с заданными точками и производными на краях. + Сплайн Эрмитa проходит через свои контрольные точки при значениях параметра из множества tList и имеет в них заданные производные. + Кубические полиномы гладко стыкуются в контрольных точках и имеют в них непрерывные первые производные. + Если производные в контрольных точках не заданы, то они рассчитываются по данной контрольной точке и двух её соседним точкам. + Для этого то трём точкам и значениям параметров в них строится парабола и вычисляется производная параболы в средней точке. + Производные в краевых контрольных точках определяются по двум точкам и условию на краю для второй производной (ноль). + \en Composite Hermite cubic spline is defined by control points pointList, the first derivatives + of spline vectorList in control points and values of the spline parameter in control point. + For unclosed curve the sets pointList, vectorList and tList must contain the same number of elements. + For closed curve the number of elements tList must be one greater than the number of elements of pointList and vectorList. + Hermite spline is a composite cubic curve. + On each region between two neighboring control points the spline is described by the cubic polynomial + with given points and derivatives at the edges. + Hermite spline passes through its control points for parameter values ??from the set tList and has in them given derivatives. + Cubic polynomials are connected smoothly at the control points and they have continuous first derivatives at these points. + If the derivatives at the control points are not specified then they are calculated by the given control point and its two neighboring points. + For this purpose parabola is constructed by three points and the values ??of parameters in these points, and after this the derivative of parabola is calculated at the middle point. + Derivatives at the boundary control points are defined by two points and the condition on the edge for the second derivative (zero). \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbHermit : public MbPolyCurve { +protected : + SArray vectorList; ///< \ru Множество производных в контрольных точках. \en Set of derivatives at the control points. + SArray tList; ///< \ru Множество параметров в контрольных точках. \en Set of parameters at the control points. + ptrdiff_t splinesCount; ///< \ru Количество сплайнов. \en The number of splines. + +protected: + MbHermit(); ///< \ru Конструктор по умолчанию. \en Constructor by default. + MbHermit( const MbHermit & ); ///< \ru Конструктор копирования. \en Copy constructor. + /** \brief \ru Конструктор по набору точек и признаку замкнутости. + \en Constructor by point set and an attribute of closedness. \~ + \details \ru Конструктор по набору точек и признаку замкнутости. + \en Constructor by point set and an attribute of closedness. \~ + \param[in] initList - \ru Массив точек кривой. + Для замкнутой кривой количество точек должно быть не меньше трех, + для разомкнутой кривой - не меньше двух. + \en An array of curve points. + For a closed curve the number of points must be no less than three, + for an open curve - no less than two. \~ + \param[in] cls - \ru Замкнутость кривой. + \en A curve closedness. \~ + */ + MbHermit( const SArray & initList, bool cls ); + + MbHermit( const SArray & initParams, const SArray & initPoints, bool cls ); + MbHermit( const SArray & initParams, const SArray & initPoints, const SArray & initVectors, bool cls ); + MbHermit( const SArray & initParams, const SArray & initPoints, const SArray & vLabels, bool cls ); + MbHermit( const MbCartPoint & p1, const MbCartPoint & p2 ); // \ru Конструктор по двум точкам \en Constructor by two points + MbHermit( double t1, const MbCartPoint & p1, const MbVector & v1, + double t2, const MbCartPoint & p2, const MbVector & v2 ); // \ru Конструктор по двум точкам и производным в этих точках \en Constructor by two points and derivatives at this points. +public : + virtual ~MbHermit(); + +public : + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbHermit * Create( const MbHermit & ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initList - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit * Create( const SArray & initList, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit * Create( const SArray & initParams, const SArray & initPoints, + bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initVectors - \ru Набор производных в контрольных точках. + \en Set of derivatives at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit * Create( const SArray & initParams, const SArray & initPoints, + const SArray & initVectors, bool cls ); + /** \brief \ru Создать сплайн, согласованный с LoftSurface. + \en Create spline, agreed with LoftSurface. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] vLabels - \ru Массив, содержащий номера соседних точек с одинаковыми производными. + \en Array, containing indexes of points with same derivative. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit * Create( const SArray & initParams, const SArray & initPoints, + const SArray & vLabels, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать прямолинейный сплайн и установить параметры сплайна.\n + \en Create a straight and set parameters of spline.\n \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + */ + static MbHermit * Create( const MbCartPoint & p1, const MbCartPoint & p2 ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] t1 - \ru Начальный параметр. + \en The initial parameter. \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] v1 - \ru Касательный вектор к кривой в начальной точке. + \en A tangent vector to the curve at the start point. \~ + \param[in] t2 - \ru Конечный параметр. + \en The final parameter. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + \param[in] v2 - \ru Касательный вектор к кривой в конечной точке. + \en A tangent vector to the curve at the end point. \~ + */ + static MbHermit * Create( double t1, const MbCartPoint & p1, const MbVector & v1, + double t2, const MbCartPoint & p2, const MbVector & v2 ); + +public : + VISITING_CLASS( MbHermit ); + + // \ru Установить параметры сплайна \en Set parameters of spline + bool Init( const SArray & initPoints, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, + const SArray & initVectors, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, + const SArray & vLabels, bool cls ); + void Init( const MbHermit & init ); + void Init( double t1, const MbCartPoint & p1, const MbVector & v1, + double t2, const MbCartPoint & p2, const MbVector & v2 ); + bool Init( double t1, double t2 ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + + // \ru Удалить часть кривой между параметрами t1 и t2 \en Delete a part of a curve between parameters t1 and t2 + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть кривой между параметрами t1 и t2 \en Save a curve part between t1 and t2 parameters + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + // \ru Создать NURBS представление кривой \en Create a NURBS representation of the curve + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + virtual MbContour * NurbsContour() const; + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en Third derivative + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of approximation step with consideration of curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности \en Calculation of approximation step by angular tolerance + + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на кривую \en Point projection on the curve + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину разомкнутой \en Calculate the open metric length + virtual bool GetWeightCentre( MbCartPoint & wc ) const; // \ru Посчитать центр тяжести кривой \en Calculate the gravity center of the curve + virtual void CalculateGabarit( MbRect & r ) const; // \ru Определить габариты \en Calculate bounding box + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness + + virtual size_t GetCount() const; + + // \ru Выдать индекс точки, ближайшей к заданной \en Get index of the nearest point to the given one + virtual ptrdiff_t GetNearPointIndex( const MbCartPoint & pnt ) const; + + virtual void Rebuild(); // \ru Пересчитать кривую \en Rebuild the curve + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + virtual void AddPoint( const MbCartPoint & pnt ); // \ru Добавить точку в конец массива \en Add a point to the end of array + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Вставить точку по индексу \en Insert a point by index + virtual void InsertPoint( double t, const MbCartPoint & pnt, double xEps, double yEps ); // \ru Вставить точку. \en Insert a point. + virtual void InsertPoint( double t, const MbCartPoint & pnt, const MbVector & v, double xEps, double yEps ); // \ru Вставить точку и производную. \en Insert a point and derivetive. + virtual void SetCurveValue( double t, const MbCartPoint & pnt, double tDelta, const MbVector & v, double xEps, double yEps ); // \ru Установить точку и производную на участке. \en Set a point and derivetive at region. + virtual void ChangePoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить точку \en Replace a point + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку \en Remove a point + void GetVector( ptrdiff_t index, MbVector & vec ) const; + MbCartPoint & SetPoint( ptrdiff_t index ); + MbVector & SetVector ( ptrdiff_t index ); + bool SetTangentVectors( const SArray & tauVectors ); // \ru vectorList[i] сделать параллельными tauVectors[i] \en Make vectorList[i] parallel to tauVectors[i] + virtual size_t GetPointsCount() const; // \ru Выдать количество точек \en Get the number of points + virtual size_t GetParamsCount() const; // \ru Выдать количество параметров \en Get the number of parameters. + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Установить параметр \en Set parameter + virtual double GetParam( ptrdiff_t index ) const; + // \ru Создание копии циклически перебросом части кривой с началом в t1 или t2 для замкнутой пространственной кривой на поверхности. \en Creation of a copy by cyclic flip of a curve part starting at t1 or t2 for a closed spatial curve on surface. + virtual MbCurve * CicleCopy( double t1, double t2 ) const; + + // \ru Выдать интервал влияния точки \en Get the interval of point influence + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; + virtual void SetBegEndDerivesEqual(); // \ru Установить равные производные на краях \en Set equal derivatives at the edges + virtual void ClosedBreak(); // \ru Сделать незамкнутой, оставив совпадающими начало и конец \en Make unclosed, leave coinciding start and end + + bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + void CalculateDerivatives(); + void SetLimitVector( int n, const MbVector & v ); + /// \ru Создать кривую путём сращивания части данной кривой с частью кривой init. \en Create a curve by joining a part of this curve with a part of "init" curve. + MbHermit * CurvesCombine( double t0, double w0, bool add, + const MbHermit & init, double t1, double w1, double koef ) const; + + size_t GetVectorListCount() const { return vectorList.Count(); } + void GetVectorList( SArray & vectors ) const { vectors = vectorList; } + const MbVector & _GetVectorList( size_t i ) const { return vectorList[i]; } + MbVector & _SetVectorList( size_t i ) { MbPolyCurve::Refresh(); return vectorList[i]; } + + size_t GetTListCount() const { return tList.Count(); } + virtual void GetTList( SArray & params ) const { params = tList; } + double _GetTList( size_t i ) const { return tList[i]; } + + // \ru Добавить точки и параметры в конец кривой в заданной последовательности. \en Parameters and points add to end successively. + bool AddPoints( SArray & params, SArray & points ); + // \ru Вставить точки и параметры в перед кривой в заданной последовательности. \en Parameters and points insetr to beg successively. + bool InsertPoints( SArray & params, SArray & points ); + + /// \ru Определение максимального индекса массива параметров слева. \en Determination of the maximum index of parameter array on the left. + ptrdiff_t GetIndex( double t ) const; + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + + /** \} */ + void LocalCoordinate( double & t, + ptrdiff_t & index1, ptrdiff_t & index2, + double & param1, double & param2, + double & paramD, double & paramW, + double & quota1, double & quota2 ) const; + +private: + bool Break( MbHermit & trimPart, double t1, double t2 ) const; // \ru Выделать часть \en Make a part + void CheckClosed( double epsilon ); // \ru Проверить и установить признак замкнутости кривой. \en Check and set closedness attribute of curve. + bool SetCorrection( size_t ind, double tDelta ); // \ru Скорректировать кривую по индексу. \en Curve correction by index. + void CalculateValues( size_t i1, size_t i2 ); // \ru Скорректировать кривую на интервале i1-i2. \en Curve correction on the interval i1-i2. + + void operator = ( const MbHermit & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbHermit ) +}; + +IMPL_PERSISTENT_OPS( MbHermit ) + +//------------------------------------------------------------------------------ +/// \ru Определение местных координат области поверхности \en Definition of local coordinates in a surface region +// --- +inline void MbHermit::LocalCoordinate( double & t, + ptrdiff_t & index1, ptrdiff_t & index2, + double & param1, double & param2, + double & paramD, double & paramW, + double & quota1, double & quota2 ) const +{ +#define EPS_NULL(a,epsilon) ((a) < epsilon && (a) > -epsilon) // проверка значения в epsilon-окрестности нуля без вызова функции ::fabs + + double tmin = tList[0]; + double tmax = tList[splinesCount]; + bool bmin = t < tmin; + + if ( bmin || t > tmax ) { // \ru Параметр вне границ \en Parameter is out of bounds + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t-tmin) / tmp) * tmp; + } + else { + if ( bmin ) { // \ru Начальный участок \en Starting piece + t = tmin; + index1 = 0; + index2 = 1; + } + else { // \ru Конечный участок \en Ending piece + t = tmax; + index1 = splinesCount - 1; + index2 = splinesCount % (uppIndex + 1); + } + param1 = tList[index1]; + param2 = tList[index1+1]; + paramD = param2 - param1; + paramW = 1.0 / paramD; + double tparam1 = t - param1; + double tparam2 = param2 - t; + if ( EPS_NULL( tparam1, DOUBLE_EPSILON ) ) { //::fabs(tparam1) < DOUBLE_EPSILON + quota1 = 1.0; + quota2 = 0.0; + } + else if ( EPS_NULL( tparam2, DOUBLE_EPSILON ) ) { // ::fabs(tparam2) < DOUBLE_EPSILON + quota1 = 0.0; + quota2 = 1.0; + } + else { + quota1 = tparam2 * paramW; + quota2 = tparam1 * paramW; + } + return; + } + } + ptrdiff_t index11 = index1 + 1; + // \ru Устанавливаем диапазон поиска \en Set the search range + if ( index11 > 0 && index1 < splinesCount ) { + param1 = tList[index1]; + param2 = tList[index11]; + if ( param1 <= t && t < param2 ) { // \ru Предыдущее значение верно \en The previous value is true + double tparam1 = t - param1; + double tparam2 = param2 - t; + index2 = index11 % (uppIndex + 1); + paramD = param2 - param1; + paramW = 1.0 / paramD; + if ( EPS_NULL( tparam1, DOUBLE_EPSILON ) ) { // ::fabs(tparam1) < DOUBLE_EPSILON + quota1 = 1.0; + quota2 = 0.0; + } + else if ( EPS_NULL( tparam2, DOUBLE_EPSILON ) ) { // ::fabs(tparam2) < DOUBLE_EPSILON + quota1 = 0.0; + quota2 = 1.0; + } + else { + quota1 = tparam2 * paramW; + quota2 = tparam1 * paramW; + } + return; + } + index2 = index11; + if ( index1>0 ) + index1--; + if ( t < tList[index1] ) + index1 = 0; + if ( index2 < splinesCount ) + index2++; + if ( t >= tList[index2] ) + index2 = splinesCount; + } + else { + index1 = 0; + index2 = splinesCount; + } + + ptrdiff_t ind, delta = index2 - index1; // \ru Диапазон \en A range + // \ru Поиск половинным делением \en Search by bisection + while ( delta > 1 ) { + ind = index1 + ( delta / (ptrdiff_t)2 ); // \ru Индекс в середине \en The index in the middle + if ( t < tList[ind] ) // \ru Если t меньше серединного параметра \en If t is less than the middle parameter + index2 = ind; // \ru Изменить правую границу \en Change the right bound + else + index1 = ind; // \ru Изменить левую границу \en Change the left bound + delta = index2 - index1; // \ru Диапазон \en A range + } + + index2 = index2 % (uppIndex + 1); + param1 = tList[index1]; + param2 = tList[index1+1]; + paramD = param2 - param1; + paramW = 1.0 / paramD; + double tparam1 = t - param1; + double tparam2 = param2 - t; + if ( EPS_NULL( tparam1, DOUBLE_EPSILON ) ) { // ::fabs(tparam1) < DOUBLE_EPSILON + quota1 = 1.0; + quota2 = 0.0; + } + else if ( EPS_NULL( tparam2, DOUBLE_EPSILON ) ) { // ::fabs(tparam2) < DOUBLE_EPSILON + quota1 = 0.0; + quota2 = 1.0; + } + else { + quota1 = tparam2 * paramW; + quota2 = tparam1 * paramW; + } + +#undef EPS_NULL +} + + +//------------------------------------------------------------------------------ +/// \ru Вычисление вектора производной в средней точке по трём точкам параболы \en Calculation of derivative vector at the middle point by three points of parabola +// pPrev = pointList[i-1] +// point = pointList[i] +// pNext = pointList[i+1] +// paramDeltaPrev = tList[i] - tList[i-1] +// paramDeltaNext = tList[i+1] - tList[i] +// derivative = vectorList[i] +// --- +inline +void HermitDerivative( const MbCartPoint & pPrev, const MbCartPoint & point, const MbCartPoint & pNext, + double paramDeltaPrev, double paramDeltaNext, + MbVector & derivative ) +{ + double dt = paramDeltaNext + paramDeltaPrev; + double dtPrev = -dt * paramDeltaPrev; + double dtNext = dt * paramDeltaNext; + if ( ::fabs(dtPrev) > Math::paramRegion && ::fabs(dtNext) > Math::paramRegion ) { + // \ru Находим из равенства производной в средней точке параболы, построенной по трём точкам \en Find from equation of the derivative at the middle point of the parabola built by three points +//double _dtPrev = 1.0 / dtPrev; // \ru Не используется из-за BUG_20548 //исправляет BUG_62835 \en Isn't used because BUG_20548 //fixes BUG_62835 +//double _dtNext = 1.0 / dtNext; // \ru Не используется из-за BUG_20548 \en Isn't used because BUG_20548 +// derivative.Set( pPrev, paramDeltaNext * _dtPrev, point, -dt * _dtPrev, +//pNext, paramDeltaPrev * _dtNext, point, -dt * _dtNext ); // \ru Ломается 2)Часть дейдвуда.c3d //модели не ломаются \en Crashes 2) Part of deadwood.c3d //models are not crash + derivative.Set( pPrev, paramDeltaNext / dtPrev, point, -dt / dtPrev, + pNext, paramDeltaPrev / dtNext, point, -dt / dtNext ); // \ru Не ломается 4)7-016.c3d \en Isn't crash 4)7-016.c3d + } + else { + if ( ::fabs(dt) > NULL_EPSILON ) + derivative = (pNext - pPrev) / dt; + } +} + + +#endif // __CUR_HERMIT_H diff --git a/C3d/Include/cur_hermit3d.h b/C3d/Include/cur_hermit3d.h new file mode 100644 index 0000000..6a48a28 --- /dev/null +++ b/C3d/Include/cur_hermit3d.h @@ -0,0 +1,451 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cоставной кубический сплайн Эрмитa. + \en Composite Hermite cubic spline. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_HERMIT3D_H +#define __CUR_HERMIT3D_H + + +#include + + +class MATH_CLASS MbHermit; + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоставной кубический сплайн Эрмитa в трёхмерном пространстве. + \en Composite Hermite cubic spline in three-dimensional space. \~ + \details \ru Cоставной кубический сплайн Эрмитa определяется контрольными точками pointList, первыми производными + сплайна vectorList в контрольных точках и значениями параметра сплайна tList в контрольных точках. + Для не замкнутой кривой множества pointList, vectorList и tList должны содержать одинаковое количество элементов. + Для замкнутой кривой количество элементов tList должно быть на единицу больше, чем количество элементов pointList и vectorList. + Сплайн Эрмитa является оставной кубический кривой. + На каждом участке между двумя соседними контрольными точками сплайн описывается кубическим полиномом + с заданными точками и производными на краях. + Сплайн Эрмитa проходит через свои контрольные точки при значениях параметра из множества tList и имеет в них заданные производные. + Кубические полиномы гладко стыкуются в контрольных точках и имеют в них непрерывные первые производные. + Если производные в контрольных точках не заданы, то они рассчитываются по данной контрольной точке и двух её соседним точкам. + Для этого то трём точкам и значениям параметров в них строится парабола и вычисляется производная параболы в средней точке. + Производные в краевых контрольных точках определяются по двум точкам и условию на краю для второй производной (ноль). + \en Composite Hermite cubic spline is defined by control points pointList, the first derivatives + of spline vectorList in control points and values of the spline parameter in control point. + For unclosed curve the sets pointList, vectorList and tList must contain the same number of elements. + For closed curve the number of elements tList must be one greater than the number of elements of pointList and vectorList. + Hermite spline is a composite cubic curve. + On each region between two neighboring control points the spline is described by the cubic polynomial + with given points and derivatives at the edges. + Hermite spline passes through its control points for parameter values ??from the set tList and has given derivatives at these points. + Cubic polynomials are connected smoothly at the control points and they have continuous first derivatives at these points. + If the derivatives at the control points are not specified then they are calculated by the given control point and its two neighboring points. + For this purpose parabola is constructed by three points and the values ??of parameters in these points, and after this the derivative of parabola is calculated at the middle point. + Derivatives at the boundary control points are defined by two points and the condition on the edge for the second derivative (zero). \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbHermit3D : public MbPolyCurve3D { +protected : + SArray vectorList; ///< \ru Множество производных в контрольных точках. \en Set of derivatives at the control points. + SArray tList; ///< \ru Множество параметров в контрольных точках. \en Set of parameters at the control points. + ptrdiff_t splinesCount; ///< \ru Количество сплайнов. \en The number of splines. + +protected : + MbHermit3D(); ///< \ru Конструктор по умолчанию. \en Constructor by default. + MbHermit3D( const MbHermit3D & ); ///< \ru Конструктор копирования. \en Copy constructor. + MbHermit3D( const SArray & initPoints, bool cls ); + MbHermit3D( const SArray & initParams, const SArray & initPoints, bool cls ); + MbHermit3D( const SArray & initParams, const SArray & initPoints, const SArray & initVectors, bool cls ); + MbHermit3D( const SArray & initParams, const SArray & initPoints, const SArray & vLabels, bool cls ); + MbHermit3D( const MbHermit &, const MbPlacement3D & ); + MbHermit3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); // \ru Конструктор по двум точкам. \en Constructor by two points. + MbHermit3D( double t1, const MbCartPoint3D & p1, const MbVector3D & v1, + double t2, const MbCartPoint3D & p2, const MbVector3D & v2 ); // \ru Конструктор по двум точкам и производным в этих точках. \en Constructor by two points and derivatives at this points. + +public: + virtual ~MbHermit3D(); + +public: + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbHermit3D * Create( const MbHermit3D & ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initList - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit3D * Create( const SArray & initList, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit3D * Create( const SArray & initParams, const SArray & initPoints, + bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initVectors - \ru Набор производных в контрольных точках. + \en Set of derivatives at the control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit3D * Create( const SArray & initParams, const SArray & initPoints, + const SArray & initVectors, bool cls ); + /** \brief \ru Создать сплайн, согласованный с LoftSurface. + \en Create spline, agreed with LoftSurface. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initParams - \ru Набор параметров в контрольных точках. + \en Set of parameters at the control points. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] vLabels - \ru Массив, содержащий номера соседних точек с одинаковыми производными. + \en Array, containing indexes of points with same derivative. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + static MbHermit3D * Create( const SArray & initParams, const SArray & initPoints, + const SArray & vLabels, bool cls ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] bezier - \ru Двумерный сплайн. + \en The two-dimensional spline. \~ + \param[in] place - \ru Локальная система координат сплайна. + \en Local coordinate system of spline. \~ + */ + static MbHermit3D * Create( const MbHermit & init, const MbPlacement3D & plane ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать прямолинейный сплайн и установить параметры сплайна.\n + \en Create a straight spline and set parameters of spline.\n \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + */ + static MbHermit3D * Create( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] t1 - \ru Начальный параметр. + \en The initial parameter. \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] v1 - \ru Касательный вектор к кривой в начальной точке. + \en A tangent vector to the curve at the start point. \~ + \param[in] t2 - \ru Конечный параметр. + \en The final parameter. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + \param[in] v2 - \ru Касательный вектор к кривой в конечной точке. + \en A tangent vector to the curve at the end point. \~ + */ + static MbHermit3D * Create( double t1, const MbCartPoint3D & p1, const MbVector3D & v1, + double t2, const MbCartPoint3D & p2, const MbVector3D & v2 ); + +public : + VISITING_CLASS( MbHermit3D ); + + // \ru Установить параметры сплайна \en Set parameters of spline + bool Init( const SArray & initPoints, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, + const SArray & initVectors, bool cls ); + bool Init( const SArray & initParams, + const SArray & initPoints, + const SArray & vLabels, bool cls ); + void Init( const MbHermit3D & ); + void Init( const MbHermit &, const MbPlacement3D & ); + void Init( double t1, const MbCartPoint3D & p1, const MbVector3D & v1, + double t2, const MbCartPoint3D & p2, const MbVector3D & v2 ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать \en Transform. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Поворот \en Rotation + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная \en Third derivative + // \ru Функции для работы внутри и вне области определения кривой. \en Functions for working inside and outside of the curve domain. \~ + virtual void _PointOn ( double t, MbCartPoint3D &p ) const; + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether a curve is planar. + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness + + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if curve is planar + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Give a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called for a two-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + // \ru Общие функции полигональной кривой \en Common functions of polygonal curve + + virtual void Rebuild(); // \ru Пересчитать кривую \en Rebuild the curve + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + virtual void AddPoint ( const MbCartPoint3D & pnt ); // \ru Добавить точку в конец массива \en Add a point to the end of array + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & pnt ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D & pnt, double metrEps ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D & pnt, const MbVector3D & der, double metrEps ); // \ru Добавить точку и производную. \en Add a point and derivetive. + virtual void SetCurveValue( double t, const MbCartPoint3D & pnt, double tDelta, const MbVector3D & der, double metrEps ); // \ru Установить точку и производную на участке. \en Set a point and derivetive at region. + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку \en Remove a point + virtual bool ChangePoint( ptrdiff_t index, const MbCartPoint3D & pnt ); // \ru Заменить точку \en Replace a point + void GetVector ( ptrdiff_t index, MbVector3D & vec ) const; + bool SetTangentVectors( const SArray & tauVectors ); // \ru vectorList[i] сделать параллельными tauVectors[i] \en Make vectorList[i] parallel to tauVectors[i] + virtual size_t GetPointsCount() const; // \ru Выдать количество точек \en Get the number of points + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки \en Get the interval of point influence + virtual ptrdiff_t GetNearPointIndex( const MbCartPoint3D & pnt ) const; // \ru Выдать индекс точки, ближайшей к заданной \en Get the point index which is nearest to the given + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Загнать параметр получить локальный индексы и параметры \en Move parameter into domain, get local indices and parameters + virtual double GetParam( ptrdiff_t i ) const; // \ru Выдать параметр для точки с номером \en Get parameter for point with index + + virtual bool NearPointProjection ( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual void GetWeightCentre( MbCartPoint3D &wc ) const; // \ru Посчитать центр тяжести кривой \en Calculate the gravity center of the curve + virtual void CalculateGabarit( MbCube & gab ) const; // \ru Вычислить габарит кривой \en Calculate the bounding box of curve + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + + // \ru Функции только 3D кривой \en Function for 3D-curve + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + + virtual size_t GetCount() const; + // \ru Установить область изменения параметра. \en Set range of parameter. + bool SetLimitParam( double newTMin, double newTMax ); + void CalculateDerivatives(); + void SetLimitVector( ptrdiff_t n, const MbVector3D & v ); + + size_t GetVectorListCount() const { return vectorList.size(); } + void GetVectorList( SArray & vectors ) const { vectors = vectorList; } + const MbVector3D & _GetVectorList( size_t i ) const { return vectorList[i]; } + MbVector3D & _SetVectorList( size_t i ) { MbPolyCurve3D::Refresh(); return vectorList[i]; } + + size_t GetTListCount() const { return tList.size(); } + void GetTList( SArray & params ) const { params = tList; } + double _GetTList( size_t i ) const { return tList[i]; } + + void LocalCoordinate( double & t, + ptrdiff_t & index1, ptrdiff_t & index2, + double & param1, double & param2, + double & paramD, double & paramW, + double & quota1, double & quota2 ) const; + ptrdiff_t GetIndex( double t ) const; +private: + bool Break( MbHermit3D & trimPart, double t1, double t2 ) const; // \ru Разбить на две части \en Split into two parts + bool SetCorrection( size_t ind, double tDelta ); // \ru Скорректировать кривую по индексу. \en Curve correction by index. + void CalculateValues( size_t i1, size_t i2 ); // \ru Скорректировать кривую на интервале i1-i2. \en Curve correction on the interval i1-i2. + + void operator = ( const MbHermit3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbHermit3D ) +}; + +IMPL_PERSISTENT_OPS( MbHermit3D ) + +//------------------------------------------------------------------------------ +// \ru Определение местных координат области поверхности \en Definition of local coordinates in a surface region +// --- +inline void MbHermit3D::LocalCoordinate( double & t, + ptrdiff_t & index1, ptrdiff_t & index2, + double & param1, double & param2, + double & paramD, double & paramW, + double & quota1, double & quota2 ) const +{ + double tmin = tList[0]; + double tmax = tList[splinesCount]; + bool bmin = t < tmin; + + if ( bmin || t > tmax ) { // \ru Параметр вне границ \en Parameter is out of bounds + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t - tmin) / tmp) * tmp; + } + else { + if ( bmin ) { // \ru Начальный участок \en Starting piece + t = tmin; + index1 = 0; + index2 = 1; + } + else { // \ru Конечный участок \en Ending piece + t = tmax; + index1 = splinesCount-1; + index2 = (index1 + 1) % (uppIndex + 1); + } + param1 = tList[index1]; + param2 = tList[index1+1]; + paramD = ( param2 - param1 ); + paramW = 1.0 / paramD; + if ( ::fabs(t - param1) < DOUBLE_EPSILON ) { + quota1 = 1.0; + quota2 = 0.0; + } + else if ( ::fabs(t - param2) < DOUBLE_EPSILON ) { + quota1 = 0.0; + quota2 = 1.0; + } + else { + quota1 = ( param2 - t) * paramW; + quota2 = ( t - param1) * paramW; + } + return; + } + } + + // \ru Устанавливаем диапазон поиска \en Set the search range + if ( index1>=0 && index10 ) + index1--; + if ( t < tList[index1] ) + index1 = 0; + if ( index2 < splinesCount ) + index2++; + if ( t >= tList[index2] ) + index2 = splinesCount; + } + else { + index1 = 0; + index2 = splinesCount; + } + + ptrdiff_t ind, delta = index2 - index1; // \ru Диапазон \en A range + + // \ru Поиск половинным делением \en Search by bisection + while ( delta>1 ) { + ind = index1 + ( delta / (ptrdiff_t)2 ); // \ru Индекс в середине \en The index in the middle + if ( t < tList[ind] ) // \ru Если t больше серединного параметра \en If t is greater than the middle parameter + index2 = ind; // \ru Изменить правую границу \en Change the right bound + else + index1 = ind; // \ru Изменить левую границу \en Change the left bound + delta = index2 - index1; // \ru Диапазон \en A range + } + index2 = index2 % (uppIndex+1); + param1 = tList[index1]; + param2 = tList[index1+1]; + paramD = ( param2 - param1 ); + paramW = 1.0 / paramD; + if ( ::fabs(t - param1) < DOUBLE_EPSILON ) { + quota1 = 1.0; + quota2 = 0.0; + } + else if ( ::fabs(t - param2) < DOUBLE_EPSILON ) { + quota1 = 0.0; + quota2 = 1.0; + } + else { + quota1 = ( param2 - t ) * paramW; + quota2 = ( t - param1 ) * paramW; + } +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление вектора производной в средней точке по трём точкам параболы \en Calculation of derivative vector at the middle point by three points of parabola +// pPrev = pointList[i-1] +// point = pointList[i] +// pNext = pointList[i+1] +// paramDeltaPrev = tList[i] - tList[i-1] +// paramDeltaNext = tList[i+1] - tList[i] +// derivative = vectorList[i] +// --- +inline +void HermitDerivative( const MbCartPoint3D & pPrev, const MbCartPoint3D & point, const MbCartPoint3D & pNext, + double paramDeltaPrev, double paramDeltaNext, + MbVector3D & derivative ) +{ + double dt = paramDeltaNext + paramDeltaPrev; + double dtPrev = -dt * paramDeltaPrev; + double dtNext = dt * paramDeltaNext; + if ( ::fabs(dtPrev) > Math::paramRegion && ::fabs(dtNext) > Math::paramRegion ) { + // \ru Находим из равенства производной в средней точке параболы, построенной по трём точкам \en Find from equation of the derivative at the middle point of the parabola built by three points + double _dtPrev = 1.0 / dtPrev; + double _dtNext = 1.0 / dtNext; + derivative.Set( pPrev, paramDeltaNext * _dtPrev, point, -dt * _dtPrev, + pNext, paramDeltaPrev * _dtNext, point, -dt * _dtNext ); // \ru Не ломается 2)Часть дейдвуда.c3d \en Isn't crash 2)Part of deadwood.c3d +// derivative.Set( pPrev, paramDeltaNext / dtPrev, point, -dt / dtPrev, +//pNext, paramDeltaPrev / dtNext, point, -dt / dtNext ); // \ru Ломается 4)7-016.c3d \en // crashed 4)7-016.c3d + } + else { + if ( ::fabs(dt) > NULL_EPSILON ) + derivative = (pNext - pPrev) / dt; + } +} + + +#endif // __CUR_HERMIT3D_H diff --git a/C3d/Include/cur_line.h b/C3d/Include/cur_line.h new file mode 100644 index 0000000..0baa480 --- /dev/null +++ b/C3d/Include/cur_line.h @@ -0,0 +1,313 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Прямая в двумерном пространстве. + \en Line in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_LINE_H +#define __CUR_LINE_H + + +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Прямая в двумерном пространстве. + \en Line in two-dimensional space. \~ + \details \ru Прямая линия ведёт себя как бесконечный объект, хотя в своих данных имеет граничные значения параметра tmin и tmax. + В отличие от других кривых в методах вычисления радиуса-вектора и его производных прямая не корректирует параметр t при его выходе за предельные значения tmin и tmax. \n + Радиус-вектор прямой описывается векторной функцией \n + r(t) = origin + (t direction). + \en Straight line behaves as an infinite object although its data has boundary parameter values tmin and tmax. + In contrast to curves in the calculation methods of radius-vector and its derivatives the line doesn't correct parameter "t" if it is outside the values tmin and tmax. \n + Radius-vector of line is described by the vector function \n + r(t) = origin + (t direction). \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbLine : public MbCurve { +private : + MbCartPoint origin; ///< \ru Начальная точка. \en Start point. + MbDirection direction; ///< \ru Вектор направления. \en A direction vector. + +public : + MbLine(); + MbLine( const MbCartPoint & initP, const MbDirection & initDirect ); + MbLine( const MbCartPoint & initP, const MbVector & initV ); + MbLine( const MbCartPoint & initP, double angle ); // \ru Прямая по точке и углу \en Line by a point and angle + MbLine( const MbCartPoint & p1, const MbCartPoint & p2 ); // \ru Прямая по двум точкам (в случае совпадения точек принимается горизонтальное направление) \en Line by two points (in the case of points coincidence the horizontal direction is taken) + MbLine( double a, double b, double c ); // \ru Инициализация прямой по коэффициентам \en Initialization of a line by coefficients +//protected : + MbLine( const MbLine & ); +public : + virtual ~MbLine(); + +public : + VISITING_CLASS( MbLine ); + + /** \ru \name Функции инициализации прямой. + \en \name Line initialization functions. + \{ */ + // \ru Различные варианты инициализации прямой \en Different variants for the initialization of line + void Init( const MbLine & other ) { origin = other.origin; direction = other.direction; } + void Init( const MbCartPoint & pnt, double angle ) { origin = pnt; direction = angle; } + void Init( const MbCartPoint & pnt, const MbDirection & dir ) { origin = pnt; direction = dir; } + void Init( const MbCartPoint & pnt, const MbVector & dir ) { origin = pnt; direction = dir; } + void Init( const MbCartPoint & p1, const MbCartPoint & p2 ) { origin = p1; direction.Calculate( p1, p2 ); } + void Init( double a, double b, double c ); // \ru Инициализация прямой по коэффициентам \en Initialization of a line by coefficients + + /** \} */ + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSimilar( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the 'curve' curve is duplicate of current curve. + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void AddYourGabaritTo ( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к \en Add bounding box into a straight box + virtual void AddYourGabaritMtr( MbRect &, const MbMatrix & ) const; // \ru Добавь в прям-к свой габарит с учетом матрицы \en Add bounding rectangle into a box with consideration of the matrix + + virtual void CalculateGabarit ( MbRect & ) const; // \ru Рассчитать габарит кривой. \en Calculate bounding rectangle. + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding rectangle into local coordinate system. + + virtual bool IsVisibleInRect( const MbRect &, bool exact = false ) const; // \ru Виден ли объект в заданном прям-ке \en Whether the object is visible in the given rectangle + using MbCurve::IsVisibleInRect; + virtual double DistanceToPoint( const MbCartPoint & ) const; // \ru Расстояние до точки \en Distance to a point + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions describing the domain of a curve. + \{ */ + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Functions for working in the domain of a curve. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct the parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Function for working inside and outside of the curve domain. + Function _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct a parameter + when it is outside domain. If non-closed curve is outside of the domain + in the general case it continues along a tangent, which it has at the respective end. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual MbCurve * Offset( double rad ) const; // \ru Смещение прямой \en Shift of line + + // \ru Удалить часть прямой между параметрами t1 и t2 \en Remove a part of the line between t1 and t2 parameters + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + + // \ru Оставить часть прямой между параметрами t1 и t2 \en Save a part of the line between t1 and t2 parameters + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + virtual MbCurve * Trimmed ( double t1, double t2, int sense ) const; + + virtual bool HasLength( double & ) const; // \ru Метрическая длина \en The metric length + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + + // \ru Вычисление минимальной длины кривой между двумя точками на ней \en Calculation of minimal length of a curve between two points on it + virtual double LengthBetween2Points( MbCartPoint & p1, MbCartPoint & p2, + MbCartPoint * pc = NULL ) const; + + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of approximation step with consideration of deviation angle + + double DistanceToPointSign( const MbCartPoint & to ) const; // \ru Расстояние от прямой до точки со знаком \en Signed distance from the line to the point + + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru iloc_InItem = 1 - точка находится слева от прямой, \en Iloc_InItem = 1 - point is located to the left of the line, + // \ru iloc_OnItem = 0 - точка находится на прямой, \en Iloc_OnItem = 0 - point is located on the line, + // \ru iloc_OutOfItem = -1 - точка находится справа от прямой. \en Iloc_OutOfItem = -1 - point is located to the right of the line. + virtual MbeItemLocation PointRelative ( const MbCartPoint & p, double eps = Math::LengthEps ) const; + virtual double PointProjection ( const MbCartPoint & ) const; // \ru Проекция точки на кривую \en Point projection on the curve + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + // \ru Вычисление всех перпендикуляров к кривой из данной точки \en Calculation of all perpendiculars to the curve from a given point + virtual void PerpendicularPoint( const MbCartPoint & pnt, SArray & tFind ) const; + + virtual bool GetMiddlePoint ( MbCartPoint & ) const; // \ru Выдать среднюю точку кривой \en Calculate a middle point on a curve + virtual bool GetWeightCentre( MbCartPoint & ) const; // \ru Выдать центр прямой \en Get the center of line + + bool operator == ( const MbLine & ) const; // \ru Проверка на равенство \en Check for equality + bool operator != ( const MbLine & ) const; // \ru Проверка на неравенство \en Check for inequality + + bool IsHorizontal( double eps = Math::AngleEps ) const { return ::fabs( direction.ay ) < eps; } // \ru Проверка горизонтальности \en Check for horizontality + bool IsVertical ( double eps = Math::AngleEps ) const { return ::fabs( direction.ax ) < eps; } // \ru Проверка вертикальности \en Check for verticality + + bool IsSimilar ( const MbLine & ) const; // \ru Проверка одинаковости двух прямых \en Check for sameness of two lines + bool IsParallel( const MbLine & other, double epsilon = Math::AngleEps ) const; // \ru Проверка параллельности двух прямых \en Check for parallelism of two lines + double DistanceToParallel( const MbLine & ) const; // \ru Расстояние до параллельной прямой \en The distance to the parallel line + + virtual void IntersectHorizontal( double y, SArray & cross ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with the horizontal line + virtual void IntersectVertical ( double x, SArray & cross ) const; // \ru Пересечение с вертикальной прямой \en Intersection with the vertical line + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change to the opposite direction of a curve + virtual bool IsClosed() const; // \ru Проверка замкнутости \en Check for closedness + virtual bool IsBounded() const; // \ru Определить, является ли кривая ограниченной. \en Define whether the curve is bounded. + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness + + // \ru Дать приращение параметра, соответствующее единичной длине в пространстве \en Get increment of parameter, corresponding to the unit length in space + virtual double GetParamToUnit() const; + virtual double GetParamToUnit( double t ) const; + + void SetPoint( const MbCartPoint & pnt ) { origin = pnt; } // \ru Установить новую базовую точку \en Set the new base point + void GetPoint( MbCartPoint & pnt ) const { pnt = origin; } // \ru Выдать базовую точку \en Get the base point + void GetDirection( MbDirection & dir ) const { dir = direction; } // \ru Выдать вектор наклона прямой \en Get the vector of a line inclination + void SetDirection( const MbDirection & dir ) { direction = dir; } // \ru Установить вектор наклона прямой \en Set the vector of a line inclination + void SetDirection( const MbVector & v ) { direction = v; } + + void SetAngle( double angle ) { direction = angle; } // \ru Установить новый угол \en Set the new angle + double GetAngle() const { return direction.DirectionAngle(); } // \ru Выдать значение угла наклона \en Get the value of an angle inclination + + // \ru Создать NURBS представление кривой \en Create a NURBS representation of the curve + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS copy of the curve + virtual MbContour * NurbsContour() const; + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en The number of partitions for passage in the operations + + ptrdiff_t IntersectRect( MbRect & rect, MbCartPoint * cross ) const; // \ru Пересечение прямой с прямоугольником \en Intersection of a line with rectangle + void Implicit( double & A, double & B, double & C ) const; // \ru Выдать коэффициенты неявного представления \en Get coefficients of implicit representation + + const MbCartPoint & GetOrigin() const { return origin; } + const MbDirection & GetDirection() const { return direction; } + MbCartPoint & SetOrigin() { return origin; } + MbDirection & SetDirection() { return direction; } + + MbCartPoint Origin() const { MbCartPoint p( origin ); return p; } + MbVector Derive() const { MbVector v( direction.ax, direction.ay ); return v; } + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + +private: + void operator = ( const MbLine & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLine ) +}; // MbLine + +IMPL_PERSISTENT_OPS( MbLine ) + +//------------------------------------------------------------------------------ +// \ru Расстояние от прямой до точки со знаком \en Signed distance from the line to the point +// --- +inline double MbLine::DistanceToPointSign( const MbCartPoint & to ) const { + return direction.ax * ( to.y - origin.y ) - direction.ay * ( to.x - origin.x ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbLine::operator == ( const MbLine & with ) const { + return (origin == with.origin) && ( direction.Colinear( with.direction ) ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbLine::operator != ( const MbLine & with ) const { + return !(*this == with); +} + +//------------------------------------------------------------------------------ +// \ru Проверка параллельности двух прямых \en Check for parallelism of two lines +// --- +inline bool MbLine::IsParallel( const MbLine & other, double epsilon ) const { + return fabs( direction.ay * other.direction.ax - + direction.ax * other.direction.ay ) < epsilon; +} + +//------------------------------------------------------------------------------ +// \ru Проверка одинаковости двух прямых \en Check for sameness of two lines +// --- +inline bool MbLine::IsSimilar( const MbLine & other ) const { + return IsParallel( other ) && fabs( DistanceToPointSign( other.origin ) ) < Math::LengthEps; +} + +//------------------------------------------------------------------------------ +// \ru Расстояние до параллельной прямой \en The distance to the parallel line +// --- +inline double MbLine::DistanceToParallel( const MbLine & to ) const { + return DistanceToPoint( to.origin ); +} + +//------------------------------------------------------------------------------ +// \ru Выдать коеффициенты неявного представления \en Get coefficients of implicit representation +// --- +inline void MbLine::Implicit( double & A, double & B, double & C ) const { + A = -direction.ay; + B = direction.ax; + C = - (A*origin.x + B*origin.y); +} + + +//------------------------------------------------------------------------------ +// \ru Определение параметров t1, t2 точки пересечения прямых, заданных точкой и вектором направления \en Definition of parameters t1, t2 of the intersection point of lines given a point and a direction vector +// --- +inline bool LineLineCrossParams( const MbCartPoint & origin1, const MbVector & direction1, + const MbCartPoint & origin2, const MbVector & direction2, + double & t1, double & t2 ) +{ + double d = direction1.y * direction2.x - direction1.x * direction2.y; + + if ( ::fabs( d ) > EPSILON ) { + double dx = origin2.x - origin1.x; + double dy = origin2.y - origin1.y; + + t2 = ( direction1.x * dy - direction1.y * dx ) / d; + t1 = ( direction2.x * dy - direction2.y * dx ) / d; + + return true; + } + return false; // \ru Прямые совпадают или параллельны \en Lines coincide or are parallel +} + + +#endif // __CUR_LINE_H diff --git a/C3d/Include/cur_line3d.h b/C3d/Include/cur_line3d.h new file mode 100644 index 0000000..fe39407 --- /dev/null +++ b/C3d/Include/cur_line3d.h @@ -0,0 +1,193 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Прямая в трехмерном пространстве. + \en Line in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_LINE3D_H +#define __CUR_LINE3D_H + + +#include + + +class MATH_CLASS MbLine; + + +//------------------------------------------------------------------------------ +/** \brief \ru Прямая в трехмерном пространстве. + \en Line in three-dimensional space. \~ + \details \ru Прямая линия ведёт себя как бесконечный объект, хотя в своих данных имеет граничные значения параметра tmin и tmax. + В отличие от других кривых в методах вычисления радиуса-вектора и его производных прямая не корректирует параметр t при его выходе за предельные значения tmin и tmax. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией\n + r(t) = origin + (t direction). + \en Straight line behaves as an infinite object although its data has boundary parameter values tmin and tmax. + In contrast to curves in the calculation methods of radius-vector and its derivatives the line doesn't correct parameter "t" if it is outside the values tmin and tmax. \n + Radius-vector of the curve in the method PointOn(double&t,MbCartPoint3D&r) is described by the vector function\n + r(t) = origin + (t direction). \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbLine3D : public MbCurve3D { +private : + MbCartPoint3D origin; ///< \ru Начальная точка. \en Start point. + MbVector3D direction; ///< \ru Вектор направления. \en A direction vector. + +public : + MbLine3D(); + MbLine3D( const MbCartPoint3D & initP, const MbVector3D & initV ); + MbLine3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); +protected: + MbLine3D( const MbLine3D & ); +public : + virtual ~MbLine3D(); + +public : + VISITING_CLASS( MbLine3D ); + + void Init( const MbLine3D & init ); + void Init( const MbCartPoint3D & p0, const MbVector3D & dir ); + void Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + void Init( const MbPlacement3D & pos, const MbLine & line ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать \en Transform + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Расстояние до точки \en Distance to a point + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить габарит кривой в куб. \en Add a bounding box of a curve to a cube. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Функции кривой для работы вне области определения параметрической кривой \en Functions of curve for working outside the domain of parametric curve + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + // \ru Построить NURBS копию кривой \en Create a NURBS copy of the curve + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS copy of the curve + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + /// \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual void CalculateGabarit( MbCube & ) const; + // \ru Вычислить габарит в локальной системе координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & ) const; + + // \ru Все проекции точки на кривую \en All point projections on the curve + // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; + + bool operator == ( const MbLine3D & with ) const; // \ru Проверка на равенство \en Check for equality + bool operator != ( const MbLine3D & with ) const; // \ru Проверка на неравенство \en Check for inequality + + virtual void GetCentre ( MbCartPoint3D & c ) const; // \ru Выдать центр кривой \en Get the center of curve + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether a curve is planar + + virtual double GetParamToUnit() const; // \ru Дать приращение параметра, осреднённо соответствующее единичной длине в пространстве \en Get increment of parameter, corresponding to the unit length in space + virtual double GetParamToUnit( double t ) const; // \ru Дать приращение параметра, соответствующее единичной длине в пространстве \en Get increment of parameter, corresponding to the unit length in space + + // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + virtual MbCurve * GetMapPsp( const MbMatrix3D &, double zNear, + MbRect1D * pRgn = NULL ) const; + virtual void CalculatePolygon( const MbStepData & stepData, MbPolygon3D & ) const; // \ru pассчитать полигон \en Calculate a polygon + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + + const MbCartPoint3D & GetOrigin() const { return origin; } + const MbVector3D & GetDirection() const { return direction;} + MbCartPoint3D & SetOrigin() { return origin; } + MbVector3D & SetDirection() { return direction;} + void SetOrigin( const MbCartPoint3D & p ) { origin = p; } + void SetDirection( const MbVector3D & v ) { direction = v; } + bool RoundColinear ( const MbLine3D & with, double eps = Math::angleRegion ) const; // \ru Грубая коллинеарность \en Rough collinearity + bool Colinear ( const MbLine3D & with, double eps = Math::angleRegion ) const; // \ru Коллинеарность \en Collinearity + bool Orthogonal( const MbLine3D & with, double eps = Math::angleRegion ) const; // \ru Ортогональность \en Orthogonality + +private: + void operator = ( const MbLine3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLine3D ) +}; + +IMPL_PERSISTENT_OPS( MbLine3D ) + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbLine3D::operator == ( const MbLine3D &with ) const { + return (origin == with.origin) && ( direction.Colinear( with.direction ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbLine3D::operator != ( const MbLine3D &with ) const { + return !(*this == with); +} + + +//------------------------------------------------------------------------------ +// \ru Грубая коллинеарность по скалярному произведению \en Rough colinearity by dot product +// --- +inline bool MbLine3D::RoundColinear( const MbLine3D &with, double eps ) const { + return direction.RoundColinear( with.direction, eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Коллинеарность \en Collinearity +// --- +inline bool MbLine3D::Colinear( const MbLine3D &with, double eps ) const { + return direction.Colinear( with.direction, eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Ортогональность \en Orthogonality +// --- +inline bool MbLine3D::Orthogonal( const MbLine3D &with, double eps ) const { + return direction.Orthogonal( with.direction, eps ); +} + + +#endif // __CUR_LINE3D_H diff --git a/C3d/Include/cur_line_segment.h b/C3d/Include/cur_line_segment.h new file mode 100644 index 0000000..d9a02c6 --- /dev/null +++ b/C3d/Include/cur_line_segment.h @@ -0,0 +1,329 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Отрезок прямой в двумерном пространстве. + \en Line segment in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_LINE_SEGMENT_H +#define __CUR_LINE_SEGMENT_H + + +#include +#include + + +class MATH_CLASS MbLine; +class DiskreteLengthData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезок прямой в двумерном пространстве. + \en Line segment in two-dimensional space. \~ + \details \ru Отрезок прямой описывается начальной точкой point1 и конечной точкой point2.\n + Область определения параметра отрезка располагается в пределах от нуля до единицы. + Начальной точке отрезка point1 соответствует параметр tmin=0, конечной точке отрезка point2 соответствует параметр tmax=1.\n + Радиус-вектор отрезка описывается векторной функцией\n + r(t) = ((1 - t) point1) + (t point2).\n + \en Line segment is described by the start point "point1" and the end point "point2". \n + Domain of a line segment is the range [0, 1]. + The start point of line segment corresponds to parameter tmin=0, the end point of line segment corresponds to parameter tmax=1.\n + Radius-vector of line segment is described by the vector function \n + r(t) = ((1 - t) point1) + (t point2).\n \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbLineSegment : public MbCurve { +private : + MbCartPoint point1; ///< \ru Начальная точка. \en Start point. + MbCartPoint point2; ///< \ru Конечная точка. \en End point. + +public : + MbLineSegment(); + MbLineSegment( double u1, double v1, double u2, double v2 ) : MbCurve(), point1( u1, v1 ), point2( u2, v2 ) {} + MbLineSegment( const MbCartPoint &p1, const MbCartPoint &p2 ); + MbLineSegment( const MbCartPoint &p, const MbVector &dir, double t1, double t2 ); + MbLineSegment( const MbCartPoint &initP, double x1, double x2 ); + MbLineSegment( const MbLine & line, double t1, double t2, int sense ); + MbLineSegment( const MbLineSegment & lseg, double t1, double t2 ); + MbLineSegment( double t1, double t2, double s, bool bTIsX ); +//protected: + MbLineSegment( const MbLineSegment & ); +public : + virtual ~MbLineSegment(); + +public : + VISITING_CLASS( MbLineSegment ); + + /** \ru \name Функции инициализации отрезка. + \en \name Line segment initialization functions. + \{ */ + // \ru Установить параметры отрезка \en Set the parameters of line segment + void Init( const MbLineSegment & ); + void Init( const MbCartPoint &p1, const MbCartPoint &p2 ); + void Init( const MbCartPoint &pnt, double x1, double x2 ); + void Init( double t1, double t2 ); + void Init1( const MbCartPoint &p1, const MbCartPoint &p2, double &len, double &angle ); + void Init2( const MbCartPoint &p1, MbCartPoint &p2, const double &len, double &angle ); + void Init3( const MbCartPoint &p1, MbCartPoint &p2, double &len, const double &angle, + const DiskreteLengthData * diskrData = NULL ); + void Init4( MbCartPoint &p1, const MbCartPoint &p2, const double &len, double &angle ); + void Init5( MbCartPoint &p1, const MbCartPoint &p2, double &len, const double &angle, + const DiskreteLengthData * diskrData = NULL ); + void Init6( const MbCartPoint &p1, MbCartPoint &p2, const double &len, const double &angle ); + void Init7( MbCartPoint &p1, const MbCartPoint &p2, const double &len, const double &angle ); + void Init8( MbCartPoint &p1, MbCartPoint &p2, double &len, double &angle, + const DiskreteLengthData & diskrData, bool correctP1 ); + void Init9( const MbCartPoint & p1, MbCartPoint & p2, double & len, double & angle, + const DiskreteLengthData & diskrData, bool keepX ); + + /** \} */ + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the 'curve' curve is duplicate of current curve. + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual void AddYourGabaritTo ( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к \en Add bounding box into a straight box + virtual void CalculateGabarit ( MbRect & ) const; // \ru Определить габариты кривой \en Determine the bounding box of the curve + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const ; // \ru Добавь в прям-к свой габарит с учетом матрицы \en Add bounding box into a box with consideration of the matrix + virtual double DistanceToPoint( const MbCartPoint & to ) const; // \ru Расстояние до точки \en Distance to a point + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике \en Whether the object is visible in the given rectangle + using MbCurve::IsVisibleInRect; + virtual bool IsCompleteInRect( const MbRect & r ) const; // \ru Виден ли объект полностью в в заданном прямоугольнике \en Whether the object is entirely visible in the given rectangle + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости \en Check for closedness + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности \en Check for degeneracy + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions: PointOn, FirstDer, SecondDer, ThirdDer,... correct the parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct parameter + when it is out of domain bounds. When parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; // \ru Точка на кривой или на её продолжении \en Point on the curve or on its extension + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Function of moving by curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of approximation step with consideration of curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности \en Calculation of approximation step by angular tolerance + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common function of curve. + \{ */ + virtual double Curvature( double t ) const; // \ru Кривизна усеченной кривой \en Curvature of a trimmed curve + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление кривой \en Change direction of a curve + + virtual MbCurve * Offset( double rad ) const; // \ru Смещение отрезка \en Shift of a line segment + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS copy of the curve + + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть усеченной кривой между параметрами t1 и t2 \en Delete a part of a trimmed curve between parameters t1 and t2 + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть усеченной кривой между параметрами t1 и t2 \en Keep a part of the trimmed curve between parameters t1 and t2 + // \ru Выдать характерную точку усеченной кривой если она ближе чем dmax \en Get characteristic point of trimmed curve if it is closer than dmax + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + virtual bool IsInRectForDeform( const MbRect & r ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the specified rectangle for the deformation + + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru iloc_InItem = 1 - точка находится слева по направлению, \en Iloc_InItem = 1 - the point is on the left, + // \ru iloc_OnItem = 0 - точка находится по направлению, \en Iloc_OnItem = 0 - the point is on the direction, + // \ru iloc_OutOfItem = -1 - точка находится справа по направлению. \en Iloc_OutOfItem = -1 - the point is on the right. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на отрезок \en Point projection on the line segment + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + virtual void PerpendicularPoint( const MbCartPoint & pnt, SArray & tFind ) const; // \ru Вычисление всех перпендикуляров к кривой из данной точки \en Calculation of all perpendiculars to the curve from a given point + virtual void IntersectHorizontal( double y, SArray & cross ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with the horizontal line + virtual void IntersectVertical ( double x, SArray & cross ) const; // \ru Пересечение с вертикальной прямой \en Intersection with the vertical line + + virtual bool HasLength( double & length ) const; + virtual double GetMetricLength() const; // \ru Метрическая длина \en The metric length + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Evaluation of the metric length of the curve + // \ru Вычисление минимальной длины кривой между двумя точками на ней \en Calculation of minimal length of a curve between two points on it + virtual double LengthBetween2Points( MbCartPoint & p1, MbCartPoint & p2, MbCartPoint * pc = NULL ) const; + + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + virtual double CalculateLength( double t1, double t2 ) const; // \ru Посчитать метрическую длину отрезка от параметра t1 до t2 с заданной точностью \en Coclculate the metric length of the line segment from parameter 't1' to 't2' with the given tolerance + virtual bool GetMiddlePoint ( MbCartPoint & ) const; // \ru Выдать среднюю точку отрезка \en Get the middle point on a line segment + virtual bool GetCentre ( MbCartPoint & ) const; // \ru Выдать центр отрезка \en Get the center of a line segment + virtual bool GetWeightCentre( MbCartPoint & ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves are similar for merge (joining) + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en The number of partitions for passage in the operations + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curves equally spaced by the arc length + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + void ThroughPoint( double t, const MbCartPoint & pnt ); // \ru Пройти через точку при данном параметре \en Pass through the point in the given parameter + void InsertPoint( double t, const MbCartPoint & pnt ); // \ru Вставить точку \en Insert a point + double GetAngle() const; // \ru Выдать значение угла наклона отрезка \en Get the value of an angle inclination of a line segment + MbDirection GetDirection() const; // \ru Выдать вектор наклона отрезка \en Get the vector of a line segment inclination + bool IsParallel( const MbLineSegment & seg, double eps = Math::AngleEps ) const; // \ru Проверка параллельности двух прямых \en Check for parallelism of two lines + const MbCartPoint & GetPoint1() const { return point1; } + const MbCartPoint & GetPoint2() const { return point2; } + MbCartPoint & SetPoint1() { return point1; } + MbCartPoint & SetPoint2() { return point2; } + void GetPoint1( MbCartPoint & p ) const { p = point1; } + void GetPoint2( MbCartPoint & p ) const { p = point2; } + void SetPoint1( const MbCartPoint & p ) { point1 = p; } + void SetPoint2( const MbCartPoint & p ) { point2 = p; } + void SetLimitPoint( ptrdiff_t number, const MbCartPoint & pnt ); // \ru Заменить точку отрезка \en Replace the point of a line segment + void CheckParameter( double & t ) const; // \ru Проверка и коррекция параметра \en Check and correction of parameter + + // \ru Работа с базовой прямой \en Work with the base line + MbCartPoint Origin() const { MbCartPoint p( point1 ); return p; } + MbVector Derive() const { MbVector v( point1, point2 ); return v; } + MbDirection Direction() const { MbDirection v( point1, point2 ); return v; } + bool Extend( const MbCartPoint & point ); // \ru Удлинить отрезок до проекции точки point \en Extend line segment to projection of point "point" + double PointProjectionOnBaseLine( const MbCartPoint & pnt ) const; // \ru Проекция на прямую \en Projection on the line + double PointProjectionOnBaseLine( const MbCartPoint & pnt, MbCartPoint & proj ) const; // \ru Проекция на прямую \en Projection on the line + double DistanceToPointOnBaseLine( const MbCartPoint & pnt ) const; // \ru Расстояние от точки до проекции на прямую \en Distance from a point to a projection on the line + bool IsHorizontal( double eps = Math::paramEpsilon ) const { return ::fabs(point1.y - point2.y) < eps; } // \ru Проверка горизонтальности \en Check for horizontality + bool IsVertical ( double eps = Math::paramEpsilon ) const { return ::fabs(point1.x - point2.x) < eps; } // \ru Проверка вертикальности \en Check for verticality + +//private: + const MbLineSegment & operator = ( const MbLineSegment & ); // \ru Реализовано \en Implemented + + /** \} */ + + void ReadAsLineSeg( reader & in ); // \ru Чтение. + void WriteAsLineSeg( writer & out ) const; // \ru Запись. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLineSegment ) +}; // MbLineSegment + +IMPL_PERSISTENT_OPS( MbLineSegment ) + +//------------------------------------------------------------------------------ +// \ru Инициализировать по отрезку \en Initialize by a line segment +// --- +inline void MbLineSegment::Init( const MbLineSegment & ls ) { + point1 = ls.point1; + point2 = ls.point2; +} + +//------------------------------------------------------------------------------ +// \ru Пересчитать параметры отрезка \en Recalculate the parameters of the line segment +// --- +inline void MbLineSegment::Init( const MbCartPoint & p1, const MbCartPoint & p2 ) { + point1 = p1; + point2 = p2; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация горизонтального отрезка для штриховки \en Initialization of a horizontal segment for hatching +// --- +inline void MbLineSegment::Init( const MbCartPoint & pnt, double x1, double x2 ) { + point1 = pnt; + point2 = pnt; + point1.x += x1; + point2.x += x2; +} + +//------------------------------------------------------------------------------ +// \ru Заменить точку отрезка \en Replace the point of a line segment +// --- +inline void MbLineSegment::SetLimitPoint( ptrdiff_t number, const MbCartPoint & pnt ) +{ + if ( number == 1 ) // \ru Меняем 1-ую точку \en Change the first point + point1 = pnt; + else + point2 = pnt; +} + +//------------------------------------------------------------------------------ +// \ru Выдать значение угла наклона отрезка \en Get the value of an angle inclination of a line segment +// --- +inline double MbLineSegment::GetAngle() const { + MbDirection d0( point1, point2 ); + return d0.DirectionAngle(); +} + +//------------------------------------------------------------------------------ +// \ru Выдать вектор наклона отрезка \en Get the vector of a line segment inclination +// --- +inline MbDirection MbLineSegment::GetDirection() const { + MbDirection d0( point1, point2 ); + return d0; +} + +//------------------------------------------------------------------------------ +// \ru Проверка параллельности двух прямых \en Check for parallelism of two lines +// --- +inline bool MbLineSegment::IsParallel( const MbLineSegment & seg, double eps ) const { + MbDirection d0( point1, point2 ); + MbDirection d1( seg.point1, seg.point2 ); + return ( ::fabs( d0.ay * d1.ax - d0.ax * d1.ay ) < eps ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка и коррекция параметра \en Check and correction of parameter +// --- +inline void MbLineSegment::CheckParameter( double & t ) const { + if ( t < 0 ) t = 0; + if ( t > 1 ) t = 1; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация по другому отрезку \en Initialization by another segment +// --- +inline const MbLineSegment & MbLineSegment::operator = ( const MbLineSegment & other ) { + point1 = other.point1; + point2 = other.point2; + + return *this; +} + + +#endif // __CUR_LINE_SEGMENT_H diff --git a/C3d/Include/cur_line_segment3d.h b/C3d/Include/cur_line_segment3d.h new file mode 100644 index 0000000..10187de --- /dev/null +++ b/C3d/Include/cur_line_segment3d.h @@ -0,0 +1,154 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Отрезок прямой в трёхмерном пространстве. + \en Line segment in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_LINE_SEGMENT3D_H +#define __CUR_LINE_SEGMENT3D_H + + +#include + + +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbLine3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Отрезок прямой в трёхмерном пространстве. + \en Line segment in three-dimensional space. \~ + \details \ru Отрезок прямой описывается начальной точкой point1 и конечной точкой point2.\n + Область определения параметра отрезка располагается в пределах от нуля до единицы. + Начальной точке отрезка point1 соответствует параметр tmin=0, конечной точке отрезка point2 соответствует параметр tmax=1.\n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией\n + r(t) = ((1 - t) point1) + (t point2).\n + \en Line segment is described by the start point "point1" and the end point "point2". \n + Domain of a line segment is the range [0, 1]. + The start point of line segment corresponds to parameter tmin=0, the end point of line segment corresponds to parameter tmax=1.\n + Radius-vector of the curve in the method PointOn(double&t,MbCartPoint3D&r) is described by the vector function\n + r(t) = ((1 - t) point1) + (t point2).\n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbLineSegment3D : public MbCurve3D { +private : + MbCartPoint3D point1; ///< \ru Начальная точка. \en Start point. + MbCartPoint3D point2; ///< \ru Конечная точка. \en End point. + +public : + MbLineSegment3D() : MbCurve3D(), point1(), point2() {} + explicit MbLineSegment3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + explicit MbLineSegment3D( const MbCartPoint3D & p, const MbVector3D & v ); + explicit MbLineSegment3D( const MbCartPoint3D & p, const MbVector3D & v, double t ); + MbLineSegment3D( const MbLine3D & initLine, double t1, double t2 ); + MbLineSegment3D( const MbLineSegment &, const MbPlacement3D & plane ); +protected: + MbLineSegment3D( const MbLineSegment3D & ); +public : + virtual ~MbLineSegment3D(); + +public : + VISITING_CLASS( MbLineSegment3D ); + + // \ru Установить параметры отрезка. \en Set the parameters of line segment. + void Init( const MbLineSegment3D & ); + void Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + void Init( const MbCartPoint3D & p0, const MbVector3D & v0 ); + void Init( const MbPlacement3D &, const MbLineSegment & ); + void Init( double t1, double t2 ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Функции кривой для работы вне области определения параметрической кривой \en Functions of curve for working outside the domain of parametric curve + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить Nurbs-копию кривой \en Construct NURBS copy of the curve + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double CalculateMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; + virtual double CalculateLength( double t1, double t2 ) const; + + virtual void CalculateGabarit ( MbCube & ) const; // \ru Выдать габарит кривой \en Get the bounding box of curve + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual void GetCentre ( MbCartPoint3D & wc ) const; // \ru Посчитать центр кривой \en Calculate a center of curve + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; // \ru Посчитать центр тяжести кривой \en Calculate the gravity center of the curve + virtual double Curvature( double t ) const; // \ru Кривизна усеченной кривой \en Curvature of a trimmed curve + virtual bool NearPointProjection ( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of curve. + virtual MbCurve * GetMapPsp( const MbMatrix3D &, double zNear, MbRect1D * pRgn = NULL ) const; // \ru Дать перспективную плоскую проекцию кривой. \en Get a planar geometric projection of curve. + + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual size_t GetCount () const; + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether a curve is planar + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + virtual void CalculatePolygon( const MbStepData & stepData, MbPolygon3D & polygon ) const; // \ru Рассчитать полигон \en Calculate a polygon + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curves equally spaced by the arc length + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves are similar for merge (joining) + + const MbCartPoint3D & GetPoint1() const { return point1; } + const MbCartPoint3D & GetPoint2() const { return point2; } + MbCartPoint3D & SetPoint1() { return point1; } + MbCartPoint3D & SetPoint2() { return point2; } + void GetPoint1( MbCartPoint3D & p ) const { p = point1; } + void GetPoint2( MbCartPoint3D & p ) const { p = point2; } + void SetPoint1( const MbCartPoint3D & p ) { point1 = p; } + void SetPoint2( const MbCartPoint3D & p ) { point2 = p; } + void SetLimitPoint( ptrdiff_t number, const MbCartPoint3D &pnt ); // \ru Заменить точку отрезка \en Replace the point of a line segment + + /// \ru Является ли объект смещением \en Whether the object is a shift + virtual bool IsShift ( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + +private: + void operator = ( const MbLineSegment3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLineSegment3D ) +}; + +IMPL_PERSISTENT_OPS( MbLineSegment3D ) + +#endif // __CUR_LINE_SEGMENT3D_H diff --git a/C3d/Include/cur_nurbs.h b/C3d/Include/cur_nurbs.h new file mode 100644 index 0000000..6a64f65 --- /dev/null +++ b/C3d/Include/cur_nurbs.h @@ -0,0 +1,1020 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерная NURBS кривая. + \en Two-dimensional NURBS curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_NURBS_H +#define __CUR_NURBS_H + + +#include +#include +#include +#include +#include +#include +#include // BUG_22943, VASE2.SAT +#include +#include +#include +#include + + +class MATH_CLASS MbLine; +class MATH_CLASS MbBezier; +class MATH_CLASS MbContour; + + +//------------------------------------------------------------------------------ +/** \brief \ru NURBS кривая в двумерном пространстве. + \en NURBS curve in two-dimensional space. \~ + \details \ru NURBS кривая определяется контрольными точками pointList, + весами контрольных точек weights, узловым вектором knots и порядком сплайна degree.\n + Аббревиатура NURBS получена из первых букв словосочетания Non-Uniform Rational B-Spline. + NURBS кривая не проходит через свои контрольные точки. + Узловой вектор knots должен представлять собой неубывающую последовательность действительных чисел. + Множества pointList и weights должны содержать одинаковое количество элементов. + Для не замкнутой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс degree. + Для замкнутой кривой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс 2*degree-1. + Минимальное значение параметра сплайна равно значению элемента узлового вектора с индексом degree-1. + Максимальное значение параметра сплайна равно значению элемента узлового вектора с индексом, равным последнему элементу минус degree-1. + Расчет кривой в каждой своей точке производится на основе нормированных неоднородных В-сплайнов.\n + Семейство В-сплайнов определяется заданной неубывающей последовательностью узловых параметров и заданным порядком B-сплайна.\n + \en NURBS curve is defined by 'pointList' control points, + weights of control points ('weights'), knot vector ('knots') and order of spline ('degree').\n + Abbreviation of NURBS is obtained from the first letters of the Non-Uniform Rational B-Spline phrase. + NURBS curve doesn't pass through its control points. + 'knots' knot vector has to be not decreasing sequence of real numbers. + 'pointList' and 'weights' sets have to contain the same count of elements. + For not closed curve 'knots' knot vector has to contain the count of elements of 'pointList' set plus 'degree'. + For closed curve 'knots' knot vector has to contain the count of elements of 'pointList' set plus 2*degree-1. + Minimal value of spline parameter is equal to value of element of knot vector with degree-1 index. + Maximal value of spline parameter is equal to value of element of knot vector with index, which is equal to index of last element minus degree-1. + Curve calculation at each point is performed by normalized non-uniform B-splines.\n + Family of B-splines is defined by given crescent sequence of knot parameters and given order of B-spline.\n \~ + \ingroup Curves_2D +*/ +// --- + +class MATH_CLASS MbNurbs : public MbPolyCurve { +private: + ptrdiff_t degree; ///< \ru Порядок В-сплайна (порядок = степень + 1). \en Order of B-spline (order = degree + 1). + ptrdiff_t uppKnotsIndex; ///< \ru Последний индекс узлового вектора. \en Last index of knot vector. + SArray knots; ///< \ru Узловой вектор. \en Knot vector. + SArray weights; ///< \ru Множество весов контрольных точек. \en Set of weights of the control points. + MbeNurbsCurveForm form; ///< \ru Форма кривой. \en Form of curve. + +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbNurbsAuxiliaryData : public AuxiliaryData { + public: + double tCalc; ///< \ru Текущее значение параметра, по которому вычислены временные данные кривой. \en Current value of parameter the curve temporary data are calculated by. + double * nd; ///< \ru B - базис. \en B - basis. + MbHomogeneous * h0; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous * h1; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous * h2; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous * h3; ///< \ru Текущий сегмент. \en Current segment. + double * wc; ///< \ru Насчитанные значения весов (может быть ноль). \en Calculated values of points (can be null). + MbVector rc[cdt_CountDer]; ///< \ru Насчитанные значения точек. \en Calculated values of points. + ptrdiff_t leftIndex; ///< \ru Левый индекс узлового вектора. \en Left index of knot vector. + double * m_left; + double * m_right; + public: + MbNurbsAuxiliaryData(); + MbNurbsAuxiliaryData( const MbNurbsAuxiliaryData & init ); + virtual ~MbNurbsAuxiliaryData(); + void FreeMemory(); + bool CatchMemory( ptrdiff_t, bool ); + }; // MbNurbsAuxiliaryData + + mutable CacheManager cache; + +public://protected: + DEPRECATE_DECLARE MbNurbs(); +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по порядку, точкам, параметрам и признаку замкнутости. + При недопустимых параметрах initDegree и points поведение кривой не определено.\n + \en Constructor by order, points, parameters and an attribute of closedness. + If parameters initDegree and points is invalid then the curve behavior is undefined. \n \~ + \param[in] degree - \ru Порядок сплайна. + Должен быть больше единицы. Не должен превышать количество контрольных точек. + \en A spline order. + It must be greater than unity. It shouldn't exceed count of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. Количество точек должно быть больше или равно двум. + \en Set of control points. Count of points must be greater than or equal to two. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + Количество весов должно соответствовать количеству точек. + \en Set of weights for control points. + Count of weights must be equal to count of points. \~ + \param[in] knots - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + + */ + template + MbNurbs( ptrdiff_t degree, bool cls, const PointsVector & points, + const DoubleVector * weights, const DoubleVector * knots ); + MbNurbs( const MbNurbs & ); +public : + virtual ~MbNurbs(); + +private: + static MbNurbs * Create(); +public: + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbNurbs * Create( const MbNurbs & ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + template + static MbNurbs * Create( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed ) + { + MbNurbs * resNurbs = Create(); + if ( !resNurbs->Init( initDegree, initPoints, initClosed ) ) + ::DeleteItem( resNurbs ); + return resNurbs; + } + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] initWeights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + */ + template + static MbNurbs * Create( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed, + const DoubleVector * initWeights ) + { + MbNurbs * resNurbs = Create(); + if ( !resNurbs->Init( initDegree, initPoints, initClosed, initWeights ) ) + ::DeleteItem( resNurbs ); + return resNurbs; + } + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initWeights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] initKnots - \ru Неубывающая последовательность весов. + \en Non-decreasing sequence of weights. \~ + \param[in] initForm - \ru Тип построения. + \en Type of construction. \~ + */ + template + static MbNurbs * Create( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints, + const DoubleVector & initWeights, const DoubleVector & initKnots, + MbeNurbsCurveForm initForm = ncf_Unspecified ) + { + MbNurbs * resNurbs = Create(); + if ( !resNurbs->Init( initDegree, initClosed, initPoints, initWeights, initKnots, initForm ) ) + ::DeleteItem( resNurbs ); + return resNurbs; + } + + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Сплайн, проходящий через заданные точки при заданных параметрах.\n + В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n + \en Spline passing through given points at given parameters.\n + In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] points - \ru Набор точек, через которые проходит сплайн. + \en Set of points which the spline passes through. \~ + \param[in] params - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + */ + static MbNurbs * CreateThrough( ptrdiff_t degree, bool cls, const SArray & points, + const SArray & params ); + /** \brief \ru Заполнить NURBS по данным parasolid. + \en Fill NURBS by parasolid data. \~ + \details \ru Заполнить NURBS по данным parasolid.\n + \en Fill NURBS by parasolid data.\n \~ + \param[in] degree - \ru Степень сплайна. + \en Order of spline. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] rational - \ru Является ли кривая рациональной. Если true - строится NURBS, false - кривая Безье. + \en Whether the curve is rational. if true then NURBS is created, false - Bezier curve. \~ + \param[in] count - \ru Количество контрольных точек. + \en Count of control points. \~ + \param[in] verts - \ru Массив координат точек. Если сплайн рациональный, четвертая координата - вес точки. + \en An array of coordinates of points. If spline is rational, then the fourth coordinate - weight of point. \~ + \param[in] vertsCount - \ru Количество элементов в массиве verts. + \en Count of elements in 'verts' array. \~ + \param[in] mul - \ru Массив с данными о кратности каждого узла. + \en Array with multiplicity of each knot. \~ + \param[in] mulCount - \ru Количество элементов в массиве mul. + \en Count of elements in 'mul' array. \~ + \param[in] knots - \ru Массив со значениями параметров в узлах. Каждое значение представлено один раз. + Информация о кратности узла лежит в элементе массива mul с тем же номером. + \en Array with values of parameters at knots. Each value is presented only once. + Information about knot multiplicity is in the element of 'mul' array with the same index. \~ + \param[in] knotsCount - \ru Количество элементов в массиве knots. + \en Count of elements in 'knots' array. \~ + \param[in] scl - \ru Коэффициент масштабирования. + \en A scale factor. \~ + */ + static MbNurbs * CreateParasolid( ptrdiff_t degree, bool closed, bool rational, ptrdiff_t count, + const CcArray & verts, ptrdiff_t vertsCount, + const CcArray & mul, ptrdiff_t mulCount, + const CcArray & knots, ptrdiff_t knotsCount, + double scl ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline. \n \~ + \param[in] p1 - \ru Начальная точка, через которую проходит сплайн. + \en The initial point the spline passes through. \~ + \param[in] v1 - \ru Касательный вектор к кривой в начальной точке. + \en A tangent vector to the curve at the start point. \~ + \param[in] p2 - \ru Конечная точка, через которую проходит сплайн. + \en The final point the spline passes through. \~ + \param[in] v2 - \ru Касательный вектор к кривой в конечной точке. + \en A tangent vector to the curve at the end point. \~ + */ + static MbNurbs * CreateCube( const MbCartPoint & p1, const MbVector & v1, const MbCartPoint & p2, const MbVector & v2 ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Конструктор сплайна, описывающего дугу конического сечения.\n + \en Constructor of a spline describing the arc of a conic section. \n \~ + \param[in] points - \ru Набор из четырех точек, через которое проходит сечение. + Первая и последняя точки определяют начало и конец дуги, соответственно. + \en A set of four points the section passes through. + The first and last points define the beginning and ending of the arc respectively. \~ + */ + static MbNurbs * CreateArc( const SArray & points ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Конструктор сплайна, описывающего дугу окружности.\n + \en Constructor of a spline describing the arc of a circle. \n \~ + \param[in] a2 - \ru Половина угла раствора. + \en A half opening angle. \~ + \param[in] p1 - \ru Начальная точка дуги. + \en The starting point of the arc. \~ + \param[in] p2 - \ru Конечная точка дуги. + \en The end point of the arc. \~ + */ + static MbNurbs * CreateArc( double a2, const MbCartPoint & p1, const MbCartPoint & p2 ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Конструктор сплайна, описывающего волнистую линию.\n + \en Constructor of a spline describing a wavy line. \n \~ + \param[in] p1 - \ru Начальная точка кривой. + \en Start point of curve. \~ + \param[in] p2 - \ru Конечная точка кривой. + \en End point of curve. \~ + \param[in] height - \ru Высота гребешка волны. + \en Height of the wave. \~ + \param[in] periode - \ru Период волны. + \en Period of the wave. \~ + */ + static MbNurbs * CreateWavyLine( const MbCartPoint & p1, const MbCartPoint & p2, double height, double periode ); + +public : + VISITING_CLASS( MbNurbs ); + + /** \ru \name Функции инициализации NURBS-кривой. + \en \name Functions of NURBS curve initialization. + \{ */ + // \ru Приведенные ниже функции меняют степень degree, поэтому в них необходим вызов CatchMemory(); \en The following functions change the degree "degree" therefore they call CatchMemory(); + + /// \ru Установить параметры сплайна по заданной NURBS-кривой. \en Set the spline parameters by a given NURBS curve. + void Init( const MbNurbs & ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + */ + template + bool Init( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed ) + { + if ( ::IsValidNurbsParams( initDegree, initClosed, initPoints.size() ) ) + { + Refresh(); // Must come first, since frees allocated memory + + degree = initDegree; + form = ncf_Unspecified; + closed = initClosed; + uppIndex = (ptrdiff_t)initPoints.size() - 1; + pointList.assign( initPoints.begin(), initPoints.end() ); + weights.assign( initPoints.size(), 1.0 ); + + DefineKnotsVector(); + return true; + } + + return false; + } + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] initWeights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + */ + template + bool Init( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed, + const DoubleVector * initWeights ) + { + if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, initWeights ) ) + { + Refresh(); // Must come first, since frees allocated memory + + degree = initDegree; + form = ncf_Unspecified; + closed = initClosed; + uppIndex = (ptrdiff_t)initPoints.size() - 1; + pointList.assign( initPoints.begin(), initPoints.end() ); + + if ( initWeights != NULL ) { + if ( (ptrdiff_t)initWeights->size() == uppIndex + 1 ) + weights.assign( initWeights->begin(), initWeights->end() ); + else { + C3D_ASSERT_UNCONDITIONAL( false ); // Wrong size of weights vector + weights.assign( initPoints.size(), 1.0 ); + } + } + else { + weights.assign( initPoints.size(), 1.0 ); + } + + DefineKnotsVector(); + return true; + } + + return false; + } + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initWeights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] initKnots - \ru Неубывающая последовательность весов. + \en Non-decreasing sequence of weights. \~ + \param[in] initForm - \ru Тип построения. + \en Type of construction. \~ + */ + template + bool Init( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints, + const DoubleVector & initWeights, const DoubleVector & initKnots, + MbeNurbsCurveForm initForm = ncf_Unspecified ) + { + if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, &initWeights, &initKnots ) ) { + Refresh(); // Must come first, since frees allocated memory + + degree = initDegree; + closed = initClosed; + pointList = initPoints; + form = initForm; + weights = initWeights; + knots = initKnots; + + uppIndex = (ptrdiff_t)pointList.size() - 1; + uppKnotsIndex = (ptrdiff_t)knots.size() - 1; + + SetClamped(); + return true; + } + return false; + } + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] knots - \ru Неубывающая последовательность узлов. + \en Non-decreasing sequence of knots. \~ + \param[in] nPoints - \ru Количество контрольных точек. + \en Count of control points. \~ + \param[in] nKnots - \ru Количество узлов. + \en Count of knots. \~ + */ + bool Init( ptrdiff_t degree, bool cls, const CcArray & points, + const CcArray & knots, ptrdiff_t nPoints, ptrdiff_t nKnots ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Сплайн, проходящий через заданные точки при заданных параметрах.\n + В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n + \en Spline passing through given points at given parameters.\n + In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] cls - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] points - \ru Набор точек, через которые проходит сплайн. + \en Set of points which the spline passes through. \~ + \param[in] params - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + */ + bool InitThrough( ptrdiff_t degree, bool cls, const SArray & points, + const SArray & params ); + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализировать прямолинейный сплайн.\n + \en Initialize a straight spline. \n \~ + \param[in] t1 - \ru Начальный узел. + \en The initial knot. \~ + \param[in] p1 - \ru Начальная точка, через которую проходит сплайн. + \en The initial point the spline passes through. \~ + \param[in] t2 - \ru Конечный узел. + \en The final knot. \~ + \param[in] p2 - \ru Конечная точка, через которую проходит сплайн. + \en The final point the spline passes through. \~ + */ + bool InitLine( double t1, const MbCartPoint & p1, double t2, const MbCartPoint & p2 ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализировать кубическую кривую как сплайн.\n + \en Initialize a cubic curve as a spline. \n \~ + \param[in] p1 - \ru Начальная точка, через которую проходит сплайн. + \en The initial point the spline passes through. \~ + \param[in] v1 - \ru Касательный вектор к кривой в начальной точке. + \en A tangent vector to the curve at the start point. \~ + \param[in] p2 - \ru Конечная точка, через которую проходит сплайн. + \en The final point the spline passes through. \~ + \param[in] v2 - \ru Касательный вектор к кривой в конечной точке. + \en A tangent vector to the curve at the end point. \~ + */ + bool InitCube( const MbCartPoint & p1, const MbVector & v1, const MbCartPoint & p2, const MbVector & v2 ); + + // \ru Интерполяция. \en Interpolation. + + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн второго порядка по точкам, параметрам и признаку замкнутости. + \en Create a planar spline of second-order by points, parameters and attribute of closedness. \~ + */ + static MbNurbs * CreateNURBS2( const SArray & points, const SArray & params, bool cls ); + + /// \ru Создать кубический NURBS по точкам, через которые он проходит, и параметрам сопряжения. \en Create cubic NURBS by parameters of conjugation and points which it passes through. + static MbNurbs * CreateNURBS4( const SArray &, MbeSplineParamType spType, + const MbPntMatingData & begData, + const MbPntMatingData & endData ); + /// \ru Создать кубический NURBS по интерполяционным точкам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points and data of conjugation at each point. + static MbNurbs * CreateNURBS4( const SArray &, MbeSplineParamType spType, + bool closed, + RPArray< MbPntMatingData > & ); + /// \ru Создать кубический NURBS по интерполяционным точкам, их параметрам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points, parameters and data of conjugation at each point. + static MbNurbs * CreateNURBS4( const SArray &, const SArray &, + bool closed, + RPArray< MbPntMatingData > & ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по точкам, признаку замкнутости и типу параметризации.\n + Сплайн проходит через точки. Используется граничное условие отсутствия узла. + \en Create a planar spline of fourth order by points, attribute of closedness and parametrization type.\n + NURBS passes through points. Used boundary condition of knot absence. \~ + */ + static MbNurbs * CreateNURBS4( const SArray &, bool cls, MbeSplineParamType spType, + MbeSplineCreateType useInitThrough = sct_Version2 ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по точкам, параметрам и признаку замкнутости.\n + Используется граничное условие отсутствия узла. + \en Create a planar spline of fourth order by points, parameters and attribute of closedness.\n + Used boundary condition of knot absence. \~ + */ + static MbNurbs * CreateNURBS4( const SArray & points, const SArray & params, bool cls, + MbeSplineCreateType useInitThrough = sct_Version2 ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по весам, точкам, параметрам и признаку замкнутости.\n + Используется граничное условие отсутствия узла. + \en Create a planar spline of fourth order by weights, points, parameters and attribute of closedness.\n + Used boundary condition of knot absence. \~ + */ + static MbNurbs * CreateNURBS4( const SArray & weights, const SArray & points, + SArray & params, bool cls ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по точкам, параметрам и признаку замкнутости + с граничными условиями - заданными векторами первых или вторых производных.\n + Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций. + \en Create a planar spline of fourth order by points, parameters and attribute of closedness + with boundary conditions - given vectors of first or second derivatives.\n + Has 2 multiple internal knots, belongs to class of differentiable (but not twice differentiable) functions. \~ + \param[in] bfstS - \ru Если true, то начальное граничное условие - вектор первой производной, иначе - вектор второй производной. + \en If true, then start boundary condition is the vector of the first derivative, otherwise - the vector of the second derivative. \~ + \param[in] bfstN - \ru Если true, то конечное граничное условие - вектор первой производной, иначе - вектор второй производной. + \en If true, then end boundary condition is the vector of first derivative, otherwise - vector of second derivative. \~ + */ + static MbNurbs * CreateNURBS4( const SArray & points, const SArray & params, + const MbVector &, const MbVector &, bool cls, + bool bfstS = true, bool bfstN = true ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по точкам, производным, параметрам и признаку замкнутости.\n + Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций. + \en Create a planar spline of fourth order by points, derivatives, parameters and attribute of closedness.\n + It has 2 multiple internal knots, belongs to the class of differentiable (but not twice differentiable) functions. \~ + */ + static MbNurbs * CreateNURBS4( const SArray & points, const SArray & vectors, + const SArray & params, bool cls ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать плоский сплайн четвертого порядка по составному сплайну Безье четвертого порядка.\n + Внимание! Парамеризация отлична от параметризации исходной кривой Безье. + \en Create a planar spline of fourth order by composite Bezier spline of fourth order.\n + If closedness is necessary - call UnClamped( bezier.IsClosed() ). \~ + */ + static MbNurbs * CreateNURBS4( const MbBezier & ); + + /// \ru Установить сопряжение на конце. \en Set conjugation at the end. + bool AttachG( MbPntMatingData & connectData, bool beg ); + + /// \ru Увеличить порядок кривой, не изменяя ее геометрическую форму и параметризацию. \en Increase order of curve without changing its geometric shape and parametrization. + bool RaiseDegree ( ptrdiff_t, double relEps = Math::paramEpsilon ); + /// \ru Уменьшить порядок кривой на 1, не изменяя ее геометрическую форму и параметризацию. \en Decrease order of curve by 1 without changing its geometric shape and parametrization. + bool ReductionDegree( double relEps = Math::paramEpsilon ); + /// \ru Задать порядок сплайна. \en Set the spline order. + void SetDegree( ptrdiff_t newDegree ); + /// \ru Увеличить порядок на 1. \en Increase the order by 1. + void DegreeIncrease(); + /// \ru Установить тип формы. \en Set the type of shape. + void SetFormType( MbeNurbsCurveForm f ) { form = f; } + /// \ru Точка на кратном узле. \en The point on a multiple knot. + bool PointOnMultipleKnot( const MbCartPoint & point ) const; + + /** \} */ + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая other копией данной кривой? \en Whether the curve is duplicate of current curve. + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными. \en Make elements equal. + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот. \en Rotation. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions describing the domain of a curve. + \{ */ + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual bool IsClosed() const; // \ru Замкнутость кривой. \en A curve closedness. + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой. \en Check curve degeneracy. + virtual bool IsPeriodic() const; // \ru Периодичность замкнутой кривой. \en Periodicity of a closed curve. + + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is out of domain bounds. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & pnt ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная. \en First derivative. + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная. \en Second derivative. + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная. \en Third derivative. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + // \ru Вычислить значения производных для заданного параметра. \en Calculate derivatives of object for given parameter. \~ + void Derivatives( double & t, bool ext, MbVector & fir, MbVector * sec, MbVector * thi ) const; + + // \ru Функции, продолжающие кривую не по касательной как _PointOn() и др., а по кривой. \en Functions which do not continue curve along the tangent as _PointOn (), etc., and along a curve. + /// \ru Точка на продолжении кривой. \en Point on the curve extension. + void ExtPointOn ( double t, MbCartPoint & pnt ) const; + /// \ru Первая производная на продолжении кривой. \en The first derivative on the curve extension. + void ExtFirstDer ( double t, MbVector & fd ) const; + /// \ru Вторая производная на продолжении кривой. \en The second derivative on the curve extension. + void ExtSecondDer( double t, MbVector & sd ) const; + /// \ru Третья производная на продолжении кривой. \en The third derivative on the curve extension. + void ExtThirdDer ( double t, MbVector & td ) const; + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + // \ru Добавить габарит в прямоугольник. \en Add a bounding box to rectangle. + virtual void CalculateGabarit ( MbRect & ) const; + virtual bool IsStraight() const; // \ru Прямолинейность кривой. \en Straightness of curve. + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + // \ru Вычислить метрическую длину кривой.\en Calculate the metric length of a curve. + virtual double CalculateLength( double t1, double t2 ) const; + + virtual size_t GetCount() const; + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & tParameters ) const; // \ru Построить NURBS копию кривой. \en Construct a NURBS copy of a curve. + virtual MbContour * NurbsContour() const; + + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное. \en Set the opposite direction of curve. + + // \ru Определить, является ли кривая репараметризованно такой же. \en Define whether a reparameterized curve is the same. + virtual bool IsReparamSame( const MbCurve & curve, double & factor ) const; + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны. \en Calculation of the approximation step with consideration of the curvature radius. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности. \en Calculation of the approximation step by angular tolerance. + + virtual void CalculatePolygon( double sag, MbPolygon & ) const; + + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть поликривой между параметрами t1 и t2. \en Remove a part of the polyline between t1 and t2 parameters. + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть поликривой между параметрами t1 и t2. \en Save a part of the polyline between t1 and t2 parameters. + + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация. \en Deformation. + virtual bool GoThroughPoint( MbCartPoint &p0 ); // \ru Прохождение сплайна через точку. \en Passing of spline through the point. + virtual void TangentPoint( const MbCartPoint & pnt, SArray & tFind ) const; // \ru Вычисление всех касательных к кривой из данной точки. \en Calculation of all tangents to the curve from a given point. + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; // \ru Определение особых точек офсетной кривой. \en Determination of singular points of the offset curve. + + virtual bool GetCentre( MbCartPoint & ) const; // \ru Выдать центр кривой. \en Give the curve center. + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetAxisPoint( MbCartPoint & p ) const; // \ru Выдать центр оси кривой. \en Give the curve axis center. + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива). \en Whether the curves to union (joining) are similar. + + /// \ru Касание сплайна прямой. \en Touching the spline by line. + void MakeTangentLine( MbLine * line ); + /// \ru Определить выпуклую оболочку сегмента кривой. \en Determine the convex hull of the curve segment. + void ConvexHull( ptrdiff_t seg, MbCartPoint * p ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + /** \} */ + /** \ru \name Общие функции полигональной кривой. + \en \name Common functions of polygonal curve. + \{ */ + + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки B-сплайна. \en Get range of influence of B-spline point. + + virtual void Rebuild(); // \ru Перестроить B-сплайн. \en Rebuild B-spline. + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set the closedness attribute. + + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку. \en Remove the point. + virtual void RemovePoints(); // \ru Удалить все точки. \en Delete all points. + + virtual void AddPoint( const MbCartPoint & pnt ); // \ru Добавить точку в конец массива. \en Add point to the end of the array. + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Вставить точку по индексу. \en Insert a point by index. + virtual void InsertPoint( double t, const MbCartPoint & pnt, double xEps, double yEps ); // \ru Вставить точку. \en Insert a point. + virtual void ChangePoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить вершину pointList[index] на pnt. \en Replace the vertex pointList[index] with pnt. + virtual bool ChangePointsValue( const SArray & pntList ); // \ru Заменить точки новыми при сохранении остальных параметров. \en Replace points with new one and save the other parameters. + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Загнать параметр, получить локальный индексы и параметры. \en Move parameter, get local indices and parameters. + virtual double GetParam( ptrdiff_t i ) const; + virtual size_t GetParamsCount() const; + + virtual void ResetTCalc() const; // \ru Сбросить текущее значение параметра \en Reset the current value of the parameter + // \ru Расстояние до точки. \en The distance to a point. + virtual double DistanceToPoint( const MbCartPoint & to ) const; + // \ru Расстояние до точки, если оно меньше d. \en Distance to the point if it is less than d. + virtual bool DistanceToPointIfLess( const MbCartPoint & to, double & d ) const; + // \ru Найти проекцию точки на кривую. \en Find the point projection to the curve. + virtual double PointProjection( const MbCartPoint & pnt ) const; + // \ru Найти проекцию точки на кривую. \en Find the point projection to the curve. + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + virtual void GetStartPoint( MbCartPoint & ) const; + virtual void GetEndPoint ( MbCartPoint & ) const; + + /** \} */ + /** \ru \name Функции B-сплайна. + \en \name Functions of B-spline. + \{ */ + + /// \ru Добавить точку с весом. \en Add a point with weight. + void AddPoint( ptrdiff_t index, const MbCartPoint & pnt, double weight ); + /// \ru Добавить точку в конец массива. \en Add point to the end of the array. + void AddPoint( const MbCartPoint & pnt, double weight ); + /// \ru Сделать контур из NURBS-кривой. \en Create a contour from the NURBS curve. + MbContour * CreateContour() const; + /// \ru Выделить часть. \en Break a part. + MbNurbs * Break( double t1, double t2 ) const; + + /// \ru Получить форму В-сплайна. \en Get form of B-spline. + MbeNurbsCurveForm GetFormType() const { return form; } + + /// \ru Выдать порядок сплайна. \en Get the spline order. + ptrdiff_t GetDegree() const { return degree; } + /// \ru Вернуть признак рациональности, но не регулярности кривой. \en Get attribute of rationality, but no regularity of curve. + bool IsRational() const; + + template + void GetWeights( Weights & wts ) const { std::copy( weights.begin(), weights.end(), std::back_inserter(wts) ); } + size_t GetWeightsCount() const { return weights.size(); } + double GetWeight( size_t ind ) const { return weights[ind]; } + double & SetWeight( size_t ind ) { return weights[ind]; } + + template + void GetKnots( Knots & kts ) const { std::copy( knots.begin(), knots.end(), std::back_inserter(kts) ); } + size_t GetKnotsCount() const { return knots.size(); } + double GetKnot( size_t ind ) const { return knots[ind]; } + double & SetKnot( size_t ind ) { return knots[ind]; } + ptrdiff_t GetUppKnotsIndex() const { return uppKnotsIndex; } + + // \ru BEG: для библиотеки (хорошо бы избавиться) \en BEG: for the library (it would be good to get rid of this) + /// \ru Добавить точку в конец массива. \en Add point to the end of the array. + void LtAddPoint ( MbCartPoint & pnt, double weight ) { C3D_ASSERT_UNCONDITIONAL( false ); pointList.push_back( pnt ); weights.push_back( weight ); } + /// \ru Добавить характерную точку в степенном представлении в конец массива. \en Add a control point with degree representation to the end of the array. + void LtAddPowerPoint( MbCartPoint & pnt ) { C3D_ASSERT_UNCONDITIONAL( false ); pointList.push_back( pnt ); } + /// \ru Добавить узел в конец узлового вектора. \en Add a knot to the end of knot vector. + void LtAddKnot ( double knot ) { C3D_ASSERT_UNCONDITIONAL( false ); knots.push_back( knot ); } + /// \ru Задать порядок сплайна. \en Set the spline order. + void LtSetDegree( ptrdiff_t newDegree ) { C3D_ASSERT_UNCONDITIONAL( false ); if ( newDegree >= 2 && form == ncf_Unspecified ) { degree = newDegree; } } + /// \ru Установить признак замкнутости. \en Set the closedness attribute. + void LtSetClosed( bool cls ) { C3D_ASSERT_UNCONDITIONAL( false ); if ( form == ncf_Unspecified ) { closed = cls; } } + /// \ru Изменить степень, замкнутость и тип формы. \en Change degree, closedness and type of shape. + void LtSetData( ptrdiff_t d, bool c, MbeNurbsCurveForm f ); + /// \ru Перестроить сплайн после накачки из библиотеки. \en Rebuild the spline. + bool LtRebuild(); + /// \ru Инициализация. \en Initialization. + void LtInit(); + // \ru Преобразование кусочно степенной формы в NURBS-кривую. \en Convert a piecewise exponential form to a NURBS-curve. + bool LtInitPowerArc(); + bool LtTrimmed( double t1, double t2, int sense = 1 ); + // \ru END: для библиотеки (хорошо бы избавиться) \en END: for the library (it would be good escape) + + /// \ru Создать Bezier форму Nurbs. \en Create a Bezier shape of Nurbs. + void Bezier( MbNurbs & bezierForm ) const; + /// \ru Присоединить nurbs. \en Attach nurbs. + bool Concatenate( MbNurbs & ); + + /// \ru Задать вес для вершины. \en Set weight for control point. + void SetWeight( ptrdiff_t pointNumber, double newWeight ); + + /// \ru Получить кратность узла. \en Get the knot multiplicity. + ptrdiff_t KnotMultiplicity( ptrdiff_t knotIndex ) const; + /// \ru Определение базисного узлового вектора. \en Determination of basis knot vector. + void DefineKnotsVector(); + /// \ru Переопределение базисного узлового вектора из Close в Open. \en Redetermination of the basis knot vector from Close to Open. + bool OpenKnotsVector(); + /// \ru Переопределение базисного узлового вектора из Open в Close. \en Redetermination of the basis knot vector from Open to Close. + bool CloseKnotsVector(); + /// \ru Сдвинуть параметр замкнутого сплайна. \en Shift parameter of closed spline. + void CyclicShift( ptrdiff_t interval ); + void CyclicShift( double t ); + bool BasicFunctions( double & t, ptrdiff_t k, CcArray & values, ptrdiff_t & left, double & sum ); + + void CheckForm(); + /// \ru Преобразовать кривую в коническое сечение, если это возможно. \en Transform a curve into a conic section if it is possible. + MbCurve * ConvertToConic(); + /// \ru Установить область изменения параметра. \en Set the range of parameter. + bool SetLimitParam( double newTMin, double newTMax ); + + // \ru Базовые операции над NURBS-кривой. \en Base operation with NURBS curve. + + /// \ru Добавление нового узла; возвращает количество узлов, которые удалось вставить. \en Addition of a new knots; returns the number of knots which have been inserted. + ptrdiff_t InsertKnots( double & newKnot, ptrdiff_t multiplicity, double relEps ); + /// \ru Удалить кратный внутренний узел id, num раз; вернуть количество удалений, которое удалось сделать. \en Remove multiple internal 'id' knot 'num' times, return count of removals was successfully made. + ptrdiff_t RemoveKnot( ptrdiff_t id, ptrdiff_t num, double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon ); + /// \ru Удалить все внутренние узлы, если это возможно. \en Remove all internal knots if it is possible. + void RemoveAllKnots( double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon ); + /// \ru Преобразовать данный nurbs в форму Безье, узловой вектор в зажатый. \en Convert this nurbs to Bezier form; knot vector to clamped. + bool DecomposeCurve(); + + /// \ru Преобразовать узловой вектор в зажатый (если кривая замкнута и clm = false) или разжатый (если кривая не замкнута и clm = true). \en Transform knot vector to clamped (if curve is closed and clm = false) or unclamped (if curve is open and clm = true). + bool UnClamped( bool clm ); + /// \ru Добавить кривую в конец. \en Add curve to the end. + void AddCurve ( MbNurbs &, bool bmerge = true ); + /// \ru Добавить кривые в конец. \en Add curves to the end. + template + void AddCurves( NurbsCurves & curves ) + { + for ( size_t i = 0, icount = curves.size(); i < icount; ++i ) { + if ( curves[i] != NULL ) + AddCurve( *curves[i] ); + } + } + /** \brief \ru Разбить кривую. + \en Split the curve. \~ + \details \ru Разбить недифференцируемую NURBS-кривую четвертой степени в трижды кратном внутреннем узле.\n + Если внутренних трижды кратных узлов не существует, то в массив заносится копия кривой.\n + Если bline = true, то проверить вырожденность в прямую, если прямая - преобразовать в прямую. + \en Split the non-differentiable NURBS-curve of fourth degree at internal knot with multiplicity of three.\n + If there are no internal knots with multiplicity of three, then the array is filled with copy of curve.\n + If bline = true, then check the curve for degeneration into a line, if it is a line then transform to a line. \~ + */ + bool BreakC0NURBS4( RPArray &, bool bline = true ); + /// \ru Разбить NURBS-кривую в местах, где кривая не дифференцируема. Параметризация не сохраняется. \en Split NURBS-curve at places where the curve is non-differentiable. Parametrization does not remain. + bool BreakC0( RPArray & ); + /// \ru Расширить незамкнутую NURBS-кривую по касательным. \en Extend open NURBS-curve by tangents. + bool ExtendNurbs( double, double, bool bmerge = false ); + + /** \brief \ru Замкнуть кривую. + \en Make curve closed. \~ + \details \ru Замкнуть фактически замкнутую кривую.\n + То есть если первая и последняя точки кривой совпадают, но она реализована как незамкнутая, + то одна из совпадающих точек убирается и кривая делается замкнутой. + \en Make actually closed curve closed.\n + That is, if the first and the last points of curve are coincident, but curve implemented as open, + then one of coincident points is taken away and curve becomes closed. \~ + */ + void FixClosedNurbs(); + + /** \} */ + +protected: + virtual bool CanChangeClosed() const; // \ru Можно ли поменять признак замкнутости. // ЯТ К6 \en Whether it is possible to change the attribute of closedness. // ЯТ К6 + +private: // \ru Системные методы. \en System methods. + bool CatchMemory( MbNurbsAuxiliaryData * cache ) const; // \ru Выделить память. \en Allocate memory. + void FreeMemory( MbNurbsAuxiliaryData * cache ) const; // \ru Освободить память. \en Free memory. + void VerifyParam( double & t ) const; // \ru Загнать параметр t в параметрическую область кривой. \en Parameter set in the curve region. + void CalculateSegment( double & t, MbNurbsAuxiliaryData * cache ) const; // \ru Рассчитать базисные функции и разностные формы на участке. \en Calculate the basis functions and differential forms on the region. + void CalculateSpline( ptrdiff_t n, MbNurbsAuxiliaryData * cache ) const; // \ru Рассчитать точку NURBS-кривой или производную n-го порядка. \en Calculate point of NURBS-curve or n-th order derivative. + void CalculateSplineWeight( double & t, ptrdiff_t n, MbNurbsAuxiliaryData * cache ) const; + bool InitSegments( MbNurbsAuxiliaryData * cache ) const; + + // \ru Служебные аналоги публичных функций, которые используют заданный кэш. \en Service analogs of public functions that use a given cache. + void PointOn( double & t, MbCartPoint & pnt, MbNurbsAuxiliaryData * ucache ) const; // \ru Точка на кривой. \en Point on the curve. + void FirstDer( double & t, MbVector & fd, MbNurbsAuxiliaryData * ucache ) const; // \ru Первая производная. \en First derivative. + void SecondDer( double & t, MbVector & sd, MbNurbsAuxiliaryData * ucache ) const; // \ru Вторая производная. \en Second derivative. + void Derivatives( double & t, bool ext, MbVector & fir, MbVector * sec, MbVector * thi, MbNurbsAuxiliaryData * ucache ) const; + + void SetClamped(); // \ru Делаем зажатый узловой вектор. \en Set clamped knots vector. + + void ResetCache(); // \ru Очистить кэш главного потока, сбросить остальные кэши. \en Clear main thread cache, reset other caches. + bool NurbsPlus( MbNurbs & nurbs, double tin, double tax ) const; + + // \ru Расчет весовых функций и их первых производных. \en Calculation of weight functions and its first derivatives. + ptrdiff_t WeightFunctions( double & x, CcArray & ) const; + // \ru Вычисление шага аппроксимации в обе стороны. \en Calculation of approximation step in both directions. + double StepD( double & t, double sag, bool checkAngle = false, double angle = 0.0, MbNurbsAuxiliaryData * cache = NULL ) const; + // \ru Вычисление шага аппроксимации сплайна второго порядка. \en Calculation of approximation step of second order spline. + double PolylineStep( double t, bool half, MbNurbsAuxiliaryData * cache ) const; + // \ru Уточнить проекцию \en Specify projection. + double SpecifyProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, double t, bool ext ) const; + + void operator = ( const MbNurbs & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbs ) +}; + +IMPL_PERSISTENT_OPS( MbNurbs ) + + +//------------------------------------------------------------------------------ +// конструктор математического В-сплайн +// --- +template +MbNurbs::MbNurbs( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints, + const DoubleVector * initWeights, const DoubleVector * initKnots ) + : MbPolyCurve ( ) + , degree ( 0 ) + , uppKnotsIndex( SYS_MAX_T ) // максимальный индекс узлового вектора + , knots ( ) + , weights ( ) + , form ( ncf_Unspecified ) // форма В-сплайна + , cache ( ) +{ + if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, initWeights, initKnots ) ) { + pointList.assign( initPoints.begin(), initPoints.end() ); + uppIndex = (ptrdiff_t)pointList.size() - 1; // количество точек + + closed = initClosed; + degree = initDegree; // степень В-сплайна + + if ( initWeights != NULL ) + weights.assign( initWeights->begin(), initWeights->end() ); + else + weights.assign( initPoints.size(), 1.0 ); + + if ( initKnots != NULL ) { + knots.assign( initKnots->begin(), initKnots->end() ); + uppKnotsIndex = (ptrdiff_t)knots.size() - 1; + } + else { + DefineKnotsVector(); + } + + Refresh(); + } +} + +//------------------------------------------------------------------------------ +// \ru Добавить точку в конец массива. \en Add point to the end of the array. +// --- +inline void MbNurbs::AddPoint( const MbCartPoint & pnt, double weight ) +{ + pointList.push_back( pnt ); + weights.push_back( weight ); + form = ncf_Unspecified; + Rebuild(); +} + + +//------------------------------------------------------------------------------ +// \ru Является ли сплайн прямолинейным \en Whether the spline is straight +// --- +template +bool IsStraightNurbs( const Nurbs & nurbs, double mEps = METRIC_EPSILON ) +{ + bool isStraight = false; + + if ( !nurbs.IsClosed() ) { + SArray wts( 0, 1 ); + nurbs.GetWeights( wts ); + size_t wtsCnt = wts.size(); + + isStraight = true; + if ( wtsCnt > 1 ) { + double wt0 = wts[0]; + for ( size_t k = 1; k < wtsCnt; k++ ) { + double wt = wts[k]; + if ( ::fabs(wt0 - wt) > EXTENT_EQUAL ) { + isStraight = false; + break; + } + } + } + if ( isStraight ) { + isStraight = false; + SArray pnts( 0, 1 ); + nurbs.GetPointList( pnts ); + if ( c3d::ArePointsOnLine( pnts, mEps ) ) + isStraight = true; + } + } + + return isStraight; +} + + +#endif // __CUR_NURBS_H diff --git a/C3d/Include/cur_nurbs3d.h b/C3d/Include/cur_nurbs3d.h new file mode 100644 index 0000000..e4dd3a7 --- /dev/null +++ b/C3d/Include/cur_nurbs3d.h @@ -0,0 +1,762 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пространственная NURBS кривая. + \en A spatial NURBS curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_NURBS3D_H +#define __CUR_NURBS3D_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbNurbs; +class MATH_CLASS MbBezier3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru NURBS кривая в трехмерном пространстве. + \en NURBS curve in three-dimensional space. \~ + \details \ru NURBS кривая определяется контрольными точками pointList, + весами контрольных точек weights, узловым вектором knots и порядком сплайна degree.\n + Аббревиатура NURBS получена из первых букв словосочетания Non-Uniform Rational B-Spline. + NURBS кривая не проходит через свои контрольные точки. + Узловой вектор knots должен представлять собой неубывающую последовательность действительных чисел. + Множества pointList и weights должны содержать одинаковое количество элементов. + Для не замкнутой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс degree. + Для замкнутой кривой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс 2*degree-1. + Минимальное значение параметра сплайна равно значению элемента узлового вектора с индексом degree-1. + Максимальное значение параметра сплайна равно значению элемента узлового вектора с индексом, равным последнему элементу минус degree-1. + Расчет кривой в каждой своей точке производится на основе нормированных неоднородных В-сплайнов.\n + Семейство В-сплайнов определяется заданной неубывающей последовательностью узловых параметров и заданным порядком B-сплайна.\n + \en NURBS curve is defined by 'pointList' control points, + 'weights' weights of control points, 'knots' knot vector and 'degree' spline order.\n + Abbreviation of NURBS is obtained from the first letters of the Non-Uniform Rational B-Spline phrase. + NURBS curve doesn't pass through its control points. + 'knots' knot vector has to be nondecreasing sequence of real numbers. + 'pointList' and 'weights' sets have to contain the same count of elements. + For not closed curve knot vector 'knots' has to contain the count of elements of 'pointList' set plus 'degree'. + For closed curve knot vector 'knots' has to contain the count of elements of 'pointList' set plus 2*degree-1. + Minimal value of spline parameter is equal to value of the element of knot vector with degree-1 index. + Maximal value of spline parameter is equal to the value of element of knot vector with index, which is equal to index of the last element minus degree-1. + Curve calculation at each point is performed using normalized non-uniform B-splines.\n + Family of B-splines is defined by the given nondecreasing sequence of knot parameters and the given order of B-spline.\n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbNurbs3D : public MbPolyCurve3D { +private : + ptrdiff_t degree; ///< \ru Порядок В-сплайна (порядок = степень + 1). \en Order of B-spline (order = degree + 1). + ptrdiff_t uppKnotsIndex; ///< \ru Последний индекс узлового вектора. \en Last index of knot vector. + SArray weights; ///< \ru Множество весов контрольных точек. \en Set of weights of the control points. + SArray knots; ///< \ru Узловой вектор сплайна. \en Knot vector of the spline. + MbeNurbsCurveForm form; ///< \ru Форма кривой. \en Shape of curve. + +private: + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbNurbs3DAuxiliaryData : public AuxiliaryData { + public: + double tCalc; ///< \ru Текущее значение параметра, по которому вычислены временные данные кривой. \en Current value of parameter the curve temporary data are calculated by. + double * nd; ///< \ru B - базис. \en B - basis. + MbHomogeneous3D * h0; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous3D * h1; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous3D * h2; ///< \ru Текущий сегмент. \en Current segment. + MbHomogeneous3D * h3; ///< \ru Текущий сегмент. \en Current segment. + double * wc; ///< \ru Насчитанные значения весов (может быть ноль). \en Calculated values of points (can be null). + MbVector3D rc[cdt_CountDer]; ///< \ru Насчитанные значения точек. \en Calculated values of points. + ptrdiff_t leftIndex; ///< \ru Левый индекс узлового вектора. \en Left index of knot vector. + double * m_left; + double * m_right; + public: + MbNurbs3DAuxiliaryData(); + MbNurbs3DAuxiliaryData( const MbNurbs3DAuxiliaryData & init ); + virtual ~MbNurbs3DAuxiliaryData(); + void FreeMemory(); + bool CatchMemory( ptrdiff_t, bool ); + }; // MbNurbs3DAuxiliaryData + + mutable CacheManager cache; + +protected: + MbNurbs3D(); + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор плоского сплайна пространстве. + \en Constructor of planar spline in space. \~ + */ + MbNurbs3D( const MbNurbs &, const MbPlacement3D & ); + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по порядку, точкам, параметрам и признаку замкнутости.\n + \en Constructor by order, points, parameters and an attribute of closedness.\n \~ + \param[in] deg - \ru Порядок сплайна. + Должен быть больше единицы. Не должен превышать количество контрольных точек. + \en A spline order. + Must be greater than unity. Shouldn't exceed the count of control points. \~ + \param[in] cls - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + Количество точек должно быть больше или равно двум. + \en Set of control points. + Count of points must be greater than or equal to two. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + Количество весов должно соответствовать количеству точек. + \en Set of weights for control points. + Count of weights must be equal to count of points. \~ + \param[in] knots - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + + */ + MbNurbs3D( ptrdiff_t deg, bool cls, const SArray & points, + const SArray * weights = NULL, const SArray * knots = NULL ); + MbNurbs3D( const MbNurbs3D & ); +public : + virtual ~MbNurbs3D(); + +public : + VISITING_CLASS( MbNurbs3D ); + + /** \brief \ru Создать копию сплайна. + \en Create copy of spline. \~ + \details \ru Создать копию сплайна.\n + \en Create copy of spline.\n \~ + */ + static MbNurbs3D * Create( const MbNurbs3D & ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] nurbs - \ru Двумерный сплайн. + \en The two-dimensional spline. \~ + \param[in] place - \ru Локальная система координат сплайна. + \en Local coordinate system of spline. \~ + */ + static MbNurbs3D * Create( const MbNurbs & nurbs, const MbPlacement3D & place ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + */ + static MbNurbs3D * Create( ptrdiff_t degree, const SArray & points, bool closed, + const SArray * weights = NULL ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] knots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + + */ + static MbNurbs3D * Create( ptrdiff_t degree, bool closed, const SArray & points, + const SArray & knots ); + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Создать сплайн и установить параметры сплайна.\n + \en Create spline and set parameters of spline.\n \~ + \param[in] initDegree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] initClosed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] initPoints - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] initWeights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] initKnots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + \param[in] initForm - \ru Тип построения. + \en Type of construction. \~ + + */ + template + static MbNurbs3D * Create( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints, + const DoubleVector & initWeights, const DoubleVector & initKnots, + MbeNurbsCurveForm initForm = ncf_Unspecified ) + { + MbNurbs3D * resNurbs = new MbNurbs3D; + if ( !resNurbs->Init( initDegree, initClosed, initPoints, initWeights, initKnots, initForm ) ) + ::DeleteItem( resNurbs ); + return resNurbs; + } + /** \brief \ru Создать сплайн. + \en Create spline. \~ + \details \ru Сплайн, проходящий через заданные точки при заданных параметрах.\n + В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n + \en Spline passing through the given points at the given parameters.\n + In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] cls - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор точек, через которые проходит сплайн. + \en Set of points which the spline passes through. \~ + \param[in] params - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + \param[in] aKnots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + */ + static MbNurbs3D * CreateThrough( ptrdiff_t degree, bool cls, const SArray & points, + const SArray & params, SArray * aKnots = NULL ); + /** \brief \ru Заполнить NURBS по данным parasolid. + \en Fill NURBS by parasolid data. \~ + \details \ru Заполнить NURBS по данным parasolid.\n + \en Fill NURBS by parasolid data.\n \~ + \param[in] degree - \ru Степень сплайна. + \en Order of spline. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] rational - \ru Является ли кривая рациональной. Если true - строится NURBS, false - кривая Безье. + \en Whether the curve is rational. if true - NURBS is created, false - Bezier curve. \~ + \param[in] count - \ru Количество контрольных точек. + \en Count of control points. \~ + \param[in] verts - \ru Массив координат точек. Если сплайн рациональный, четвертая координата - вес точки. + \en An array of coordinates of points. If spline is rational, then the fourth coordinate is the weight of a point. \~ + \param[in] vertsCount - \ru Количество элементов в массиве verts. + \en Count of elements in 'verts' array. \~ + \param[in] mul - \ru Массив с данными о кратности каждого узла. + \en Array with multiplicity of each knot. \~ + \param[in] mulCount - \ru Количество элементов в массиве mul. + \en Count of elements in 'mul' array. \~ + \param[in] knots - \ru Массив со значениями параметров в узлах. Каждое значение представлено один раз. + Информация о кратности узла лежит в элементе массива mul с тем же номером. + \en Array with values of parameters at knots. Each value is presented only once. + Information about knot multiplicity is in the element of 'mul' array with the same index. \~ + \param[in] knotsCount - \ru Количество элементов в массиве knots. + \en Count of elements in 'knots' array. \~ + \param[in] scl - \ru Коэффициент масштабирования. + \en Scale factor. \~ + */ + static MbNurbs3D * CreateParasolid( ptrdiff_t degree, bool closed, bool rational, ptrdiff_t count, + const CcArray & verts, ptrdiff_t vertsCount, + const CcArray & mul, ptrdiff_t mulCount, + const CcArray & knots, ptrdiff_t knotsCount, + double scl ); + +public: + /// \ru Установить параметры сплайна. \en Set parameters of the spline. + void Init( const MbNurbs3D & ); + void Init( const MbNurbs &, const MbPlacement3D & ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of the spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + */ + bool Init( ptrdiff_t degree, const SArray & points, bool closed, + const SArray * weights = NULL ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of the spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] knots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + + */ + bool Init( ptrdiff_t degree, bool closed, const SArray & points, + const SArray & knots ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of the spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] knots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + \param[in] initForm - \ru Тип построения. + \en Type of construction. \~ + + */ + template + bool Init( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints, + const DoubleVector & initWeights, const DoubleVector & initKnots, + MbeNurbsCurveForm initForm = ncf_Unspecified ) + { + bool bRes = ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, &initWeights, &initKnots ); + + if ( bRes ) { + Refresh(); // Must come first, since frees allocated memory + + pointList = initPoints; + uppIndex = (ptrdiff_t)pointList.size() - 1; + closed = initClosed; + form = initForm; + degree = initDegree; + uppKnotsIndex = (ptrdiff_t)initKnots.size() - 1; + weights = initWeights; + knots = initKnots; + + SetClamped(); + } + else if ( ::IsValidNurbsParams( initDegree, initClosed, initPoints.size(), initWeights.size() ) ) { + // Lets try to redefine knots vector (BUG_42356) + Refresh(); // Must come first, since frees allocated memory + pointList = initPoints; + uppIndex = (ptrdiff_t)pointList.size() - 1; + closed = initClosed; + form = ncf_Unspecified; + degree = initDegree; + weights = initWeights; + + DefineKnotsVector(); + C3D_ASSERT_UNCONDITIONAL( false ); // Wrong constructor use + // Valid variants: + // 1. Really, result is false + // 2. The result should have 3 positions, + // 3. Initial knots should be analyzed and corrected + bRes = true; // Not been deleted recurring point for a closed curve + } + + return bRes; + } + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of the spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] weights - \ru Набор весов для контрольных точек. + \en Set of weights for control points. \~ + \param[in] begData - \ru Параметр сопряжения в начальной точке сплайна. + \en Parameter of conjugation at the start point of the spline. \~ + \param[in] endData - \ru Параметр сопряжения в конечной точке сплайна. + \en Parameter of conjugation at the end point of the spline. \~ + */ + bool Init( ptrdiff_t degree, const SArray & points, const SArray & weights, + MbPntMatingData & begData, + MbPntMatingData & endData ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Установить параметры сплайна.\n + \en Set parameters of the spline.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] closed - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор контрольных точек. + \en Set of control points. \~ + \param[in] knots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + \param[in] nPoints - \ru Число контрольных точек. + \en The number of control points. \~ + \param[in] endData - \ru Количество узлов. + \en Count of knots. \~ + */ + bool Init( ptrdiff_t degree, bool closed, const CcArray & points, + const CcArray & knots, ptrdiff_t nPoints, ptrdiff_t nKnots ); + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Сплайн, проходящий через заданные точки при заданных параметрах.\n + В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n + \en Spline passing through the given points at the given parameters.\n + In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~ + \param[in] degree - \ru Порядок сплайна. + \en A spline order. \~ + \param[in] cls - \ru Признак замкнутости. + \en Closedness attribute. \~ + \param[in] points - \ru Набор точек, через которые проходит сплайн. + \en Set of points which the spline passes through. \~ + \param[in] params - \ru Последовательность узловых параметров. + \en Sequence of knot parameters. \~ + \param[in] aKnots - \ru Неубывающая последовательность узлов. + \en Nondecreasing sequence of knots. \~ + */ + bool InitThrough( ptrdiff_t degree, bool cls, const SArray & points, + const SArray & params, SArray * aKnots = NULL ); + /// \ru Установить тип формы. \en Set the type of shape. + void SetFormType( MbeNurbsCurveForm f ) { form = f; } + + // \ru Общие функции математического объекта. \en The common functions of the mathematical object. + + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая копией данной кривой? \en Whether the curve is a duplicate of the current curve. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + void GetControlPoints( SArray & s ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + + // \ru Общие функции кривой. \en Common functions of curve. + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual bool IsClosed() const; // \ru Замкнутость кривой. \en A curve closedness. + virtual bool IsPeriodic() const; // \ru Периодичность замкнутой кривой. \en Periodicity of a closed curve. + virtual bool IsStraight() const; // \ru Прямолинейность кривой. \en Straightness of curve. + // \ru Функции для работы внутри области определения кривой. \en Functions for working inside of the curve domain. \~ + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой. \en Point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная. \en The first derivative. + virtual void SecondDer ( double & t, MbVector3D & ) const; // \ru Вторая производная. \en The second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t. \en The third derivative with respect to t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + // \ru Вычислить значения производных для заданного параметра. \en Calculate derivatives of object for given parameter. \~ + void Derivatives( double & t, bool ext, MbVector3D & fir, MbVector3D * sec, MbVector3D * thi ) const; + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага аппроксимации. \en Calculation of step of approximation. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации. \en Calculation of step of approximation. + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS копию кривой. \en Construct a NURBS copy of a curve. + + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const; + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой \en Get the axis of the curve + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called for a two-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Ближайшая проекция точки на кривую. \en The nearest projection of a point onto the curve. + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; + + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + + // \ru Определить, является ли кривая репараметризованно такой же. \en Determine whether a reparameterized curve is the same. + virtual bool IsReparamSame( const MbCurve3D & curve, double & factor ) const; + + virtual bool IsDegenerate ( double eps = METRIC_PRECISION ) const; // \ru Проверка вырожденности кривой. \en Check the curve degeneracy. + void SetDegenerate(); // \ru Стать вырожденным. \en Became degenerate. + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой. \en Creation of a trimmed curve. + /// \ru Усечение кривой. \en Trim the curve. + MbNurbs3D * Trimm( double t1, double t2, int sense ) const; + + // \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual void CalculateGabarit( MbCube & cube ) const; + // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateMetricLength() const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double CalculateLength( double t1, double t2 ) const; + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + // \ru Общие функции полигональной кривой. \en Common functions of the polygonal curve. + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки B-сплайна. \en Get the range of influence of a B-spline point. + + virtual void Rebuild(); // \ru Перестроить B-сплайн. \en Rebuild B-spline. + virtual void SetClosed( bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + + virtual void AddPoint ( const MbCartPoint3D & ); // \ru Добавить точку в конец массива. \en Add a point to the end of the array. + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & p ); // \ru Добавить точку. \en Add a point. + virtual void InsertPoint( double t, const MbCartPoint3D & p, double eps ); // \ru Добавить точку. \en Add a point. + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку. \en Remove the point. + virtual void RemovePoints(); // \ru Удалить все точки. \en Delete all points. + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Загнать параметр в область задания, получить локальный индексы и параметры. \en Drive parameter into the definition domain, get local indices and parameters. + virtual double GetParam( ptrdiff_t i ) const; // \ru Выдать параметр для точки с заданным номером. \en Get parameter for a point with the given index. + virtual void ResetTCalc() const; // \ru Сбросить текущее значение параметра \en Reset the current value of the parameter + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + // \ru Функции B-сплайн кривой. \en Functions of B-spline curve. + /// \ru Выделить часть кривой. \en Extract a piece of a curve. + MbNurbs3D * Break( double t1, double t2 ) const; + /// \ru Задать вес для вершины. \en Set weight for a control point. + void SetWeight( ptrdiff_t pointNumber, double newWeight ); + /// \ru Добавить точку с весом. \en Add a point with weight. + void AddPoint ( ptrdiff_t index, const MbCartPoint3D & pnt, double weight ); + + // \ru Функции B-сплайна. \en Functions of B-spline. + /// \ru Добавление нового узла с заданной кратностью. \en Add a new knot with the given multiplicity. + void InsertKnots ( double & newKnot, ptrdiff_t multiplicity, double relEps = Math::paramEpsilon ); + /// \ru Добавление новых узлов равномерно в промежуток от idBegin до idBegin+1. \en Add new equally spaced knots into the range from idBegin to idBegin+1. + void InsertKnotsInRegion( ptrdiff_t idBegin ); + + /// \ru Удалить кратный внутренний узел id num раз, вернуть количество удалений, которое удалось сделать. \en Remove multiple internal 'id' knot 'num' times, return count of removals which were successfully made. + ptrdiff_t RemoveKnot( ptrdiff_t id, ptrdiff_t num, double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon ); + + /// \ru Удалить узел id 1 раз, не проверяя точность изменения кривой. \en Remove knot 'id' once without checking the accuracy of the curve modification. + bool RemoveKnotAlways( ptrdiff_t id ); + + /// \ru Удалить все внутренние узлы, если это возможно. \en Remove all the internal knots if it is possible. + void RemoveAllKnots( double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon ); + /// \ru Преобразовать данный NURBS в форму кривой Безье. \en Transform current NURBS into Bezier curve. + bool DecomposeCurve(); + + /// \ru Увеличить порядок NURBS-кривой, не меняя ее геометрическую форму и парамеризацию. \en Increase the order of a NURBS-curve without changing its geometric shape and parameterization. + bool RaiseDegree ( ptrdiff_t, double relEps = Math::paramEpsilon ); + /// \ru Уменьшить порядок кривой на 1. \en Decrease the order of a curve by 1. + bool ReductionDegree( double relEps = Math::paramEpsilon ); + + /// \ru Получить кратность узла с заданным номером. \en Get multiplicity of a knot with a given index. + ptrdiff_t KnotMultiplicity( ptrdiff_t knotIndex ) const; + /// \ru Определение базисного узлового вектора. \en Definition of the basis knot vector. + void DefineKnotsVector(); + /// \ru Переопределение базисного узлового вектора из Close в Open. \en Redefine the basis knot vector from Close to Open. + bool OpenKnotsVector (); + /// \ru Переопределение базисного узлового вектора из Open в Close. \en Redefine the basis knot vector from Open to Close. + bool CloseKnotsVector (); + + /// \ru Установить область изменения параметра. \en Set the range of parameter. + bool SetLimitParam ( double pmin, double pmax ); + /// \ru Добавить кривую в конец. \en Add a curve to the end. + void AddCurve ( MbNurbs3D &, bool bmerge = true ); + /// \ru Добавить кривые в конец. \en Add curves to the end. + void AddCurves ( const RPArray & ); + + /// \ru Репераметризовать кривую в соответствии с длиной в случае, если кривая получена из набора кривых Безье. \en Reparameterize a curve according to the length if the curve is obtained from a set of Bezier curves. + bool ReparamCurveInBezierForm(); + + /// \ru Получить форму В-сплайна. \en Get the form of B-spline. + MbeNurbsCurveForm GetFormType() const { return form; } + /// \ru Получить порядок В-сплайна. \en Get the order of B-spline. + ptrdiff_t GetDegree() const { return degree; } + /// \ru Вернуть признак рациональности, но не регулярности кривой. \en Get the attribute of rationality, but not regularity of a curve. + bool IsRational() const; + + size_t GetWeightsCount() const { return weights.Count(); } + void GetWeights( SArray & wts ) const { wts = weights; } + double GetWeight( size_t ind ) const { return weights[ind]; } + double & SetWeight( size_t ind ) { return weights[ind]; } + + size_t GetKnotsCount() const { return knots.Count(); } + void GetKnots( SArray & knts ) const { knts = knots; } + double GetKnot ( size_t ind ) const { return knots[ind]; } + double & SetKnot ( size_t ind ) { return knots[ind]; } + ptrdiff_t GetUppKnotsIndex() const { return uppKnotsIndex; } + + // \ru Функции только 3D кривой. \en Functions of 3D curve only. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of a curve. + + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях с поверхностями. \en Count of subdivisions for pass in operations with surfaces. + + /// \ru Установить сопряжение на конце. \en Set conjugation at the end. + bool AttachG( MbPntMatingData & connectData, bool beg, bool isWrongAttachG1_K12 = false ); + + /// \ru Создать кубический NURBS по точкам, через которые он проходит, и параметрам сопряжения. \en Create cubic NURBS by parameters of conjugation and points which it passes through. + static MbNurbs3D * CreateNURBS4( const SArray &, MbeSplineParamType spType, + const MbPntMatingData & begData, + const MbPntMatingData & endData, + MbeSplineCreateType useInitThrough ); + /// \ru Создать кубический NURBS по интерполяционным точкам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points and data of conjugation at each point. + static MbNurbs3D * CreateNURBS4( const SArray &, MbeSplineParamType spType, + bool closed, + RPArray< MbPntMatingData > &, + MbeSplineCreateType useInitThrough ); + /// \ru Создать кубический NURBS по интерполяционным точкам, их параметрам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points, parameters and data of conjugation at each point. + static MbNurbs3D * CreateNURBS4( const SArray &, const SArray &, + bool closed, + RPArray< MbPntMatingData > &, + MbeSplineCreateType useInitThrough ); + /// \ru Создать кубический NURBS по точкам, через которые он проходит, и признаку замкнутости. \en Create a cubic NURBS by the attribute of closedness and points which it passes through. + static MbNurbs3D * CreateNURBS4( const SArray &, bool cls, MbeSplineParamType spType, + MbeSplineCreateType useInitThrough = sct_Version2 ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать незамкнутый сплайн четвертого порядка по точкам, параметрам и признаку замкнутости.\n + Используется граничное условие отсутствия узла.\n + \en Create an open spline of fourth order by points, parameters and the attribute of closedness.\n + Used boundary condition of knot absence.\n \~ + */ + static MbNurbs3D * CreateNURBS4( const SArray & points, const SArray & params, bool cls, + MbeSplineCreateType useInitThrough = sct_Version2 ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать незамкнутый сплайн четвертого порядка по точкам, параметрам и признаку замкнутости.\n + Используется граничное условие отсутствия узла. + \en Create an open spline of fourth order by points, parameters and the attribute of closedness.\n + Used boundary condition of knot absence. \~ + */ + static MbNurbs3D * CreateNURBS4( const SArray & weights, const SArray & points, + SArray & params, bool cls ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать сплайн четвертого порядка по точкам, параметрам и признаку замкнутости + с граничными условиями - заданными векторами первых или вторых производных.\n + Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций.. + \en Create a spline of the fourth order by points, parameters and the attribute of closedness + with boundary conditions - given vectors of the first or the second derivatives.\n + Has 2 multiple internal knots, belongs to the class of differentiable (but not twice differentiable) functions. \~ + \param[in] bfstS - \ru Если true, то начальное граничное условие - вектор первой производной, иначе - вектор второй производной. + \en If true, then start boundary condition is the vector of the first derivative, otherwise - the vector of the second derivative. \~ + \param[in] bfstN - \ru Если true, то конечное граничное условие - вектор первой производной, иначе - вектор второй производной. + \en If true, then end boundary condition - vector of first derivative, otherwise - vector of second derivative. \~ + */ + static MbNurbs3D * CreateNURBS4( const SArray &, const SArray &, + const MbVector3D &, const MbVector3D &, bool cls, + bool bfstS = true, bool bfstN = true ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать сплайн четвертого порядка по точкам, производным, параметрам и признаку замкнутости.\n + Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций. + \en Create a spline of the fourth order by points, derivatives, parameters and the attribute of closedness.\n + Has 2 multiple internal knots, belongs to the class of differentiable (but not twice differentiable) functions. \~ + */ + static MbNurbs3D * CreateNURBS4( const SArray & points, const SArray & vectors, + const SArray & params, bool cls ); + /// \ru Создать сплайн четвертого порядка c учетом изломов кривой \en Create a spline of the fourth order taking breaks of curve into account + static MbNurbs3D * CreateNURBS4WithBreak( const SArray &, const SArray &, + const SArray &, bool cls ); + /** \brief \ru Интерполяция. + \en Interpolation. \~ + \details \ru Создать сплайн четвертого порядка по составному сплайну Безье четвертого порядка.\n + Внимание! Параметризация отлична от параметризации исходной кривой Безье. + \en Create a spline of the fourth order by a composite Bezier spline of the fourth order.\n + Attention! Parameterization is different from the parameterization of the source Bezier curve. \~ + */ + static MbNurbs3D * CreateNURBS4( const MbBezier3D & ); + /** \brief \ru Разбить кривую. + \en Split the curve. \~ + \details \ru Разбить недифференцируемую NURBS-кривую четвертой степени в трижды кратном внутреннем узле.\n + Если внутренних трижды кратных узлов не существует, то в массив заносится копия кривой.\n + Если bline = true, то проверить вырожденность в прямую, если прямая - преобразовать в прямую. + \en Split the non-differentiable NURBS-curve of the fourth degree at an internal knot with multiplicity of three.\n + If there is no internal knots with multiplicity of three, then a copy of the curve is added to the array.\n + If bline = true, then check the curve for degeneration into a line, if it is a line - transform to a line. \~ + */ + bool BreakC0NURBS4( RPArray &, bool bline = true ) const; + + /// \ru Расширить незамкнутую NURBS-кривую по касательным. \en Extend an open NURBS-curve by tangents. + bool ExtendNurbs( double, double, bool bmerge = false ); + + /// \ru Преобразовать узловой вектор в зажатый (если кривая замкнута и clm = false) или разжатый (если кривая не замкнута и clm = true). \en Transform knot vector to a clamped one (if the curve is closed and clm = false) or unclamped one (if the curve is open and clm = true). + bool UnClamped( bool clm, bool savePointsCount = false ); + /// \ru Преобразовать кривую в коническое сечение, если это возможно. \en Transform a curve into a conic section if it is possible. + MbCurve3D * ConvertToConic(); + /// \ru Разбить NURBS-кривую в местах, где кривая не дифференцируема. Если кривая дифференцируема, то добавляется копия кривой. \en Split a NURBS-curve at places where the curve is non-differentiable. If the curve is differentiable, then the curve copy is added. + bool BreakC0( RPArray & ); + + /** \brief \ru Замкнуть кривую. + \en Make the curve closed. \~ + \details \ru Замкнуть фактически замкнутую кривую.\n + То есть если первая и последняя точки кривой совпадают, но она реализована как незамкнутая, + то одна из совпадающих точек убирается и кривая делается замкнутой. + \en Make the actually closed curve closed.\n + That is, if the first and the last points of curve are coincident, but curve was implemented as open, + then one of the coincident points is took away and the curve becomes closed. \~ + */ + void FixClosedNurbs(); + /// \ru Получить значение параметра, соответствующего узловой точке с номером num. \en Get value of the parameter corresponding to a knot point with 'num' index. + double GetBSplineParameter ( size_t num ) const; + +private: + bool CatchMemory( MbNurbs3DAuxiliaryData * cache ) const; // \ru Выделить память. \en Allocate memory. + void FreeMemory ( MbNurbs3DAuxiliaryData * cache ) const; // \ru Освободить память. \en Free memory. + void VerifyParam( double & t ) const; // \ru Загнать параметр t в параметрическую область кривой. \en Parameter set in the curve region. + void CalculateSegment( double & t, MbNurbs3DAuxiliaryData * cache ) const; + void CalculateSpline( ptrdiff_t n, MbNurbs3DAuxiliaryData * cache ) const; + void CalculateSplineWeight( double & t, ptrdiff_t n, MbNurbs3DAuxiliaryData * cache ) const; + bool InitSegments( MbNurbs3DAuxiliaryData * cache ) const; + + // \ru Вычислить значения производных для заданного параметра, используя заданный кэш. \en Calculate derivatives of object for given parameter using defined cache. \~ + void DerivativesEx( double & t, bool ext, MbVector3D & fir, MbVector3D * sec, MbVector3D * thi, MbNurbs3DAuxiliaryData * ucache ) const; + + void SetClamped(); // \ru Делаем зажатый узловой вектор. \en Set clamped knots vector. + + void ResetMainCache() const; // \ru Очистить кэш главного потока. Использует блокировку кэша. \en Reset main thread cache. Use cache lock. + + MbNurbs3D * NurbsPlus( double tin, double tax ) const; + + // \ru BEG: Внутренние функции CreateNURBS4 по двум сопряжениям. \en BEG: Internal CreateNURBS4 functions by two conjugations. + // \ru Создать интерполяционный кубический NURBS, удовлетворяющий условиям сопряжения по касательным. \en Create an interpolation cubic NURBS meeting conditions of conjugation by tangents. + bool AttachG1_NURBS4( const SArray &, const SArray & params, + const MbPntMatingData & begData, + const MbPntMatingData & endData ); + // \ru Создать интерполяционный кубический NURBS, удовлетворяющий условиям сопряжения со вторым порядком гладкости. \en Create an interpolation cubic NURBS meeting conditions of conjugation with the second order of smoothness. + bool AttachG2_NURBS4( const SArray &, const SArray & params, + const MbPntMatingData & begData, + const MbPntMatingData & endData ); + // \ru END: Внутренние функции CreateNURBS4 по двум сопряжениям. \en END: Internal CreateNURBS4 functions by two conjugations. + + // \ru BEG: Внутренние функции CreateNURBS4 по массиву сопряжений. \en BEG: Internal CreateNURBS4 functions by an array of conjugations. + // \ru Построение интерполяционного NURBS4 с возможными заданными управляющими параметрами. \en Create an interpolation NURBS4 with possibly given driving parameters. + bool CreateC2_NURBS4( const SArray &, MbeSplineParamType spType, + RPArray< MbPntMatingData > &, + const SArray &, + MbeSplineCreateType useInitThrough, + bool cls = false ); + // \ru Построение интерполяционного незамкнутого NURBS4 в общем случае \en Create an interpolation open NURBS4 in general case + // \ru С возможными заданными управляющими параметрами в средних точках. \en With possibly given driving parameters at middle points. + // \ru Считаем, что данные для сопряжений заданы корректно. Этот факт проверяется до запуска функции. \en Consider that the given data for conjugations is correct. This fact is checked before calling the function. + static MbNurbs3D * CreateC2Nurbs4Common( const SArray & arPoints, + RPArray< MbPntMatingData > & inferredData, + const SArray & arParams, + const SArray & arKnots, + ptrdiff_t addCount, + bool cls, + MbeSplineCreateType useInitThrough, + size_t deg = 4 ); + // \ru END: Внутренние функции CreateNURBS4 по массиву сопряжений. \en END: Internal CreateNURBS4 functions by an array of conjugations. + + // \ru Расчет весовых функций и их первых производных. \en Calculation of weight functions and their first derivatives. + ptrdiff_t WeightFunctions ( double & x, CcArray & m ) const; + /// \ru Вычисление шага аппроксимации. \en Calculation of a step of approximation. + double StepD( double t, double sag, bool checkAngle, double angle = Math::lowRenderAng, MbNurbs3DAuxiliaryData * cache = NULL ) const; + // \ru Вычисление шага аппроксимации сплайна второго порядка. \en Calculation of approximation step of second order spline. + double PolylineStep( double t, bool half, MbNurbs3DAuxiliaryData * cache ) const; + // \ru Уточнить проекцию \en Specify projection. + double SpecifyProjection( const MbCartPoint3D & pnt, double t, bool ext ) const; + + void operator = ( const MbNurbs3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbs3D ) +}; + +IMPL_PERSISTENT_OPS( MbNurbs3D ) + + +#endif // __CUR_NURBS3D_H diff --git a/C3d/Include/cur_nurbs_vector.h b/C3d/Include/cur_nurbs_vector.h new file mode 100644 index 0000000..2832663 --- /dev/null +++ b/C3d/Include/cur_nurbs_vector.h @@ -0,0 +1,116 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru NURBS вектор 2D. + \en 2D vector of NURBS. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_NURBS_VECTOR_H +#define __CUR_NURBS_VECTOR_H + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Nurbs-вектор. + \en Nurbs-vecor. \~ + \details \ru Двумерный Nurbs-вектор. \n + \en Two-Dimensional Nurbs-vecor. \n \~ + \ingroup Data_Structures +*/ +// --- +class MbNURBSVector2D { +public: + double * x; + double * y; + double * w; + +public: + MbNURBSVector2D() : x( NULL ), y( NULL ), w( NULL ) {} + ~MbNURBSVector2D(); // \ru освободить память \en free memory + +public: + bool CatchMemory( ptrdiff_t count, bool bWeight ); // \ru выделить память \en allocate memory + void Init( ptrdiff_t i, const MbCartPoint &ip, double iw ); + void SetZero( ptrdiff_t i ); + void Set( ptrdiff_t i, const MbNURBSVector2D & p, ptrdiff_t ip ); + void Dec( ptrdiff_t i, const MbNURBSVector2D & p1, ptrdiff_t ip1, const MbNURBSVector2D & p2, ptrdiff_t ip2, double kk ); + void Set( ptrdiff_t i, const MbNURBSVector2D & p, ptrdiff_t ip, double kk ); + +private: + void FreeMemory(); // \ru освободить память \en free memory + MbNURBSVector2D( const MbNURBSVector2D & ); // \ru не реализовано \en not implemented + void operator = ( const MbNURBSVector2D & ); // \ru не реализовано \en not implemented +}; + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector2D::Init( ptrdiff_t i, const MbCartPoint &ip, double iw ) { + if ( w != NULL ) { + x[i] = ( ip.x * iw ); + y[i] = ( ip.y * iw ); + w[i] = iw; + } + else { + x[i] = ip.x; + y[i] = ip.y; + } +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector2D::SetZero( ptrdiff_t i ) { + x[i] = 0.0; + y[i] = 0.0; + if ( w != NULL ) + w[i] = 0.0; +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector2D::Set( ptrdiff_t i, const MbNURBSVector2D &p, ptrdiff_t ip ) { + x[i] = p.x[ip]; + y[i] = p.y[ip]; + if ( w != NULL ) + w[i] = p.w[ip]; +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector2D::Dec( ptrdiff_t i, + const MbNURBSVector2D & p1, ptrdiff_t ip1, + const MbNURBSVector2D & p2, ptrdiff_t ip2, + double kk ) +{ + x[i] = ( (p2.x[ip2] - p1.x[ip1]) * kk ); + y[i] = ( (p2.y[ip2] - p1.y[ip1]) * kk ); + if ( w != NULL ) + w[i] = ( (p2.w[ip2] - p1.w[ip1]) * kk ); +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector2D::Set( ptrdiff_t i, const MbNURBSVector2D & p, ptrdiff_t ip, double kk ) +{ + x[i] = ( p.x[ip] * kk ); + y[i] = ( p.y[ip] * kk ); + if ( w != NULL ) + w[i] = ( p.w[ip] * kk ); +} + + +#endif // __CUR_NURBS_VECTOR_H + diff --git a/C3d/Include/cur_nurbs_vector3d.h b/C3d/Include/cur_nurbs_vector3d.h new file mode 100644 index 0000000..869d4dd --- /dev/null +++ b/C3d/Include/cur_nurbs_vector3d.h @@ -0,0 +1,187 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Nurbs-вектор. + \en Nurbs-vecor. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_NURBS_VECTOR3D_H +#define __CUR_NURBS_VECTOR3D_H + +#include +#include + +//------------------------------------------------------------------------------ +/** \brief \ru Координаты для Nurbs-вектора. + \en Coordinates for Nurbs-vector. \~ + \details \ru Тройка координат для трехмерного Nurbs-вектора. \n + \en Three coordinates for three-dimensional Nurbs-vector. \n \~ +\ingroup Data_Structures +*/ +// --- +struct DoubleTriple +{ + double x; + double y; + double z; + + // \ru Инициализация. \en Initialization. + void Init( double xx, double yy, double zz ) { x = xx; y = yy; z = zz; } + + // \ru Инициализация. \en Initialization. + void Init( const DoubleTriple & ip ) { Init( ip.x, ip.y, ip.z ); } + + // \ru Инициализация. \en Initialization. + void Init( const DoubleTriple & ip, double iw ) { Init( ip.x * iw, ip.y * iw, ip.z * iw ); } + + // \ru Инициализация. \en Initialization. + void Init( const MbCartPoint3D & ip, double iw ) { Init( ip.x * iw, ip.y * iw, ip.z * iw ); } + + // \ru Присвоение значений. \en Values assignment. + void Dec( const DoubleTriple & p1, const DoubleTriple & p2, double kk ) { + Init( ( p2.x - p1.x ) * kk, ( p2.y - p1.y ) * kk, ( p2.z - p1.z ) * kk ); + } + +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Nurbs-вектор. + \en Nurbs-vector. \~ + \details \ru Трёхмерный Nurbs-вектор. \n + \en Three-Dimensional Nurbs-vector. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbNURBSVector { + std::vector _vec; + std::vector _w; + bool useWeights; + +public: + MbNURBSVector() : useWeights( false ) {} + ~MbNURBSVector(); // \ru освободить память \en free memory + +public: + bool CatchMemory( ptrdiff_t count, bool bWeight ); // \ru выделить память \en allocate memory + void FreeMemory(); // \ru освободить память \en free memory + void Init( ptrdiff_t i, const DoubleTriple & ip, double iw ); + void Init( ptrdiff_t i, double ipx, double ipy, double ipz, double iw ); + void SetZero( ptrdiff_t i ); + void Set( ptrdiff_t i, const MbNURBSVector & p, ptrdiff_t ip ); + void Dec( ptrdiff_t i, const MbNURBSVector & p1, ptrdiff_t ip1, const MbNURBSVector & p2, ptrdiff_t ip2, double kk ); + void Set( ptrdiff_t i, const MbNURBSVector & p, ptrdiff_t ip, double kk ); + void Set( ptrdiff_t i, const DoubleTriple * t, double * ww, ptrdiff_t ip ); + void Set( ptrdiff_t i, const DoubleTriple & t ); + + double& x( ptrdiff_t i ) { return _vec[i].x; } + double& y( ptrdiff_t i ) { return _vec[i].y; } + double& z( ptrdiff_t i ) { return _vec[i].z; } + double& w( ptrdiff_t i ) { return _w[i]; } + const double& x( ptrdiff_t i ) const { return _vec[i].x; } + const double& y( ptrdiff_t i ) const { return _vec[i].y; } + const double& z( ptrdiff_t i ) const { return _vec[i].z; } + const double& w( ptrdiff_t i ) const { return _w[i]; } + bool UseWeights() { return useWeights; } + + DoubleTriple& operator [] ( ptrdiff_t i ) { return _vec[i]; } + const DoubleTriple& operator [] ( ptrdiff_t i ) const { return _vec[i]; } + +private: + MbNURBSVector( const MbNURBSVector & ); // \ru не реализовано \en not implemented + void operator = ( const MbNURBSVector & ); // \ru не реализовано \en not implemented +}; + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::Init( ptrdiff_t i, const DoubleTriple & ip, double iw ) +{ + if ( !useWeights ) { + _vec[i].Init( ip.x, ip.y, ip.z ); + } + else { + _vec[i].Init( ip.x * iw, ip.y * iw, ip.z * iw ); + w(i) = iw; + } +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::Init( ptrdiff_t i, double ipx, double ipy, double ipz, double iw ) +{ + if ( !useWeights ) { + x(i) = ipx; + y(i) = ipy; + z(i) = ipz; + } + else { + x(i) = ( ipx * iw ); + y(i) = ( ipy * iw ); + z(i) = ( ipz * iw ); + w(i) = iw; + } +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::SetZero( ptrdiff_t i ) { + x(i) = 0.0; + y(i) = 0.0; + z(i) = 0.0; + if ( useWeights ) + w(i) = 0.0; +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::Set( ptrdiff_t i, const MbNURBSVector & p, ptrdiff_t ip ) { + _vec[i].Init( p[ip].x, p[ip].y, p[ip].z ); + if ( useWeights ) + w(i) = p.w(ip); +} + + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::Dec( ptrdiff_t i, + const MbNURBSVector & p1, ptrdiff_t ip1, + const MbNURBSVector & p2, ptrdiff_t ip2, + double kk ) +{ + _vec[i].Init( ( p2[ip2].x - p1[ip1].x ) * kk, ( p2[ip2].y - p1[ip1].y ) * kk, ( p2[ip2].z - p1[ip1].z ) * kk ); + if ( useWeights ) + w(i) = ( (p2.w(ip2) - p1.w(ip1)) * kk ); +} + +//------------------------------------------------------------------------------ +// +// --- +inline void MbNURBSVector::Set( ptrdiff_t i, const MbNURBSVector & p, ptrdiff_t ip, double kk ) { + _vec[i].Init( p[ip].x * kk, p[ip].y * kk, p[ip].z * kk ); + if ( useWeights ) + w(i) = ( p.w(ip) * kk ); +} + +inline void MbNURBSVector::Set( ptrdiff_t i, const DoubleTriple * t, double * ww, ptrdiff_t ip ) +{ + _vec[i].Init( t[ip].x , t[ip].y , t[ip].z ); + if ( useWeights && ww != NULL ) + w(i) = ww[ip]; +} + +inline void MbNURBSVector::Set( ptrdiff_t i, const DoubleTriple & t ) +{ + _vec[i].Init( t.x , t.y , t.z ); +} + +#endif // __CUR_NURBS_VECTOR3D_H diff --git a/C3d/Include/cur_offset_curve.h b/C3d/Include/cur_offset_curve.h new file mode 100644 index 0000000..81cabed --- /dev/null +++ b/C3d/Include/cur_offset_curve.h @@ -0,0 +1,296 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Эквидистантная продолженная кривая. + \en Offset extended curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_OFFSET_CURVE_H +#define __CUR_OFFSET_CURVE_H + + +#include +#include +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Эквидистантная продолженная кривая. + \en Offset extended curve. \~ + \details \ru Эквидистантная продолженная кривая строится смещением точек базовой кривой вдоль нормали к ней. \n + Параметры "offsetTmin, offsetTmax" задают смещение точек базовой кривой в точках tmin, tmax. + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией \n + r(t) = basisCurve(t) + (Offset0(t) * normal(t)), где normal(t) - нормаль базовой кривой. \n + Базовой кривой для эквидистантной кривой не может служить другая эквидистантная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Offset extended curve is constructed by shifting points of the base curve along a normal to it. \n + The "offsetTmin, offsetTmax" parameters set shift of base curve on begin and end points. + Radius-vector of the curve in the method PointOn(double&t,MbCartPoint3D&r) is described by the function \n + r(t) = basisCurve(t) + (Offset0(t) * normal(t)), where normal(t) - normal of base curve. \n + Base curve for offset curve can not be other offset curve. + In such situation it changes to the initial base curve. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbOffsetCurve : public MbCurve { +protected : + MbCurve * basisCurve; ///< \ru Базовая кривая (всегда не NULL) \en Base curve (always not NULL). + double tmin; ///< \ru Начальный параметр basisCurve. \en Start parameter of basisCurve. + double tmax; ///< \ru Конечный параметр basisCurve. \en End parameter of basisCurve. + bool closed; ///< \ru Замкнутость basisCurve. \en Closedness of basisCurve. + double offsetTmin; ///< \ru Смещение от базовой кривой по нормали в точке tmin. \en The offset from the base curve along normal in point tmin. + double offsetTmax; ///< \ru Смещение от базовой кривой по нормали в точке tmax. \en The offset from the base curve along normal in point tmax. + MbeOffsetType type; ///< \ru Тип смещения точек: константный, линейный или кубический. \en The type of points offset: constant, or linear, or cubic. + double deltaTmin; ///< \ru Увеличение tmin параметра базовой кривой. \en Increase of tmin of base curve parameter. + double deltaTmax; ///< \ru Увеличение tmax параметра базовой кривой. \en Increase of tmax of base curve parameter. + MbMatrix transform; ///< \ru Матрица преобразования (используется при разных масштабных коэффициентах трансформации). \en A transformation matrix (is used for different scale transformation). + + mutable MbRect rect; ///< \ru Габаритный прямоугольник \en Bounding box + mutable double metricLength; ///< \ru Метрическая длина \en The metric length + +public : + MbOffsetCurve( const MbCurve & bc, double dist, double t1, double t2, bool same ); + MbOffsetCurve( const MbCurve & bc, double dist, double t1, double t2, const MbMatrix & matr, bool same ); + MbOffsetCurve( const MbCurve & bc, double dist, bool same ); + MbOffsetCurve( const MbCurve & bc, double dist, const MbMatrix & matr, bool same ); + + /** \brief \ru Конструктор по базовой кривой и смещению c приращениями параметров. + \en Constructor by base curve and offset with increments of parameters. \~ + \details \ru Смещение задано на краях параметрической области базовой кривой и может изменяться по константному, линейному и кубическому законам.\n + Приращение параметров нужно использовать для изменения области определения кривой относительно базовой кривой. + \en The offset displacement is defined in the begin and the end of the parametric region of the base curve and can be changed by constant, linear and cubic laws.\n + Increment of parameters needs to be used for change of curve domain relative to base curve. \~ + \param[in] bc - \ru Базовая кривая. + \en Base curve. \~ + \param[in] d1 - \ru Смещение в точке Tmin базовой кривой. + \en Offset distance on point Tmin of base curve. \~ + \param[in] d2 - \ru Смещение в точке Tmax базовой кривой. + \en Offset distance on point Tmax of base curve. \~ + \param[in] t - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[in] t1 - \ru Минимальный параметр кривой. + \en The maximum parameter of offset curve. \~ + \param[in] t2 - \ru Максимальный параметр кривой. + \en The minimum parameter of offset curve. \~ + \param[in] matr - \ru Матрица преобразования (единичная или анизотропная). + \en The matrix (single or anisotropic). \~ + \param[in] same - \ru Признак использования оригинала базовой кривой, а не ее копии. + \en Attribute of usage of original of base curve, not copy. \~ + */ + MbOffsetCurve( const MbCurve & bc, double d1, double d2, MbeOffsetType t, double t1, double t2, const MbMatrix & matr, bool same ); + +protected : + MbOffsetCurve( const MbOffsetCurve &, MbRegDuplicate * ireg ); +private: + MbOffsetCurve( const MbOffsetCurve & ); // \ru Не реализовано. \en Not implemented. +public : + virtual ~MbOffsetCurve (); + +public : + VISITING_CLASS( MbOffsetCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSimilar ( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the 'curve' curve is duplicate of current curve. + virtual void AddYourGabaritTo( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к \en Add bounding box into a straight box + + /** \} */ + /** \ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + /** \brief \ru Инициализация по смещению и приращениям параметров. + \en Initialization by offset and increments of parameters. \~ + \details \ru Смещение задано на краях параметрической области базовой кривой и может изменяться по константному, линейному и кубическому законам.\n + Приращение параметров нужно использовать для изменения области определения кривой относительно базовой кривой. + \en The offset displacement is defined in the begin and the end of the parametric region of the base curve and can be changed by constant, linear and cubic laws.\n + Increment of parameters needs to be used for change of curve domain relative to base curve. \~ + \param[in] d1 - \ru Смещение в точке Tmin базовой кривой. + \en Offset distance on point Tmin of base curve. \~ + \param[in] d2 - \ru Смещение в точке Tmax базовой кривой. + \en Offset distance on point Tmax of base curve. \~ + \param[in] t - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[in] t1 - \ru Увеличение tmin параметра + \en Increment of tmin parameter \~ + \param[in] t2 - \ru Увеличение tmax параметра + \en Increment of tmax parameter \~ + */ + void Init( double d1, double d2, MbeOffsetType t, double t1, double t2 ); + void Init( double d, double t1, double t2 ); + void Init( double t1, double t2 ); + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is outside domain. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & pnt ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct parameter + when it is out of domain bounds. When parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Function of moving by curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of approximation step with consideration of deviation angle + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common function of curve. + \{ */ + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual MbCurve * Offset( double rad ) const; // \ru Смещение смещенной кривой \en Offset of the offset curve + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change to the opposite direction of a curve + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + // BUG_54628 + // \ru Функция не работает для самопересекающейся кривой \en This function does not work for self-intersecting curve + // \ru Проекция точки на кривую \en Point projection on the curve + // virtual double PointProjection( const MbCartPoint & pnt ) const; + + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + // \ru Удалить часть смещенной кривой между параметрами t1 и t2 \en Delete a part of a offset curve between parameters t1 and t2 + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть смещенной кривой между параметрами t1 и t2 \en Save a part of a offset curve between t1 and t2 parameters + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); + virtual MbCurve * Trimmed ( double t1, double t2, int sense ) const; + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + bool Break( MbNurbs &nurbs, double t1, double t2, ptrdiff_t degree ); + + virtual bool IsBounded() const; // \ru Признак ограниченной кривой \en Attribute of a bounded curve + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + + virtual bool HasLength( double & length ) const; + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Evaluation of the metric length of the curve + + virtual const MbCurve & GetBasisCurve() const; + virtual MbCurve & SetBasisCurve(); + + virtual bool GetAxisPoint( MbCartPoint & p ) const; // \ru Точка для построения оси \en A point to the axis construction + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en The number of partitions for passage in the operations + + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; // \ru Определение особых точек офсетной кривой \en Determination of singular points of the offset curve + virtual double Curvature( double t ) const; // \ru Кривизна кривой \en Curvature of the curve + // \ru Сдвинуть параметр t на расстояние len \en Move parameter t on the distance len + virtual bool DistanceAlong( double & t1, double ln, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves are similar for merge (joining) + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + void SetBasisCurve( MbCurve & ); // \ru Установить базовую кривую \en Set the base curve + // \ru Тип смещения точек. \en The type of points offset. + MbeOffsetType GetOffsetType() const { return type; } + // \ru Постоянное ли смещение точек? \en Is const the offset type? + bool IsConstOffset() const { return ( (type == off_Empty) || (type == off_Const) ); } + // \ru Величина смещения. \en The offset distance. + double GetDistance( size_t i = 0 ) const { + if ( i == 1 ) return offsetTmax; + return offsetTmin; + } + + /** \brief \ru Установить величины смещения. + \en Set offset distances. \~ + \param[in] d - \ru Новая величина смещения + \en New offset distance \~ + */ + void SetDistance( double d, size_t i = 0 ); + + const MbRect & GetGabarit() const { if ( rect.IsEmpty() ) CalculateGabarit( rect ); return rect; } + void SetDirtyGabarit() const { rect.SetEmpty(); } + const double & GetDmin() const { return deltaTmin; } // \ru Дать расширение начала \en Get extension of start + const double & GetDmax() const { return deltaTmax; } // \ru Дать расширение конца \en Get extension of end + void SetDmin( double d ) { deltaTmin = d; } // \ru Установить расширение начала \en Set extension of start + void SetDmax( double d ) { deltaTmax = d; } // \ru Установить расширение конца \en Set extension of end + + double GetBegExtend() const { return deltaTmin; } // \ru Дать расширение начала \en Get extension of start + double GetEndExtend() const { return deltaTmax; } // \ru Дать расширение конца \en Get extension of end + int ExtendedParam( double &t ) const; // \ru Проверка, лежит ли параметр в пределах \en Check if parameter is in range + void GetCurves( RPArray & curves ); // \ru Дать составляющие кривые \en Get curves + + bool operator == ( const MbOffsetCurve & ) const; // \ru Проверка на равенство \en Check for equality + bool operator != ( const MbOffsetCurve & ) const; // \ru Проверка на неравенство \en Check for inequality + + bool SubstrateParamOn( double &t, double &delta ) const; // \ru Находится ли параметр в пределах подложки \en Check if parameter is in the range of substrate + bool IsMatrixSingle() const { return transform.IsSingle(); } ///< \ru Является ли матрица преобразования единичной. \en Whether the transformation matrix is unit. + const MbMatrix & GetMatrix() const { return transform; } ///< \ru Матрица преобразования. \en A transformation matrix. + + /** \} */ + +private: + // \ru Вычисление эквидистанты и её производных. \en The offset calculation and it derivatives calculation. + double Offset0 ( double t ) const; + double OffsetT ( double t ) const; + double OffsetTT ( double t ) const; + double OffsetTTT( double t ) const; + + void operator = ( const MbOffsetCurve & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbOffsetCurve ) +}; // MbOffsetCurve + +IMPL_PERSISTENT_OPS( MbOffsetCurve ) + +#endif // __CUR_OFFSET_CURVE_H diff --git a/C3d/Include/cur_offset_curve3d.h b/C3d/Include/cur_offset_curve3d.h new file mode 100644 index 0000000..f86fdf3 --- /dev/null +++ b/C3d/Include/cur_offset_curve3d.h @@ -0,0 +1,214 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Эквидистантная кривая в трехмерном пространстве. + \en Offset curve in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_OFFSET_CURVE3D_H +#define __CUR_OFFSET_CURVE3D_H + + +#include +#include +#include + + +class MATH_CLASS MbSpine; + + +//------------------------------------------------------------------------------ +/** \brief \ru Эквидистантная кривая в трехмерном пространстве. + \en Offset curve in three-dimensional space. \~ + \details \ru Эквидистантная кривая строится смещением точек базовой кривой вдоль некоторого вектора, + направление которого может меняться вдоль кривой. \n + Вектор offset задаёт смещение начальной точки базовой криаой. + В процессе движения вдоль кривой вектор offset сохраняет своё положение в движущейся локальной системе координат, + начало которой совпадает с текущей точкой базовой кривой. + Одна из осей движущейся локальной системы координат всегда совпадает с касательной базовой кривой, + а две другие оси ортогональны ей. + Базовой кривой для эквидистантной кривой не может служить другая эквидистантная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Offset curve is constructed by shifting points of the base curve along some vector, + direction of which can be changed along the curve. \n + Vector "offset" sets the offset of start point of the base curve. + While moving along a curve the vector "offset" keeps the position in the moving local coordinate system, + origin coincides with the current point of the base curve. + One of the axes of the moving local coordinate system is always the same as the tangent of the base curve, + and the other two axes are orthogonal to it. + Base curve for offset curve can not be other offset curve. + In this situation it changes to the initial base curve. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbOffsetCurve3D : public MbCurve3D { +protected : + MbSpine * basisCurve; ///< \ru Базовая кривая. \en The base curve. + double tmin; ///< \ru Начальный параметр basisCurve. \en Start parameter of basisCurve. + double tmax; ///< \ru Конечный параметр basisCurve. \en End parameter of basisCurve. + bool closed; ///< \ru Замкнутость basisCurve. \en Closedness of basisCurve. + MbVector3D offset; ///< \ru Смещение в начальной точке. \en Offset in start point. + double factorTmin; ///< \ru Множитель смещения offset в точке tmin базовой кривой. \en The offset multiplier in point tmin of base curve. + double factorTmax; ///< \ru Множитель смещения offset в точке tmax базовой кривой. \en The offset multiplier in point tmax of base curve. + MbeOffsetType type; ///< \ru Тип смещения: константный, линейный или кубический. \en The type of offset: constant, or linear, or cubic. + double deltaTmin; ///< \ru Увеличение tmin параметра базовой кривой. \en Increase of tmin of base curve parameter. + double deltaTmax; ///< \ru Увеличение tmax параметра базовой кривой. \en Increase of tmax of base curve parameter. + mutable MbCube cube; ///< \ru Габаритный куб. \en Bounding box. + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор эквидистантной кривой по спайну и вектору.\n + \en Constructor by a curve and offset vector in start point.\n \~ + \param[in] c - \ru Базовая кривая. \en The base curve. \~ + \param[in] off - \ru Вектор смещения начальной точки кривой. \en Offset in start point. \~ + \param[in] same - \ru Использовать присланную кривую (true) или ее копию (false). + \en Use same curve (true) or copy (false). \~ + \param[in] ort - \ru Ортогонализовать вектор к касательной кривой в начальной точке. + \en Ortogonalize offset vector (true) or same vector (false). \~ + */ + MbOffsetCurve3D( const MbCurve3D & c, const MbVector3D & off, bool same, bool ort, VERSION version = Math::DefaultMathVersion() ); +private : + MbOffsetCurve3D( const MbOffsetCurve3D & ); // \ru Не реализовано. \en Not implemented. +protected: + MbOffsetCurve3D( const MbOffsetCurve3D & init, MbRegDuplicate * ireg ); + +public : + virtual ~MbOffsetCurve3D(); + +public: + VISITING_CLASS( MbOffsetCurve3D ); + + /** \brief \ru Инициализация по смещению и приращениям параметров. + \en Initialization by offset and increments of parameters. \~ + \details \ru Смещение задано на краях параметрической области базовой кривой и может изменяться по константному, линейному и кубическому законам.\n + Приращение параметров нужно использовать для изменения области определения кривой относительно базовой кривой. + \en The offset displacement is defined in the begin and the end of the parametric region of the base curve and can be changed by constant, linear and cubic laws.\n + Increment of parameters needs to be used for change of curve domain relative to base curve. \~ + \param[in] d1 - \ru Смещение в точке Tmin базовой кривой. + \en Offset distance on point Tmin of base curve. \~ + \param[in] d2 - \ru Смещение в точке Tmax базовой кривой. + \en Offset distance on point Tmax of base curve. \~ + \param[in] t - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[in] dt1 - \ru Изменение tmin параметра + \en The change of tmin parameter \~ + \param[in] dt2 - \ru Изменение tmax параметра + \en The change of tmax parameter \~ + */ + void Init( double d1, double d2, MbeOffsetType t, double dt1, double dt2 ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * ireg ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void Refresh (); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб \en Add bounding box into a cube + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; + virtual double GetTMax() const; + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closedness + virtual double GetPeriod() const; // \ru Период кривой \en Curve period + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & p ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector3D & fd ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & sd ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & td ) const; // \ru Третья производная по t \en Third derivative with respect to t + + // \ru ЗАКОМЕНТАРЕНО в связи с необходимостью использовать строгое продолжение по касательной \en COMMENTED because it is necessary to use a strong extension by the tangent + //virtual void _PointOn ( double t, MbCartPoint3D &p ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + //virtual void _FirstDer ( double t, MbVector3D &fd ) const; // \ru Первая производная \en The first derivative + //virtual void _SecondDer( double t, MbVector3D &sd ) const; // \ru Вторая производная \en The second derivative + //virtual void _ThirdDer ( double t, MbVector3D &td ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of approximation step + virtual double DeviationStep( double t, double angle ) const; + + virtual const MbCurve3D & GetBasisCurve() const; + virtual MbCurve3D & SetBasisCurve(); +//virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual size_t GetCount() const; + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether a curve is planar + + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if curve is planar + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + /// \ru Смещение в начальной точке. \en Offset in the start point. + const MbVector3D & GetOffsetVector() const { return offset; } + // \ru Тип смещения точек. \en The type of points offset. + MbeOffsetType GetOffsetType() const { return type; } + // \ru Постоянное ли смещение точек? \en Is const the offset type? + bool IsConstOffset() const { return ( (type == off_Empty) || (type == off_Const) ); } + // \ru Множитель смещения. \en The offset multiplier. + double GetFactor( size_t i = 0 ) const { + if ( i == 1 ) return factorTmax; + return factorTmin; + } + + /** \brief \ru Установить множитель смещения. \en Set offset multiplier. \~ + \param[in] d - \ru Новый множитель смещения. \en New offset multiplier. \~ + */ + void SetFactor( double d, size_t i = 0 ); + // \ru Проверить факторы и тип. \en Check factors and typr. + void CheckFactor(); + + const MbCube & GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } // \ru Выдать габарит кривой \en Get the bounding box of curve + bool IsSelfIntersect() const; + /** \brief \ru Поиск точек излома оффсетной кривой. + \en Search of break points of the offset curve. \~ + \details \ru Для нахождения точек точек излома используется характеристическая функция Ratio(), + представляющая собой разность аналитически и численно посчитанной производной деленную + на модуль аналитической производной и величину шага, использованного для численного рассчета производной. + Увеличение этой функции на порядок по сравнению с ее значением в гладкой области означает точку излома. \n + \en To find the break points using the characteristic function Ratio(), + which represents a difference between the analytical and numerical calculated derivative divided + by module of analytical derivative and step used for numerical calculation of the derivative. + Increase of this function on the order in comparison with its value in smooth region is a break point. \n \~ + \param[out] breakParams - \ru Массив параметров точек излома + \en Parameter array of break points \~ + */ + void FindBreakParams( SArray & breakParams ) const; + int ExtendedParam( double &t ) const; // \ru Проверка, лежит ли параметр в пределах \en Check if parameter is in range + +private: + // \ru Вычисление множителя смещения и его производных. \en The offset multiplier and it derivatives. + double Factor0 ( double t ) const; + double FactorT ( double t ) const; + double FactorTT ( double t ) const; + double FactorTTT( double t ) const; + + void operator = ( const MbOffsetCurve3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbOffsetCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbOffsetCurve3D ) + + +#endif // __CUR_OFFSET_CURVE3D_H diff --git a/C3d/Include/cur_plane_curve.h b/C3d/Include/cur_plane_curve.h new file mode 100644 index 0000000..30c34cc --- /dev/null +++ b/C3d/Include/cur_plane_curve.h @@ -0,0 +1,194 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Плоская кривая в трехмерном пространстве. + \en Plane curve in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_PLANE_CURVE_H +#define __CUR_PLANE_CURVE_H + + +#include +#include +#include + + +class MATH_CLASS MbContour; + + +//------------------------------------------------------------------------------ +/** \brief \ru Плоская кривая в трехмерном пространстве. + \en Plane curve in three-dimensional space. \~ + \details \ru Плоская кривая описывается двумерной кривой curve в плоскости XY локальной системы координат position. \n + Радиус-вектор кривой в методе PointOn(double&t,MbCartPoint3D&r) описывается векторной функцией: \n + r(t) = position.origin + (position.axisX point.x) + (position.axisY point.y), + где point = curve(t); + \en Plane curve is described by two-dimensional uv-curve in the XY-plane of the local coordinate system "position". \n + The radius-vector of curve in the method PointOn(double&t,MbCartPoint3D&r) is described by a vector function: \n + r(t) = position.origin + (position.axisX point.x) + (position.axisY point.y), + where point = curve(t); \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbPlaneCurve : public MbCurve3D { +protected : + MbPlacement3D position; ///< \ru Локальная система координат, в плоскости XY которой расположена кривая. \en The local coordinate system in XY plane of which the curve is located. + MbCurve * curve; ///< \ru Двумерная кривая (не может быть NULL). \en A two-dimensional uv-curve (can not be NULL). + +public : + /// \ru same = false - копировать кривую init. \en Same = false - copy the curve "init". + MbPlaneCurve( const MbPlacement3D &, const MbCurve & init, bool same ); +protected: + MbPlaneCurve( const MbPlaneCurve & ); +public : + virtual ~MbPlaneCurve(); + +public : + VISITING_CLASS( MbPlaneCurve ); + + void Init( const MbPlaneCurve &init ); + void Init( const MbPlacement3D &pl, MbCurve &initCurve ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией \en Whether the object is a copy + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать \en Transform. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Расстояние до точки \en Distance to a point + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; // \ru Являются ли объекты идентичными в пространстве \en Are the objects identical in space? + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + virtual void Normal ( double & t, MbVector3D & ) const; // \ru Вектор главной нормали \en Vector of the principal normal + // \ru Функции кривой для работы вне области определения параметрической кривой \en Functions of curve for working outside the domain of parametric curve + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en First derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en Second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en Third derivative with respect to t + virtual void _Normal ( double t, MbVector3D & ) const; // \ru Вектор главной нормали \en Vector of the principal normal + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; + + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Creation of a trimmed curve + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + virtual double Curvature( double ) const; // \ru Кривизна кривой \en Curvature of the curve + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Evaluation of the metric length of the curve + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double CalculateLength( double t1, double t2 ) const; + // \ru Сдвинуть параметр t на расстояние len по направлению \en Shift the parameter t by the distance 'len' in the direction + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + virtual bool IsPlanar() const; // \ru Является ли кривая плоской \en Whether a curve is planar + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of contour\curve are smooth. + // \ru Ближайшая точка кривой к плейсменту \en The nearest point of a curve by the placement + virtual double DistanceToPlace( const MbPlacement3D & place, double & t0, double & angle ) const; + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of curve + virtual MbCurve * GetMapPsp( const MbMatrix3D &, double zNear, + MbRect1D * pRgn = NULL ) const; + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой \en Get the curve axis + virtual void GetCentre ( MbCartPoint3D & wc ) const; + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual size_t GetCount () const; + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curves equally spaced by the arc length + + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой \en Calculate the bounding box of curve + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Give a planar curve and placement, if the spatial curve is planar (after using the DeleteItem must be called for a two-dimensional curve) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы) \en Get a surface curve if spatial curve is lying on the surface (after the using call DeleteItem for arguments) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Заполнить плейсемент, если кривая плоская \en Fill the placement if curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + MbCurve * GetCurve ( const MbPlacement3D & , MbMatrix & ) const; // \ru Дать плоскую кривую \en Get the plane curve + MbCurve * MakeCurve( const MbPlacement3D & ) const; + MbCurve3D * MakeCurve() const; // \ru Дать пространственную кривую \en Get the spatial curve + + void SetCurve( const MbCurve & ); // \ru Заменить плоскую кривую \en Replace the plane curve + void SetOrigin( const MbCartPoint3D & org ) { position.SetOrigin(org); } + + const MbPlacement3D & GetPlacement() const { return position; } + const MbCurve & GetCurve() const { return *curve; } // \ru Дать плоскую кривую \en Get the plane curve + MbCurve & SetCurve() { return *curve; } // \ru Дать плоскую кривую \en Get the plane curve + + // \ru Является ли объект смещением? \en Is the object a shift? + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves are similar for merge (joining) + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + +private: + void operator = ( const MbPlaneCurve & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPlaneCurve ) +}; + +IMPL_PERSISTENT_OPS( MbPlaneCurve ) + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздать пространственную кривую. + \en Create a spatial curve. \~ + \details \ru Создать пространственную кривую как точное представление двумерной кривой на плоскости. + \en Create a spatial curve as an accurate representation of the two-dimensional uv-curve on the plane. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (MbCurve3D *) MakeCurve3D( const MbCurve & curve, const MbPlacement3D & ); + + +//------------------------------------------------------------------------------- +// \ru Создать по плоской кривой подложке пространственную кривую \en Create a spatial curve from plane curve of substrate +// \ru (кривой должен кто-то владеть иначе она может быть уничтожена) \en (someone must own the curve otherwise it can be destroyed) +// --- +MbCurve3D & GetCurve3DWithCheckingPlaneCur( MbCurve3D & initCur ); + + +#endif // __CUR_PLANE_CURVE_H diff --git a/C3d/Include/cur_point_curve.h b/C3d/Include/cur_point_curve.h new file mode 100644 index 0000000..f306747 --- /dev/null +++ b/C3d/Include/cur_point_curve.h @@ -0,0 +1,186 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая, вырожденная в точку. + \en The curve degenerated to a point. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_POINT_CURVE_H +#define __CUR_POINT_CURVE_H + +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая, вырожденная в точку. + \en The curve degenerated to a point. \~ + \details \ru Кривая, вырожденная в точку, описывается точкой. + Для согласования с другими кривыми кривая формально может быть замкнутой или разомкнутой и + быть заданной на определённой области определения. \n + \en The curve degenerated to a point is described by point. + For consistency with other curves the curve can be closed or open formally and + be given on the specific domain. \n \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbPointCurve : public MbCurve { +protected: + MbCartPoint point; ///< \ru Точка. \en A point. + bool closed; ///< \ru Признак замкнутости \en A closedness attribute + double tmin; ///< \ru Начальное значение параметра. \en Initial value of parameter. + double tmax; ///< \ru Конечное значение параметра. \en Final value of parameter. + +public : + MbPointCurve( const MbCartPoint &p, double t1, double t2, bool cl ); + MbPointCurve( const MbCartPoint &p, bool cl ); + MbPointCurve( bool cl ); +protected: + MbPointCurve( const MbPointCurve & ); +public : + virtual ~MbPointCurve(); + +public : + VISITING_CLASS( MbPointCurve ); + + /** \ru \name Функции кривой, вырожденной в точку. + \en \name Functions of curve degenerated to a point. + \{ */ + void Init( const MbCartPoint &p, double t1, double t2, bool cl ); + void Init( double t1, double t2, bool cl ); + void Init( const MbCartPoint &p ); + void SetTMin ( double t ) { tmin = t; } + void SetTMax ( double t ) { tmax = t; } + void SetClosed( bool cl ) { closed = cl; } + + /** \} */ + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make equal elements + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); + virtual void AddYourGabaritTo ( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к \en Add bounding box into a straight box + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const; // \ru Добавь в прям-к свой габарит с учетом матрицы \en Add bounding box into a box with consideration of the matrix + virtual double DistanceToPoint( const MbCartPoint & to ) const; // \ru Расстояние до точки \en Distance to a point + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether the 'curve' curve is duplicate of current curve. + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике \en Whether the object is visible in the given rectangle + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости \en Check for closedness + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is out of domain bounds. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on curve + virtual void FirstDer ( double & t, MbVector & v ) const; // \ru Первая производная \en First derivative + virtual void SecondDer( double & t, MbVector & v ) const; // \ru Вторая производная \en Second derivative + virtual void ThirdDer ( double & t, MbVector & v ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct parameter + when it is out of domain bounds. When parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; // \ru Точка на кривой или на её продолжении \en Point on the curve or on its extension + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Function of moving by curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of approximation step with consideration of curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности \en Calculation of approximation step by angular tolerance + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common function of curve + \{ */ + virtual double Curvature( double t ) const; // \ru Кривизна усеченной кривой \en Curvature of a trimmed curve + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление кривой \en Change direction of a curve + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности \en Check for degeneracy + virtual bool HasLength( double & length ) const; + + virtual MbCurve * Offset( double rad ) const; // \ru Смещение отрезка \en Shift of a line segment + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + // \ru Удалить часть усеченной кривой между параметрами t1 и t2 \en Delete a part of a truncated curve between parameters t1 and t2 + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть усеченной кривой между параметрами t1 и t2 \en Keep a part of the trimmed curve between parameters t1 and t2 + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru Возвращает результат : \en Returning result: + // \ru iloc_OutOfItem = -1 - точка находится вне кривой, \en Iloc_OutOfItem = -1 - point is outside of the curve, + // \ru iloc_OnItem = 0 - точка находится на кривой. \en Iloc_OnItem = 0 - point is located on the curve, + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на отрезок \en Point projection on the line segment + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Point projection on the curve or its extension in the projection search area + virtual void IntersectHorizontal( double y, SArray & cross ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with the horizontal line + virtual void IntersectVertical ( double x, SArray & cross ) const; // \ru Пересечение с вертикальной прямой \en Intersection with the vertical line + + virtual double GetMetricLength() const; // \ru Метрическая длина \en The metric length + virtual bool GetMiddlePoint ( MbCartPoint & ) const; // \ru Выдать среднюю точку отрезка \en Calculate a middle point on a line segment + virtual bool GetCentre ( MbCartPoint & ) const; // \ru Выдать центр отрезка \en Get the center of a line segment + virtual bool GetWeightCentre( MbCartPoint & ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en The number of partitions for passage in the operations + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + const MbCartPoint & GetPoint() const { return point; } + MbCartPoint & SetPoint() { return point; } + + /** \} */ + +private: + void CheckParameter( double & t ) const; + void operator = ( const MbPointCurve & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPointCurve ) +}; // MbPointCurve + +IMPL_PERSISTENT_OPS( MbPointCurve ) + +#endif // __CUR_POINT_CURVE_H diff --git a/C3d/Include/cur_polycurve.h b/C3d/Include/cur_polycurve.h new file mode 100644 index 0000000..7c51bab --- /dev/null +++ b/C3d/Include/cur_polycurve.h @@ -0,0 +1,357 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая в двумерном пространстве, заданная точками. + \en Curve in two-dimensional space, defined by points. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_POLYCURVE_H +#define __CUR_POLYCURVE_H + + +#include +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая в двумерном пространстве, заданная точками. + \en Curve in two-dimensional space, defined by points. \~ + \details \ru Родительский класс кривых в двумерном пространстве, заданных контрольными точками: + MbBezier, MbCubicSpline, MbHermit, MbNurbs, MbPolyline. \n + \en Parent class of curves in two-dimensional space, defined by control points: + MbBezier, MbCubicSpline, MbHermit, MbNurbs, MbPolyline. \n \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbPolyCurve : public MbCurve, public MbNestSyncItem { +protected : + SArray pointList; ///< \ru Множество контрольных точек. \en Set of control points. + ptrdiff_t uppIndex; ///< \ru Количество участков кривой (равно количество контрольных точек минус единица). \en Count of curve pieces (is equal to count of control points minus one). + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + mutable MbRect rect; ///< \ru Габаритный прямоугольник. \en Bounding rectangle. + mutable double metricLength; ///< \ru Метрическая длина сплайна. \en Metric length of a spline. + +protected: + MbPolyCurve(); ///< \ru Конструктор по умолчанию. \en Default constructor. + MbPolyCurve( const MbPolyCurve & pCurve ); ///< \ru Конструктор копирования. \en Copy-constructor. +public : + virtual ~MbPolyCurve(); ///< \ru Деструктор. \en Destructor. + +public : + VISITING_CLASS( MbPolyCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const = 0; // \ru Тип элемента \en Type of element + virtual MbePlaneType Type() const; // \ru Тип элемента \en Type of element + virtual bool SetEqual( const MbPlaneItem & ) = 0; // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Является ли кривая curve копией данной кривой ? \en Whether curve 'curve' is a duplicate of the current curve. + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента \en Create a copy of the element + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавь свой габарит в прямой прям-к \en Add your own gabarit into the given bounding rectangle + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for description of a curve domain. + \{ */ + virtual double GetTMax() const = 0; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const = 0; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости сплайна \en Check the spline closedness + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + if it is out of domain bounds. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & pnt ) const = 0; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & fd ) const = 0; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & sd ) const = 0; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const = 0; // \ru Третья производная \en The third derivative + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const = 0; + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness. + virtual bool HasLength( double & length ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; // \ru Изменение направления кривой на противоположное \en Change curve direction to the opposite one + + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + virtual bool IsInRectForDeform( const MbRect & r ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the given rectangle for deformation + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en Count of subdivisions for pass in operations + + // \ru Дать метрическую длину кривой. \en Get metric length of curve. + virtual double GetMetricLength() const; + // \ru Дать оценочную длину кривой. \en Get evaluation length of curve. + virtual double GetLengthEvaluation() const; + // \ru Выдать характерную точку полилинии если она ближе чем dmax \en Get control point of polyline if it is closer than 'dmax' + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Общие функции полигональной кривой + \en \name Common functions of polygonal curve + \{ */ + virtual size_t GetPointsCount() const; ///< \ru Выдать количество контрольных точек. \en Get count of control points. + + /** \brief \ru Выдать характерную точку. + \en Get control point. \~ + \details \ru Возвращает характерную точку кривой по ее индексу. + Если индекс отрицательный - возвращает первую точку. + Если индекс больше максимального доступного, то возвращается последняя точка. + \en Returns control point of the curve by its index. + If the index is negative - returns the first point. + If the index is greater than the maximum available, then the last point is returned. \~ + \param[in] index - \ru Номер характерной точки. + \en Index of control point. \~ + \param[out] pnt - \ru Характерная точка. + \en Control point. \~ + */ + virtual void GetPoint( ptrdiff_t index, MbCartPoint & pnt ) const; // \ru Выдать точку \en Get point + + virtual ptrdiff_t GetNearPointIndex( const MbCartPoint & pnt ) const; ///< \ru Выдать индекс точки, ближайшей к заданной. \en Get index of the point nearest to the given one. + + /** \brief \ru Вернуть интервал влияния точки кривой. + \en Get the range of influence of point of the curve. \~ + \details \ru Определяет, на каком интервале параметра кривой скажется + изменение характерной точки с индексом index. + \en Determines which range of curve parameter will be affected by + changing of the control point with 'index' index. \~ + \param[in] index - \ru Номер характерной точки. + \en Index of control point. \~ + \param[out] t1 - \ru Минимальный параметр интервала влияния. + \en Minimal parameter of the range of influence. \~ + \param[out] t2 - \ru Максимальный параметр интервала влияния. + \en Maximal parameter of the range of influence. \~ + */ + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const = 0; + + virtual void Rebuild() = 0; ///< \ru Перестроить кривую. \en Rebuild curve. + virtual void SetClosed( bool cls ); ///< \ru Установить признак замкнутости. \en Set attribute of closedness. + + virtual void SetBegEndDerivesEqual(); ///< \ru Установить равные производные на краях. \en Set equal derivatives at the ends. + virtual void ClosedBreak(); ///< \ru Сделать незамкнутой, оставив совпадающими начало и конец. \en Make curve open, keeping coincidence of the beginning and the end. + + virtual void RemovePoint( ptrdiff_t index ); ///< \ru Удалить характерную точку с заданным индексом. \en Remove control point with given index. + virtual void RemovePoints(); ///< \ru Удалить все точки. \en Remove all points. + + virtual void AddPoint( const MbCartPoint & pnt ); ///< \ru Добавить точку в конец массива контрольных точек. \en Add point to the end of the array of control points. + + /** \brief \ru Изменить характерные точки. + \en Change control points. \~ + \details \ru Если количество точек в заданном массиве совпадает с текущим количеством точев, + то массив точек заменяется на новый. Если не совпадает, то характерные точки не меняются, + функция возвращает false. + \en If count of points in the given array is equal to the current count of points, + then the array of points is replaced by the new one. If not equal, then the control points are not changed, + the function returns false. \~ + \param[in] pntList - \ru Заданный массив контрольных точек. + \en The given array of control points. \~ + \return \ru true - если точки были изменены. + \en True if points have been changed. \~ + */ + virtual bool ChangePointsValue( const SArray & pntList ); // \ru Поменять точки \en Swap points + + /** \brief \ru Вставить точку в массив контрольных точек. + \en Insert a point to the array of control points. \~ + \details \ru Вставить заданную точку после точки с индексом index. + В функции не проверяется корректность индекса. + Надо заранее удостоверится, что заданный индекс меньше количества точек в массиве. + \en Insert the given point after the point with 'index' index. + Correctness of the index isn't checked in the function. + It is necessary to make sure in advance that the given index is less than the count of points in array. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] index - \ru Индекс, после которого надо вставить точку. + \en Index of point to insert a point after. \~ + */ + virtual void AddAfter( const MbCartPoint & pnt, ptrdiff_t index ); + + /** \brief \ru Вставить точку в массив контрольных точек. + \en Insert a point to the array of control points. \~ + \details \ru Вставить заданную точку по индексу. + \en Insert the given point by index. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] index - \ru Индекс, по которому надо вставить точку. + \en Index to insert a point by. \~ + */ + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ) = 0; // \ru Вставить точку по индексу \en Insert point by index + + /** \brief \ru Вставить точку в массив контрольных точек. + \en Insert a point to the array of control points. \~ + \details \ru Вставить точку, которая будет соответствовать параметру t кривой. + Если параметр t отличается от параметра некоторой точки меньше, чем на заданную погрешность, + то новая точка не вставляется, заменяется уже существующая близкая по параметру точка. + \en Insert a point which corresponds to parameter 't' of the curve. + If parameter 't' differs from the parameter of some point less than by the given tolerance, + then the new point isn't inserted, already existent point close by parameter is replaced. \~ + \param[in] t - \ru Параметр новой точки. + \en Parameter of the new point. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] xEps - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEps - \ru Точность по y. + \en Tolerance in y direction. \~ + */ + virtual void InsertPoint( double t, const MbCartPoint & pnt, double xEps, double yEps ) = 0; // \ru Вставить точку \en Insert a point + + /** \brief \ru Вставить точку в массив контрольных точек. + \en Insert a point to the array of control points. \~ + \details \ru Вставить точку и соответствующий ей вектор производной, + которая будет соответствовать параметру t кривой. + Если параметр t отличается от параметра некоторой точки меньше, чем на заданную погрешность, + то новая точка не вставляется, заменяется уже существующая близкая по параметру точка. + \en Insert a point and derivative vector corresponding to it, + which will correspond to parameter 't' of the curve. + If parameter 't' differs from the parameter of some point less than by the given tolerance, + then the new point isn't inserted, already existent point close by parameter is replaced. \~ + \param[in] t - \ru Параметр новой точки. + \en Parameter of the new point. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] v - \ru Производная в заданной точке. + \en Derivative at the given point. \~ + \param[in] xEps - \ru Точность по x. + \en Tolerance in x direction. \~ + \param[in] yEps - \ru Точность по y. + \en Tolerance in y direction. \~ + */ + virtual void InsertPoint( double t, const MbCartPoint & pnt, const MbVector & v, double xEps, double yEps ); // \ru Вставить точку по индексу \en Insert point by index + + /** \brief \ru Заменить полюс. + \en Replace a pole. \~ + \details \ru В общем случае функция эквивалентна ChangePoint() и заменяет характерную точку с указанным индексом. + \en Generally the function is equivalent to ChangePoint() and replaces a control point with the specified index. \~ + \param[in] index - \ru Индекс изменяемой точки. + \en Index of a point to be changed. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + */ + virtual void ChangePole ( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить полюс \en Replace a pole + + /** \brief \ru Заменить точку. + \en Replace a point. \~ + \details \ru Заменить точку. \n + \en Replace a point. \n \~ + \param[in] index - \ru Индекс изменяемой точки. + \en Index of a point to be changed. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + */ + virtual void ChangePoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Заменить точку \en Replace a point + + /** \brief \ru Переместить параметр в область определения кривой. + \en Drive a parameter into the curve domain. \~ + \details \ru Проверить параметр. Если он выходит за диапазон изменения параметров кривой, то + в случае замкнутой кривой привести его в область определения, изменяя на период. + В случае незамкнутой кривой - сделать равным ближайшему граничному параметру. + Определить индексы характерный точек, между которыми находится заданный параметр, + и их параметрические значения. + \en Check parameter. If it is out of the range of the curve parameters, then + in case of closed curve drive it into the definition domain with changing by period. + In case of open curve - make equal to the nearest boundary parameter. + Determine indices of control points the given parameter is between, + and also determine their parametric values. \~ + \param[in, out] t - \ru На входе - заданный параметр. На выходе - параметр в области определения кривой. + \en On input - the given parameter. On output - parameter in the curve definition domain. \~ + \param[out] i0 - \ru Индекс характерной точки слева от заданного параметра. + \en Index of control point to the left of the given parameter. \~ + \param[out] i1 - \ru Индекс характерной точки справа от заданного параметра. + \en Index of control point to the right of the given parameter. \~ + \param[out] t0 - \ru Параметр характерной точки слева от заданного параметра. + \en Parameter of control point to the left of the given parameter. \~ + \param[out] t1 - \ru Параметр характерной точки справа от заданного параметра. + \en Parameter of control point to the right of the given parameter. \~ + \return \ru true - если операция выполнена успешно. + \en True if the operation succeeded. \~ + */ + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const = 0; // \ru Загнать параметр получить локальный индексы и параметры \en Drive parameter into domain, get local indices and parameters + virtual double GetParam( ptrdiff_t i ) const = 0;///< \ru Вернуть параметр, соответствующий точке с указанным индексом. \en Get parameter corresponding to the point with specified index. + virtual size_t GetParamsCount() const = 0; ///< \ru Выдать количество параметров. \en Get count of parameters. + virtual void GetTList( SArray & params ) const; + + size_t GetPointListCount() const { return pointList.Count(); } ///< \ru Выдать количество характерный точек. \en Get count of control points. + ptrdiff_t GetPointListMaxIndex() const { return pointList.MaxIndex(); } ///< \ru Выдать максимальный индекс массива контрольных точек. \en Get maximal index of array of control points. + template + void GetPoints( Points & pnts ) const { std::copy( pointList.begin(), pointList.end(), std::back_inserter( pnts ) ); } ///< \ru Вернуть массив контрольных точек. \en Get array of control points. + void GetPointList( SArray & pnts ) const { pnts = pointList; } ///< \ru Вернуть массив контрольных точек. \en Get array of control points. + bool ReplacePoints( const SArray & pnts ); ///< \ru Заменить набор контрольных точек. \en Replace the set of control points. + + const MbCartPoint & GetPointList( size_t i ) const { return pointList[i]; } ///< \ru Вернуть характерную точку с заданным индексом. \en Get control point with the given index. + MbCartPoint & SetPointList( size_t i ) { Refresh(); return pointList[i]; } ///< \ru Вернуть характерную точку с заданным индексом. \en Get control point with the given index. + + ptrdiff_t GetUppIndex() const { return uppIndex; } ///< \ru Вернуть максимальный индекс массива контрольных точек. \en Get the maximal index of array of control points. + size_t GetSegmentsCount() const { return (uppIndex > 0) ? (uppIndex + (!!closed)) : 0; } ///< \ru Вернуть количество интервалов. \en Get count of ranges. + + /** \brief \ru Дать информацию для функции NurbsCurve. + \en Get information for NurbsCurve function. \~ + \details \ru Дать информацию для функции NurbsCurve. + Если отрезок кривой проходит через pmin у замкнутой кривой (например, [0.2, 1.1] для замкнутой кривой с параметризацией [0, 1]) + то i1, i2 учитывают это и могут нумероваться не с 0, а с GetPointsCount(), т.е. через период. + \en Get information for NurbsCurve function. + If curve segment passes through 'pmin' of a closed curve (for example, [0.2, 1.1] for closed curve with parameterization [0, 1]), + then i1, i2 consider it and can be enumerated from GetPointsCount(), i.e. by period, instead of 0. \~ + \param[in] epsilon - \ru Заданная точность. + \en Given accuracy. \~ + \param[in] pmin - \ru Параметр начала аппроксимируемой части кривой. + \en Parameter of the beginning of the curve piece being approximated . \~ + \param[in] pmax - \ru Параметр конца аппроксимируемой части кривой. + \en Parameter of the end of a curve piece being approximated. \~ + \param[in] i1 - \ru Индекс следующего за pmin значения параметра. + \en Index of the parameter value next 'pmin' . \~ + \param[in] t1 - \ru Индекс предшествующего pmax значения параметра. + \en Index of the parameter value preceding 'pmax'. \~ + \param[in] i2 - \ru Параметр следующей за pmin характерной точки. + \en Parameter of the control point next 'pmin' . \~ + \param[in] t2 - \ru Параметр предшествующей pmax характерной точки. + \en Parameter of the control point preceding 'pmax' . \~ + */ + bool NurbsParam( double epsilon, double & pmin, double & pmax, + ptrdiff_t & i1, double & t1, ptrdiff_t & i2, double & t2 ) const; + /** \} */ + +protected: + virtual bool CanChangeClosed() const; ///< \ru Определить, можно ли поменять признак замкнутости. \en Determine whether it is possible to change an attribute of closedness. + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + bool CompositeDistanceAlong( double & t, double len, int curveDir, double eps, const SArray & tList ) const; + // \ru Рассчитать метрическую длину сегмента кривой. \en Calculate metric length of curve segment. + double SegmentCalculateLength( double w1, double w2, size_t n, double * x, double * w ) const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + bool SegmentDistanceAlong( double & t1, double ln, int curveDir, double eps, double stepMax, size_t n, double * x, double * w ) const; + +private: + void operator = ( const MbPolyCurve & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS( MbPolyCurve ) +}; // MbPolyCurve + + +IMPL_PERSISTENT_OPS( MbPolyCurve ) + + +#endif // __CUR_POLYCURVE_H diff --git a/C3d/Include/cur_polycurve3d.h b/C3d/Include/cur_polycurve3d.h new file mode 100644 index 0000000..d068a46 --- /dev/null +++ b/C3d/Include/cur_polycurve3d.h @@ -0,0 +1,152 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая в трехмерном пространстве, заданная контрольными точками. + \en Curve in three-dimensional space, defined by control points. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_POLYCURVE3D_H +#define __CUR_POLYCURVE3D_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая в трехмерном пространстве, заданная точками. + \en Curve in three-dimensional space, defined by points. \~ + \details \ru Родительский класс кривых в трехмерном пространстве, заданных контрольными точками: + MbBezier3D, MbCubicSpline3D, MbHermit3D, MbNurbs3D, MbPolyline3D. \n + \en Parent class of curves in three-dimensional space, defined by control points: + MbBezier3D, MbCubicSpline3D, MbHermit3D, MbNurbs3D, MbPolyline3D. \n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbPolyCurve3D : public MbCurve3D, public MbNestSyncItem { +protected : + ptrdiff_t uppIndex; ///< \ru Количество участков кривой (равно количество контрольных точек минус единица). \en Count of curve pieces (is equal to count of control points minus one). + SArray pointList; ///< \ru Множество контрольных точек. \en Set of control points. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + mutable double metricLength; ///< \ru Метрическая длина кривой. \en Metric length of curve. + mutable double lengthEvaluation; ///< \ru Оценочная длина кривой. \en Estimated length of a curve. + mutable MbCube cube; ///< \ru Габаритный куб кривой. \en Bounding box of curve. + +protected: + MbPolyCurve3D(); + MbPolyCurve3D( const MbPolyCurve3D & ); +public : + virtual ~MbPolyCurve3D(); + +public : + VISITING_CLASS( MbPolyCurve3D ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента \en Type of element + virtual MbeSpaceType Type() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб \en Add your own bounding box into the cube + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые поверхности \en Get basis surfaces + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + + // \ru Общие функции кривой \en Common functions of curve + + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const = 0; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const = 0; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const = 0; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const = 0; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const = 0; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const = 0; + + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const = 0; // \ru Создание усеченной кривой \en Create a trimmed curve + + virtual double GetTMax() const = 0; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const = 0; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closedness + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; // \ru Изменить направление \en Change direction + + virtual double GetMetricLength() const; // \ru Выдать метрическую длину ограниченной кривой \en Get metric length of bounded curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether the curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if the curve is planar + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const = 0; + + // \ru Общие функции полигональной кривой \en Common functions of polygonal curve + + virtual void Rebuild() = 0; // \ru Перестроить кривую \en Rebuild curve + virtual void SetClosed ( bool cls ); // \ru Установить признак замкнутости \en Set attribute of closedness + virtual ptrdiff_t GetNearPointIndex( const MbCartPoint3D & ) const;// \ru Выдать индекс точки, ближайшей к заданной \en Get index of the point nearest to the given one + virtual void AddPoint ( const MbCartPoint3D & ); // \ru Добавить точку в конец массива \en Add a point to the end of the array + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & ) = 0; // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D &, double ) = 0; // \ru Добавить точку \en Add a point + virtual void RemovePoint( ptrdiff_t index ); // \ru Удалить точку \en Remove the point + virtual void RemovePoints(); // \ru Удалить все точки \en Delete all points + virtual bool ChangePoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Заменить точку \en Replace a point + virtual void GetPoint ( ptrdiff_t index, MbCartPoint3D & ) const; // \ru Выдать точку \en Get point + virtual size_t GetPointsCount() const; // \ru Выдать количество точек \en Get count of points + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const = 0; // \ru Выдать интервал влияния точки кривой \en Get the interval of point influence + void GetLineSegments( RPArray & segments ) const; // \ru Выдать массив отрезков \en Get the array of segments + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const = 0; // \ru Загнать параметр получить локальный индексы и параметры \en Drive parameter into domain, get local indices and parameters + virtual double GetParam( ptrdiff_t i ) const = 0; + virtual size_t GetCount() const; + // \ru Периодичность \en Periodicity + virtual bool IsPointsPeriodic( ptrdiff_t & begPointNumber, // \ru Номер первой точки \en Index of the first point + ptrdiff_t & endPointNumber, // \ru Номер последней точки \en Index of the last point + ptrdiff_t & period ) const; // \ru Количество точек в периоде \en Count of points in period + + const MbCube & GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } // \ru Выдать габарит кривой \en Get bounding box of curve + + size_t GetPointListCount() const { return pointList.Count(); } + ptrdiff_t GetPointListMaxIndex() const { return pointList.MaxIndex(); } + template + void GetPoints( Points & pnts ) const { std::copy( pointList.begin(), pointList.end(), std::back_inserter( pnts ) ); } ///< \ru Вернуть массив контрольных точек. \en Get array of control points. + void GetPointList( SArray & pnts ) const { pnts = pointList; } // \ru Получить характерные точки \en Get control points + const MbCartPoint3D & GetPointList( size_t i ) const { return pointList[i]; } // \ru Характерные точки \en Control points + MbCartPoint3D & SetPointList( size_t i ) { return pointList[i]; } // \ru Характерные точки \en Control points + + ptrdiff_t GetUppIndex() const { return uppIndex; } + size_t GetSegmentsCount() const { return (uppIndex > 0) ? (uppIndex + (!!closed)) : 0; } + + // \ru Дать информацию для функции NurbsCurve \en Get information for NurbsCurve function + bool NurbsParam( double epsilon, double & pmin, double & pmax, + ptrdiff_t & i1, double & t1, ptrdiff_t & i2, double & t2 ) const; + +protected: + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + bool CompositeDistanceAlong( double & t, double len, int curveDir, double eps, const SArray & tList ) const; + // \ru Рассчитать метрическую длину сегмента кривой. \en Calculate metric length of curve segment. + double SegmentCalculateLength( double w1, double w2, size_t n, double * x, double * w ) const; + // \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len. + bool SegmentDistanceAlong( double & t1, double ln, int curveDir, double eps, double stepMax, size_t n, double * x, double * w ) const; + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbPolyCurve3D & ); + + DECLARE_PERSISTENT_CLASS( MbPolyCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbPolyCurve3D ) + +#endif // __CUR_POLYCURVE3D_H diff --git a/C3d/Include/cur_polyline.h b/C3d/Include/cur_polyline.h new file mode 100644 index 0000000..fc3b585 --- /dev/null +++ b/C3d/Include/cur_polyline.h @@ -0,0 +1,334 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Ломаная линия в двумерном пространстве. + \en Polyline in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_POLYLINE_H +#define __CUR_POLYLINE_H + +#include +#include + + +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbCubicSpline; +class MATH_CLASS MbContour; +class MbRegDuplicate; +class MbRegTransform; +class MbPolylineSearchTree; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ломаная линия в двумерном пространстве. + \en Polyline in two-dimensional space. \~ + \details \ru Ломаная линия в двумерном пространстве определяется контрольными точками pointList. + Параметр ломаной в контрольных точках принимают целочисленные значения, начиная с нуля. + Ломаная проходит через свои контрольные точки при целочисленных значениях параметра. + Параметр ломаной изменяется от нуля до k, + где k - количество контрольных точек минус один для не замкнутой ломаной и k - количество контрольных для замкнутой ломаной. + Производная ломаной на каждом участке постоянна и равна вектору, построенному между двумя соседними контрольными точками. + \en Polyline in two-dimensional space is defined by 'pointList' control points. + Parameters of polyline at control points take on integer values starting from zero. + Polyline passes through its control points at integer values of parameter. + Parameter of a polyline changes from zero to 'k', + where 'k' - count of control points minus one for an open polyline and 'k' - count of control points for a closed polyline. + Derivative of polyline is constant at each piece and is equal to vector constructed between two neighboring control points. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbPolyline : public MbPolyCurve { +private : + ptrdiff_t segmentsCount; ///< \ru Число сегментов ломаной линии. \en Count of segments of polyline. +private: + mutable MbPolylineSearchTree * searchTree; ///< \ru Дерево габаритов для ускорения поиска сегментов. \en A tree of bounding boxes for segment search acceleration. + +public : + // \ru Конструктор отрезка. \en Constructor of a segment. + MbPolyline( const MbCartPoint & p1, const MbCartPoint & p2 ) + : MbPolyCurve() + , segmentsCount( 1 ) + , searchTree( NULL ) + { + pointList.reserve( 2 ); + pointList.push_back( p1 ); + pointList.push_back( p2 ); + uppIndex = 1; + closed = false; + } + // \ru Конструктор по набору точек и признаку замкнутости. \en Constructor by points and closedness state. + template + MbPolyline( const Points & initList, bool cls ) + : MbPolyCurve() + , segmentsCount( UNDEFINED_INT_T ) + , searchTree( NULL ) + { + Init( initList, cls ); + } + /// \ru Конструктор по прямоугольнику. \en Constructor by a rectangle. + MbPolyline( MbRect & ); + /// \ru Конструктор наклонного прямоугольника. \en Constructor of inclined rectangle. + MbPolyline( const MbCartPoint & p1, double height, double weight, const MbDirection & angle ); + // \ru Конструктор копирования. \en Copy constructor. + MbPolyline( const MbPolyline & ); +public : + virtual ~MbPolyline(); + +public : + VISITING_CLASS( MbPolyline ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether curve 'curve' is a duplicate of the current curve. + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for description of a curve domain. + \{ */ + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of the parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + Исключение составляет MbLine (прямая). + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + if it is out of domain bounds. + Except MbLine (line). + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en The third derivative + + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + Исключение составляют дуги эллипса и окружности - они продолжаются в соответствии со своими уравнениями. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... don't correct parameter + if it is out of domain bounds. If the parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + Except arcs of an ellipse or a circle - they are extended according to their equations. + \{ */ + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции инициализации кривой. + \en \name Initialization functions of a curve. + \{ */ + /// \ru Инициализация по другой ломаной. \en Initialization by another polyline. + void Init( const MbPolyline & ); + /// \ru Инициализация по точкам и признаку замкнутости. \en Initialization by points and an attribute of closedness. + template + bool Init( const Points & initList, bool cls ) + { + if ( initList.size() > 1 ) { + pointList.clear(); + pointList = initList; + uppIndex = (ptrdiff_t)pointList.size() - 1; + closed = cls; + // if curve is closed then the start and the end points have to be different + if ( (uppIndex > 1) && closed && c3d::EqualPoints( pointList.front(), pointList.back(), Math::LengthEps ) ) { + closed = true; + pointList.erase( pointList.begin() + uppIndex ); + uppIndex--; + } + segmentsCount = (uppIndex > 0) ? ( uppIndex + !!closed ) : 0; + Refresh(); // сбросить кривую + return true; + } + return false; + } + /// \ru Построение прямоугольника. \en Construction of a rectangle. + void Init( const MbCartPoint & p1, const MbCartPoint & p2 ); + /// \ru Построение правильного многоугольника. \en Construction of a regular polygon. + void Init( ptrdiff_t nVertex, const MbCartPoint & pc, double rad, const MbCartPoint & on, bool describe ); + /// \ru Построение наклонного прямоугольника. \en Constructor of an inclined rectangle. + void Init( const MbCartPoint & p1, double height, double weight, const MbDirection & angle ); + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual MbCurve * Offset( double rad ) const; // \ru Смещение полилинии \en Shift of polyline + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; + virtual MbContour * NurbsContour() const; + + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of step of approximation + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации по угловой толерантности \en Calculation of step of approximation by angular tolerance + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change curve direction to the opposite one + + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + // \ru Посчитать метрическую длину с заданной точностью \en Calculate metric length with given tolerance + virtual double CalculateLength( double t1, double t2 ) const; + // \ru Положение точки относительно полилинии. \en Point position relative to the polyline. + // \ru Возвращает результат : \en Returning result: + // \ru iloc_InItem = 1 - точка находится слева от полилинии, \en Iloc_InItem = 1 - point is to the left of the polyline, + // \ru iloc_OnItem = 0 - точка находится на полилинии, \en Iloc_OnItem = 0 - point is on the polyline, + // \ru iloc_OutOfItem = -1 - точка находится справа от полилинии. \en Iloc_OutOfItem = -1 - point is to the right of the polyline. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + virtual double PointProjection( const MbCartPoint & ) const; // \ru Проекция точки на кривую \en Point projection on the curve + + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const; // \ru Добавь в прям-к свой габарит с учетом матрицы \en Add your own gabarit taking the matrix into account + virtual void CalculateGabarit ( MbRect & ) const; // \ru Определить габариты кривой \en Determine the bounding box of a curve + + // \ru Сдвинуть параметр t на расстояние len по направлению \en Translate parameter 't' by distance 'len' along the direction + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + virtual double DistanceToPoint( const MbCartPoint & to ) const; // \ru Расстояние до точки \en Distance to a point + virtual bool DistanceToPointIfLess( const MbCartPoint & toP, double & d ) const; // \ru Расстояние до точки, если оно меньше d \en Distance to a point if it is less than 'd' + virtual bool GetMiddlePoint( MbCartPoint & midPoint ) const; // \ru Выдать среднюю точку кривой \en Get mid-point of a curve + + virtual bool GoThroughPoint( MbCartPoint & ); // \ru Пройти через точку \en Pass through point + ptrdiff_t GoThroughPoint( double t, MbCartPoint & p, double eps ); + + /** \} */ + /** \ru \name Общие функции полигональной кривой + \en \name Common functions of polygonal curve + \{ */ + + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки кривой \en Get the interval of point influence + virtual void Rebuild(); // \ru Перестроить кривую \en Rebuild curve + + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть кривой между параметрами t1 и t2 \en Remove piece of polyline between parameters t1 and t2 + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть кривой между параметрами t1 и t2 \en Keep piece of polyline between parameters t1 and t2 + + virtual void IntersectHorizontal( double y, SArray & ) const; // \ru Пересечение с горизонтальной прямой \en Intersection with a horizontal line + virtual void IntersectVertical ( double x, SArray & ) const; // \ru Пересечение с вертикальной прямой \en Intersection with a vertical line + virtual void SelfIntersect( SArray &, double metricEps = Math::LengthEps ) const; // \ru Самопересечение полилинии \en Self-intersection of a polyline + + // \ru Прямые, проходящие под углом к оси 0X и касательные к кривой \en Lines passing angularly to the 0X axis and tangent to the curve + virtual void Isoclinal( const MbVector & angle, SArray & tFind ) const; + + virtual bool GetCentre( MbCartPoint & ) const; // \ru Выдать центр полилинии \en Get center of a polyline + virtual bool GetWeightCentre( MbCartPoint & ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en Count of subdivisions for pass in operations + + void CheckParameter( double & ) const; ///< \ru Проверка параметра. \en Check parameter. + ptrdiff_t ChangeThroughPoint( const MbCartPoint & ); + + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ); // \ru Вставить точку по индексу \en Insert point by index + virtual void InsertPoint( double t, const MbCartPoint & pnt, double, double ); // \ru Вставить точку \en Insert a point + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Установить параметр \en Set parameter + virtual double GetParam( ptrdiff_t i ) const; + virtual size_t GetParamsCount() const; + + double Area() const; // \ru Площадь замкнутого многоугольника \en Area of closed a polygon + int Orientation() const; // \ru Ориентация замкнутого многоугольника \en Orientation of a closed polygon + + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of a contour\curve are smooth. + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + /** \} */ + /** \ru \name Функции полилинии + \en \name Functions of polyline + \{ */ + + void Trimm( SArray & point, double t1, double t2 ) const; + + // \ru Выдать среднюю точку сегмента полилинии \en Get mid-point of a segment of a polyline + bool GetSegmentMiddlePoint( const MbCartPoint & from, MbCartPoint & midPoint ) const; + // \ru Выдать линейный сегмент полилинии \en Get linear segment of a polyline + bool GetLinearSegment( const MbCartPoint & from, MbCartPoint & p1, MbCartPoint & p2 ) const; + void GetLineSegments( RPArray & segments ) const; // \ru Выдать массив отрезков \en Get the array of segments + bool GetSegmentLength( const MbCartPoint & from, double & length ) const; // \ru Выдать длину сегмента полилинии \en Get length of segment of a polyline + ptrdiff_t FindNearestSegment( const MbCartPoint & from ) const; // \ru Найти ближайший к точке сегмент полилинии \en Find the segment of polyline nearest to a point + MbContour * CreateContour() const; // \ru Сделать контур из полилинии \en Create a contour from a polyline + // \ru Вставка фаски между двумя соседними элементами \en Insert a chamfer between two neighboring elements + bool ChamferTwoSegments( ptrdiff_t & index, double len, double angle, + bool type, bool firstSeg = true ); + bool Chamfer( double len, double angle, bool type ); // \ru Вставка фаски. \en Insertion of the chamfer. + MbeState RemoveChamfer( const MbCartPoint & pnt ); // \ru Удалить фаску полилинии. \en Remove a chamfer of a polyline. + // \ru Построить точки и параметры для гладкого сплайна. \en Create points and parameters for a smooth spline. + bool GetSplinePoints( SArray & points, SArray & arParams ) const; + MbCubicSpline * CubicSpline() const; // \ru Построить гладкий сплайн из ломаной. \en Create a smooth spline from a polyline. + ptrdiff_t GetSegmentsCount() const { return segmentsCount; } + + /** \brief \ru Определить точки пересечения с отрезком. + \en Determine points of intersection with a line segment. \~ + \details \ru Определить точки пересечения ломаной и отрезка. \n + \en Determine intersection points of the polyline and a line segment. \n \~ + \param[in] lineSegment - \ru Отрезок. + \en A line segment. \~ + \param[in] xEps - \ru Погрешность по U. + \en U-accuracy. \~ + \param[out] ttPolyline - \ru Массив параметров на ломаной. + \en An array of parameters on the polyline. \~ + \param[out] ttSegment - \ru Массив параметров на отрезке. + \en An array of parameters on the line segment. \~ + \return \ru Количество точек пересечения. + \en The number of cross points. \~ + */ + template + size_t SegmentIntersection( const MbLineSegment & lineSegment, double xEps, double yEps, ParamsVector & ttPolyline, ParamsVector & ttSegment ) const; + /// \ru Определить положение точки относительно кривой при известном индексе ближайшего сегмента. \en Define the point position relative to the curve when the nearest segment index is known. + bool PointRelative( const MbCartPoint & pnt, ptrdiff_t nearestSegmentIndex, double eps, MbeItemLocation & iLoc ) const; + /// \ru Определить номер сегмента (или пару номеров сегментов) по параметру на ломаной. \en Define segment index (or pair of segment indices) by parameter on polyline. + bool FindSegmentPair( double t, c3d::IndicesPair & ) const; + /// \ru Определить расстояние от точки до сегмента ломаной как отрезка. \en Calculate distance from a point to segment of polyline. + double DistanceToPolylineSegment( size_t, const MbCartPoint & ) const; + /// \ru Самопересечение ломаной. \en Self-intersection of a polyline. + bool IsSelfIntersecting( double metricEps = Math::LengthEps ) const; + + /** \} */ + +protected: + /// \ru Удалить дерево поиска сегментов. \en Delete segments search tree. + void DeleteSearchTree() const; + /// \ru Создать и заполнить дерево поиска сегментов. \en Create and fill segments search tree. + bool CreateSearchTree() const; + /// \ru Поиск ближайших к точке сегментов по дереву поиска. \en Nearest to point segments by search tree. + bool FindNearestSegmentsByTree( const MbCartPoint &, c3d::IndicesVector & ) const; + /// \ru Поиск пересекающихся с отрезком сегментов по дереву поиска. \en Intersecting of line segment and segments of polyline by search tree. + bool FindIntersectingSegmentsByTree( const MbCartPoint & p1, const MbCartPoint & p2, double xEps, double yEps, c3d::IndicesVector & ) const; + /// \ru Самопересечение ломаной. \en Self-intersection of a polyline. + template + bool SelfIntersect( CrossPointsVector &, bool tillFirst, double metricEps ) const; + +private: + void operator = ( const MbPolyline & ); // \ru Не реализовано. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPolyline ) +}; + +IMPL_PERSISTENT_OPS( MbPolyline ) + +#endif // __CUR_POLYLINE_H diff --git a/C3d/Include/cur_polyline3d.h b/C3d/Include/cur_polyline3d.h new file mode 100644 index 0000000..0100dd0 --- /dev/null +++ b/C3d/Include/cur_polyline3d.h @@ -0,0 +1,245 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Ломаная линия в трехмерном пространстве. + \en Polyline in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_POLYLINE3D_H +#define __CUR_POLYLINE3D_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbPolyline; +class MATH_CLASS MbItem; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ломаная линия в трехмерном пространстве. + \en Polyline in three-dimensional space. \~ + \details \ru Ломаная линия в трехмерном пространстве определяется контрольными точками pointList. + Параметр ломаной в контрольных точках принимают целочисленные значения, начиная с нуля. + Ломаная проходит через свои контрольные точки при целочисленных значениях параметра. + Параметр ломаной изменяется от нуля до k, + где k - количество контрольных точек минус один для не замкнутой ломаной и k - количество контрольных для замкнутой ломаной. + Производная ломаной на кождом участке постоянна и равна вектору, построенному между двумя соседними контрольными точками. + \en Polyline in three-dimensional space is defined by 'pointList' control points. + Parameters of polyline at control points take on integer values starting from zero. + Polyline passes through its control points at integer values of parameter. + Parameter of a polyline changes from zero to 'k', + where 'k' - count of control points minus one for an open polyline and 'k' - count of control points for a closed polyline. + Derivative of polyline is constant at each piece and is equal to vector constructed between two neighboring control points. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbPolyline3D : public MbPolyCurve3D { +private : + ptrdiff_t segmentsCount; ///< \ru Число сегментов ломаной. \en Count of segments of polyline. + +public : + /// \ru Конструктор отрезка. \en Constructor of a segment. + MbPolyline3D( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + /// \ru Конструктор по набору точек и признаку замкнутости. \en Constructor by points and closedness state. + MbPolyline3D( const SArray & initList, bool cls ) + : MbPolyCurve3D( ) + , segmentsCount( 0 ) + { + Init( initList, cls ); + } + /// \ru Конструктор по набору точек и признаку замкнутости. \en Constructor by points and closedness state. + MbPolyline3D( const std::vector & initList, bool cls ) + : MbPolyCurve3D( ) + , segmentsCount( 0 ) + { + Init( initList, cls ); + } + /// \ru Конструктор по плоской ломаной. \en Constructor by planar polyline. + MbPolyline3D( const MbPolyline &, const MbPlacement3D & ); + MbPolyline3D( const CcArray & initList, ptrdiff_t count, bool cls, double scale ); ///< \ru Используется в конвертере Parasolid. \en Used in converter of Parasolid. +protected : + // \ru Конструктор копирования. \en Copy constructor. + MbPolyline3D( const MbPolyline3D & ); +public : + virtual ~MbPolyline3D(); + +public : + VISITING_CLASS( MbPolyline3D ); + + /// \ru Инициализация по другой ломаной. \en Initialization by another polyline. + void Init( const MbPolyline3D & ); + /// \ru Инициализация по другой плоской ломаной. \en Initialization by another planar polyline. + void Init( const MbPolyline &, const MbPlacement3D & ); + /// \ru Инициализация по точкам и признаку замкнутости. \en Initialization by points and an attribute of closedness. + template + bool Init( const Points & initList, bool cls ) { + if ( initList.size() > 1 ) { + pointList = initList; + uppIndex = (ptrdiff_t)pointList.size() - 1; + closed = cls; + // if curve is closed then the start and the end points have to be different + if ( uppIndex>1 && closed && c3d::EqualPoints( pointList.front(), pointList.back(), Math::metricRegion ) ) { + pointList.erase( pointList.begin() + uppIndex ); + uppIndex--; + } + segmentsCount = ( uppIndex > 0 ) ? ( uppIndex + !!closed ) : 0; + Refresh(); + } + return false; + } + /// \ru Построение прямоугольника. \en Construction of a rectangle. + void Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать \en Transform + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const;// \ru Расстояние до точки \en Distance to a point + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + // \ru Общие функции полилинии \en Common functions of polyline + + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const;// \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная \en The third derivative + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + // \ru Построить NURBS копию кривой \en Create a NURBS copy of the curve + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; + + virtual MbCurve3D * TrimmBreak( double t1, double t2, int sense ) const; + void Trimm( SArray & points, double t1, double t2 ) const; + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of the parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual double Step ( double t, double sag ) const; // \ru Шаг параметра с учетом радиуса кривизны \en Step of parameter with consideration of curvature + virtual double DeviationStep( double t, double angle ) const; // \ru Шаг параметра по заданному углу отклонения касательной \en Step of parameter by a given angle of deviation of tangent + + virtual void CalculateGabarit( MbCube & ) const; // \ru Определить габариты кривой \en Determine the bounding box of a curve + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system + + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual void GetCentre ( MbCartPoint3D & wc ) const; // \ru Посчитать центр кривой \en Calculate the center of a curve + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; // \ru Посчитать центр тяжести кривой \en Calculate the gravity center of the curve + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + + // \ru Общие функции полигональной кривой \en Common functions of polygonal curve + + virtual void Rebuild(); // \ru Перестроить кривую \en Rebuild curve + virtual void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const; // \ru Выдать интервал влияния точки кривой \en Get the interval of point influence + + // \ru Функции только 3D кривой \en Functions of 3D curve only + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The nearest point projection to the curve + virtual void InsertPoint( ptrdiff_t index, const MbCartPoint3D & ); // \ru Добавить точку \en Add a point + virtual void InsertPoint( double t, const MbCartPoint3D &, double ); // \ru Добавить точку \en Add a point + virtual bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const; // \ru Установить параметр \en Set parameter + virtual double GetParam( ptrdiff_t i ) const; // \ru Выдать параметр для точки с номером \en Get parameter for a point with index + + void CheckParameter( double & ) const; ///< \ru Проверка параметра. \en Check parameter. + + //virtual bool GoThroughPoint( double t, MbCartPoint3D & p ); // \ru Пройти через точку \en Pass through point + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of a curve. + virtual MbCurve * GetMapPsp( const MbMatrix3D &, double zNear, MbRect1D * pRgn = NULL ) const; // \ru Дать перспективную плоскую проекцию кривой. \en Get a planar geometric projection of a curve. + + virtual size_t GetCount() const; + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of a contour\curve are smooth. + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + bool UnClamped( bool ); + void DeleteEqPoints( double absEps ); // \ru Удалить одинаковые точки \en Remove equal points + void AddAt( const MbCartPoint3D & spsP, ptrdiff_t i ); + ptrdiff_t GetSegmentsCount() const { return segmentsCount; } + +private: + void operator = ( const MbPolyline3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPolyline3D ) +}; + +IMPL_PERSISTENT_OPS( MbPolyline3D ) + +//------------------------------------------------------------------------------ +/** \brief \ru Построить пространственный проволочный каркас по полигональному объекту. + \en Create a spatial wireframe by a mesh \~ + \details \ru Построить набор пространственных кривых, характеризующих полигональных объект. \n + \en Create a spatial wireframe by a mesh. \n \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) MakeSpaceWireFrame( const MbItem & item, RPArray & wire ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить плоский проволочный каркас по полигональному объекту. + \en Create a planar wireframe by a mesh \~ + \details \ru Построить пространственных набор кривых, являющихся проекциями кривых, характеризующих полигональных объект, на плоскость XY локальной системы координат. \n + \en Create a planar wireframe by a mesh. \n \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) MakePlaneWireFrame( const MbItem & item, const MbPlacement3D & place, + RPArray & wire ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить плоский проволочный каркас по полигональному объекту в перспективе. + \en Create a planar wireframe by a mesh in perspective \~ + \details \ru Построить пространственных набор кривых, являющихся проекциями кривых в перспективе, характеризующих полигональных объект, на плоскость XY локальной системы координат. \n + \en Create a planar wireframe by a mesh in perspective. \n \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) MakePlaneVistaWireFrame( const MbItem & item, const MbPlacement3D & place, + const MbCartPoint3D & vista, RPArray & wire ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить плоский проволочный каркас по полигональному объекту. + \en Create a planar wireframe by a mesh \~ + \details \ru Построить набор двумерных кривых, являющихся проекциями пространственных кривых, характеризующих полигональных объект, на плоскость XY локальной системы координат. \n + \en Create a planar wireframe by a mesh. \n \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) MakePlaneWireFrame( const MbItem & item, const MbPlacement3D & place, + RPArray & wire ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Построить плоский проволочный каркас по полигональному объекту в перспективе. + \en Create a planar wireframe by a mesh in perspective \~ + \details \ru Построить набор двумерных кривых, являющихся проекциями в перспективе пространственных кривых, характеризующих полигональных объект, на плоскость XY локальной системы координат. \n + \en Create a planar wireframe by a mesh in perspective. \n \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) MakePlaneVistaWireFrame( const MbItem & item, const MbPlacement3D & place, + const MbCartPoint3D & vista, RPArray & wire ); + + +#endif // __CUR_POLYLINE3D_H diff --git a/C3d/Include/cur_projection_curve.h b/C3d/Include/cur_projection_curve.h new file mode 100644 index 0000000..4a1a994 --- /dev/null +++ b/C3d/Include/cur_projection_curve.h @@ -0,0 +1,317 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Проекционная кривая. + \en Projection curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_PROJECTION_CURVE_H +#define __CUR_PROJECTION_CURVE_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; +class MbRegTransform; +class MbRegDuplicate; +class MbCurveIntoNurbsInfo; + + +//------------------------------------------------------------------------------ +/** \brief \ru Проекционная кривая. + \en Projection curve. \~ + \details \ru Проекционная кривая строится в параметрическом пространстве поверхности + как проекция пространственной кривой spaceCurve на поверхность surface. + Если поверхность не плоская, то предполагается, что пространственная кривая лежит на поверхности. + Двумерная кривая curve содержит начальные приближения для точного вычисления проекционной кривой. + \en Projection curve is constructed in parametric space of surface + as projection of spatial curve 'spaceCurve' onto surface 'surface'. + If surface isn't planar, then it is considered that spatial curve lies on surface. + Two-dimensional curve 'curve' contains initial approximations for precise calculation of the projection curve. \~ +*/ +// --- +class MATH_CLASS MbProjCurve : public MbCurve { +private : + MbCurve3D * spaceCurve; ///< \ru Пространственная кривая (всегда не NULL). \en Spatial curve (always not NULL). + MbSurface * surface; ///< \ru Поверхность (всегда не NULL). \en Surface (always not NULL). + MbCurve * curve; ///< \ru Проекция пространственной кривой на поверхность (служит начальным приближением), всегда не NULL. \en Projection of a spatial curve onto a surface (is used as initial approximation), always not NULL. + MbMatrix3D * into; ///< \ru Матрица пересчета в систему координат плоскости. Для случая плоской поверхности surface. Вычисляется заново при изменении поверхности. \en A matrix of transformation to the plane coordinate system. In case of planar surface 'surface'. Recalculated at surface change. + bool belong; ///< \ru Проецируемая кривая лежит на поверхности. \en Projecting curve lies on the surface. + + mutable MbRect rect; ///< \ru Габарит проекционной кривой в параметрическом пространстве поверхности. \en Bounding box of projection curve in parametric space of surface. + mutable double metricLength; ///< \ru Метрическая длина проекционной кривой. \en Metric length of the projection curve. + mutable double tMiddle; ///< \ru Параметр на кривой, соответствующий метрической середине кривой. \en Parameter on the curve corresponding to the metric middle of the curve. + + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbProjCurveAuxiliaryData : public AuxiliaryData { + public: + double t0; ///< \ru Исходный параметр. \en Initial parameter. + double t; ///< \ru Модифицированный параметр. \en Modified parameter. + bool ext; ///< \ru Флаг расчета на продолжении. \en Extension flag. + + MbVector pcDers[cdt_CountDer]; ///< \ru Точка и производные двумерной кривой. \en Curve point and derivatives. + MbVector3D scDers[cdt_CountDer]; ///< \ru Точка и производные трехмерной кривой. \en Space curve point and derivatives. + + MbProjCurveAuxiliaryData(); + MbProjCurveAuxiliaryData( const MbProjCurveAuxiliaryData & ); + virtual ~MbProjCurveAuxiliaryData(); + + bool IsChanged( double pmin, double pmax, double p, bool pext ) const + { + bool changed = false; + if ( p != t0 ) + changed = true; + else if ( ext != pext ) { + changed = true; + if ( pmin <= p && p <= pmax ) + changed = false; + } + return changed; + } + void Init(); + void Init( const MbProjCurveAuxiliaryData & ); + void Move( const MbVector & ); + }; + + mutable CacheManager cache; + +public : + /** \brief \ru Конструктор по пространственной кривой, поверхности и двумерной кривой. + \en Constructor by spatial curve, surface and two-dimensional curve. \~ + \details \ru Конструктор по пространственной кривой, поверхности и двумерной кривой. \n + Двумерная кривая используется как начальное приближение для расчета проекционной кривой. \n + В конструкторе используется копия подложки поверхности. \n + \en Constructor by spatial curve, surface and two-dimensional curve. \n + Two-dimensional curve is used as initial approximation for calculation of projection curve. \n + Copy of surface substrate is used in the constructor. \n \~ + \param[in] sCurve - \ru Проецируемая пространственная кривая. + \en A projected spatial curve. \~ + \param[in] sameSpaceCurve - \ru Использовать ли оригинал пространственной кривой. + \en Use the original of the spatial curve. \~ + \param[in] surface - \ru Поверхность для проецирования пространственной кривой. + \en A target surface. \~ + \param[in] pCurve - \ru Параметрическая кривая - начальное приближение для проецирования пространственной кривой. + \en A parametric curve - initial approximation for projecting of a spatial curve. \~ + \param[in] samePlaneCurve - \ru Использовать ли оригинал параметрической кривой. + \en Use the original of the parametric curve. \~ + \param[in] iReg - \ru Регистратор дублирования. + \en Registrar of duplication. \~ + */ + MbProjCurve( const MbCurve3D & sCurve, bool sameSpaceCurve, + const MbSurface & surface, + const MbCurve & pCurve, bool samePlaneCurve, + MbRegDuplicate * iReg = NULL ); + +private: + MbProjCurve( const MbProjCurve &, MbRegDuplicate * ireg ); + +public : + virtual ~MbProjCurve(); + +public : + VISITING_CLASS( MbProjCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSimilar ( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether curve 'curve' is a duplicate of the current curve. + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void AddYourGabaritTo ( MbRect & ) const; // \ru Добавь в прям-к свой габарит \en Add your own bounding rectangle into the given rectangle + virtual void CalculateGabarit ( MbRect & ) const; // \ru Определить габариты кривой. \en Determine bounding box of curve. + virtual void CalculateLocalGabarit( const MbMatrix &, MbRect & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for description of a curve domain. + \{ */ + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of the parameter + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + if it is out of domain bounds. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & v ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & v ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector & v ) const; // \ru Третья производная \en The third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + Исключение составляют дуги эллипса и окружности - они продолжаются в соответствии со своими уравнениями. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... don't correct parameter + if it is out of domain bounds. If the parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + Except arcs of an ellipse or a circle - they are extended according to their equations. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void _FirstDer ( double t, MbVector & v ) const; // \ru Первая производная \en The first derivative + virtual void _SecondDer( double t, MbVector & v ) const; // \ru Вторая производная \en The second derivative + virtual void _ThirdDer ( double t, MbVector & v ) const; // \ru Третья производная \en The third derivative + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на кривую. \en Point projection on the curve. + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции. \en Projection of a point onto the curve or its extension in the projection region. + + virtual bool HasLength( double & ) const; // \ru Метрическая длина кривой. \en Metric length of a curve. + virtual double GetMetricLength() const; // \ru Метрическая длина кривой. \en Metric length of a curve. + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой. \en Estimation of metric length of the curve. + // \ru Вычислить метрическую длину кривой от параметра t1 до t2. \en Calculate the metric length of unclosed curve from parameter t1 to parameter t2. + virtual double CalculateLength( double t1, double t2 ) const; + + virtual bool GetMiddlePoint( MbCartPoint & ) const; // \ru Вычислить среднюю точку кривой. \en Calculate mid-point of curve. + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change curve direction to the opposite one + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + // \ru Удалить часть кривой между параметрами t1 и t2 \en Delete a part of a curve between parameters t1 and t2 + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть кривой между параметрами t1 и t2 \en Keep a piece of a curve between parameters t1 and t2 + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of step of approximation with consideration of angle of deviation + + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + + const MbCurve3D & GetSpaceCurve() const { return *spaceCurve; } + const MbSurface & GetSurface () const { return *surface; } + const MbCurve & GetParamCurve() const { return *curve; } + + bool SetSameSurface( const MbSurface & s ); ///< \ru Заменить поверхность на такую же. \en Whether the projecting curve lies on the surface. + + bool IsBelong() const { return belong; } ///< \ru Лежит ли проецируемая кривая на поверхности. \en Whether the projecting curve lies on the surface. + + bool InvertNormal( MbRegTransform * = NULL ); ///< \ru Инвертировать нормаль, если поверхность - плоскость. \en Invert normal if the surface is a plane. + + bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); ///< \ru Изменение носителя. \en Change a carrier. + + /// \ru Получить 2d сплайн с данной относительной точностью аппроксимирующий данную кривую. \en Get 2d spline which approximates given curve with a given relative tolerance. + MbCurve * CreateSpline( double relEps, MbRect1D * pRgn = NULL ) const; + + /// \ru Создать кривую путём сращивания части данной кривой с частью другой кривой. \en Create a curve by joining a part of this curve with a part of other curve. + MbProjCurve * AddCurve( const MbProjCurve &, double accuracy, VERSION version = Math::DefaultMathVersion() ) const; + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива). \en Whether the curves for union (joining) are similar. + /** \} */ + +private: + void CheckPoint ( double & t, bool ext, MbCartPoint & cPoint ) const; // \ru Обнулить данные, вычислить точку \en Set data to zero, calculate point. + void CheckFirst ( double & t, bool ext, MbVector & cFirst ) const; // \ru Вычислить производную \en Calculate derivative + void CheckSecond( double & t, bool ext, MbVector & cSecond ) const; // \ru Вычислить производную \en Calculate derivative + void CheckThird ( double & t, bool ext, MbVector & cThird ) const; // \ru Вычислить производную \en Calculate derivative + bool CalculatePoint( const MbCartPoint3D & sPoint, MbCartPoint & cPoint, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D & uuDer, MbVector3D & vvDer, MbVector3D & uvDer, MbVector3D * nor ) const; // \ru Вычислить данные для точки. \en Calculate point. + void CalculateFirst( bool result, MbCartPoint3D & surfacePoint, MbVector3D & sDeriveU, MbVector3D & sDeriveV, + MbVector3D & sDeriveUU, MbVector3D & sDeriveVV, MbVector3D & sDeriveUV, MbVector3D & sNormal, + const MbCartPoint3D & sPoint, const MbCartPoint & cPoint, const MbVector3D & sFirst, MbVector & cFirst ) const; // \ru Вычислить производную \en Calculate derivative + void CalculateSecond( const MbCartPoint3D & surfacePoint, const MbVector3D & sDeriveU, const MbVector3D & sDeriveV, + const MbVector3D & sDeriveUU, const MbVector3D & sDeriveVV, const MbVector3D & sDeriveUV, const MbVector3D & sNormal, + const MbCartPoint3D & sPoint, const MbCartPoint & cPoint, const MbVector3D & sFirst, const MbVector & cFirst, + const MbVector3D & sSecond, MbVector & cSecond ) const; // \ru Вычислить производную \en Calculate derivative + void SetBelong(); // \ru Вычисление параметра belong: лежит ли проецируемая кривая на поверхности \en Calculate 'belong' parameter: whether the projecting curve lies on the surface + void SetInto(); // \ru Инициализировать матрицу пересчета в систему координат плоскости. \en Initialize matrix of transformation to the plane coordinate system. + void PrepareCurveToTrimmed( MbCurve * curvett, double t1, double t2 ) const; // \ru Подготовить двумерную кривую к усечению \en Prepare a two-dimensional curve for trimming + + /** \brief \ru Поменять базовую поверхность на подобную. + \en Change base surface to the similar one. \~ + \details \ru Поменять базовую поверхность. Новая поверхность должна быть подобна старой. + \en Change the base surface. The new surface has to be similar to the old one. \~ + \param[in] newSurface - \ru Новая поверхность. Захватывается кривой. + \en New surface. Is captured by the curve. \~ + \param[in] matrix - \ru Матрица преобразования из старой поверхности в новую. + \en Transformation matrix from the old surface to a new one. \~ + */ + void ChangeSurfaceToSimilar( const MbSurface & newSurface, const MbMatrix & matrix, MbRegTransform * iReg ); + + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbProjCurve ) + OBVIOUS_PRIVATE_COPY( MbProjCurve ) +}; + +IMPL_PERSISTENT_OPS( MbProjCurve ) + +//------------------------------------------------------------------------------ +// \ru Изменение носимых элементов \en Change a carrier elements +// --- +bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr, MbCurve & curve ); + + +//------------------------------------------------------------------------------ +// \ru Пространственная трансформация проекционных кривых в двумерной кривой \en Spatial transformation of projection curves in two-dimensional curve +// --- +bool TransformProjCurves( MbCurve & curve, const MbMatrix3D & matr, MbRegTransform * ireg ); + + +//------------------------------------------------------------------------------ +// \ru Пространственный сдвиг проекционных кривых в двумерной кривой \en Spatial translation of projection curves in two-dimensional curve +// --- +bool MoveProjCurves( MbCurve & curve, const MbVector3D & to, MbRegTransform * ireg ); + + +//------------------------------------------------------------------------------ +// \ru Вращение проекционных кривых в двумерной кривой \en Rotation of projection curves in two-dimensional curve +// --- +bool RotateProjCurves( MbCurve & curve, const MbAxis3D & axis3d, double angle, MbRegTransform * ireg ); + + +#endif // __CUR_PROJECTION_CURVE_H diff --git a/C3d/Include/cur_reparam_curve.h b/C3d/Include/cur_reparam_curve.h new file mode 100644 index 0000000..af0579a --- /dev/null +++ b/C3d/Include/cur_reparam_curve.h @@ -0,0 +1,372 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Репараметризованная кривая в двумерном пространстве. + \en Reparametrized curve in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_REPARAM_CURVE_H +#define __CUR_REPARAM_CURVE_H + + +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Репараметризованная кривая в двумерном пространстве. + \en Reparametrized curve in two-dimensional space. \~ + \details \ru Репараметризованная кривая служит для согласования областей определения кривых. \n + Геометрически репараметризованная кривая полностью совпадает с базовой кривой basisCurve. + Репараметризованная кривая имеет другую область определения и, как следствие, другую длину своих производных. + Параметры базовой кривой и репараметризованной кривой связаны равенством: \n + dt (t - tmin) = t_basisCurve - tmin_basisCurve, где t - параметр репараметризованной кривой. + Базовой кривой для репараметризованной кривой не может служить другая репараметризованная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Reparametrized curve is used for matching domains of curves. \n + Geometrically reparametrized curve completely coincides with base curve 'basisCurve'. + Reparametrized curve has another definition domain and as a result another length of its derivatives. + Parameters of base curve and reparametrized curve are related by the equality: \n + dt (t - tmin) = t_basisCurve - tmin_basisCurve, where 't' - parameter of reparametrized curve. + Another reparametrized curve can't be the base curve for a reparametrized curve. + In this situation it changes to the initial base curve. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbReparamCurve : public MbCurve { + enum MbeReparamType { + rt_Linear, ///< \ru Линейная репараметризация. \en Linear reparametrization. + rt_Quadratic, ///< \ru Квадратичная репараметризация. \en Quadratic reparametrization. + rt_Cubic ///< \ru Кубическая репараметризация. \en Quadratic reparametrization. + }; + +protected : + MbCurve * basisCurve; ///< \ru Базовая кривая. \en The base curve. + MbeReparamType reparamType; ///< \ru Способ репараметризации. \en Way of repatametrization. + double tmin; ///< \ru Начальный параметр. \en Start parameter. + double tmax; ///< \ru Конечный параметр. \en End parameter. + double q; ///< \ru Коэффициент при кубическом члене репараметризующего многочлена. \en The coefficient of the cubic term of the reparametrizing polynomial. + double a; ///< \ru Коэффициент при квадратичном члене репараметризующего многочлена. \en The coefficient of the quadratic term of the reparametrizing polynomial. + double b; ///< \ru Коэффициент при линейном члене репараметризующего многочлена. \en The coefficient of the linear term of the reparametrizing polynomial. + double c; ///< \ru Свободный коэффициент репараметризующего многочлена. \en The free coefficient of the reparametrizing polynomial. + +public : + MbReparamCurve( const MbCurve &, double t1, double t2 ); + MbReparamCurve( const MbCurve &, const double t1, const double t2, const double begFirstDerValue ); + MbReparamCurve( const MbCurve &, double t1, double t2, double derBeg, double derEnd ); +protected: + MbReparamCurve( const MbReparamCurve & ); +public : + virtual ~MbReparamCurve(); + +public : + VISITING_CLASS( MbReparamCurve ); + + void Init( double t1, double t2 ); + void Init( double t1, double t2, double begFirstDerValue ); + void Init( double t1, double t2, double der1, double der2 ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual bool IsSimilar ( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar + virtual bool SetEqual( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual void Transform( const MbMatrix & matr, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual MbCurve * Offset( double rad ) const; // \ru Смещение усеченной кривой \en Shift of a trimmed curve + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + virtual MbContour * NurbsContour() const; // \ru Построить контур \en Create a contour + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавь свой габарит в прямой прям-к \en Add your own gabarit into the given bounding rectangle + virtual void CalculateGabarit( MbRect & r ) const; // \ru Определить габариты кривой \en Determine the bounding box of a curve + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике \en Whether the object is visible in the given rectangle + using MbCurve::IsVisibleInRect; + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for description of a curve domain. + \{ */ + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of the parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + Исключение составляет MbLine (прямая). + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + if it is out of domain bounds. + Except MbLine (line). + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en The third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + Исключение составляют дуги эллипса и окружности - они продолжаются в соответствии со своими уравнениями. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... don't correct parameter + if it is out of domain bounds. If the parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + Except arcs of an ellipse or a circle - they are extended according to their equations. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Functions of moving along the curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double DeviationStep( double t, double _atol ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + /** \} */ + + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменение направления кривой на противоположное \en Change curve direction to the opposite one + virtual double DistanceToPoint( const MbCartPoint & toP ) const; // \ru Расстояние до точки \en Distance to a point + virtual bool DistanceToPointIfLess( const MbCartPoint & toP, double & d ) const; // \ru Расстояние до точки, если оно меньше d \en Distance to a point if it is less than 'd' + virtual MbeState Deformation( const MbRect &, const MbMatrix & ); // \ru Деформация \en Deformation + // \ru Удалить часть кривой между параметрами t1 и t2 \en Delete a part of a curve between parameters t1 and t2 + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); + // \ru Оставить часть кривой между параметрами t1 и t2 \en Keep a piece of a curve between parameters t1 and t2 + virtual MbeState TrimmPart( double t1, double t2, MbCurve *& part2 ); + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + virtual bool IsBounded() const; // \ru Признак ограниченной кривой \en Attribute of a bounded curve + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of a contour\curve are smooth. + virtual bool IsCompleteInRect( const MbRect & r ) const; // \ru Виден ли объект полностью в в заданном прямоугольнике \en Whether the object is completely visible in the given rectangle + virtual double CalculateMetricLength() const; // \ru Посчитать метрическую длину \en Calculate the metric length + virtual bool HasLength( double & length ) const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + virtual double Curvature ( double t ) const; // \ru Кривизна кривой \en Curvature of the curve + + virtual double CalculateLength( double t1, double t2 ) const; + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru Возвращает результат : \en Returning result: + // \ru iloc_InItem = 1 - точка находится слева от кривой, \en Iloc_InItem = 1 - point is to the left of the curve, + // \ru iloc_OnItem = 0 - точка находится на кривой, \en Iloc_OnItem = 0 - point is on the curve, + // \ru iloc_OutOfItem = -1 - точка находится справа от кривой. \en Iloc_OutOfItem = -1 - point is to the right of the curve. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual double PointProjection( const MbCartPoint & ) const; // \ru Проекция точки на кривую \en Point projection on the curve + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Проекция точки на кривую или её продолжение в области поиска проекции \en Projection of a point onto the curve or its extension in the projection region + // \ru Вычисление всех перпендикуляров к кривой из данной точки \en Calculation of all the perpendiculars to the curve from a given point + virtual void PerpendicularPoint( const MbCartPoint & pnt, SArray & tFind ) const; + virtual bool SmallestPerpendicular( const MbCartPoint & pnt, double & tProj ) const; // \ru Нахождение ближайшего перпендикуляра к кривой из данной точки \en Calculation of the closest perpendicular to the curve from the given point + virtual void TangentPoint( const MbCartPoint & pnt, SArray & tFind ) const; // \ru Вычисление всех касательных к кривой из данной точки \en Calculation of all the tangents to the curve from a given point + virtual void IntersectHorizontal( double y, SArray & ) const; // \ru Пересечение кривой с горизонтальной прямой \en Intersection of a curve with a horizontal line + virtual void IntersectVertical ( double x, SArray & ) const; // \ru Пересечение с вертикальной прямой \en Intersection with a vertical line + virtual void SelfIntersect( SArray &, double metricEps = Math::LengthEps ) const; // \ru Самопересечение произвольной кривой \en Self-intersection of an arbitrary curve + + // \ru Определение особых точек офсетной кривой \en Determination of special points of an offset curve + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; + virtual bool GetMiddlePoint( MbCartPoint & ) const; // \ru Выдать среднюю точку кривой \en Get mid-point of a curve + virtual bool GoThroughPoint( MbCartPoint & p0 ); + // \ru Вычисление минимальной длины кривой между двумя точками на ней \en Calculate the minimal curve length between two points on it + virtual double LengthBetween2Points( MbCartPoint & p1, MbCartPoint & p2, MbCartPoint * pc = NULL ) const; + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; // \ru Выдать характерную точку кривой если она ближе чем dmax \en Get control point of curve if it is closer than 'dmax' + virtual bool GetWeightCentre( MbCartPoint & c ) const; // \ru Выдать центр тяжести кривой \en Get the center of gravity of the curve + virtual bool GetCentre( MbCartPoint & c ) const; // \ru Выдать центр кривой \en Get center of curve + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; // \ru Сдвинуть параметр t на расстояние len по направлению \en Translate parameter 't' by distance 'len' along the direction + virtual bool GetAxisPoint( MbCartPoint & p ) const; // \ru Точка для построения оси \en Point for the axis construction + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en Count of subdivisions for pass in operations + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curve equally spaced by the arc length + + void ParameterInto( double & ) const; // \ru Перевод параметра базовой кривой в локальный параметр \en Transformation of the base curve parameter to a local parameter + void ParameterFrom( double & ) const; // \ru Перевод локального параметра в параметр базовой кривой \en Transformation of a local parameter to the base curve parameter + double EpsilonInto( double eps ) const; // \ru Перевод точности параметра базовой кривой в точность локального параметра \en Transformation of the base curve parameter tolerance to a local parameter tolerance + double EpsilonFrom( double eps ) const; // \ru Перевод точности локального параметра в точность параметра базовой кривой \en Transformation of a local parameter tolerance to the base curve parameter tolerance + + virtual const MbCurve & GetBasisCurve() const; + virtual MbCurve & SetBasisCurve(); + + void SetBasisCurve( MbCurve & ); // \ru Заменить плоскую кривую \en Replace the planar curve + double Tmin() const { return tmin; } // \ru Начальный параметр \en Start parameter + double Tmax() const { return tmax; } // \ru Конечный параметр \en End parameter + double Dt() const { return b; } // \ru Производная параметра кривой basisCurve по параметру \en Derivative of parameter of 'basisCurve' curve by parameter + void SetTmin( double t ); + void SetTmax( double t ); + void SetDt ( double d ); + + MbeReparamType GetReparamType() const { return reparamType; } // \ru Тип параметризации. \en Parameterization type. + + // \ru !!! геометрия подложки тождественна геометрии кривой, отлична параметризация !!! \en !!! geometry of substrate is identical to geometry of curve, parameterization is different !!! + virtual const MbCurve & GetSubstrate() const; // \ru Выдать подложку или себя \en Get substrate or itself + virtual MbCurve & SetSubstrate(); // \ru Выдать подложку или себя \en Get substrate or itself + virtual int SubstrateCurveDirection() const; // \ru Направление подложки относительно кривой или наоборот \en Direction of substrate relative to the curve or vice versa + virtual void SubstrateToCurve( double & ) const; // \ru Преобразовать параметр подложки в параметр кривой \en Transform a substrate parameter to the curve parameter + virtual void CurveToSubstrate( double & ) const; // \ru Преобразовать параметр кривой в параметр подложки \en Transform a curve parameter to the substrate parameter + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + bool IsLinear() const { return (reparamType == rt_Linear); } // \ru Является ли репараметризация линейной? \en Is the re-parametrization linear? + + /** \} */ + +private: + void operator = ( const MbReparamCurve & ); // \ru Не реализовано. \en Not implemented. + double CubicRoot( double t ) const; // \ru Решение кубического уравнения. \en Solution of cubic equation. + void Explore( double t, double * par, double * dpar, double * ddpar, double * dddpar ) const; // \ru Параметр базовой кривой и его производные. \en The base curve parameter and its derivatives. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbReparamCurve ) +}; // MbReparamCurve + +IMPL_PERSISTENT_OPS( MbReparamCurve ) + +//------------------------------------------------------------------------------ +// \ru Перевод параметра базовой кривой в новый параметр \en Transformation of the base curve parameter to a new parameter +// --- +inline void MbReparamCurve::ParameterInto( double & t ) const { + if ( reparamType == rt_Linear ) + t = ( t - c ) / b; + else if ( reparamType == rt_Quadratic ) { + C3D_ASSERT( ::fabs(a) > NULL_EPSILON ); + const double discriminant = b * b + 4.0 * a * (t - c); + if ( discriminant > EXTENT_EQUAL ) + t = 0.5 * ( ::sqrt(discriminant) - b ) / a; + else + t = -0.5 * b / a; + } + else if( reparamType == rt_Cubic ) { + bool close = basisCurve->IsClosed(); + double bTmin = basisCurve->GetTMin(), bTmax = basisCurve->GetTMax(); + if ( !close && ( t < bTmin || t > bTmax ) ) { + double t0 = ( t < bTmin ) ? tmin : tmax; + double par = ( t < bTmin ) ? bTmin : bTmax; + double dpar = 3.0 * q * t0 * t0 + 2.0 * a * t0 + b; + t = t0 + ( t - par ) / dpar; + } + else { + double n = 0.0; + if ( close ) { + double period = bTmax - bTmin; + n = ::floor( (t - bTmin) / period ); + t -= n * period; + } + t = CubicRoot( t ); + if( n != 0.0 ) + t += n * ( tmax - tmin ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Перевод нового параметра в параметр базовой кривой \en Transformation of a new parameter to the base curve parameter +// --- +inline void MbReparamCurve::ParameterFrom( double & t ) const { + if ( reparamType == rt_Linear ) + t = b * t + c; + else if ( reparamType == rt_Quadratic ) + t = a * t * t + b * t + c; + else if ( reparamType == rt_Cubic ) + Explore( t, &t, 0, 0, 0 ); +} + + +//------------------------------------------------------------------------------ +// \ru Перевод точности параметра базовой кривой в точность локального параметра \en Transformation of the base curve parameter tolerance to a local parameter tolerance +// --- +inline double MbReparamCurve::EpsilonInto( double eps ) const { + double res = 0.0; + + if ( reparamType == rt_Linear ) { + if ( ::fabs(b) > Math::paramEpsilon ) + res = eps / b; + } + else if ( reparamType == rt_Quadratic ) { + const double bmin = 2.0 * a * tmin + b; + const double bmax = 2.0 * a * tmax + b; + const double div = std_max( bmin, bmax ); + if ( ::fabs(div) > Math::paramEpsilon ) + res = eps / div; + } + else if ( reparamType == rt_Cubic ) { + const double bmin = 3.0 * q * tmin * tmin + 2.0 * a * tmin + b; + const double bmax = 3.0 * q * tmax * tmax + 2.0 * a * tmax + b; + const double div = std_max( bmin, bmax ); + if ( ::fabs( div ) > Math::paramEpsilon ) + res = eps / div; + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод точности локального параметра в точность параметра базовой кривой \en Transformation of a local parameter tolerance to the base curve parameter tolerance +// --- +inline double MbReparamCurve::EpsilonFrom( double eps ) const { + double res = 0.0; + + if ( reparamType == rt_Linear ) + return eps * b; + else if ( reparamType == rt_Quadratic ) { + const double bmin = 2.0 * a * tmin + b; + const double bmax = 2.0 * a * tmax + b; + const double mul = std_min( bmin, bmax ); + res = eps * mul; + } + else if ( reparamType == rt_Cubic ) { + const double bmin = 3.0 * q * tmin * tmin + 2.0 * a * tmin + b; + const double bmax = 3.0 * q * tmax * tmax + 2.0 * a * tmax + b; + const double mul = std_min( bmin, bmax ); + res = eps * mul; + } + + return res; +} + + +#endif // __CUR_REPARAM_CURVE_H diff --git a/C3d/Include/cur_reparam_curve3d.h b/C3d/Include/cur_reparam_curve3d.h new file mode 100644 index 0000000..f8d8e1c --- /dev/null +++ b/C3d/Include/cur_reparam_curve3d.h @@ -0,0 +1,267 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Репараметризованная кривая в трехмерном пространстве. + \en Reparametrized curve in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_REPARAM_CURVE3D_H +#define __CUR_REPARAM_CURVE3D_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Репараметризованная кривая в трехмерном пространстве. + \en Reparametrized curve in three-dimensional space. \~ + \details \ru Репараметризованная кривая служит для согласования областей определения кривых. \n + Геометрически репараметризованная кривая полностью совпадает с базовой кривой basisCurve. + Репараметризованная кривая имеет другую область определения и, как следствие, другую длину своих производных. + Параметры базовой кривой и репараметризованной кривой связаны равенствами: \n + Для линейной репараметризации b * (t - tmin) = t_basisCurve - tmin_basisCurve, где t - параметр репараметризованной кривой. + Для квадратичной репараметризации t_basisCurve = a * t * t + b * t + c, где t - параметр репараметризованной кривой. + При квадратичной репараметризации можно выбирать не только новый диапазон параметров, но и величину первой производной в начале кривой. + Базовой кривой для репараметризованной кривой не может служить другая репараметризованная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Reparametrized curve is used for matching domains of curves. \n + Geometrically reparametrized curve completely coincides with base curve 'basisCurve'. + Reparametrized curve has another definition domain and as a result another length of its derivatives. + Parameters of base curve and reparametrized curve are related by the equality: \n + For linear reparametrization b * (t - tmin) = t_basisCurve - tmin_basisCurve, where 't' - parameter of reparametrized curve. + For quadratic reparametrization t_basisCurve = a * t * t + b * t + c, where 't' - parameter of reparametrized curve. + When the quadratic reparametrization is used it is possible to define the first derivative value at the beginning of the curve. + Another reparametrized curve can't be the base curve for a reparametrized curve. + In this situation it changes to the initial base curve. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbReparamCurve3D : public MbCurve3D { + enum MbeReparamType { + rt_Linear, ///< \ru Линейная репараметризация. \en Linear reparametrization. + rt_Quadratic, ///< \ru Квадратичная репараметризация. \en Quadratic reparametrization. + rt_Cubic ///< \ru Кубическая репараметризация. \en Quadratic reparametrization. + }; + +protected: + MbCurve3D * basisCurve; ///< \ru Базовая кривая. \en The base curve. + MbeReparamType reparamType; ///< \ru Способ репараметризации. \en Way of repatametrization. + double tmin; ///< \ru Начальный параметр. \en Start parameter. + double tmax; ///< \ru Конечный параметр. \en End parameter. + double q; ///< \ru Коэффициент при кубическом члене репараметризующего многочлена. \en The coefficient of the cubic term of the reparametrizing polynomial. + double a; ///< \ru Коэффициент при квадратичном члене репараметризующего многочлена. \en The coefficient of the quadratic term of the reparametrizing polynomial. + double b; ///< \ru Коэффициент при линейном члене репараметризующего многочлена. \en The coefficient of the linear term of the reparametrizing polynomial. + double c; ///< \ru Свободный коэффициент репараметризующего многочлена. \en The free coefficient of the reparametrizing polynomial. + +protected: + MbReparamCurve3D( const MbReparamCurve3D &, MbRegDuplicate * ); +private : + MbReparamCurve3D( const MbReparamCurve3D & ); // \ru Не реализовано. \en Not implemented. +public : + MbReparamCurve3D( const MbCurve3D &, double t1, double t2 ); + MbReparamCurve3D( const MbCurve3D &, double t1, double t2, double begFirstDerValue ); + MbReparamCurve3D( const MbCurve3D &, double t1, double t2, double derBeg, double derEnd ); + + virtual ~MbReparamCurve3D(); + +public : + VISITING_CLASS( MbReparamCurve3D ); + + void Init( double t1, double t2 ); + void Init( double t1, double t2, double begFirstDerValue ); + void Init( double t1, double t2, double der1, double der2 ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией \en Whether the object is a copy + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Расстояние до точки \en Distance to a point + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; // \ru Являются ли объекты идентичными в пространстве \en Whether the objects are equal in space + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; + virtual double GetTMax() const; + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void Normal ( double & t, MbVector3D & ) const;// \ru Вектор главной нормали \en Vector of the principal normal + // \ru Функции кривой для работы вне области определения параметрической кривой \en Functions of curve for working outside the domain of parametric curve + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void _Normal ( double t, MbVector3D & ) const;// \ru Вектор главной нормали \en Vector of the principal normal + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + virtual const MbCurve3D & GetBasisCurve() const; + virtual MbCurve3D & SetBasisCurve(); + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Create a trimmed curve + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double CalculateMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double CalculateLength( double t1, double t2 ) const; + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + virtual double GetLengthEvaluation() const; + + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system + virtual bool IsDegenerate( double eps = METRIC_PRECISION ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Являются ли стыки контура\кривой гладкими? \en Whether the joints of a contour\curve are smooth. + virtual double Curvature ( double ) const; // \ru Кривизна кривой \en Curvature of the curve + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual void CalculatePolygon( const MbStepData & stepData, MbPolygon3D &polygon ) const; // \ru pассчитать полигон \en Calculate a polygon + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой \en Calculate the bounding box of a curve + virtual void GetCentre( MbCartPoint3D & ) const; // \ru Посчитать центр кривой \en Calculate the center of a curve + virtual void GetWeightCentre( MbCartPoint3D & ) const; // \ru Посчитать центр тяжести кривой \en Calculate the gravity center of the curve + + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги \en Get n points of curve equally spaced by the arc length + + // \ru Ближайшая проекция точки на кривую \en The nearest projection of a point onto the curve + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; + // \ru Определение точек касания изоклины \en Determination of tangent points of isocline + virtual void GetIsoclinal( const MbVector3D & nor, SArray & tIso ) const; + /// \ru Найти все особые точки функции кривизны кривой. + /// \en Find all the special points of the curvature function of the curve. + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + + // \ru Прохождение кривой через точку \en Passing of curve through a point + //virtual bool GoThroughPoint( double t, MbCartPoint3D & p0 ); + // \ru Касание кривой через точку с заданной производной \en Tangent of curve through point with the given derivative + //virtual bool GoThroughPointWithDerive( double t, MbCartPoint3D & p0, MbVector3D & v0 ); + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of a curve + + virtual size_t GetCount() const; + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Change a carrier + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether the curve is planar + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой \en Get axis of curve + + void ParameterInto( double & ) const; // \ru Перевод параметра базовой кривой в локальный параметр \en Transformation of the base curve parameter to a local parameter + void ParameterFrom( double & ) const; // \ru Перевод локального параметра в параметр базовой кривой \en Transformation of a local parameter to the base curve parameter + + void SetBasisCurve( MbCurve3D & ); // \ru Заменить плоскую кривую \en Replace the planar curve + double Tmin() const { return tmin; } // \ru Начальный параметр \en Start parameter + double Tmax() const { return tmax; } // \ru Конечный параметр \en End parameter + double Dt() const { return b; } // \ru Производная параметра кривой basisCurve по параметру \en Derivative of parameter of 'basisCurve' curve by parameter + void SetTmin( double t ); + void SetTmax( double t ); + void SetDt ( double d ); + + // \ru !!! геометрия подложки тождественна геометрии кривой, отлична параметризация !!! \en !!! geometry of substrate is identical to geometry of curve, parameterization is different !!! + virtual const MbCurve3D & GetSubstrate() const; // \ru Выдать подложку или себя \en Get substrate or itself + virtual MbCurve3D & SetSubstrate(); // \ru Выдать подложку или себя \en Get substrate or itself + virtual int SubstrateCurveDirection() const; // \ru Направление подложки относительно кривой или наоборот \en Direction of substrate relative to the curve or vice versa + virtual void SubstrateToCurve( double & ) const; // \ru Преобразовать параметр подложки в параметр кривой \en Transform a substrate parameter to the curve parameter + virtual void CurveToSubstrate( double & ) const; // \ru Преобразовать параметр кривой в параметр подложки \en Transform a curve parameter to the substrate parameter + // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if the curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы) \en Get a surface curve if a spatial curve is on a surface (call DeleteItem for arguments after using ) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Является ли объект смещением \en Whether the object is a shift + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + bool IsLinear() const { return (reparamType == rt_Linear); } // \ru Является ли репараметризация линейной? \en Is the re-parametrization linear? + +private: + void operator = ( const MbReparamCurve3D & ); // \ru Не реализовано. \en Not implemented. + double CubicRoot( double t ) const; // \ru Решение кубического уравнения. \en Solution of cubic equation. + void Explore( double t, double * par, double * dpar, double * ddpar, double * dddpar ) const; // \ru Параметр базовой кривой и его производные. \en The base curve parameter and its derivatives. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbReparamCurve3D ) +}; // MbReparamCurve3D + +IMPL_PERSISTENT_OPS( MbReparamCurve3D ) + +//------------------------------------------------------------------------------ +/// \ru Перевод параметра базовой кривой в новый параметр. \en Transformation of the base curve parameter to a new parameter. +// --- +inline void MbReparamCurve3D::ParameterInto( double & t ) const { + if ( reparamType == rt_Linear ) + t = ( t - c ) / b; + else if( reparamType == rt_Quadratic ){ + C3D_ASSERT( ::fabs(a) > NULL_EPSILON ); + const double discriminant = b * b + 4.0 * a * (t - c); + if ( discriminant > EXTENT_EQUAL ) + t = 0.5 * ( ::sqrt(discriminant) - b ) / a; + else + t = -0.5 * b / a; + } + else if ( reparamType == rt_Cubic ) { + bool close = basisCurve->IsClosed(); + double bTmin = basisCurve->GetTMin(), bTmax = basisCurve->GetTMax(); + if ( !close && ( t < bTmin || t > bTmax ) ) { + double t0 = ( t < bTmin ) ? tmin : tmax; + double par = ( t < bTmin ) ? bTmin : bTmax; + double dpar = 3.0 * q * t0 * t0 + 2.0 * a * t0 + b; + t = t0 + ( t - par ) / dpar; + } + else { + double n = 0.0; + if ( close ) { + double period = bTmax - bTmin; + n = ::floor( (t - bTmin) / period ); + t -= n * period; + } + t = CubicRoot( t ); + if ( n != 0.0 ) + t += n * ( tmax - tmin ); + } + } +} + +//------------------------------------------------------------------------------ +/// \ru Перевод нового параметра в параметр базовой кривой. \en Transformation of a new parameter to the base curve parameter. +// --- +inline void MbReparamCurve3D::ParameterFrom( double & t ) const { + if ( reparamType == rt_Linear ) + t = b * t + c; + else if( reparamType == rt_Quadratic ) + t = a * t * t + b * t + c; + else if ( reparamType == rt_Cubic ) + Explore( t, &t, 0, 0, 0 ); +} + + +#endif // __CUR_REPARAM_CURVE3D_H diff --git a/C3d/Include/cur_silhouette_curve.h b/C3d/Include/cur_silhouette_curve.h new file mode 100644 index 0000000..abee7d9 --- /dev/null +++ b/C3d/Include/cur_silhouette_curve.h @@ -0,0 +1,242 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Линия очерка или cилуэтная кривая поверхности. + \en Isocline curve or silhouette curve of surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_SILHOUETTE_CURVE_H +#define __CUR_SILHOUETTE_CURVE_H + + +#include +#include + + +struct AuxiliarySilhouetteData; +struct CurvaturePointData; + +//------------------------------------------------------------------------------ +/** \brief \ru Линия очерка или силуэтная кривая поверхности. + \en Isocline curve or silhouette curve of surface. \~ + \details \ru Линии, отделяющие видимую часть поверхности от невидимой её части называются силуэтными линиями. + Силуэтные линии могут проходить как по краю поверхности, так и внутри неё. + В последнем случае силуэтные линии называют линиями очерка. + При переходе через линию очерка нормаль поверхности меняет направление по отношению к линии визирования. \n + Линией визирования называется линия, проходящая через точку наблюдения и точку поверхности. + В точках линии очерка нормаль поверхности ортогональна линии визирования. + В общем случае у поверхности линий очерка может быть несколько. \n + Если параметр species==cbt_Ordinary, то кривая является точной. \n + Если параметр species==cbt_Specific, то кривая построена по упорядоченной совокупности + двумерных точек на параметрической плоскости поверхности. + Эта совокупность точек представлена в виде сплайна на поверхности. + Сплайн при значениях параметра, соответствующих опорным точкам, совпадает с силуэтной линией, + при других значениях параметра он проходит вблизи силуэтной линии. + Для любого значения параметра сплайна точки силуэтной линии вычисляются с достаточной точностью + из решения системы уравнений для силуэтной линии поверхности. \n + Каждая линия очерка или замкнута, или оканчивается на краях поверхности. + Для разных направлений взгляда существует своя совокупность линий очерка, + поэтому при повороте поверхности линии очерка необходимо строить заново. \n + Линия очерка используется для построения проекции поверхности. \n + Линию очерка могут иметь поверхности, обладающие кривизной хотя бы вдоль одного параметра. + \en Lines separating the visible part of a surface from its invisible part are called silhouette lines. + Silhouette lines can pass both by the surface boundary and inside it. + In the last case silhouette lines are called isocline curves. + The normal of a surface changes the direction relative to the line of sight while moving through isocline curve. \n + The line passing through a point of a surface and the observation point is called the line of sight. + The normal of surface is orthogonal to the line of sight at points of isocline curve. + Generally there can be several isocline curves of surface. \n + If parameter 'species' is equal to cbt_Ordinary, then the curve is exact. \n + If parameter 'species' is equal to cbt_Specific, then the curve is constructed by an ordered set of + two-dimensional points in parametric space of surface. + This set of points is represented as spline on surface. + Spline coincides with the silhouette line at values of parameter corresponding to support points, + it passes near the silhouette line at other values of parameter. + For any parameter of a spline the points of silhouette line are calculated with enough tolerance + from solution of system of equations for silhouette line of surface. \n + Each isocline curve is either closed or terminates at surface boundaries. + For the different directions of view there is a set of isocline curves, + therefore the isocline curves need to be rebuilt at surface rotation. \n + Isocline curve is used for construction of surface projection. \n + The surfaces having curvature along at least one parameter can have the isocline curve. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbSilhouetteCurve : public MbSurfaceCurve { + +protected: + MbeCurveBuildType species; ///< \ru Вид кривой (точная полностью или только в отдельных точках). \en Curve type (exact completely or in separate points only). + bool perspective; ///< \ru Перспективная или параллельная проекция. \en Perspective or parallel projection. + MbVector3D eye; ///< \ru Вектор взгляда (для параллельной проекции) или радиус-вектор точки наблюдения (для перспективной проекции). \en Vector of view (for parallel projection) or radius-vector of point of view (for perspective projection). + MbAxis3D * lathe; ///< \ru Ось кругового проецирования (проекции токарного сечения). \en The axis for rotate projection. + MbCurve3D * approxCurve; ///< \ru Пространственное представление линии очерка. \en The spatial representation of isocline curve. + bool approxExact; ///< \ru Точная ли кривая approxCurve. \en Is exact approxCurven. + + AuxiliarySilhouetteData * silhData; ///< \ru Общие параметры силуэтной линии, используемые в алгоритмах ее точного представления. + ///< \en General parameters of a silhouette line used in its exact presentation algorithms. +public : + /// \ru Конструктор по поверхности, двумерной кривой, типу кривой, матрице и флагу перспективы. \en Constructor by surface, two-dimensional curve, type of curve, matrix and flag of perspective. + MbSilhouetteCurve( const MbSurface & surf, const MbCurve & crv, MbeCurveBuildType _species, + const MbMatrix3D & m, bool p ); + /// \ru Конструктор по поверхности, двумерной кривой, типу кривой, вектору взгляда и флагу перспективы. \en Constructor by surface, two-dimensional curve, type of curve, vector of view and flag of perspective. + MbSilhouetteCurve( const MbSurface & surf, const MbCurve & crv, MbeCurveBuildType _species, + const MbVector3D & e, bool p, const MbAxis3D * axis = NULL ); +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbSilhouetteCurve( const MbSilhouetteCurve &, MbRegDuplicate * ); +private: + MbSilhouetteCurve( const MbSilhouetteCurve & ); // \ru Не реализовано!!! \en Not implemented!!! +public: + virtual ~MbSilhouetteCurve(); + +public: + VISITING_CLASS( MbSilhouetteCurve ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get element type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, являются ли объекты одинаковыми. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru Общие функции кривой. \en Common functions of curve. + // \ru Функции для работы в области определения. \en Functions for working in the definition domain. + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate a point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + /// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. + virtual void Normal( double & t, MbVector3D & ) const; + // \ru Функции для работы вне области определения. \en Functions for working outside of definition domain. + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + /// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. + virtual void _Normal( double t, MbVector3D & ) const; + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + /// \ru Вычислить кривизну кривой. \en Calculate curvature of curve. + virtual double Curvature( double t ) const; + // \ru Функции приближённого быстрого вычисления точки и производных на кривой. \en Functions of approximate fast calculation of point and derivatives on the curve. + virtual void FastApproxExplore( double & t, MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec ) const; + + // \ru Вычислить шаг параметра по заданному углу отклонения касательной. \en Calculate step of parameter by a given angle of deviation of tangent. + virtual double DeviationStep( double t, double angle ) const; + // \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual void CalculateGabarit( MbCube & ) const; + // \ru Определить, является ли кривая плоской. \en Determine whether the curve is planar. + virtual bool IsPlanar() const; + // \ru Заполнить плейсмент, если кривая плоская. \en Fill the placement if the curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using ). + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place3d, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Создать усеченную кривую. \en Create a trimmed curve + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; + // \ru Дать плоскую проекцию кривой(локальная система координат, шаг, параметрическая область). \en Get the planar projection of a curve (local coordinate system, step, parametric region). + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + + virtual double GetMetricLength() const; // \ru Метрическая длина кривой \en Metric length of a curve + virtual double GetLengthEvaluation() const; // \ru Оценить метрическую длину кривой. \en Estimate the metric length of a curve. + + virtual double GetParamToUnit() const; // \ru Дать приращение параметра, осреднённо соответствующее единичной длине в пространстве. \en Get parameter increment which averagingly corresponds to the unit length in space. + virtual double GetParamToUnit( double t ) const; // \ru Дать приращение параметра, соответствующее единичной длине в пространстве. \en Get parameter increment which corresponds to the unit length in space. + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + + virtual MbeCurveBuildType GetBuildType() const; // \ru Дать тип кривой. \en Get type of curve. + virtual bool InsertPoint( double & t ); // \ru Вставить точку и выдать её параметр. \en Insert point and get its parameter. + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Определить, подобные ли кривые для объединения (слива). \en Determine whether the curves for union (joining) are similar. + + /// \ru Определить, существует ли точное пространственное представление линии очерка. \en Determine whether the exact spatial representation of isocline curve exists. + bool IsExactSpaceCurve() const { return (approxExact && approxCurve != NULL); } + /// \ru Получить указатель на кривую точного пространственное представление линии очерка. (Может и не быть). \en Get a pointer to the curve of exact spatial representation of isocline curve. (Can be absent). + const MbCurve3D * GetExactSpaceCurve() const { return approxExact ? approxCurve : NULL; } + + /// \ru Дать пространственную копию линии очерка. \en Construct a new spatial copy of isocline curve. + const MbCurve3D * GetApproxCurve() const { return approxCurve; } + bool InsertPointToApproxCurve( double & t ); // \ru Вставить точку аппроксимационную кривую и выдать её параметр. \en Insert point to approximation curve and get its parameter. + /// \ru Установить тип линии очерка. \en Set type of isocline curve. + void SetBuildType( MbeCurveBuildType spec ) { species = spec; } + /// \ru Вычислить точку. \en Calculate a point. + void GetPointOn ( double & t, MbCartPoint3D & ) const; + /// \ru Вычислить первую производную. \en Calculate the first derivative. + void GetFirstDer( double & t, MbVector3D & ) const; + + // \ru Получить текущую точку на кривой по параметру. \en Get current point on a curve by a parameter. + virtual bool GetCurvePoint( double & t, MbCartPoint & cPoint ) const; + + // \ru Найти все особые точки функции кривизны кривой. \en Find all the special points of the curvature function of the curve. + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + +private: + // Расчитать точку обрезки луча pnt0 - pnt границами поверхности surface. + bool IsCutBounds( const MbCartPoint * pnt0, MbCartPoint & pnt ) const; + // Вычислить параметр видимости в точке и его градиент. + void CalcVisibilityParam( const MbCartPoint & p, double & val, MbVector * der = NULL ) const; + // Ищем интервал между точками p1 и p2, на котором произойдет смена видимости, последовательно прибавляя в заданную сторону вектор w. + void GoToOneSide( const MbVector & w, MbCartPoint & p1, MbCartPoint & p2, double & vis1, double & vis2, MbVector &der1, MbVector & der2, int nIter, bool move1 ) const; + // Найти точку на силуэтной линии на отрезке [pnt0 - w, pnt0 + w]. + bool GetPointOnSilhouette( const MbCartPoint &pnt0, const MbVector & w, int nIter, double zEps, double & zEpsOut, MbCartPoint & silhPoint ) const; + // Найти проекцию точки на аппроксимационном сплайне на силуэтную линию по нормали к аппроксимационному сплайну. + void ExactSilhouettePoint( double h, double t, int pos, MbCartPoint & point2D ) const; + // Расчет производной через конечные разности. + void CalcFiniteDifference( double tmin, double tmax, double h, double t, int pos, int order, + std::map & points2D, std::map & points3D, std::map( &ders )[3] ) const; + // Суммирование слагаемых конечной разности. + void CalcDifference( double tmin, double tmax, double h, double t, int pos0, int order, int pos, const double( &kf )[5], double zn, + std::map & points2D, std::map & points3D, std::map( &ders )[3] ) const; + // Расчет по параметру на сплайне точной точки на силуэтной линии, а также первой и второй производной, вычисленных через конечные разности. + void AccurateExplore( double t, MbCartPoint & pnt, MbVector3D & fir, MbVector3D & sec ) const; + // Расчет параметров, используемых в алгоритмах для кривизны, в точке (положение на кривой, кривизна, нормаль, шаг). + void CurvatureExplore( double t, CurvaturePointData & cpd ) const; + // Расчет на поверхности кривизны в направлении seg. + void CurvatureOnSurfaceLine( const MbVector & seg, const MbCartPoint & p, double & curv, double & dcurv ) const; + // Анализ разрыва кривизны на поверхности на отрезке между точками p1 и p2. + bool IsCurvatureRapture( const MbCartPoint & p1, const MbCartPoint & p2 ) const; + // Поиск экстремума на интервале pd1 - pd2 методом золотого сечения. Начиная с точки prev до точки pd2, кривизна монотоно убывает/возрастает. + void CurvatureExtremeBinarySearch( const CurvaturePointData & pd1, const CurvaturePointData & pd2, CurvaturePointData & prev, + bool isMax, double eps, std::vector & spPoints ) const; + // Проверка интервала на кривой на разрыв кривизны. + void CheckRapture( double t1, double t2, std::vector & spPoints ) const; + // Найти разрывы кривизны на участке кривой pd1 - pd2. Начиная с точки prev до точки pd2, кривизна монотоно убывает/возрастает. + void FindCurvatureRaptures( const CurvaturePointData & pd1, const CurvaturePointData & pd2, CurvaturePointData & prev, + double paramAccuracy, std::vector & points ) const; + // \ru Проверить параметр и вычислить параметрическую точки. \en Check parameter and calculate parametric points. + bool CorrectPoint( double & t, bool ext, MbCartPoint & cPoint, MbVector & cFirst, MbVector * cSecond, MbVector * cThird ) const; + void CalculatePoint ( double & t, bool ext, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + void CalculateFirst ( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + void CalculateSecond( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + void CalculateThird ( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Решить уравнения для определения точек очерка. \en Solve equations for determination of outline points. + MbeNewtonResult SilhouetteNewton( const MbCartPoint3D & point, const MbVector3D & vector, + const MbRect & wrkRect, // \ru Рабочая область поиска \en Working region of search + double funcEpsilon, size_t iterLimit, + double & u, double & v ) const; + +private: + /// \ru Построить точную пространственную копию кривой. \en Construct the exact spatial curve copy. + bool CreateExactCurve(); + /// \ru Построить новую пространственную копию линии очерка. \en Construct a new spatial copy of isocline curve. + bool CreateApproxCurve(); + + void operator = ( const MbSilhouetteCurve & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSilhouetteCurve ) +}; + +IMPL_PERSISTENT_OPS( MbSilhouetteCurve ) + + +#endif // __CUR_SILHOUETTE_CURVE_H diff --git a/C3d/Include/cur_spiral.h b/C3d/Include/cur_spiral.h new file mode 100644 index 0000000..d5aa2c7 --- /dev/null +++ b/C3d/Include/cur_spiral.h @@ -0,0 +1,171 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Спираль. + \en Spiral. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_SPIRAL_H +#define __CUR_SPIRAL_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Спираль. + \en Spiral. \~ + \details \ru Родительский класс спиралей: MbConeSpiral, MbCrookedSpiral, MbCurveSpiral. \n + \en Parent class for spirals: MbConeSpiral, MbCrookedSpiral, MbCurveSpiral. \n \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbSpiral: public MbCurve3D { +protected: + MbPlacement3D position; ///< \ru Локальная система координат (положение центра). \en Local coordinate system (location of center). + double step; ///< \ru Шаг спирали. \en A pitch of spiral. + double tmin; ///< \ru Минимальное значение параметра спирали. \en Minimal value of parameter of spiral. + double tmax; ///< \ru Максимальное значение параметра спирали. \en Maximal value of parameter of spiral. + + /** \brief \ru Метрическая длина кривой. + \en Metric length of a curve. \~ + \details \ru Метрическая длина кривой расчитывается только при запросе длины объекта. Метрическая длина кривой в конструкторе кривой и после модификации кривой принимает отрицательное значение. + \en Metric length of a curve is calculated only at the request. Metric length of a curve is undefined (negative) after object constructor and after object modifications. \n \~ + */ + mutable double metricLength; + /** \brief \ru Габаритный куб кривой. + \en Bounding box of a curve. \~ + \details \ru Габаритный куб кривой расчитывается только при запросе габарита объекта. Габаритный куб в конструкторе кривой и после модификации кривой принимает неопределенное значение. + \en Bounding box of a curve is calculated only at the request. Bounding box of a curve is undefined after object constructor and after object modifications. \n \~ + */ + mutable MbCube cube; + +protected: + MbSpiral() : position(), step( 1.0 ), tmin( 0.0 ), tmax( M_PI2 ), metricLength( -1.0 ), cube() {} + MbSpiral( const MbPlacement3D & pl ) : position( pl ), step( 0.0 ), tmin( 0.0 ), tmax( 0.0 ), metricLength( -1.0 ), cube() {} + MbSpiral( const MbPlacement3D & pl, double height, double st ); // \ru По высоте и шагу \en By height and pitch + MbSpiral( const MbPlacement3D & pl, double s, double t1, double t2 ); + MbSpiral( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, double st, bool left = false ); + MbSpiral( const MbSpiral & init ); +public : + virtual ~MbSpiral(); + +public : + VISITING_CLASS( MbSpiral ); + + void Init( const MbSpiral & init ); + void Init( const MbPlacement3D & place ); + void Init( double height, double st ); // \ru Установить высоту и шаг \en Set height and pitch + void Init( const MbPlacement3D & place, double height, double st ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента \en Type of element + virtual MbeSpaceType Type() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб \en Add your own bounding box into the cube + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & properties ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of the parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double & t, MbCartPoint3D & ) const = 0; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector3D & ) const = 0; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector3D & ) const = 0; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector3D & ) const = 0; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const = 0; + + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; // \ru Изменить направление \en Change direction + + virtual double GetMetricLength() const; // \ru Выдать метрическую длину ограниченной кривой \en Get metric length of bounded curve + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual double Curvature( double t ) const; // \ru Кривизна \en Curvature + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of step of approximation + virtual double DeviationStep( double t, double angle ) const; + + virtual size_t GetCount() const; + double GetSpiralPeriod() const; // \ru Вернуть период \en Get period + + // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if the curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Является ли объект смещением \en Whether the object is a shift + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual void GetCentre( MbCartPoint3D & c ) const; // \ru Выдать центр \en Get center + + // \ru Функции спирали \en Functions of spiral + + virtual void SetStep( double s ) = 0; // \ru Изменить шаг \en Change step + virtual double GetSpiralRadius ( double t ) const = 0; // \ru Выдать физический радиус спирали \en Get physical radius of spiral + inline void CheckParam( double & t ) const; + void GetDirection ( MbVector3D & v ) const { v = position.GetAxisZ(); } + bool GetAxis( MbAxis3D & axis ) const; // \ru Дать ось спирали \en Get axis of spiral + double GetStep() const { return step; } // \ru Выдать шаг \en Get step + double GetSpiralStep() const; // \ru Выдать физический шаг спирали \en Get physical pitch of spiral + double GetAngle() const { return tmax-tmin; } // \ru Выдать полный угол спирали \en Get full angle of spiral + void SetTMin( double t ) { tmin = t; Refresh(); } // \ru Изменить граничный угол \en Change boundary angle + void SetTMax( double t ) { tmax = t; Refresh(); } // \ru Изменить граничный угол \en Change boundary angle + void SetLimit( double t1, double t2 ) { tmin = std_min( t1, t2 ); tmax = std_max( t1, t2 ); Refresh(); } + + const MbPlacement3D & GetPlacement() const { return position; } + bool IsPositionNormal() const { return ( !position.IsAffine() ); } + +private: + void operator = ( const MbSpiral & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS( MbSpiral ) +}; + +IMPL_PERSISTENT_OPS( MbSpiral ) + +//------------------------------------------------------------------------------ +// \ru Проверка параметра кривой \en Check parameter of curve +//--- +inline void MbSpiral::CheckParam( double & t ) const +{ + if ( t < tmin ) + t = tmin; + if ( t > tmax ) + t = tmax; +} + + +//------------------------------------------------------------------------------ +// \ru Выдать физический шаг спирали \en Get physical pitch of spiral +//--- +inline double MbSpiral::GetSpiralStep() const +{ + if ( position.IsNormal() ) + return step; + else if ( position.IsOrthogonal() ) { + return (step * position.GetAxisZ().Length()); + } + return 0.0; +} + + +#endif // __CUR_SPIRAL_H diff --git a/C3d/Include/cur_surface_curve.h b/C3d/Include/cur_surface_curve.h new file mode 100644 index 0000000..774ec95 --- /dev/null +++ b/C3d/Include/cur_surface_curve.h @@ -0,0 +1,355 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая на поверхности. + \en Curve on surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_SURFACE_CURVE_H +#define __CUR_SURFACE_CURVE_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbRect; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbContourOnSurface; +class MATH_CLASS MbCurveTessellation; +class MbCurveIntoNurbsInfo; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая на поверхности. + \en Curve on surface. \~ + \details \ru Кривая на поверхности строится путём введения зависимости параметров поверхности u и v + от некоторого общего для них параметра t: u=u(t), v=v(t). \n + Параметры поверхности u и v являются координатами двумерной точки в пространстве параметров поверхности. + Кривая на поверхности описывается поверхностью surface и двумерной кривой в пространстве параметров curve. + Поверхностью surface может быть любая поверхность, кроме MbCurveBoundedSurface. \n + Для заданного параметра t кривой curve вычисляется двумерная точка w=[u v] области параметров поверхности, + далее для параметров u и v поверхностью surface вычисляется точка кривой на поверхности. + Параметры u и v поверхности могут выходить за пределы её области определения. \n + Кривая на поверхности может быть периодической, + если периодической является двумерная кривая curve или + если кривая curve имеет совпадающие производные на краях и крайние точки кривой + смещены на соответствующий период периодической по первому или второму параметру поверхности surface. + \en Curve on surface is constructed by introduction of dependence of u and v surface parameters + from some parameter t common for them: u=u(t), v=v(t). \n + u and v surface parameters are coordinates of two-dimensional point in space of surface parameters. + Curve on surface is described by 'surface' surface and two-dimensional curve 'curve' in space of parameters. + Any surface except MbCurveBoundedSurface can be surface 'surface'. \n + two-dimensional point w=[u v] of region of surface parameters is calculated for a given parameter t of curve 'curve', + further, a point of curve on surface is calculated for u and v parameters of 'surface' surface. + u and v surface parameters can exceed the bounds of its domain. \n + Curve on surface can be periodic, + if two-dimensional curve 'curve' is periodic or + if curve 'curve' has coinciding derivatives at the end points and the curve end points + is shifted by corresponding period of 'surface' surface which is periodic by first or second parameter. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbSurfaceCurve : public MbCurve3D { +protected : + MbCurve * curve; ///< \ru Плоская кривая в uv-пространстве (всегда не NULL). \en Planar curve in uv-space (always not NULL). + MbSurface * surface; ///< \ru Указатель на поверхность (всегда не NULL). \en Pointer to the surface (always not NULL). + bool closed; ///< \ru Флаг замкнутости поверхностной кривой. \en An attribute of closedness of surface of curve. + + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + mutable MbCube cube; ///< \ru Габаритный куб. \en Bounding box. + mutable double metricLength; ///< \ru Метрическая длина кривой. \en Metric length of a curve. \~ + mutable double lengthEvaluation; ///< \ru Оценочная длина кривой. \en Estimated length of a curve. + mutable double curveRadius; ///< \ru Радиус кривой, если она является дугой окружности в пространстве. \en The radius of the curve, if the curve is a spatial arc. + mutable ThreeStates isStraight; ///< \ru Флаг прямолинейности. \en A straightness flag. + SPtr tessellation; ///< \ru Разбивка кривой. \en Curve tessellation. + + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbSurfaceCurveAuxiliaryData : public AuxiliaryData { + public: + double t; ///< \ru Модифицированный параметр. \en Modified parameter. + + MbVector pDers[cdt_CountDer]; ///< \ru Точка и производные двумерной кривой. \en Curve point and derivatives. + MbVector3D sDers[sdt_CountDer]; ///< \ru Точка и производные поверхности. \en Surface point and derivatives. + MbVector3D sNorm; ///< \ru Нормаль поверхности. \en Surface normal. + + MbSurfaceCurveAuxiliaryData(); + MbSurfaceCurveAuxiliaryData( const MbSurfaceCurveAuxiliaryData & ); + virtual ~MbSurfaceCurveAuxiliaryData(); + + void Init(); + void Init( const MbSurfaceCurveAuxiliaryData & ); + void Move( const MbVector3D & ); + }; + + mutable CacheManager cache; + +public : + /// \ru Конструктор кривой на поверхности. \en Constructor of curve on surface. + MbSurfaceCurve( const MbSurface &, const MbCurve &, bool same, MbRegDuplicate * iReg = NULL ); + /// \ru Конструктор отрезка прямой на поверхности. \en Constructor of a line segment on surface. + MbSurfaceCurve( const MbSurface &, const MbCartPoint & p0, const MbCartPoint & p1, MbePlaneType type = pt_Curve ); + /// \ru Конструктор граничной кривой поверхности. \en Constructor of boundary curve of surface. + MbSurfaceCurve( const MbSurface &, ptrdiff_t pnt1, ptrdiff_t pnt2, MbePlaneType type = pt_Curve ); +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbSurfaceCurve( const MbSurfaceCurve &, MbRegDuplicate * ); + /// \ru Конструктор копирования кривой с той же поверхностью для CurvesDuplicate(). \en Copy-constructor of a curve with the same surface for CurvesDuplicate(). + explicit MbSurfaceCurve( const MbSurfaceCurve * ); +private: + MbSurfaceCurve( const MbSurfaceCurve & ); // \ru Не реализовано!!! \en Not implemented!!! + +public : + virtual ~MbSurfaceCurve(); + +public: + /// \ru Реализация функции, инициирующей посещение объекта. \en Implementation of a function initializing a visit of an object. + VISITING_CLASS( MbSurfaceCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get element type. + virtual MbeSpaceType Type() const; // \ru Дать тип элемента. \en Get element type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + /// \ru Копия кривой с той же поверхностью. \en Copy of curve with the same surface. + MbSurfaceCurve & CurvesDuplicate() const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, являются ли объекты одинаковыми. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавить свой габарит в куб. \en Add your own bounding box into a cube. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Общие функции кривой. + \en \name Common functions of curve. + \{ */ + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual bool IsClosed() const; // \ru Проверить замкнутость кривой. \en Check for curve closedness. + virtual double GetPeriod() const; // \ru Вернуть период периодической кривой. \en Get period of a periodic curve. + + // \ru Функции для работы в области определения. \en Functions for working in the definition domain. + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate a point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Функции для работы вне области определения. \en Functions for working outside of definition domain. + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore ( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + // \ru Установить параметры NURBS. \en Set parameters of NURBS. + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создать усеченную кривую. \en Create a trimmed curve + + // \ru Вычислить ближайшую проекцию точки на кривую. \en Calculate the nearest projection of a point onto the curve. + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + void SetTesselation( const MbContourOnSurface & contour, size_t indSegment ); // \ru Установить разбиение из контура. \en Set tessellation from contour. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой. \en Get a planar projection of a curve. + /// \ru Вычислить плоскую проекцию кривой в частных случаях. \en Calculate planar projection of a curve in special cases. + MbCurve * GetParticularMap( const MbMatrix3D & into, MbRect1D * pRgn, + VERSION version ) const; + + virtual bool IsStraight() const; // \ru Определить, является ли линия прямолинейной. \en Determine whether the line is straight. + virtual void ChangeCarrier ( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменить носитель. \en Change the carrier. + virtual bool ChangeCarrierBorne( const MbSpaceItem &, MbSpaceItem &, const MbMatrix & matr ); // \ru Изменить носимые элементы. \en Change a carrier elements. + virtual bool IsPlanar() const; // \ru Определить, является ли кривая плоской. Прямолинейные кривые являются плоскими, но без определённой ЛСК. \en Determine whether the curve is planar. Straight lines is planar but without certain placement. + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Определить, являются ли стыки контура\кривой гладкими. \en Determine whether the joints of contour\curve are smooth. + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual double GetMetricLength() const; // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double GetLengthEvaluation() const; // \ru Оценить метрическую длину кривой. \en Estimate the metric length of a curve. + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой. \en Get the curve axis. + virtual void GetCentre ( MbCartPoint3D & c ) const; // \ru Выдать центр кривой. \en Get center of curve. + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; // \ru Выдать центр тяжести кривой. \en Get center of mass of curve. + + // \ru Вычислить ближайшую точку кривой к плейсменту. \en Calculate the curve point nearest to a placement. + virtual double DistanceToPlace( const MbPlacement3D & place, double & t0, double & angle ) const; + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using ). + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place3d, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get a surface curve if a spatial curve is on a surface (call DeleteItem for arguments after use). + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Заполнить плейсмент, если кривая плоская. \en Fill the placement if the curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Дать тип кривой. \en Get type of curve. + virtual MbeCurveBuildType GetBuildType() const; + /** \brief \ru Вставить точку по параметру. + \en Insert point by parameter. \~ + \details \ru Вставить точку по желаемому параметру и выдать фактический параметр. \n + \en Insert point by desirable parameter and get the actual parameter. \n \~ + \param[in] t - \ru Параметр на кривой, куда надо вставить точку. + \en Parameter on the curve where it is necessary to insert a point. \~ + \return \ru Возвращает true, если произошла вставка точки. + \en Returns true if a point was inserted. \~ + */ + virtual bool InsertPoint( double & t ); + + /// \ru Определить, является ли объект смещением. \en Determine whether the object is a translation. + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + /// \ru Определить, подобные ли кривые для объединения (слива). \en Determine whether the curves for union (joining) are similar. + virtual bool IsSimilarToCurve( const MbCurve3D & other, double precision = METRIC_PRECISION ) const; + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of a curve with equally spaced by the arc length. + + // \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual size_t GetCount() const; + + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous? + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); // \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length. + + /** \} */ + + /// \ru Определить, является ли кривая curve копией этой кривой. \en Determine whether the 'curve' curve is a duplicate of the current curve. + bool IsSameCurvePoints( const MbSurfaceCurve * scurve, double accuracy, bool sameSense ) const; + /// \ru Вычислить нормаль к поверхности. \en Calculate surface normal. + void SurfaceNormal( double & t, MbVector3D &, bool ext = false ) const; + /// \ru Получить параметры поверхности по параметру на кривой. \en Get surface parameters by a parameter on the curve. + void SurfaceParams( double & t, double & u, double & v, bool ext = false ) const; + /// \ru Вычислить параметрический габарит кривой. \en Calculate parametric bounding box of the curve. + void CalculateUVLimits( MbRect & uvRect ) const; + /// \ru Вычислить U-пары от V. \en Calculate U-pairs from V. + void GetUPairs( double v, SArray & u, SArray & t ) const; + /// \ru Вычислить V-пары от U. \en Calculate V-pairs from U. + void GetVPairs( double u, SArray & v, SArray & t ) const; + + /// \ru Построить участок пространственной копии кривой. \en Construct a piece of a spatial curve copy. + MbCurve3D * MakeCurve( double t1, double t2 ) const; + /// \ru Построить пространственную копию кривой. \en Construct a spatial curve copy. + MbCurve3D * MakeCurve() const; + /// \ru Построить точную пространственную копию кривой. \en Construct the exact spatial curve copy. + MbCurve3D * CreateCurve() const; + /// \ru Создать пространственную кривую по линии u, v. \en Create a spatial curve by u, v lines. + MbCurve3D * CreateUV() const; + + /// \ru Вычислить левый перпендикуляр к кривой в плоскости поверхности. \en Calculate the left perpendicular to a curve at level of surface. + void Transversal( double & t, MbVector3D & f ) const; + + /// \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + bool IsCurveEqual ( const MbSpaceItem & ) const; + /// \ru Сделать равной кривую. \en Make curve equal. + bool SetCurveEqual( const MbSpaceItem & ); + + /// \ru Дать кривую. \en Get curve. + const MbCurve & GetCurve() const { return *curve; } + /// \ru Дать поверхность. \en Get surface. + const MbSurface & GetSurface() const { return *surface; } + /// \ru Дать кривую. \en Get curve. + MbCurve & SetCurve() + { + metricLength = -1.0; + cache.Reset( true ); + return *curve; + } + /// \ru Дать поверхность. \en Get surface. + MbSurface & SetSurface() + { + metricLength = -1.0; + cache.Reset( true ); + return *surface; + } + + /// \ru Заменить кривую. \en Replace curve. + bool ChangeCurve ( const MbCurve & ); + /// \ru Заменить поверхность. \en Replace surface. + bool ChangeSurface( const MbSurface & ); + /// \ru Заменить кривую и поверхность. \en Replace curve and surface. + bool ChangeSurfaceCurve( const MbSurfaceCurve & ); + + /// \ru Установить область изменения параметра. \en Set range of parameter. + bool SetLimitParam( double newTMin, double newTMax ); + + /// \ru Получить текущую точку на кривой по параметру. \en Get current point on a curve by a parameter. + virtual bool GetCurvePoint( double & t, MbCartPoint & cPoint ) const; + +protected: + void CheckParam ( double & t, bool ext ) const; // \ru Проверить и изменить при необходимости параметр. \en Check and correct parameter. + void CalculatePoint ( double & t, bool ext, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + void CalculateFirst ( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + void CalculateSecond( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + void CalculateThird ( double & t, bool ext, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + /// \ru Попытаться создать пространственную кривую по проекционной кривой. \en Try to create a spatial curve from a projection curve. + MbCurve3D * TryProjection() const; + /// \ru Вычислить точку двумерной и пространственной кривой. \en Calculate a point on two-dimensional curve and on the curve. + void Explorer( double & t, bool ext, MbCartPoint & cPnt, MbCartPoint3D & pnt ) const; + void Explorer( double & t, bool ext, + MbCartPoint & cPnt, MbVector & cFir, MbVector & cSec, MbVector * cThird, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D & uuDer, MbVector3D & vvDer, MbVector3D & uvDer, MbVector3D & nor ) const; + + /** \brief \ru Проверить и установить замкнутость кривой. + \en Check and set the curve closedness. \~ + \details \ru Проверить и установить признак замкнутости кривой. \n + Вызывать после самостоятельного изменения двумерной кривой. + \en Check and set attribute of curve closedness. \n + To be called after independent changing of two-dimensional curve. \~ + */ + void CheckClosed(); + + /** \brief \ru Удалить кэши. + \en Delete caches. \~ + \details \ru Удалить кэши. \n + \en Delete caches. \n + */ + void CacheReset(); + +private: + // \ru Объявить оператор приравнивания по ссылке, \en Declare operator of assignment by reference + // \ru чтобы не был вызван по умолчанию оператор приравнивания по значению \en To prevent default calling of the assignment operator by value + void operator = ( const MbSurfaceCurve & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSurfaceCurve ) + + friend class MbSurfaceIntersectionCurve; +}; + +IMPL_PERSISTENT_OPS( MbSurfaceCurve ) + +#endif // __CUR_SURFACE_CURVE_H diff --git a/C3d/Include/cur_surface_intersection.h b/C3d/Include/cur_surface_intersection.h new file mode 100644 index 0000000..7a2a469 --- /dev/null +++ b/C3d/Include/cur_surface_intersection.h @@ -0,0 +1,813 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая пересечения двух поверхностей. + \en Intersection curve of two surfaces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_SURFACE_INTERSECTION_H +#define __CUR_SURFACE_INTERSECTION_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSurfaceIntersectionData; +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbReparamCurve; +class MbCurveIntoNurbsInfo; + +namespace c3d // namespace C3D +{ + typedef SPtr IntersectionCurveSPtr; + typedef SPtr ConstIntersectionCurveSPtr; + + typedef std::vector IntersectionCurvesVector; + typedef std::vector ConstIntersectionCurvesVector; + + typedef std::vector IntersectionCurvesSPtrVector; + typedef std::vector ConstIntersectionCurvesSPtrVector; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая пересечения двух поверхностей. + \en Intersection curve of two surfaces. \~ + \details \ru Кривая пересечения поверхностей содержит две кривые на пересекаемых поверхностях + curveOne и curveTwo, подчинённые следующим правилам:\n + 1. кривые имеют одинаковые области определения,\n + 2. кривые выдают один и тот же радиус-вектор и его производные при одинаковых параметрах, то есть, кривые одинаково направлены и совпадают в пространстве.\n + Параметр buildType кривой пересечения информирует о том, каким образом выполняется второе правило. + Если параметр buildType==cbt_Ordinary или buildType==cbt_Boundary, то правила выполняются точно. + Если параметр buildType==cbt_Specific или buildType==cbt_Tolerant, то второе правило выполняются приближённо. \n + В общем случае (buildType==cbt_Specific) кривая пересечения поверхностей представлена в виде двух двумерных сплайнов curveOne.curve и curveTwo.curve. + Сплайны проходят через двумерные опорные точки в пространстве параметров поверхностей curveOne.surface и curveTwo.surface, соответственно. + Каждой опорной точке сплайна curveOne соответствует опорная точка сплайна curveTwo. + В соответствующих опорных точках параметры сплайнов равны, а сплайны совпадают в пространстве. + Таким образом, в опорных точках сплайнов второе правило кривой пересечения выполняется точно. \n + Если через опорные точки провести пространственную ломаную, то угол между её соседними отрезками не будет превышать 0,04pi. + Изменение параметра при переходе от одной опорной точки к следующей опорной точке кривой пропорционально длине участка ломаной между соседними точками. \n + Для любого значения параметра точка пересечения поверхностей вычисляются точно из решения системы уравнений пересечения поверхностей.\n + Для определения точного пересечения поверхностей между соседними опорными точками сплайнов выполняются следующие действия. + Строится плоскость, перпендикулярная отрезку, начинающемуся и оканчивающемуся в соседних опорных точках. + Далее численным методом определяется точка пересечения трёх поверхностей: curveOne.surface, curveTwo.surface и плоскости.\n + В частном случае кривая пересечения может описывать край поверхности (buildType==cbt_Boundary), тогда кривые равны и лежат на одной и той же поверхности.\n + В редких случаях второе правило кривой пересечения выполнить точно невозможно, но оно выполняется с известной погрешностью. + В этих случаях параметр buildType==cbt_Tolerant, пересекающиеся поверхности касаются друг друга по кривой пересечения, + а вычисление точки кривой из решения системы уравнений пересечения поверхностей затруднено из-за неоднозначности решения.\n + Все действия, связанные с построением кривой пересечения, обеспечением её точности и определением параметра buildType, + выполняются до вызова конструктора кривой.\n + Кривая spaceCurve может отсутствовать, она насчитывается при необходимости, ничего не знает о поверхностях и + в общем случае является аппроксимационной. Она используется там, где не важна точность.\n + Кривая пересечения поверхностей используется для стыковки поверхностей или для описания ребра стыковки двух граней. + Кривая пересечения может описывать разные типы рёбер стыковки двух граней: \n + обычное ребро - поверхности разные, двумерные кривые разные,\n + ребро-шов - поверхность одина и та же, двумерные кривые разные не равные,\n + Ребро-линия разъема - поверхности копии, двумерные кривые копии,\n + ребро-край - поверхность одина и та же, двумерная кривая одина и та же,\n + ребро-полюс - поверхность одина и та же, двумерные кривые копии.\n + Если две двумерные кривые кривых на поверхности curveOne curveTwo являются контурами, то количество сегментов в них должно быть одинаковым. + \en Intersection curve of surfaces contains two curves on intersected surfaces - + curveOne and curveTwo, conformed to the next rules:\n + 1. curves have the same domains,\n + 2. curves return the same radius-vector and its derivatives at the same parameters, that is, curves are equally directed and coincide in space.\n + 'buildType' parameter of the intersection curve informs about the way the second rule is carried out. + If 'buildType' parameter is equal to cbt_Ordinary or cbt_Boundary, then the rules are satisfied exactly. + If 'buildType' parameter is equal to cbt_Specific or cbt_Tolerant, then the rules are satisfied approximately. \n + In the common case (buildType==cbt_Specific) intersection curve of surfaces is presented in form of two splines curveOne.curve and curveTwo.curve. + Splines pass through two-dimensional support points in parameter spaces of curveOne.surface and curveTwo.surface surfaces correspondingly. + Support points of 'curveTwo' spline corresponds to each support point of 'curveOne' spline. + Parameters of splines are equal for corresponding support points, and splines coincide in space. + Thus, the second rule of intersection curve is satisfied exactly in support points. \n + If one passes a spatial polyline through the support points, then the angle between its neighboring segments won't exceed 0,04pi. + The change of parameter while moving from one support point of curve to the next one is proportional to the length of the polyline segment between the neighboring points. \n + For any value of parameter the point of surfaces intersection is calculated precisely from the solution of surfaces intersection equations system.\n + For determination of precise surfaces intersection between neighboring support points of splines the following actions are performed. + The plane perpendicular to a segment which starts and ends at neighboring support points is constructed. + Then, the point of three surfaces intersection is determined by the numerical method (curveOne.surface, curveTwo.surface and plane).\n + In specific case the intersection curve can circumscribe the surface boundary (buildType==cbt_Boundary), then the curves are equal and lie on the same surface.\n + In rare cases the second rule of the intersection curve can't be satisfied precisely, but it is satisfied with a certain error. + In these cases parameter 'buildType' is equal to cbt_Tolerant and the intersected surfaces touch each other by an intersection curve, + and calculation of point of curve from solution of surfaces intersection equation system is complicated due to the ambiguity of solution.\n + All activities related to the construction of the intersection curve, ensuring its accuracy and parameter definition buildType, + executed before the constructor of the curve.\n + 'spaceCurve' curve can be absent, it is calculated if necessary, it knows nothing about surfaces and + generally is approximating. It is used when accuracy isn't important.\n + Intersection curve of surfaces is used to connect the surfaces or to describe connection edge of two faces. + Intersection curve can describe different types of connection edges of two faces: \n + an ordinary edge - different surfaces, different two-dimensional curves,\n + a seam edge - single surface, different two-dimensional curves,\n + Parting edge - duplicated surfaces, duplicated two-dimensional curves,\n + a boundary edge - same surface, same two-dimensional curve,\n + edge-pole - same surface, duplicated two-dimensional curves.\n + if two-dimensional curves of curveOne and curveTwo curves on surface are contours, then count of segments in them has to be the same. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbSurfaceIntersectionCurve : public MbCurve3D { +private : + MbSurfaceCurve curveOne; ///< \ru Кривая на первой поверхности. \en Curve on the first surface. + MbSurfaceCurve curveTwo; ///< \ru Кривая на второй поверхности. \en Curve on the second surface. + MbeCurveBuildType buildType; ///< \ru Тип кривой по построению. \en A curve type by construction. + + mutable MbeCurveGlueType glueType; ///< \ru Тип кривой по топологии. \en A curve type by topology. + mutable MbCurve3D * spaceCurve; ///< \ru Пространственная аппроксимационная кривая. \en The spatial approximating curve. \~ + mutable double tolerance; ///< \ru Погрешность построения кривой. \en The tolerance of curve construction. \~ + mutable MbCube cube; ///< \ru Габаритный куб кривой. \en Bounding box of a curve. \~ + mutable double metricLength; ///< \ru Метрическая длина кривой. \en Metric length of a curve. \~ + mutable double lengthEvaluation; ///< \ru Оценочная длина кривой. \en Estimated length of a curve. \~ + mutable double curveRadius; ///< \ru Радиус кривой, если она является дугой окружности в пространстве. \en The radius of the curve, if the curve is a spatial arc. + + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbIntersectionCurveAuxiliaryData : public AuxiliaryData { + public: + double t; ///< \ru Модифицированный параметр. \en Modified parameter. + bool res; ///< \ru Результат итерационного процесса. \en The result of iterative intersection. + MbCartPoint uv1; ///< \ru Точка. \en Point. + MbCartPoint uv2; ///< \ru Точка. \en Point. + MbCartPoint3D pnt; ///< \ru Точка. \en Point. + MbVector3D fder; ///< \ru Первая производная. \en First derivative. + MbVector3D sder; ///< \ru Вторая производная. \en Second derivative. + MbVector3D tder; ///< \ru Третья производная. \en Third derivative. + + MbIntersectionCurveAuxiliaryData(); + MbIntersectionCurveAuxiliaryData( const MbIntersectionCurveAuxiliaryData & ); + virtual ~MbIntersectionCurveAuxiliaryData(); + + void Init(); + void Init( const MbIntersectionCurveAuxiliaryData & ); + void Move( const MbVector3D & ); + }; + + mutable CacheManager cache; + +public : + /** \brief \ru Конструктор по поверхностям и двумерным кривым. + \en Constructor by surfaces and two-dimensional curves. \~ + \details \ru Конструктор кривой пересечения по поверхностям и двумерным кривым. \n + \en Constructor of intersection curve by surfaces and two-dimensional curves. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] curve1 - \ru Первая двумерная кривая. + \en The first two-dimensional curve. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] curve2 - \ru Вторая двумерная кривая. + \en The second two-dimensional curve. \~ + \param[in] buildType - \ru Тип кривой пересечения по построению. + \en An intersection curve type by construction. \~ + \param[in] sameOne - \ru Использовать оригинал первой двумерной кривой. + \en Use the original of the first two-dimensional curve. \~ + \param[in] sameTwo - \ru Использовать оригинал второй двумерной кривой. + \en Use the original of the second two-dimensional curve. \~ + \param[in,out] iReg - \ru Регистратор дублирования. + \en Registrator of duplication. \~ + */ + MbSurfaceIntersectionCurve( const MbSurface & surf1, const MbCurve & curve1, + const MbSurface & surf2, const MbCurve & curve2, + MbeCurveBuildType buildType, bool sameOne, bool sameTwo, + MbRegDuplicate * iReg = NULL ); + /** \brief \ru Конструктор по поверхностям и двумерным точкам. + \en Constructor by surfaces and two-dimensional points. \~ + \details \ru Конструктор кривой пересечения по поверхностям и двумерным точкам. \n + \en Constructor of an intersection curve by surfaces and two-dimensional points. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] surf1p0 - \ru Начальная точка на поверхности. + \en Start point on the surface. \~ + \param[in] surf1p1 - \ru Конечная точка на поверхности. + \en End point on the surface. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] surf2p0 - \ru Начальная точка на поверхности. + \en Start point on the surface. \~ + \param[in] surf2p1 - \ru Конечная точка на поверхности. + \en End point on the surface. \~ + */ + MbSurfaceIntersectionCurve( const MbSurface & surf1, const MbCartPoint & surf1p0, const MbCartPoint & surf1p1, + const MbSurface & surf2, const MbCartPoint & surf2p0, const MbCartPoint & surf2p1 ); + /** \brief \ru Конструктор по поверхностям, двумерным кривой и точкам. + \en Constructor by surfaces, two-dimensional curves and points. \~ + \details \ru Конструктор кривой пересечения по поверхностям, двумерным кривой и точкам. \n + \en Constructor of intersection curve by surfaces, two-dimensional curves and points. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] curve1 - \ru Первая двумерная кривая. + \en The first two-dimensional curve. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] surf2p0 - \ru Начальная точка на поверхности. + \en Start point on the surface. \~ + \param[in] surf2p1 - \ru Конечная точка на поверхности. + \en End point on the surface. \~ + \param[in] buildType - \ru Тип кривой пересечения по построению. + \en An intersection curve type by construction. \~ + */ + MbSurfaceIntersectionCurve( const MbSurface & surf1, const MbCurve & curve1, + const MbSurface & surf2, const MbCartPoint & surf2p0, const MbCartPoint & surf2p1, + MbeCurveBuildType buildType ); + /** \brief \ru Конструктор по поверхностям, двумерным точкам и кривой. + \en Constructor by surfaces, two-dimensional points and curve. \~ + \details \ru Конструктор кривой пересечения по поверхностям, двумерным точкам и кривой. \n + \en Constructor of an intersection curve by surfaces, two-dimensional points and curve. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] surf1p0 - \ru Начальная точка на поверхности. + \en Start point on the surface. \~ + \param[in] surf1p1 - \ru Конечная точка на поверхности. + \en End point on the surface. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] curve2 - \ru Вторая двумерная кривая. + \en The second two-dimensional curve. \~ + \param[in] buildType - \ru Тип кривой пересечения по построению. + \en An intersection curve type by construction. \~ + */ + MbSurfaceIntersectionCurve( const MbSurface & surf1, const MbCartPoint & surf1p0, const MbCartPoint & surf1p1, + const MbSurface & surf2, const MbCurve & curve2, + MbeCurveBuildType buildType ); + /** \brief \ru Конструктор для конвертеров по поверхностям и двумерным кривым. + \en Constructor for converters by surfaces and two-dimensional curves. \~ + \details \ru Конструктор кривой пересечения для конвертеров по поверхностям и двумерным кривым. \n + \en Constructor of intersection curve for converters by surfaces and two-dimensional curves. \n \~ + \param[in] surf1 - \ru Первая поверхность. + \en The first surface. \~ + \param[in] curve1 - \ru Первая двумерная кривая. + \en The first two-dimensional curve. \~ + \param[in] surf2 - \ru Вторая поверхность. + \en The second surface. \~ + \param[in] curve2 - \ru Вторая двумерная кривая. + \en The second two-dimensional curve. \~ + \param[in] spaceCurve - \ru Аппроксимация кривой пересечения. + \en Approximation of the intersection curve. \~ + \param[in] buildType - \ru Тип кривой пересечения по построению. + \en An intersection curve type by construction. \~ + \param[in] glueType - \ru Тип кривой пересечения по топологии. + \en An intersection curve type by topology. \~ + \param[in] tol - \ru Неточность построения кривой пересечения. + \en Inaccuracy of intersection curve construction. \~ + */ + MbSurfaceIntersectionCurve( const MbSurface & surf1, const MbCurve & curve1, + const MbSurface & surf2, const MbCurve & curve2, + const MbCurve3D * spaceCurve, MbeCurveBuildType buildType, + MbeCurveGlueType glueType, double tol ); // \ru Используется в конвертерах \en Used in converters +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbSurfaceIntersectionCurve( const MbSurfaceIntersectionCurve &, MbRegDuplicate * ); + /// \ru Конструктор копирования двумерных кривых с теми же поверхностями для CurvesDuplicate(). \en Copy-constructor of two-dimensional curves with the same surfaces for CurvesDuplicate(). + explicit MbSurfaceIntersectionCurve( const MbSurfaceIntersectionCurve * ); +private: + MbSurfaceIntersectionCurve( const MbSurfaceIntersectionCurve & ); // \ru Не реализовано!!! \en Not implemented!!! +public: + virtual ~MbSurfaceIntersectionCurve(); + +public: + /// \ru Реализация функции, инициирующей посещение объекта. \en Implementation of a function initializing a visit of an object. + VISITING_CLASS( MbSurfaceIntersectionCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get element type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + /// \ru Сделать копию кривой на тех же поверхностях. \en Create a copy of a curve on the same surfaces. + MbSurfaceIntersectionCurve & CurvesDuplicate() const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, равны ли объекты. \en Determine whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавить свой габарит в куб. \en Add your own bounding box into a cube. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems( RPArray & ); // \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + // \ru Общие функции кривой. \en Common functions of curve. + + // \ru Функции описания области определения кривой. \en Functions for description of a curve domain. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual bool IsClosed() const; // \ru Проверить замкнутость кривой. \en Check for curve closedness. + virtual double GetPeriod() const; // \ru Вернуть период периодической кривой. \en Get period of a periodic curve. + virtual bool IsPeriodic() const; // \ru Проверить периодичность кривой. \en Check for curve periodic. + // \ru Функции кривой для работы в области определения кривой. \en Functions of curve for working at curve domain. + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate a point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + virtual void Tangent ( double & t, MbVector3D & ) const; // \ru Вычислить тангенциальный вектор (нормализованный). \en Calculate tangential vector (normalized). + // \ru Функции кривой для работы внутри и вне области определения кривой. \en Functions of curve for working inside and outside of the curve domain. + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore ( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + // \ru Функции приближённого быстрого вычисления точки и производных на кривой. \en Functions of approximate fast calculation of point and derivatives on the curve. + virtual void FastApproxExplore( double & t, MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + + // \ru Функции движения по кривой. \en Functions of moving along the curve. + // \ru Вычислить шаг параметра по величине прогиба кривой. \en Calculate step of parameter by value of sag of curve. + virtual double Step ( double t, double sag ) const; + // \ru Вычислить шаг параметра по углу отклонения касательной. \en Calculate step of parameter by angle of deviation of tangent. + virtual double DeviationStep( double t, double angle ) const; + // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + virtual double MetricStep ( double t, double length ) const; + // \ru Возможен ли разрыв длины первой производной? \en Is it possible to break the length of the first derivative? + bool CanDerivateJump() const; + + // \ru Преобразовать в NURBS кривую. \en Transform to a NURBS-curve. + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создать усеченную кривую. \en Create a trimmed curve + + /// \ru Создать усеченную кривую на тех же поверхностях. \en Create a trimmed curve on the same surfaces. + MbSurfaceIntersectionCurve * TrimmedIntersection( double t1, double t2, int sense ) const; + + virtual double GetMetricLength() const; // \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double GetLengthEvaluation() const; // \ru Оценить метрическую длину кривой. \en Estimate the metric length of a curve. + /**\ru Скопировать из копии готовые метрические оценки, которые в оригинале не были рассчитаны. + \en Copy the finished metric estimations from duplicate which weren't calculated in the original. \~ + \warning \ru Внимание: для скорости проверка идентичности оригинала и копии не выполняется! + \en Attention: for speed purposes the check of equality of the original and the copy isn't performed! \~ + */ + bool CopyReadyMutable( const MbSurfaceIntersectionCurve & s ); + virtual double CalculateLength( double t1, double t2 ) const; // \ru Вычислить метрическую длину. \en Calculate the metric length. + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой. \en Get the curve axis. + virtual void GetCentre( MbCartPoint3D & ) const; // \ru Вычислить центр кривой. \en Calculate the center of a curve. + virtual void GetWeightCentre( MbCartPoint3D & ) const; // \ru Вычислить центр тяжести кривой. \en Calculate the center of gravity of a curve. + // \ru Вычислить центр тяжести кривой. \en Calculate the center of gravity of a curve. + void CalculateWeightCentre( MbCartPoint3D & ) const; + + virtual void CalculateGabarit( MbCube & c ) const; // \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + // \ru Получить габарит кривой. \en Get bounding box of curve. + const MbCube & GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } + // \ru Сбросить габаритный куб. \en Reset bounding box. + void SetDirtyGabarit() const { cube.SetEmpty(); } + + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; // \ru Сдвинуть параметр t на расстояние len по направлению. \en Translate parameter 't' on the distance 'len' by the direction. + virtual void CalculatePolygon( const MbStepData & stepData, MbPolygon3D &polygon ) const; // \ru Рассчитать полигон. \en Calculate a polygon. + + // \ru Построить плоскую проекцию некоторой части пространственной кривой. \en Construct a planar projection of a piece of a space curve. + virtual MbCurve * GetMap( const MbMatrix3D & into, MbRect1D * pRegion = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + // \ru Дать проекцию ребра на плоскость. \en Get the edge projection onto plane. + virtual MbCurve * GetProjection( const MbPlacement3D & place, VERSION version ) const; + + // \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual size_t GetCount() const; + + virtual bool IsStraight() const; // \ru Определить, является ли линия прямолинейной. \en Determine whether the line is straight. + virtual void ChangeCarrier ( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменить носитель. \en Change the carrier. + virtual bool ChangeCarrierBorne( const MbSpaceItem & item, MbSpaceItem & init, const MbMatrix & matr ); // \ru Изменение носимые элементы. \en Change a carrier elements. + virtual bool IsPlanar() const; // \ru Определить, является ли кривая плоской. \en Determine whether the curve is planar. + virtual bool IsSmoothConnected( double angleEps ) const; // \ru Определить, являются ли стыки контура\кривой гладкими. \en Determine whether the joints of contour\curve are smooth. + + virtual double DistanceToPlace( const MbPlacement3D & place, double & t0, double & angle ) const; // \ru Вычислить ближайшую точку кривой к плейсменту. \en Calculate the curve point nearest to a placement. + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using ). + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place3d, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Заполнить плейсмент, если кривая плоская. \en Fill the placement if the curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get a surface curve if a spatial curve is on a surface (call DeleteItem for arguments after use). + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + + virtual double GetParamToUnit() const; // \ru Дать приращение параметра, осреднённо соответствующее единичной длине в пространстве. \en Get parameter increment which averagingly corresponds to the unit length in space. + virtual double GetParamToUnit( double t ) const; // \ru Дать приращение параметра, соответствующее единичной длине в пространстве. \en Get parameter increment which corresponds to the unit length in space. + + // \ru Определить, является ли объект смещением. \en Determine whether the object is a translation. + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + // \ru Определить, подобные ли кривые для объединения (слива). \en Determine whether the curves for union (joining) are similar. + virtual bool IsSimilarToCurve( const MbCurve3D & other, double precision = METRIC_PRECISION ) const; + // \ru Определить, являются ли объекты идентичными в пространстве? \en Determine whether the objects are equal in space. + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; + + /// \ru Получить тип кривой по топологии. \en Get a curve type by topology. + MbeCurveGlueType GetGlueType() const { return glueType; } + /// \ru Установить тип кривой по топологии. \en Set a curve type by topology. + void SetGlueType( MbeCurveGlueType type ) { glueType = type; } + /// \ru Установить тип кривой по топологии. \en Set a curve type by topology. + void SetPoleGlueType() const { glueType = cgt_Pole; } + + /// \ru Получить тип кривой по построению. \en Get a curve type by construction. + MbeCurveBuildType GetBuildType() const { return buildType; } + /// \ru Установить тип кривой по построению. \en Set a curve type by construction. + void SetBuildType( MbeCurveBuildType type ) { buildType = type; } + + // \ru Проверка параметра. \en Check parameter. + inline void CheckParam ( double & t ) const; + /// \ru Вычислить точки на пересекаемых поверхностях. \en Calculate points on intersecting surfaces. + bool PointOn( double t, MbCartPoint & r1, MbCartPoint & r2 ) const; + /// \ru Вычислить точку. \en Calculate a point. + inline void GetPointOn ( double & t, MbCartPoint3D & ) const; + /// \ru Вычислить первую производную. \en Calculate the first derivative. + inline void GetFirstDer ( double & t, MbVector3D & ) const; + + /// \ru Найти все особые точки функции кривизны кривой. + /// \en Find all the special points of the curvature function of the curve. \~ + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + + /** \brief \ru Уточнить кривую общего случая пересечения. + \en Refine a curve of intersection of common case. \~ + \details \ru Уточнить кривую общего случая пересечения с флагом cbt_Specific (для других флагов ничего не выполняется). + При флаге кривой cbt_Specific для параметра t определяются + двумерные точки на пересекаемых поверхностях и вставляются в сплайны curveOne.curve и curveTwo.curve. + \en Refine common case intersection curve with cbt_Specific flag (for other flags is performed nothing). + If a curve flag is equal to cbt_Specific, then + the two-dimensional points on intersected surfaces are determined and are inserted into curveOne.curve and curveTwo.curve splines for 't' parameter. \~ + \param[in] t - \ru Параметр точки уточнения, + \en Parameter of point to refine, \~ + \param[in] pointsPair - \ru Параметрические точки уточнения, полученные в функции PointOn( t, pointsPair->first, pointsPair->second), + \en Parametric points of refinement, obtained by the function of PointOn (t, points Pair-> first, pointsPair-> second), \~ + \param[in] tCheck - \ru Контрольный параметр точки уточнения, если он не равен t, то вставляемые точки не сдвинутся так, чтобы параметр t стал равен tCheck. + \en Control parameter of a point to refine, if it isn't equal to 't', then the inserted points won't move so that parameter 't' became equal to 'tCheck'. \~ + \return \ru Возвращает true, если произошло присоединение кривой. + \en Returns true if there was a curve joining. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + */ + bool InsertPoints ( double & t, const std::pair * pointsPair, double & tCheck ); // \ru Вставить точку и выдать её параметр. \en Insert point and get its parameter. + + /** \brief \ru Разрезать кривую на две части. + \en Cutaway a curve into two pieces. \~ + \details \ru Разрезать кривую на две части точкой кривой с заданным параметром. + \en Cutaway a curve into two pieces by a point of the curve with a given parameter. \~ + \param[in] t - \ru Параметр точки разбиения, + \en Parameter of a point to split, \~ + \param[in] beg - \ru Кривая сохранит начальную половину (true) или кривая сохранит конечную половину (false), + \en Curve will keep a beginning piece (true) or curve will keep an end piece (false) \~ + \param[in] surface - \ru Для толерантной кривой требуется указать поверхность, к кривой которой относится параметр + \en For tolerant curve it is required to specify a surface which contain a curve a parameter belongs to \~ + \return \ru Возвращает отрезанную часть кривой. + \en Returns the cut piece of curve. \~ + */ + MbSurfaceIntersectionCurve * BreakCurve( double t, bool beg, const MbSurface * surface ); ///< \ru Разбить кривую на две. \en Split curve into two. + + /** \brief \ru Усечь кривую. + \en Trim a curve. \~ + \details \ru Усечь кривую по заданным параметрам. \n + \en Trim a curve by the given parameters. \n \~ + \param[in] t1 - \ru Начальный параметр усечения, + \en Beginning parameter of trimming \~ + \param[in] t2 - \ru Конечный параметр усечения, + \en End parameter of trimming \~ + \param[in] surface - \ru Для толерантной кривой требуется указать поверхность, к кривой которой относятся параметры усечения + \en For tolerant curve it is required to specify a surface which contain a curve a trimming parameters belong to \~ + \return \ru Возвращает true, если произошло усечение. + \en Returns true if there was a curve trimming. \~ + */ + bool TruncateCurve( double t1, double t2, const MbSurface * surface ); + + /** \brief \ru Присоединить к данной кривой другую кривую. + \en Join this curve and another curve. \~ + \details \ru Сделать из двух кривых пересечения одну - вызывается для объединения двух ребер из функции MbCurveEdge::MergeEdges. + Объединяемые кривые должны описывать пересечение одних и тех же поверхностей. + Объединяются только гладко стыкующиеся кривые. + Должно быть точное совпадение кривых, поверхностей этих кривых и касательных в месте склеивания. + После присоединения другую кривую можно удалить. \n + \en Make a single curve curve from two intersection curves - is called for union of two edges from MbCurveEdge::MergeEdges function. + United curves should represent the intersection of the same surfaces. + Only smoothly joining curves are united. + There must be an exact coincidence of curves, surfaces of these curves and tangents at joining place. + Another curve can be deleted after joining. \n \~ + \param[in] addCurve - \ru Добавляемая кривая (другая кривая), + \en Curve to join (another curve), \~ + \param[in] toBegin - \ru Пристыковываем к началу this (true) или пристыковываем к концу this (false), + \en Join to the beginning of this (true) or join to the end of this (false) \~ + \param[in] fromBegin - \ru Пристыковываем начало addCurve (true) или пристыковываем конец addCurve (false), + \en Join the beginning of 'addCurve' (true) or join the end of 'addCurve' (false), \~ + \param[in] allowCntr - \ru Флаг, разрешающий заменять curveOne.curve и curveTwo.curve двумерными контурами. \n + \en Flag, which allows to replace curveOne.curve and curveTwo.curve by two-dimensional contours. \n \~ + \param[in] version - \ru Версия математики. \n + \en The version of mathematics. \n \~ + \param[in] insertInterimPoints - \ru Флаг, разрешающий вставлять дополнительные точки в кривые типа cbt_Specific. \n + \en Flag, which allows to insert interim points into curve of type cbt_Specific. \n \~ + \return \ru Возвращает true, если произошло присоединение кривой. + \en Returns true if there was a curve joining. \~ + */ + bool MergeCurves( const MbSurfaceIntersectionCurve & addCurve, bool toBegin, bool fromBegin, bool allowCntr, + const VERSION version, bool insertInterimPoints = true, double eps = PARAM_NEAR ); + + /** \brief \ru Продлить кривую. + \en Extend curve. \~ + \details \ru Продлить кривую до точки с заданным параметром. \n + \en Extend curve to a point with a given parameter. \n \~ + \param[in] t - \ru Параметр, до точки которого продлить кривую, + \en Parameter the curve extends to point of \~ + \param[in] beg - \ru Продлить начало кривой (true) или продлить конец кривой (false), + \en Extend the beginning of the curve (true) or extend the end of the curve (false) \~ + \param[in] version - \ru Версия математики. \n + \en The version of mathematics. \n \~ + \return \ru Возвращает true, если произошло продление. + \en Returns true if there was an extension. \~ + */ + bool ProlongCurve( double & t, bool beg, double sag, const VERSION version ); + /// \ru Согласовать параметрическую длину двумерных кривых. \en Match parametric length of two-dimensional curves. + void Normalize(); + + /// \ru Выбрать кривую шва по ориентации грани и ориентации двумерной кривой. \en Select a seam curve by face orientation and orientation of two-dimensional curve. + const MbCurve * ChooseCurve( const MbSurface & surf, bool faceSense, bool curveSense ) const; + /// \ru Выбрать кривую шва по ориентации грани и ориентации двумерной кривой. \en Select a seam curve by face orientation and orientation of two-dimensional curve. + MbCurve * ChooseCurve_( const MbSurface & surf, bool faceSense, bool curveSense ); + + /** \brief \ru Вычислить вектор сдвига двумерной кривой шва. + \en Calculate a shift vector of two-dimensional curve of seam. \~ + \details \ru Вычислить вектор сдвига двумерной кривой шва отрицательно ориентированной относительно заданной. \n + \en Calculate a shift vector of two-dimensional curve of seam negatively oriented with respect to the given. \n \~ + */ + bool GetMoveVector( const MbSurface & surf, bool faceSense, bool curveSense, MbVector & to ) const; + /// \ru Заменить двумерную кривую. \en Replace the two-dimensional curve. + bool ChangeCurve ( const MbCurve * oldCrv, MbCurve & newCrv ); + /// \ru Заменить поверхность. \en Replace surface. + bool ChangeSurface( const MbSurface & oldSrf, MbSurface & newSrf, bool faceSense, bool curveSense ); + /// \ru Заменить поверхности. \en Replace surfaces. + bool ChangeSurfaces( const MbSurface & surf1, const MbSurface & surf2 ); + /// \ru Заменить поверхности на такие же (IsSame) с другой кривой. \en Replace surfaces with the same ones (IsSame) with a different curve. + bool ReplaceSameSurfaces( const MbSurfaceIntersectionCurve & ); + + /// \ru Установить область изменения параметра. \en Set range of parameter. + bool SetLimitParam( double newTMin, double newTMax ); + /// \ru Поменять местами поверхностные кривые. \en Swap two-dimensional curves and surfaces. + bool SwapSurfaceCurves(); + + /// \ru Вычислить векторное произведение нормалей поверхностей. \en Calculate vector-product of normals of surfaces. + bool Direction ( double & t, MbVector3D & tau, double eps = Math::paramNear ) const; + /// \ru Вычислить векторное произведение нормалей поверхностей вблизи линии. \en Calculate vector-product of normals of surfaces near to the line. + bool NearDirection( double & t, const MbSurface & surfOne, const MbSurface & surfTwo, MbVector3D & tau, double delta, + MbCartPoint & point1, MbCartPoint & point2, + MbVector3D & normal1, MbVector3D & normal2 ) const; + /// \ru Вычислить тангенциальный и трансверсальный векторы, касательные к поверхностям. \en Calculate tangential and transversal vectors tangent to surfaces. + bool TransversalReper( double & t, MbVector3D & tau0, MbVector3D & tau1, MbVector3D & tau2 ) const; + + /// \ru Сделать равными двумерные кривые. \en Make two-dimensional curves equal. + bool SetCurveEqual( const MbSpaceItem & init ); + /// \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + bool IsCurveEqual ( const MbSpaceItem & init ) const; + + /// \ru Получить поверхностную кривую по номеру (0 - первая, 1 - вторая). \en Get surface curve by index (0 - first, 1 - second). + const MbSurfaceCurve & GetCurve( ptrdiff_t i ) const { return i ? curveTwo : curveOne; } + /// \ru Получить поверхностную кривую по номеру (0 - первая, 1 - вторая). \en Get surface curve by index (0 - first, 1 - second). + MbSurfaceCurve & SetCurve( ptrdiff_t i ) { return i ? curveTwo : curveOne; } + /// \ru Получить первую поверхностную кривую. \en Get the first surface curve. + const MbSurfaceCurve & GetCurveOne() const { return curveOne; } + /// \ru Получить первую поверхностную кривую. \en Get the first surface curve. + MbSurfaceCurve & SetCurveOne() { return curveOne; } + /// \ru Получить вторую поверхностную кривую. \en Get the second surface curve. + const MbSurfaceCurve & GetCurveTwo() const { return curveTwo; } + /// \ru Получить вторую поверхностную кривую. \en Get the second surface curve. + MbSurfaceCurve & SetCurveTwo() { return curveTwo; } + + /// \ru Получить двумерную кривую первой поверхностной кривой. \en Get two-dimensional curve of the first surface curve. + const MbCurve & GetCurveOneCurve() const { return curveOne.GetCurve(); } + /// \ru Получить двумерную кривую первой поверхностной кривой. \en Get two-dimensional curve of the first surface curve. + MbCurve & SetCurveOneCurve() { return curveOne.SetCurve(); } + /// \ru Получить двумерную кривую второй поверхностной кривой. \en Get two-dimensional curve of the second surface curve. + const MbCurve & GetCurveTwoCurve() const { return curveTwo.GetCurve(); } + /// \ru Получить двумерную кривую второй поверхностной кривой. \en Get two-dimensional curve of the second surface curve. + MbCurve & SetCurveTwoCurve() { return curveTwo.SetCurve(); } + + /// \ru Получить поверхность первой поверхностной кривой. \en Get surface of the first surface curve. + const MbSurface & GetCurveOneSurface() const { return curveOne.GetSurface(); } + /// \ru Получить поверхность первой поверхностной кривой. \en Get surface of the first surface curve. + MbSurface & SetCurveOneSurface() { return curveOne.SetSurface(); } + /// \ru Получить поверхность второй поверхностной кривой. \en Get surface of the second surface curve. + const MbSurface & GetCurveTwoSurface() const { return curveTwo.GetSurface(); } + /// \ru Получить поверхность второй поверхностной кривой. \en Get surface of the second surface curve. + MbSurface & SetCurveTwoSurface() { return curveTwo.SetSurface(); } + /// \ru Получить поверхность по номеру (0 - из первой, 1 - из второй поверхностной кривой). \en Get surface by index (0 - from first surface curve, 1 - from second one). + const MbSurface & GetSurface( ptrdiff_t i ) const { return i ? curveTwo.GetSurface() : curveOne.GetSurface(); } + /// \ru Получить поверхность по номеру (0 - из первой, 1 - из второй поверхностной кривой). \en Get surface by index (0 - from first surface curve, 1 - from second one). + MbSurface & SetSurface( ptrdiff_t i ) { return i ? curveTwo.SetSurface() : curveOne.SetSurface(); } + + /// \ru Дать указатель на первую кривую на поверхности. \en Get a pointer to the first curve on surface. + const MbSurfaceCurve * GetSCurveOne() const { return &curveOne; } + /// \ru Дать указатель на вторую кривую на поверхности. \en Get a pointer to the second curve on surface. + const MbSurfaceCurve * GetSCurveTwo() const { return &curveTwo; } + /// \ru Дать указатель на двумерную кривую. \en Get a pointer to the two-dimensional curve. + const MbCurve * GetPCurveOne () const { return &( curveOne.GetCurve() ); } + /// \ru Дать указатель на двумерную кривую. \en Get a pointer to the two-dimensional curve. + const MbCurve * GetPCurveTwo () const { return &( curveTwo.GetCurve() ); } + /// \ru Дать указатель на поверхность первой кривой. \en Get a pointer to the surface of the first curve. + const MbSurface * GetSurfaceOne() const { return &( curveOne.GetSurface() ); } + /// \ru Дать указатель на поверхность второй кривой. \en Get a pointer to the surface of the second curve. + const MbSurface * GetSurfaceTwo() const { return &( curveTwo.GetSurface() ); } + + /// \ru Получить одну из поверхностей, отличную от заданной. \en Get one of the surfaces different from the given one. + const MbSurface * GetAnotherSurface( const MbSurface & surface ) const; + /// \ru Получить одну из двумерных кривых, отличную от заданной. \en Get one of two-dimensional curves different from the given one. + const MbCurve * GetAnotherCurve ( const MbCurve & curve ) const; + + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; // \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of a curve with equally spaced by the arc length. + + /// \ru Вычислить точки изменения выпуклости-вогнутости кривой пересечения. \en Calculate points of changing the convexity-concavity of intersection curve. + MbeNewtonResult ConvexoConcaveNewton( size_t iterLimit, double & t ) const; + /// \ru Определить наличие точек изменения выпуклости-вогнутости. \en Determine existence of points of changing the convexity-concavity. + bool IsConvexoConcave( SArray & params ) const; + + /// \ru Построить участок пространственной копии кривой. \en Construct a piece of a spatial curve copy. + MbCurve3D * MakeCurve( double t1, double t2 ) const; + /// \ru Построить пространственную копию кривой. \en Construct a spatial curve copy. + MbCurve3D * MakeCurve() const; + + // \ru Функции аппроксимации неявной кривой пересечения. \en Functions for approximation of implicit intersection curve. + + /// \ru Дать пространственную аппроксимацию кривой пересечения. \en Get an approximate spatial curve for interpretation of the intersection. + const MbCurve3D * GetSpaceCurve() const; + /// \ru Дать пространственную аппроксимацию кривой пересечения. \en Get an approximate spatial curve for interpretation of the intersection. + MbCurve3D * SetSpaceCurve(); + /// \ru Дать точную пространственную копию или себя. \en Get exact spatial copy or itself. + const MbCurve3D & GetExactCurve( bool saveParams = true ) const; + /// \ru Удалить пространственную кривую. \en Remove a spatial curve. + void ReleaseSpaceCurve(); + + /// \ru Разрезать кривую пересечения на три части по заданным параметрам и вернуть одну из крайних частей в зависимости от sense. \en Cutaway an intersection curve into three pieces by given parameters and return one of end pieces depending on 'sense'. + MbSurfaceIntersectionCurve * BreakWithGap( double tt, double ttP, bool sense ); // \ru Используется в конвертерах. \en Used in converters. + + /// \ru Усечь кривую пересечения по двум точкам и заданному направлению. \en Trim intersection curve by two points and the given direction. + MbCurve3D * Trimmed( const MbCartPoint3D & p1, const MbCartPoint3D & p2, bool sense ) const; + + /// \ru Определить, гладкая ли кривая пересечения. \en Determine whether the intersection curve is smooth. + bool IsSmooth() const; + /// \ru Определить, полюсная ли кривая пересечения. \en Determine whether the intersection curve is pole. + bool IsPole() const; + /// \ru Определить, является ли кривая пересечения кривой разъема. \en Determine whether the curve is a parting curve. + bool IsSplit( bool strict = false ) const; + + /// \ru Получить толерантность кривой. \en Get tolerance of the curve. + double GetTolerance() const; + /// \ru Выставить толерантность кривой. \en Set tolerance of the curve. + void SetTolerance( double tol ) { tolerance = tol; } + /// \ru Сбросить толерантность кривой. \en Reset tolerance of the curve. + void ResetTolerance() { tolerance = UNDEFINED_DBL; } +private: + /// \ru Вычисление точек и производных пересекающихся поверхностей. \en Points and derivatives calculation for intersection surfaces. + bool Explorer( double t, bool readyOne, bool readyTwo, + MbCartPoint & pointOne, MbVector & firstOne, MbVector & secondOne, + MbCartPoint & pointTwo, MbVector & firstTwo, MbVector & secondTwo, + MbCartPoint3D & pnt1, MbVector3D & uDer1, MbVector3D & vDer1, MbVector3D & uuDer1, MbVector3D & vvDer1, MbVector3D & uvDer1, MbVector3D & nor1, + MbCartPoint3D & pnt2, MbVector3D & uDer2, MbVector3D & vDer2, MbVector3D & uuDer2, MbVector3D & vvDer2, MbVector3D & uvDer2, MbVector3D & nor2 ) const; + /// \ru Вычислить точку. \en Calculate a point. + void CalculatePointOn( double t, MbCartPoint3D & ) const; + /// \ru Вычислить первую производную. \en Calculate the first derivative. + void CalculateFirstDer( double t, MbVector3D & ) const; + /// \ru Вычислить значения точки и производных. \en Calculate the point and the first derivative. + void CalculateExplore( double t, MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + // \ru Вычислить толерантность кривой. \en Calculate tolerance of the curve. + void CalculateTolerance() const; + // \ru Создать пространственную кривую по проекционной кривой. \en Create a spatial curve from a projection curve. + void TryProjection() const; + // \ru Создать явную пространственную кривую. \en Create an explicit spatial curve. + bool CreateSpaceCurve( VERSION version = Math::DefaultMathVersion() ) const; + // \ru Создать аппроксимационную кривую по кривой пересечения \en Create an approximating curve by an intersection curve + MbCurve3D * CreateApproxCurve( bool doContinuous, double & appoxTolerance, VERSION version ) const; + + // \ru Проверить на равенство количества сегментов контуров на поверхностях. \en Check for equality of count of segments of contours on surfaces. + bool IsSurfContoursCorrect() const; + + // \ru Добавить точки одной полилинии в другую. \en Add points of one polyline to the another one. + bool AddCurveToCurve( const MbCurve & from1, const MbCurve & from2, + bool fromBegin, bool toBegin, MbeCurveBuildType & spec, + bool insertInterimPoints, const VERSION version ); + + // \ru Добавить базовые кривые усеченных кривых. \en Add the base curves of trimmed curves. + bool AddTrimmedToTrimmed( const MbCurve * addCurveOne, const MbCurve * addCurveTwo, + bool fromBegin, bool toBegin, const VERSION version ); + + // \ru Добавить базовые кривые репараметризованных кривых. \en Add the base curves of reparametrized curves. + bool AddReparamSegment( const MbCurve * fromRep, MbReparamCurve * toRep, + const MbCurve * fromOther, MbSurfaceCurve & curveOther, + bool fromBegin, bool toBegin, + const VERSION version ); + + // \ru Создать контуры из кривых. \en Create contours from curves. + void ChangeToContour( const MbCurve * addCurveOne, const MbCurve * addCurveTwo, + bool fromBegin, bool toBegin ); + +private: + // \ru Определить топологический тип кривой по внутренним данным. \en Identify topology type by internal data. + void SetGlueType() const; + +private: + void operator = ( const MbSurfaceIntersectionCurve & ); // \ru Не реализовано !!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSurfaceIntersectionCurve ) +}; + +IMPL_PERSISTENT_OPS( MbSurfaceIntersectionCurve ) + +//------------------------------------------------------------------------------ +// \ru Скопировать из копии готовые метрические оценки, которые в оригинале не были рассчитаны. \en Copy the finished metric estimations from duplicate which weren't calculated in the original. +// \ru Внимание: для скорости проверка идентичности оригинала и копии не выполняется! \en Attention: for speed purposes the check of equality of the original and the copy isn't performed! +// --- +inline bool MbSurfaceIntersectionCurve::CopyReadyMutable( const MbSurfaceIntersectionCurve & s ) +{ + bool changed = false; + + if ( lengthEvaluation < 0.0 && s.lengthEvaluation >= 0.0 ) { + lengthEvaluation = s.lengthEvaluation; + changed = true; + } + if ( metricLength < 0.0 && s.metricLength >= 0.0 ) { + metricLength = s.metricLength; + changed = true; + } + if ( cube.IsEmpty() && !s.cube.IsEmpty() ) { + cube = s.cube; + changed = true; + } + if ( spaceCurve == NULL && s.spaceCurve != NULL ) { + spaceCurve = (MbCurve3D *)&s.spaceCurve->Duplicate(); + spaceCurve->AddRef(); + changed = true; + } + + return changed; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить параметр. \en Check parameter. +// --- +inline void MbSurfaceIntersectionCurve::CheckParam( double & t ) const +{ + double tmin = std_max( curveOne.GetCurve().GetTMin(), curveTwo.GetCurve().GetTMin() ); + double tmax = std_min( curveOne.GetCurve().GetTMax(), curveTwo.GetCurve().GetTMax() ); + bool closed = ( curveOne.IsClosed() || curveTwo.IsClosed() ); + + if ( t < tmin ) { + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t - tmin) / tmp) * tmp; + } + else + t = tmin; + } + else if ( t > tmax ) { + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t - tmin) / tmp) * tmp; + } + else + t = tmax; + } +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить точку. \en Calculate a point. +// --- +inline void MbSurfaceIntersectionCurve::GetPointOn( double & t, MbCartPoint3D & pnt ) const +{ + MbCartPoint3D p1, p2; + // \ru Получить точку с кривой пересечения, лежащей на первой поверхности \en Get point on the intersection curve on the first surface + curveOne.PointOn( t, p1 ); + // \ru Получить точку с кривой пересечения, лежащей на второй поверхности \en Get point on the intersection curve on the second surface + curveTwo.PointOn( t, p2 ); + // \ru Получить точку на кривой пересечения поверхностей, как среднее \en Get point on the intersection curve as average + pnt.Set( p1, 0.5, p2, 0.5 ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить первую производную по t. \en Calculate first derivative with respect to t. +// --- +inline void MbSurfaceIntersectionCurve::GetFirstDer( double & t, MbVector3D & fd ) const +{ + MbVector3D vect1, vect2; + // \ru Вычислить производную для кривой, лежащей на первой поверхности \en Calculate derivative of curve on the first surface + curveOne.FirstDer( t, vect1 ); + // \ru Вычислить производную для кривой, лежащей на второй поверхности \en Calculate derivative of the curve on the second surface + curveTwo.FirstDer( t, vect2 ); + // \ru Получить производную на кривой пересечения поверхностей, как среднее \en Get derivative of surfaces intersection curve as average + fd.Set( vect1, 0.5, vect2, 0.5 ); +} + + +#endif // __CUR_SURFACE_INTERSECTION_H diff --git a/C3d/Include/cur_trimmed_curve.h b/C3d/Include/cur_trimmed_curve.h new file mode 100644 index 0000000..4890dcf --- /dev/null +++ b/C3d/Include/cur_trimmed_curve.h @@ -0,0 +1,234 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Усеченная кривая в двумерном пространстве. + \en Trimmed curve in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_TRMMED_CURVE_H +#define __CUR_TRMMED_CURVE_H + + +#include +#include + + +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Усеченная кривая в двумерном пространстве. + \en Trimmed curve in two-dimensional space. \~ + \details \ru Усеченная кривая описывает участок базовой кривой basisCurve, + который начинается в точке с параметром trim1 и оканчивается в точке с параметром trim2. \n + Описываемый участок может иметь направление, совпадающее с направлением базовой кривой (sense == +1), + а также может иметь направление, противоположное направлению базовой кривой (sense == -1). + Для замкнутых периодических кривых описываемый участок может содержать внутри начальную точку базовой кривой. + Базовой кривой для усеченной кривой не может служить другая усеченная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Trimmed curve describes a piece of base curve 'basisCurve' + which starts at point with 'trim1' parameter and ends at point with 'trim2' parameter. \n + Described piece can have the direction coinciding with the direction of a base curve (sense == +1), + and also can have the direction opposite to the direction of a base curve (sense == -1). + For closed periodic curves the described piece can contain the start point of base curve inside. + Another trimmed curve can't be the base curve for a trimmed curve. + In this situation it changes to the initial base curve. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbTrimmedCurve : public MbCurve { +// \ru Усечение может быть на продолжении кривой (внесенные изменения помечены как E13865) \en Trimming can be on curve extension (made changes are marked as E13865) +protected : + MbCurve * basisCurve; ///< \ru Базовая кривая (не может быть NULL). \en Base curve (can't be NULL). + double trim1; ///< \ru Параметры начальной точки \en Parameters of start point + double trim2; ///< \ru Параметры конечной точки \en Parameters of end point + int sense; ///< \ru Флаг совпадения направления с направлением базовой кривой (sense==0 не допускается) \en Flag of coincidence of the direction with the direction of the base curve (sense==0 isn't allowed) + ///< \ru Если (sense > 0), то (trim2 > trim1) \en If (sense > 0), then (trim2 > trim1) + ///< \ru Если (sense < 0), то (trim2 < trim1) \en If (sense < 0), then (trim2 < trim1) + ///< \ru Равенство trim1 и trim2 не допускается \en Equality of 'trim1' and 'trim2' isn't allowed + + mutable MbRect rect; ///< \ru Габаритный прямоугольник \en Bounding rectangle + mutable double metricLength; ///< \ru Метрическая длина усеченной кривой \en Metric length of a trimmed curve + +protected : + MbTrimmedCurve( const MbTrimmedCurve & initCurve ); + MbTrimmedCurve( MbTrimmedCurve * initCurve ); // \ru Сохранение той же базовой кривой \en Preservation of the same base curve +public : + MbTrimmedCurve( const MbCurve & initCurve, double t1, double t2, int initSense, + bool same, double eps = Math::paramEpsilon ); + // \ru Для периодической базовой кривой прии t1==t2 получим периодическую кривую со смещённым началом. \en For a periodic base curve if 't1' is equal to 't2', then obtain periodic curve with shifted beginning. +public : + virtual ~MbTrimmedCurve(); + +public : + VISITING_CLASS( MbTrimmedCurve ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbePlaneType IsA() const; // \ru Тип элемента \en Type of element + virtual MbePlaneType Type() const; // \ru Вернуть тип кривой \en Get type of curve + virtual bool IsSimilar( const MbPlaneItem & ) const; // \ru Являются ли элементы подобными \en Whether the elements are similar + virtual bool SetEqual ( const MbPlaneItem & ); // \ru Сделать элементы равными \en Make the elements equal + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли кривая curve копией данной кривой ? \en Whether curve 'curve' is a duplicate of the current curve. + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Поворот \en Rotation + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual void AddYourGabaritTo( MbRect & ) const; // \ru Добавь свой габарит в прямой прям-к \en Add your own gabarit into the given bounding rectangle + virtual bool IsInRectForDeform( const MbRect & r ) const; // \ru Виден ли объект в заданном прямоугольнике для деформации \en Whether the object is visible in the given rectangle for deformation + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + /** \} */ + + /** \ru \name Функции описания области определения кривой. + \en \name Functions for description of a curve domain. + \{ */ + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + /** \} */ + + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + \en \name Functions for working in a curve domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + if it is out of domain bounds. + \{ */ + virtual void PointOn ( double & t, MbCartPoint & p ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double & t, MbVector & fd ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double & t, MbVector & sd ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double & t, MbVector & td ) const; // \ru Третья производная \en The third derivative + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... don't correct parameter + if it is out of domain bounds. If the parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + \{ */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + virtual void _FirstDer ( double t, MbVector & v ) const; + virtual void _SecondDer( double t, MbVector & v ) const; + virtual void _ThirdDer ( double t, MbVector & v ) const; + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой. + \en \name Functions for get of the group of data inside and outside the curve's domain of parameter. + \{ */ + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Functions of moving along the curve + \{ */ + virtual double Step( double t, double sag ) const; // \ru Вычисление шага аппроксимации \en Calculation of step of approximation + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага аппроксимации с учетом угла отклонения \en Calculation of step of approximation with consideration of angle of deviation + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common functions of curve + \{ */ + + virtual double Curvature( double t ) const; // \ru Кривизна усеченной кривой \en Curvature of a trimmed curve + virtual bool HasLength( double & length ) const; + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + virtual double GetMetricLength() const; // \ru Метрическая длина \en The metric length + + virtual bool GetMiddlePoint( MbCartPoint & ) const; // \ru Вычислить среднюю точку кривой. \en Calculate mid-point of curve. + + virtual double PointProjection( const MbCartPoint & pnt ) const; // \ru Проекция точки на кривую \en Point projection on the curve + + virtual bool IsStraight() const; // \ru Признак прямолинейности кривой \en An attribute of curve straightness. + // \ru Положение точки относительно кривой. \en The point position relative to the curve. + // \ru Возвращает результат : \en Returning result: + // \ru iloc_InItem = 1 - точка находится слева от кривой, \en Iloc_InItem = 1 - point is to the left of the curve, + // \ru iloc_OnItem = 0 - точка находится на кривой, \en Iloc_OnItem = 0 - point is on the curve, + // \ru iloc_OutOfItem = -1 - точка находится справа от кривой. \en Iloc_OutOfItem = -1 - point is to the right of the curve. + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + + virtual const MbCurve & GetBasisCurve() const; // \ru Вернуть базовую кривую \en Get the base curve + virtual MbCurve & SetBasisCurve(); // \ru Вернуть базовую кривую \en Get the base curve + + virtual void Isoclinal( const MbVector & angle, SArray & tFind ) const; // \ru Прямые, проходящие под углом к оси 0X и касательные к кривой \en Lines passing angularly to the 0X axis and tangent to the curve + // \ru Выдать характерную точку усеченной кривой если она ближе чем dmax \en Get control point of trimmed curve if it is closer than 'dmax' + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ); // \ru Удалить часть усеченной кривой между параметрами t1 и t2 \en Delete a part of a trimmed curve between parameters t1 and t2 + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ); // \ru Оставить часть усеченной кривой между параметрами t1 и t2 \en Keep a part of the trimmed curve between parameters t1 and t2 + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const; + virtual MbCurve * Offset( double rad ) const; // \ru Смещение усеченной кривой \en Shift of a trimmed curve + + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + void ParameterInto( double & t ) const; // \ru Перевод параметра базовой кривой в локальный параметр \en Transformation of the base curve parameter to a local parameter + void ParameterFrom( double & t ) const; // \ru Перевод локального параметра в параметр базовой кривой \en Transformation of a local parameter to the base curve parameter + double GetBasisParameter( double & t ) const; // \ru Установить параметр в область допустимых значений \en Set the parameter into the region of the legal values + bool IsBaseParamOn( double t, double eps = Math::paramEpsilon ) const; // \ru Находится ли параметр базовой кривой в диапазоне усеченной кривой \en Whether the parameter of base curve is in range of a trimmed curve + + double GetTrim1() const { return trim1; } + double GetTrim2() const { return trim2; } + int GetSense() const { return trim2 > trim1 ? 1 : -1; } // \ru Флаг совпадения направления с направлением базовой кривой \en Flag of coincidence of the direction with the direction of base curve + void SetTrim1( double t ) { trim1 = t; InitParam( trim1, trim2, sense ); } + void SetTrim2( double t ) { trim2 = t; InitParam( trim1, trim2, sense ); } + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление кривой \en Change direction of a curve + virtual bool GetAxisPoint( MbCartPoint & p ) const; // \ru Точка для построения оси \en Point for the axis construction + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCentre ( MbCartPoint & ) const; ///< \ru Вычислить центр кривой. \en Calculate center of curve. + virtual size_t GetCount() const; // \ru Количество разбиений для прохода в операциях \en Count of subdivisions for pass in operations + + // \ru Геометрия подложки тождественна геометрии кривой, отлична параметризация \en Geometry of substrate is identical to geometry of curve, parameterization is different + virtual const MbCurve & GetSubstrate() const; // \ru Выдать подложку или себя \en Get substrate or itself + virtual MbCurve & SetSubstrate(); // \ru Выдать подложку или себя \en Get substrate or itself + virtual int SubstrateCurveDirection() const; // \ru Направление подложки относительно кривой или наоборот \en Direction of substrate relative to the curve or vice versa + virtual void SubstrateToCurve( double & ) const; // \ru Преобразовать параметр подложки в параметр кривой \en Transform a substrate parameter to the curve parameter + virtual void CurveToSubstrate( double & ) const; // \ru Преобразовать параметр кривой в параметр подложки \en Transform a curve parameter to the substrate parameter + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + void SetBasisCurve( MbCurve & newCurve ); + void InitParam( double t1, double t2, int s, double eps = Math::paramEpsilon ); + void Init( double t1, double t2, int initSense ) { + InitParam( t1, t2, initSense ); + Refresh(); + } + const MbTrimmedCurve & operator = ( const MbTrimmedCurve & source ); // \ru Присвоение параметров усеченной кривой \en Assignment of parameters of trimmed curve + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTrimmedCurve ) + /** \} */ +}; + +IMPL_PERSISTENT_OPS( MbTrimmedCurve ) + +//------------------------------------------------------------------------------ +// \ru Находится ли параметр базовой кривой в диапазоне \en Whether the parameter of the base curve is in the range +// \ru Усеченной кривой \en Of the trimmed curve +// --- +inline bool MbTrimmedCurve::IsBaseParamOn( double t, double eps ) const { + ParameterInto( t ); + return IsParamOn( t, eps ); +} + + +#endif // __CUR_TRMMED_CURVE_H diff --git a/C3d/Include/cur_trimmed_curve3d.h b/C3d/Include/cur_trimmed_curve3d.h new file mode 100644 index 0000000..f430cb6 --- /dev/null +++ b/C3d/Include/cur_trimmed_curve3d.h @@ -0,0 +1,183 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Усеченная кривая в трехмерном пространстве. + \en Trimmed curve in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CUR_TRMMED_CURVE3D_H +#define __CUR_TRMMED_CURVE3D_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Усеченная кривая в трехмерном пространстве. + \en Trimmed curve in three-dimensional space. \~ + \details \ru Усеченная кривая описывает участок базовой кривой basisCurve, + который начинается в точке с параметром trim1 и оканчивается в точке с параметром trim2. \n + Описываемый участок может иметь направление, совпадающее с направлением базовой кривой (sense == +1), + а также может иметь направление, противоположное направлению базовой кривой (sense == -1). + Для замкнутых периодических кривых описываемый участок может содержать внутри начальную точку базовой кривой. + Базовой кривой для усеченной кривой не может служить другая усеченная кривая. + В подобной ситуации выполняется переход к первичной базовой кривой. + \en Trimmed curve describes a piece of base curve 'basisCurve' + which starts at point with 'trim1' parameter and ends at point with 'trim2' parameter. \n + Described piece can have the direction coinciding with the direction of a base curve (sense == +1), + and also can have the direction opposite to the direction of a base curve (sense == -1). + For closed periodic curves the described piece can contain the start point of base curve inside. + Another trimmed curve can't be the base curve for a trimmed curve. + In this situation it changes to the initial base curve. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbTrimmedCurve3D : public MbCurve3D { +private : + MbCurve3D * basisCurve; ///< \ru Базовая кривая. \en The base curve. + double trim1; ///< \ru Параметр начальной точки базовой кривой. \en Parameter of the start point of the base curve. + double trim2; ///< \ru Параметр конечной точки базовой кривой. \en Parameter of the end point of base curve. + int sense; ///< \ru Флаг совпадения направления с направлением базовой кривой. \en Flag of coincidence of the direction with the direction of base curve. +private: + mutable double metricLength; ///< \ru Метрическая длина кривой. \en Metric length of a curve. + +public : + MbTrimmedCurve3D( const MbCurve3D & initCurve, double t1, double t2, int initSense, bool same ); + MbTrimmedCurve3D( const MbCurve3D & initCurve, const MbCartPoint3D & p0, const MbCartPoint3D & p1 ); +protected : + MbTrimmedCurve3D( const MbTrimmedCurve3D &, MbRegDuplicate * ); +private : + MbTrimmedCurve3D( const MbTrimmedCurve3D & ); // \ru Не реализовано. \en Not implemented. +public : + virtual ~MbTrimmedCurve3D(); + +public : + VISITING_CLASS( MbTrimmedCurve3D ); + + // \ru Общие функции математического объекта \en Common functions of the mathematical object + + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией \en Whether the object is a copy + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + virtual void Refresh(); // \ru Сбросить все временные данные \en Reset all temporary data + virtual void PrepareIntegralData( const bool forced ) const; // \ru Рассчитать временные (mutable) данные объекта. \en Calculate temporary (mutable) data of an object. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the basis objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Общие функции кривой \en Common functions of curve + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed() const; // \ru Проверка замкнутости кривой \en Check for curve closedness + virtual double GetPeriod() const; // \ru Вернуть период \en Get period + // \ru Функции кривой для работы в области определения параметрической кривой \en Functions of curve for working at parametric curve domain + virtual void PointOn ( double &t, MbCartPoint3D & ) const; // \ru Точка на кривой \en Point on the curve + virtual void FirstDer ( double &t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void SecondDer( double &t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void ThirdDer ( double &t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void Normal ( double &t, MbVector3D & ) const; // \ru Вектор главной нормали \en Vector of the principal normal + // \ru Функции кривой для работы вне области определения параметрической кривой \en Functions of curve for working outside the domain of parametric curve + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Точка на расширенной кривой \en Point on the extended curve + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Первая производная \en The first derivative + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Третья производная по t \en The third derivative with respect to t + virtual void _Normal ( double t, MbVector3D & ) const; // \ru Вектор главной нормали \en Vector of the principal normal + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & ) const; + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & ) const; // \ru Построить NURBS-копию кривой \en Create a NURBS-copy of the curve + + virtual const MbCurve3D & GetBasisCurve() const; + virtual MbCurve3D & SetBasisCurve(); + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой \en Create a trimmed curve + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Curvature ( double ) const; // \ru Кривизна усеченной кривой \en Curvature of a trimmed curve + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + virtual double MetricStep ( double t, double length ) const; // \ru Вычисление шага параметра по длине. \en Calculation of parameter step by the given length. + + virtual bool IsDegenerate( double eps = METRIC_PRECISION ) const; // \ru Проверка вырожденности кривой \en Check for curve degeneracy + virtual MbCurve * GetMap( const MbMatrix3D &, MbRect1D * pRgn = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; // \ru Дать плоскую проекцию кривой \en Get a planar projection of a curve + virtual size_t GetCount() const; + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Change a carrier + virtual bool IsPlanar () const; // \ru Является ли кривая плоской \en Whether the curve is planar + virtual bool IsStraight() const; // \ru Является ли линия прямолинейной \en Whether the line is straight + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual bool GetCircleAxis ( MbAxis3D & ) const; // \ru Дать ось кривой \en Get axis of curve + virtual void GetCentre( MbCartPoint3D &wc ) const; // \ru Посчитать центр кривой \en Calculate the center of a curve + + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой \en Estimation of metric length of the curve + virtual double GetMetricLength() const; // \ru Метрическая длина \en Metric length + + void SetBasisCurve( MbCurve3D & ); // \ru Заменить плоскую кривую \en Replace the planar curve + void InitParam( double t1, double t2, int initSense ); + double GetTrim1() const { return trim1; } + double GetTrim2() const { return trim2; } + int GetSense() const { return sense; } // \ru Флаг совпадения направления с направлением базовой кривой \en Flag of coincidence of the direction with the direction of base curve + + void ParameterInto( double &t ) const; // \ru Перевод параметра базовой кривой в параметр усеченной кривой \en Transformation of parameter of base curve to a parameter of trimmed curve + void ParameterFrom( double &t ) const; // \ru Перевод локального параметра в параметр базовой кривой \en Transformation of a local parameter to the base curve parameter + double GetBasisParameter( double &t ) const; // \ru Установить параметр в область допустимых значений \en Set the parameter into the region of the legal values + + bool IsBaseParamOn( double t ) const; // \ru Находится ли параметр базовой кривой в диапазоне усеченной кривой \en Whether the parameter of base curve is in range of a trimmed curve + + // \ru Ближайшая проекция точки на кривую. \en The nearest projection of a point onto the curve. + virtual bool NearPointProjection( const MbCartPoint3D &, double & t, bool ext, MbRect1D * tRange = NULL ) const; // \ru Ближайшая проекция точки на кривую \en The nearest projection of a point onto the curve + /// \ru Найти все особые точки функции кривизны кривой. + /// \en Find all the special points of the curvature function of the curve. + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + /// \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + /// \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + // \ru Геометрия базовой кривой тождественна геометрии кривой, отлична параметризация. \en Geometry of base curve is identical to geometry of curve, parameterization is different. + virtual const MbCurve3D & GetSubstrate() const; // \ru Выдать подложку или себя \en Get substrate or itself + virtual MbCurve3D & SetSubstrate(); // \ru Выдать подложку или себя \en Get substrate or itself + virtual int SubstrateCurveDirection() const; // \ru Направление подложки относительно кривой или наоборот \en Direction of substrate relative to the curve or vice versa + virtual void SubstrateToCurve( double & ) const; // \ru Преобразовать параметр подложки в параметр кривой \en Transform a substrate parameter to the curve parameter + virtual void CurveToSubstrate( double & ) const; // \ru Преобразовать параметр кривой в параметр подложки \en Transform a curve parameter to the substrate parameter + + // \ru Заполнить плейсемент, ести кривая плоская \en Fill the placement if the curve is planar + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую) \en Get the planar curve and placement if the spatial curve is planar (call DeleteItem for two-dimensional curve after using) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + // \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы) \en Get a surface curve if a spatial curve is on a surface (call DeleteItem for arguments after using ) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Является ли объект смещением \en Whether the object is a shift + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual bool IsSimilarToCurve( const MbCurve3D & curve, double precision = METRIC_PRECISION ) const; // \ru Подобные ли кривые для объединения (слива) \en Whether the curves for union (joining) are similar + +private: + void operator = ( const MbTrimmedCurve3D & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTrimmedCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbTrimmedCurve3D ) + +//------------------------------------------------------------------------------ +// \ru Находится ли параметр базовой кривой в диапазоне усеченной кривой \en Whether the parameter of base curve is in range of a trimmed curve +// --- +inline bool MbTrimmedCurve3D::IsBaseParamOn( double t ) const { + ParameterInto( t ); + return IsParamOn( t, PARAM_REGION ); +} + + +#endif // __CUR_TRMMED_CURVE3D_H diff --git a/C3d/Include/curve.h b/C3d/Include/curve.h new file mode 100644 index 0000000..2eee6c9 --- /dev/null +++ b/C3d/Include/curve.h @@ -0,0 +1,1647 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая в двумерном пространстве. + \en Curve in two-dimensional space. \~ + \details \ru Двумерные кривые используются для описания области определения параметров поверхностей, + построения трёхмерных кривых на поверхностях, кривых пересечения поверхностей, проекций + трёхмерных кривых на поверхности и плоскости локальных систем координат. + Двумерные кривые устроены аналогично трёхмерным кривым с той разницей, что вместо трёхмерных точек и векторов + в двумерных кривых используются двумерные точки и векторы. + \en Two-dimensional curves are used for description of surfaces parameters domain, + calculation of three-dimensional curves on surfaces, surfaces intersection curves, projections, + three-dimensional curves on surface and plane of local coordinate systems. + Two-dimensional curves are organizes in the same way as three-dimensional curves with a difference that instead of three-dimensional points and vectors + two-dimensional points and vectors are used in two-dimensional curves. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CURVE_H +#define __CURVE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement; +class MATH_CLASS MbNurbs; +class MATH_CLASS MbLine; +class MATH_CLASS MbContour; +class MATH_CLASS MbPolygon; +class MATH_CLASS MbCrossPoint; +class MbCurveIntoNurbsInfo; +struct MbNurbsParameters; + + +class MATH_CLASS MbCurve; +namespace c3d // namespace C3D +{ +typedef SPtr PlaneCurveSPtr; +typedef SPtr ConstPlaneCurveSPtr; + +typedef std::vector PlaneCurvesVector; +typedef std::vector ConstPlaneCurvesVector; + +typedef std::vector PlaneCurvesSPtrVector; +typedef std::vector ConstPlaneCurvesSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая в двумерном пространстве. + \en Curve in two-dimensional space. \~ + \details \ru Кривая в двумерном пространстве представляет собой векторную функцию скалярного параметра, + заданную на конечной одномерной области. Кривая представляет собой непрерывное + отображение некоторого участка числовой оси в двумерное пространство.\n + Двумерная кривая используется:\n + для плоского моделирования,\n + для описания области определения параметров поверхности,\n + для построения кривых на поверхностях,\n + для построения кривых пересечения поверхностей. + \en A curve in two-dimensional space is a vector function of a scalar parameter, + given on a finite one-dimensional space. A curve is continuous + mapping of some piece of numeric axis to two-dimensional space.\n + Two-dimensional curve is used:\n + for planar modeling,\n + for description of surface parameters domain,\n + for construction of curves on surfaces,\n + for constructing of surfaces intersection curves. \~ + \ingroup Curves_2D +*/ +// --- +class MATH_CLASS MbCurve : public MbPlaneItem { +protected: + SimpleName name; ///< \ru Имя кривой. \en A curve name. + +protected : + /// \ru Конструктор по умолчанию. \en Default constructor. + MbCurve(); + /// \ru Конструктор копирования. \en Copy-constructor. + MbCurve( const MbCurve & other ) : MbPlaneItem(), name( other.name ) {} +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbCurve(); + +public : + VISITING_CLASS( MbCurve ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbePlaneType IsA() const = 0; // \ru Тип элемента. \en A type of element. + virtual MbePlaneType Type() const; // \ru Групповой тип элемента. \en Group element type. + virtual MbePlaneType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix &, MbRegTransform * ireg = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector &, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ) = 0; // \ru Поворот вокруг точки на угол. \en Rotation at angle around a point. + virtual bool SetEqual( const MbPlaneItem & ) = 0; // \ru Сделать объект равным данному. \en Make an object equal to a given one. + virtual bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Является ли кривая curve копией данной кривой? \en Is a curve a copy of a given curve? + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + + /** \brief \ru Рассчитать временные (mutable) данные объекта. + \en Calculate temporary (mutable) data of an object. \~ + \details \ru Рассчитать временные данные объекта в зависимости от параметра forced. + Если параметр forced равен false, рассчитываются только ещё не насчитанные данные. + Если параметр forced равен true, перерасчитываются все временные данные объекта. + \en Calculate the temporary data of an object depending of the "forced" parameter. + Calculate only data that was not calculated earlier if parameter "forced" is equal false. + Recalculate all temporary data of an object if parameter "forced" is equal true. + \param[in] forced - \ru Принудительный перерасчёт. + \en Forced recalculation. \~ + */ + virtual void PrepareIntegralData( const bool forced ) const; + + virtual void AddYourGabaritTo ( MbRect & ) const = 0; // \ru Добавить в прямоугольник свой габарит. \en Add a bounding box to rectangle. + + /** \ru \name Общие функции двумерного объекта. + \en \name Common functions of two-dimensional object. + \{ */ + /** \brief \ru Добавить габарит в прямоугольник. + \en Add a bounding box to rectangle. \~ + \details \ru Добавить в прямоугольник свой габарит с учетом матрицы трансформации. + Если матрица не единичная, то происходит трансформация копии объекта по матрице и + затем к прямоугольнику добавляется габарит трансформированного объекта. + После использования копия уничтожается. + \en Add a bounding box to rectangle with taking into account of transformation matrix. + If the transformation matrix is not an identity matrix then there is performed a transformation of object's copy by the matrix and + after that a bounding box of the transformed object is added to rectangle. + A copy is destroyed after using. \~ + \param[out] rect - \ru Прямоугольник с информацией по габаритам. + \en A rectangle with information about bounds. \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + virtual void AddYourGabaritMtr( MbRect & rect, const MbMatrix & matr ) const; + /** \brief \ru Определить габаритный прямоугольник кривой. + \en Detect the bounding box of a curve. \~ + \details \ru Для получения габарита объекта присланный прямоугольник делается пустым. + Затем вычисляются габариты объекта и сохраняются в прямоугольнике rect. + \en The sent rectangle becomes empty for getting a bounding box. + Then bounding boxes of an object are calculated and saved into a rectangle 'rect'. \~ + */ + virtual void CalculateGabarit ( MbRect & ) const; + + /** \brief \ru Рассчитать габарит в локальной системы координат. + \en Calculate bounding box in the local coordinate system. \~ + \details \ru Для получения габарита объекта относительно локальной системы координат, + присланный прямоугольник делается пустым. Затем вычисляются габариты объекта в локальной системе координат + и сохраняются в прямоугольнике rect. + \en For getting a bounding box of an object relatively to the local coordinate system, + a sent rectangle becomes empty. After that bounding boxes of an object in the local coordinate system are calculated + and saved in a rectangle 'rect'. \~ + \param[in] matr - \ru Матрица перехода от текущей для объекта системы координат к локальной системе координат. + \en A transition matrix from the current coordinate system of the object to the local coordinate system. \~ + \param[out] rect - \ru Прямоугольник с информацией по габаритам. + \en A rectangle with information about bounds. \~ + */ + virtual void CalculateLocalGabarit( const MbMatrix & into, MbRect & local ) const; + + /** \brief \ru Определить видимость объекта в прямоугольнике. + \en Determine visibility of an object in rectangle. \~ + \details \ru Определить, виден ли объект в заданном прямоугольнике. Есть возможность выполнить быструю проверку + или более тщательную при соответствующем значении второго параметра. + \en Determine whether an object is visible in the given rectangle. There is a possibility to perform a fast check + or more thorough check when the second parameter has a corresponding value. \~ + \param[in] rect - \ru Заданный двумерный прямоугольник. + \en A given two-dimensional rectangle. \~ + \param[in] exact - \ru Выполнять ли более тщательную проверку? + \en Whether to perform a more thorough check. \~ + \return \ru true - объект полностью или частично содержится в прямоугольнике, иначе - false. + \en true, if the object is fully or partially contained in the rectangle, otherwise false. \~ + */ + virtual bool IsVisibleInRect ( const MbRect & rect, bool exact = false ) const; + + /** \brief \ru Определить, виден ли объект полностью в прямоугольнике. + \en Determine whether an object is fully visible in rectangle. \~ + \details \ru Объект полностью содержится в заданном прямоугольнике, если его габаритный прямоугольник вложен в заданный. + \en An object is fully contained in the given rectangle if its bounding rectangle is included in the given rectangle. \~ + \param[in] rect - \ru Прямоугольник, вложенность в который проверяется. + \en Rectangle to check inclusion to. \~ + \return \ru true - объект полностью содержится в прямоугольнике, иначе - false. + \en true, if the object is fully contained in the rectangle, otherwise false. \~ + */ + virtual bool IsCompleteInRect( const MbRect & rect ) const; + + // \ru Определить расстояние до точки. \en Determine the distance to a point. + virtual double DistanceToPoint( const MbCartPoint & toP ) const; + // \ru Вычислить расстояние до точки, если оно меньше d. \en Calculate the distance to the point if it is less than d. + virtual bool DistanceToPointIfLess( const MbCartPoint & toP, double & d ) const; + + /** \} */ + /** \ru \name Функции описания области определения кривой. + \en \name Functions for curve domain description. + \{ */ + /// \ru Получить максимальное значение параметра. \en Get the maximum value of parameter. + virtual double GetTMax () const = 0; + /// \ru Получить минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMin () const = 0; + + /** \brief \ru Определить, является ли кривая замкнутой. + \en Define whether the curve is closed. \~ + \details \ru Определить, является ли кривая замкнутой.\n + Замкнутой считается кривая, если она циклична:\n + - начальная и конечная точка кривой совпадают,\n + - производные в начальной и конечной точке совпадают; \n + если по своей природе кривая допускает изломы (контур, ломаная), + то допускается не совпадение производных; + у кривой Безье производные должны совпадать по направлению, + но могут не совпадать по модулю. + \en Define whether the curve is closed.\n + A curve is considered as closed if it is cyclic:\n + - start point is coincident with end point,\n + - derivatives in start point and end point coincide, \n + if there are breaks at curve (in cases when a curve is contour or polyline), + then derivatives may not coincide; + in Bezier curve derivatives should coincide by direction, + but they may differ by absolute value. \~ + \return \ru true, если кривая замкнута. + \en True if a curve is closed. \~ + */ + virtual bool IsClosed() const = 0; + + /** \brief \ru Вернуть период. + \en Return period. \~ + \details \ru Вернуть значение периода, если может быть кривая замкнута. Для незамкнутой кривой вернуть нуль. + \en Return the period value if a curve can be closed. Let unclosed curve return null. \~ + \return \ru Значение периода для замкнутой кривой или нуль - для незамкнутой. + \en The value of period for a closed curve or null - for unclosed curve. \~ + */ + virtual double GetPeriod() const; + + /// \ru Определить, является ли замкнутая кривая периодической. \en Define whether the curve is periodic. + virtual bool IsPeriodic() const; + + /** \brief \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. + \en Determine whether a curve is closed regardless of the smoothness of the closure. \~ + \details \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. + \en Determine whether a curve is actually closed regardless of the smoothness of the closure. \~ + */ + bool IsTouch( double eps = Math::LengthEps ) const; + + /** \} */ + /** \ru \name Функции для работы в области определения кривой. + Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения. + Исключение составляет MbLine (прямая). + \en \name Functions for working in the curve's domain. + Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is out of domain bounds. + The exception is MbLine (line). + \{ */ + + /** \brief \ru Вычислить точку на кривой. + \en Calculate a point on the curve. \~ + \details \ru Скорректировать параметры при выходе их за пределы области определения и вычислить точку на кривой. + \en Correct parameter when getting out of domain bounds and calculate a point on the curve. \~ + \param[in] t - \ru Параметр curve. + \en Curve parameter. \~ + \param[out] p - \ru Вычисленная точка на кривой. + \en A point on the curve. \~ + \ingroup Curves_2D + */ + virtual void PointOn ( double & t, MbCartPoint & p ) const = 0; + /// \ru Вычислить первую производную. \en Calculate first derivative. + virtual void FirstDer ( double & t, MbVector & v ) const = 0; + /// \ru Вычислить вторую производную. \en Calculate second derivative. + virtual void SecondDer( double & t, MbVector & v ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void ThirdDer ( double & t, MbVector & v ) const = 0; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + void Tangent ( double & t, MbVector & v ) const; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + void Tangent ( double & t, MbDirection & d ) const; + /// \ru Вычислить вектор главной нормали (нормализованный). \en Calculate main normal vector (normalized). + void Normal ( double & t, MbVector & v ) const; + /// \ru Вычислить вектор главной нормали (нормализованный). \en Calculate main normal vector (normalized). + void Normal ( double & t, MbDirection & d ) const; + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой. + Функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. При выходе за область определения незамкнутая + кривая, в общем случае, продолжается по касательной, которую она имеет на соответствующем конце. + Исключение составляют дуги эллипса и окружности - они продолжаются в соответствии со своими уравнениями. + \en \name Functions for working inside and outside the curve's domain. + Functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct parameter + when it is out of domain bounds. When parameter is out of domain bounds, an unclosed + curve is extended by tangent vector at corresponding end point in general case. + The exceptions are arcs of ellipse and arcs of circle - they are extended according to their equations. + \{ */ + + /** \brief \ru Вычислить точку на кривой и её продолжении. + \en Calculate point at curve and its extension. \~ + \details \ru Вычислить точку на кривой в том числе и за пределами области определения параметрa. + \en Calculate a point on the curve including the outside area determination parameter. \~ + \param[in] t - \ru Параметр curve. + \en Curve parameter. \~ + \param[out] p - \ru Вычисленная точка на кривой. + \en A point on the curve. \~ + \ingroup Curves_2D + */ + virtual void _PointOn ( double t, MbCartPoint & p ) const; + /// \ru Вычислить первую производную на кривой и её продолжении. \en Calculate first derivative at curve and its extension. + virtual void _FirstDer ( double t, MbVector & v ) const; + /// \ru Вычислить вторую производную на кривой и её продолжении. \en Calculate second derivative at curve and its extension. + virtual void _SecondDer( double t, MbVector & v ) const; + /// \ru Вычислить третью производную на кривой и её продолжении. \en Calculate third derivative at curve and its extension. + virtual void _ThirdDer ( double t, MbVector & v ) const; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + void _Tangent ( double t, MbVector & v ) const; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + void _Tangent ( double t, MbDirection & d ) const; + /// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. + void _Normal ( double t, MbVector & v ) const; + /// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. + void _Normal ( double t, MbDirection & d ) const; + + /** \brief \ru Вычислить значения точки и производных для заданного параметра. + \en Calculate point and derivatives of object for given parameter. \~ + \details \ru Значения точки и производных вычисляются в пределах области определения и на расширенной кривой. + \en Values of point and derivatives are calculated on parameter area and on extended curve. \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[in] ext - \ru В пределах области определения (false), на расширенной кривой (true). + \en On parameters area (false), on extended curve (true). \~ + \param[out] pnt - \ru Точка. + \en Point. \~ + \param[out] fir - \ru Производная. + \en Derivative with respect to t. \~ + \param[out] sec - \ru Вторая производная по t, если не ноль. + \en Second derivative with respect to t, if not NULL. \~ + \param[out] thir - \ru Третья производная по t, если не ноль. + \en Third derivative with respect to t, if not NULL. \~ + \ingroup Curves_3D + */ + virtual void Explore( double & t, bool ext, + MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const; + + /** \} */ + /** \ru \name Функции движения по кривой + \en \name Function of moving by curve + \{ */ + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой по величине прогиба кривой. + Вычисление шага проходит с учетом радиуса кривизны. + Шаг аппроксимации кривой выбирается таким образом, чтобы отклонение кривой от + её полигона не превышало заданную величину прогиба. + \en Calculate parameter step for the curve's approximation by its sag value. + Calculation of the step is performed with consideration of curvature radius. + A step of curve's approximation is chosen in such way, that the deviation of a curve from + its polygon does not exceed the given sag value. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] sag - \ru Максимально допустимая величина прогиба. + \en Maximum feasible sag value. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + */ + virtual double Step ( double t, double sag ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой по углу отклонения касательной. + Шаг аппроксимации кривой выбирается таким образом, + чтобы угловое отклонение касательной кривой в следующей точке + не превышало заданную величину ang. + \en Calculate parameter step for the curve's approximation by the deviation angle of the tangent vector. + A step of curve's approximation is chosen in such way, + that angular deviation of the tangent curve at the next point + does not exceed the given value ang. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] ang - \ru Максимально допустимый угол отклонения касательной. + \en The maximum feasible deviation angle of tangent. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + */ + virtual double DeviationStep( double t, double ang ) const; + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common function of curve. + \{ */ + /// \ru Вычислить кривизну кривой. \en Calculate curvature of curve. + virtual double Curvature ( double t ) const; + /// \ru Вычислить производную кривизны по параметру. \en Calculate derivative of curvature by parameter. + double CurvatureDerive( double t ) const; + /// \ru Вычислить радиус кривизны кривой со знаком. \en Calculate radius of curve with a sign. + double CurvatureRadius( double t ) const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Вычислить метрическую длину кривой и записать ее в переменную length. + \en Calculate the metric length of a curve and save the result in the variable 'length'. \~ + \param[in, out] length - \ru Вычисленная длина кривой. + \en Calculated length of a curve. \~ + \return \ru true - если длина кривой отлична от нуля. Иначе возвращает false. + \en True - if the length of a curve differs from null. Otherwise returns false. \~ + */ + virtual bool HasLength( double & length ) const = 0; + /// \ru Определить, является ли кривая ограниченной. \en Define whether the curve is bounded. + virtual bool IsBounded() const; + /// \ru Определить, является ли кривая прямолинейной. \en Define whether the curve is rectilinear.. + virtual bool IsStraight() const; + /// \ru Определить, является ли кривая вырожденной. \en Define whether the curve is degenerate.. + virtual bool IsDegenerate( double eps = Math::LengthEps ) const; + /// \ru Определить, являются ли стыки контура/кривой гладкими. \en Define whether joints of contour/curve are smooth. + virtual bool IsSmoothConnected( double angleEps ) const; + + /// \ru Вычислить параметрическую длину кривой. \en Calculate the parametric length of a curve. + double GetParamLength() const { return GetTMax() - GetTMin(); } + // \ru Функции с расчетом метрической длины перегружать все сразу, чтобы не было рассогласования. \en Functions with calculation of metric length, they should be overloaded simultaneously to avoid mismatches. + /// \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double CalculateMetricLength() const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Вычислить метрическую длину разомкнутой кривой от параметра t1 до t2. + Должно выполнятся условие t1 < t2. + \en Calculate the metric length of unclosed curve from parameter t1 to parameter t2. + The condition t1 < t2 should satisfied. \~ + \param[in] t1 - \ru Начальный параметр отрезка кривой. + \en Start parameter of a curve section. \~ + \param[in] t2 - \ru Конечный параметр отрезка кривой. + \en End parameter of a curve section. \~ + \return \ru Длина кривой. + \en Length of a curve. \~ + */ + virtual double CalculateLength( double t1, double t2 ) const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Если длина кривой уже была вычислена и запомнена в объекте, эта функция возвращает готовый результат, + не выполняя повторных вычислений. Иначе длина вычисляется с помощью функции CalculateMetricLength(). + \en If a length of a curve is already calculated and saved in the object then this function returns the existing result, + without repeating of calculations. Otherwise the length is calculated by the function CalculateMetricLength(). \~ + \return \ru Длина кривой. + \en Length of a curve. \~ + */ + virtual double GetMetricLength() const = 0; + + /** \brief \ru Сдвинуть параметр вдоль кривой. + \en Translate parameter along the curve. \~ + \details \ru Сдвинуть параметр вдоль кривой на заданное расстояние в заданном направлении. + Новое значение параметра сохраняется в переменной t. Если кривая не замкнута и длина ее части от точки с параметром t до конца в заданном направлении + меньше, чем нужное смещение, то вычисления происходят на продолжении кривой, если можно построить продолжение. + \en Translate parameter along the curve by the given distance at the given direction. + The new value of parameter is saved in the variable t. If the curve is not closed and the length of its part from the point with parameter t to the end at the given direction + is less than the required shift, then calculations are performed on extension of the curve, if it possible to construct such extension. \~ + \param[in, out] t - \ru На входе - исходное значение параметра. На выходе - новое значение параметра. + \en Input - the initial value of parameter. Output - the new value of parameter. \~ + \param[in] len - \ru Величина смещения вдоль кривой. + \en The value of shift along the curve. \~ + \param[in] curveDir - \ru Направление смещения. Если curveDir - неотрицательно, то смещение направлено в сторону увеличения параметра. + Иначе - в сторону уменьшения параметра. + \en The offset direction. If curveDir is non-negative, then the shift is directed to the side of increasing of parameter. + Otherwise - to the side of decreasing of parameter. \~ + \param[in] eps - \ru Точность вычислений. + \en Computational tolerance. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \return \ru true - если операция выполнена успешно, иначе false. + \en True - if the operation is performed successfully, otherwise false. \~ + */ + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps, + VERSION version = Math::DefaultMathVersion() ) const; + + /// \ru Сбросить текущее значение параметра. \en Reset the current value of parameter. + virtual void ResetTCalc() const; + /// \ru Изменить направления кривой на противоположное. \en Set the opposite direction of curve. + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; + /// \ru Построить эквидистантную кривую, смещённую на заданное расстояние. \en Construct the equidistant curve which is shifted by the given value. + virtual MbCurve * Offset( double rad ) const; + + /** \brief \ru Начать аппроксимацию для отрисовки. + \en Start approximation for the drawing. \~ + \details \ru В функции проверяются и при необходимости корректируются параметры начала и конца аппроксимируемой части кривой. + Вычисляется первая точка, соответствующая начальному параметру. Определяется, можно ли вычислить следующую точку. + Следующие точки вычисляются функцией GetNextPoint. + \en Parameters of start and end of approximated part of a curve are checked and corrected this is necessary. + There is calculated a first point corresponding to start parameter. There is defined whether it is possible to calculate the next point. + The next points are calculated by the function GetNextPoint. \~ + \param[in] sag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \param[in, out] tbeg - \ru Параметр, соответствующий началу аппроксимируемой части кривой. + \en Parameter corresponding to start of approximated part of a curve. \~ + \param[in, out] tend - \ru Параметр, соответствующий концу аппроксимируемой части кривой. + \en Parameter corresponding to end of approximated part of a curve. \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + \param[in, out] existNextPoint - \ru Флаг, показывающий, надо ли вычислять следующую точку (true) + или вычисленная точка соответствует концу аппроксимируемой кривой (false). + \en Flag showing whether the next point should be calculated (true by default) + or calculated point corresponds to the end of approximated curve. \~ + \return \ru true - если операция выполнена успешно, иначе false. + \en True - if the operation is performed successfully, otherwise false. \~ + */ + virtual bool BeginApprox ( double sag, double & tbeg, double & tend, MbCartPoint & pnt, bool & existNextPoint ) const; + + /** \brief \ru Вычислить очередную точку. + \en Calculate the next point. \~ + \details \ru Функция используется для расчета аппроксимации кривой, после вызова функции BeginApprox. + В ней определяется параметр для вычисления следующей точки полигона, вычисляется точка и определяется, является ли она конечной. + \en This function is used for the calculation of curve's approximation after call of the function BeginApprox. + In this function a parameter for calculation of the next point of the polygon is defined, a point is calculated and there is defined whether it is an end point. \~ + \param[in] sag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \param[in] tend - \ru Параметр, соответствующий концу аппроксимируемой части кривой. + \en Parameter corresponding to end of approximated part of a curve. \~ + \param[in, out] tcur - \ru На входе - значение параметра в последней вычисленной точке. На выходе - параметр, соответствующий новой + вычисленной точке. + \en Input - the value of parameter at the last calculated point. Output - parameter corresponding to the new + calculated point. \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + \return \ru true - если необходимы дальнейшие вычисления. false - если вычисленная точка соответствует концу аппроксимируемой кривой. + \en True - if the further calculations are required. false - if the calculated point corresponds to the end of approximated curve. \~ + */ + virtual bool GetNextPoint ( double sag, double tend, double & tcur, MbCartPoint & pnt ) const; + + /** \brief \ru Рассчитать массив точек для отрисовки. + \en Calculate an array of points for drawing. \~ + \details \ru Выдать массив отрисовочных точек с заданной стрелкой прогиба. + Если кривая представляет собой контур, то узловые точки контура дублируются. + \en Get an array of drawn points with a given sag. + If the cure is a contour then knots of a contour are duplicated. \~ + \param[in] sag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \param[in, out] poligon - \ru Полигон рассчитанных точек на кривой. + \en A polygon of calculated points on a curve. \~ + */ + virtual void CalculatePolygon( double sag, MbPolygon & poligon ) const; + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую заданную. По возможности, строит точную кривую, возможно с кратными узлами. + Количество узлов для NURBS определяется в зависимости от кривой. + \en Constructs a NURBS copy which approximates a given curve. If it is possible, constructs the accurate curve, perhaps with multiple knots. + The number of knots for NURBS is defined depending on the curve. \~ + \param[in, out] nurbs - \ru Построенная NURBS кривая. + \en A constructed NURBS-curve. \~ + \param[in] nInfo - \ru Параметры преобразования кривой в NURBS. + \en Parameters of conversion of a curve to NURBS. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo * nInfo = NULL ) const; + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую заданную в диапазоне параметров [t1, t2] с заданным направлением. + По возможности, строит точную кривую, возможно с кратными узлами. + Количество узлов для NURBS определяется в зависимости от кривой. + \en Constructs a NURBS curve which approximates a given curve inside the range [t1, t2]. with a given direction. + If it is possible, constructs the accurate curve, perhaps with multiple knots. + The number of knots for NURBS is defined depending on the curve. \~ + \param[in, out] nurbs - \ru Построенная NURBS кривая. + \en A constructed NURBS-curve. \~ + \param[in] t1 - \ru Параметр, соответствующий началу аппроксимируемой части кривой. + \en Parameter corresponding to start of approximated part of a curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу аппроксимируемой части кривой. + \en Parameter corresponding to end of approximated part of a curve. \~ + \param[in] sense - \ru Совпадает ли направление возрастания параметра вдоль NURBS кривой с направлением на исходной кривой. + sense > 0 - направление совпадает. + \en Does the direction of parameter increasing along the NURBS curve coincide with direction of the initial curve. + 'sense' > 0 - direction coincide. \~ + \param[in] nInfo - \ru Параметры преобразования кривой в NURBS. + \en Parameters of conversion of a curve to NURBS. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + virtual MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & nInfo ) const = 0; + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую исходную с заданными параметрами. + В параметрах можно задать степень и количество узлов сплайна, диапазон изменения параметра кривой. + Если в параметрах не задан флаг точной аппроксимации, то строит NURBS без кратных узлов. + \en Constructs a NURBS curve which approximates a given curve with the given parameters. + In parameters the degree and the number of knots of a spline and the range of curve's parameters changing may be set. + If the flag of accurate approximation is not set in parameters then NURBS without multiple knots is constructed. \~ + \param[in] tParameters - \ru Параметры построения NURBS копии кривой. + \en Parameters for the construction of a NURBS copy of the curve. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + virtual MbCurve * NurbsCurve( const MbNurbsParameters & tParameters ) const; + + /** \brief \ru Построить усеченную кривую. + \en Construct a trimmed curve. \~ + \details \ru Строит усеченную кривую, начало которой соответствует точке с параметром t1 и + конец - точке с параметром t2. + Можно изменить направление полученной кривой относительно исходной с помощью параметра sense. + Если кривая замкнута, можно получить усеченную кривую, проходящую через + начало кривой.\n + В случае замкнутой кривой (или для дуги - исключение) три параметра sense, t1 и t2 однозначно + определяют результат. + В случае разомкнутой кривой параметр sense и параметрами усечения должны соответствовать друг другу:\n + 1) если sense == 1, то t1 < t2,\n + 2) если sense == -1, то t1 > t2.\n + Если есть несоответствие между sense и параметрами усечения, то + приоритетным параметром считается sense. + Если параметры t1 и t2 равны и кривая замкнута, в результате должны получить замкнутую кривую. + \en Constructs a trimmed curve, a start point of which corresponds to a point with parameter t1 and + an end point corresponds to a point with parameter t2. + Direction of the constructed curve relative to the initial curve may be changed by the parameter 'sense'. + If the curve is closed, then there may be obtained a trimmed curve, passing through + the start of a curve.\n + In a case of closed curve (or for an arc - exception) three parameters 'sense', t1 and t2 clearly + define the result. + In a case of unclosed curve the parameter 'sense' and parameter of trimming should correspond each other:\n + 1) if sense == 1, then t1 < t2,\n + 2) if sense == -1, then t1 > t2,\n + If there is a discrepancy between 'sense' and parameters of trimming, then + 'sense' parameter has higher priority. + If parameters t1 and t2 are equal and the curve is closed, then in result a closed curve should be obtained. \~ + \param[in] t1 - \ru Параметр, соответствующий началу усеченной кривой. + \en Parameter corresponding to start of a trimmed curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу усеченной кривой. + \en Parameter corresponding to end of a trimmed curve. \~ + \param[in] sense - \ru Направление усеченной кривой относительно исходной.\n + sense = 1 - направление кривой сохраняется. + sense = -1 - направление кривой меняется на обратное. + \en Direction of a trimmed curve in relation to an initial curve. + sense = 1 - direction does not change. + sense = -1 - direction changes to the opposite value. \~ + \internal \ru При изменении поведения или документации метода переделать юнит-тестирование. + \en When changing of the behavior or the documentation of the method being performed, the unit-testing should be redone. \~ \endinternal + \result \ru Построенная усеченная кривая. + \en A constructed trimmed curve. \~ + */ + virtual MbCurve * Trimmed( double t1, double t2, int sense ) const = 0; + + /// \ru Аппроксимировать кривую контуром из NURBS-кривых. \en Approximate of a curve by the contour from NURBS curves. + virtual MbContour * NurbsContour() const; + + /** \brief \ru Деформировать кривую. + \en Deform the curve. \~ + \details \ru Если габаритный прямоугольник кривой пересекаться с заданным, + то кривая трансформируется в соответствии с матрицей с помощью функции Transform. + \en If the bounding rectangle of a curve intersects the given one, + then the curve is transformed according to the matrix with a help of 'Transform' function. \~ + \param[in] rect - \ru Прямоугольник, в котором проверяется видимость кривой. + \en A rectangle, in which the visibility of a curve is checked. \~ + \param[in] matr - \ru Матрица деформации. + \en A deformation matrix. \~ + \result \ru Состояние кривой после деформации. + \en A state of a curve after deformation. \~ + */ + virtual MbeState Deformation( const MbRect & rect, const MbMatrix & matr ); + + /// \ru Определить видимость кривой в прямоугольнике. \en Determine visibility of a curve in rectangle. + virtual bool IsInRectForDeform( const MbRect & ) const; + + /** \brief \ru Удалить часть кривой. + \en Delete the piece of a curve. \~ + \details \ru Удалить часть кривой между параметрами t1 и t2. Если после удаления кривая распалась на две части, + то исходный объект соответствует начальной части кривой, а в параметре part2 содержится конечная часть кривой. + Если осталась односвязной, то изменяется только исходный объект. + \en Delete a part of a curve between parameters t1 and t2. If the curve is split into two parts after deletion, + then the initial object corresponds to the start part of a curve, and parameter 'part2' contains the end part of a curve. + If the curve remained simply connected, then only the initial object changes. \~ + \param[in] t1 - \ru Начальный параметр усечения. + \en Start parameter of trimming. \~ + \param[in] t2 - \ru Конечный параметр усечения. + \en End parameter of trimming. \~ + \param[in, out] part2 - \ru Конечная часть кривой после удаления, если исходная кривая распалась на части. + Может являться единственной частью кривой после удаления, \ + если не смогли изменить саму кривую (например, для прямой MbLine), + в этом случае возвращаемый результат dp_Degenerated. + \en The end part of a curve after deletion, if an initial curve is split into parts. + It may be the only part after deletions, \ + if the curve did not change (e. g. for a curve of MbLine type), + in this case the returned value is dp_Degenerated. \~ + \result \ru Состояние кривой после модификации. + \en A state of a curve after modification. \~ + */ + virtual MbeState DeletePart( double t1, double t2, MbCurve *& part2 ) = 0; + + /** \brief \ru Оставить часть кривой. + \en Keep the piece of a curve. \~ + \details \ru Оставить часть кривой между параметрами t1 и t2.\n + В случае успеха операции возвращаемое значение равно dp_Changed и + кривая удовлетворяет следующим условиям:\n + - если исходная кривая замкнута, то начальная точка усеченной кривой должна + соответствовать параметру t1, конечная - параметру t2, + - если исходная кривая не замкнута, то начальная точка усеченной кривой должна + соответствовать минимальному параметру из t1 и t2, конечная - максимальному. + \en Leave a part of a curve between parameters t1 and t2.\n + In a case of success the returned value equals dp_Changed and + a curve satisfies to the next conditions:\n + - if an initial curve is closed then the start point of a trimmed curve should + correspond to the parameter t1, the end point - to the parameter t2, + - if an initial curve is not closed then the start point of a trimmed curve should + correspond to the minimum parameter from t1 and t2, the end point - to the maximum one. \~ + \param[in] t1 - \ru Начальный параметр усечения. + \en Start parameter of trimming. \~ + \param[in] t2 - \ru Конечный параметр усечения. + \en End parameter of trimming. \~ + \param[in, out] part2 - \ru Может заполниться результатом усечения, если не смогли изменить саму кривую. + В этом случае возвращаемый результат dp_Degenerated. + Иначе = NULL. + \en This may be filled by a result of trimming if the curve was not changed. + In this case the returned value is dp_Degenerated. + Otherwise NULL is returned. \~ + \result \ru Состояние кривой после модификации:\n + dp_Degenerated - кривая выродилась, может быть три варианта: + кривая не была изменена, так как в результате преобразования она бы выродилась, + или не была изменена, а результат усечения - part2,\n + dp_NoChanged - кривая не изменилась,\n + dp_Changed - кривая изменилась. + \en A state of a curve after modification:\n + dp_Degenerated - the curve is degenerated and there are possible three cases: + the curve was not changed, because it would degenerate in a result of transformation, + or it it was not changed and the result of trimming is 'part2',\n + dp_NoChanged - the curve was not changes, \n + dp_Changed - the curve is changed. \~ + \warning \ru Функция предназначена для внутреннего использования. + \en The function is designed for internal use only. \~ + */ + virtual MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ) = 0; + + /** \brief \ru Определить положение точки относительно кривой. + \en Define the point position relative to the curve. \~ + \details \ru Определяется, как расположена точка относительно кривой, если двигаться по кривой в положительном направлении. + \en There is defined on which side from a curve the point is located, by the positive direction of a curve. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] eps - \ru Точность определения. + \en A tolerance of detection. \~ + \result \ru iloc_InItem = 1 - если точка находится слева от кривой, \n + iloc_OnItem = 0 - если точка находится на кривой, \n + iloc_OutOfItem = -1 - если точка находится справа от кривой. + \en Iloc_InItem = 1 - if the point is on the left from a curve, \n + iloc_OnItem = 0 - if the point is on a curve, \n + iloc_OutOfItem = 1 - if the point is on the right from a curve. \~ + */ + virtual MbeItemLocation PointRelative( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + + /// \ru Положение точки относительно кривой. \en The point position relative to the curve. + virtual MbeLocation PointLocation( const MbCartPoint & pnt, double eps = Math::LengthEps ) const; + + + /// \ru Найти проекцию точки на кривую. \en Find the point projection to the curve. + virtual double PointProjection( const MbCartPoint & pnt ) const; + + /** \brief \ru Найти проекцию точки на кривую. + \en Find the point projection to the curve. \~ + \details \ru Найти проекцию точки на кривую или ее продолжение методом Ньютона по заданному начальному приближению. + \en Find the point projection to the curve or its extension by the Newton method with the given initial approximation. \~ + \param[in] p - \ru Заданная точка. + \en A given point. \~ + \param[in] xEpsilon - \ru Точность определения проекции по оси x. + \en A tolerance of detection of the projection by x axis. \~ + \param[in] yEpsilon - \ru Точность определения проекции по оси y. + \en A tolerance of detection of the projection by y axis. \~ + \param[in] iterLimit - \ru Максимальное количество итераций. + \en The maximum number of iterations. \~ + \param[in] t - \ru На входе - начальное приближение, на выходе - параметр кривой, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a curve, corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \result \ru Результат выполнения итерационного метода. + \en The result of the iterative method. \~ + */ + MbeNewtonResult PointProjectionNewton( const MbCartPoint & p, double xEpsilon, double yEpsilon, + size_t iterLimit, double & t, bool ext ) const; + + /** \brief \ru Найти проекцию точки на кривую. + \en Find the point projection to the curve. \~ + \details \ru Найти ближайшую проекцию точки на кривую или ее продолжение по заданному начальному приближению. + Если задан диапазон изменения параметра tRange - то надо найти проекцию в заданном диапазоне. + Диапазон параметра может выходить за область определения параметра кривой. + Используется метод Ньютона. + \en Find the nearest point projection to the curve or its by the given initial approximation. + If the range of parameter changing 'tRange' is set, then find a projection in the given range. + A range of parameter may not belong to the domain of a curve. + The Newton method is used. \~ + \note \ru Математическое ядро обеспечивает потокобезопасную реализацию функции для своих объектов. + \en Mathematical kernel provides a thread-safe function implementation for its objects. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] xEpsilon - \ru Точность определения проекции по оси x. + \en A tolerance of detection of the projection by x axis. \~ + \param[in] yEpsilon - \ru Точность определения проекции по оси y. + \en A tolerance of detection of the projection by y axis. \~ + \param[in,out] t - \ru На входе - начальное приближение, на выходе - параметр кривой, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a curve corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \param[in] tRange - \ru Диапазон изменения параметра, в котором надо найти решение. + \en A range of parameter changing in which the solution should be found. \~ + \result \ru true - если найдена проекция, удовлетворяющая всем входным условиям. + \en True - if there is found a projection which satisfies to all input conditions. \~ + */ + virtual bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, + double & t, bool ext, MbRect1D * tRange = NULL ) const; + + /** \brief \ru Вычислить проекцию точки на кривую. + \en Calculate the point projection to the curve. \~ + \details \ru Вычислить точку на кривой, соответствующую проекции заданной точки на эту кривую. + \en Calculate the point on the curve corresponding to the projection of the given point on this curve. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in, out] on - \ru Искомая точка - проекция. + \en The required point - projection. \~ + */ + void PointProjection( const MbCartPoint & pnt, MbCartPoint & on ) const; + + /** \brief \ru Вычислить проекцию точки на кривую. + \en Calculate the point projection to the curve. \~ + \details \ru Вычислить точку на кривой, соответствующую проекции заданной точки на эту кривую. + Если кривая - усеченная, то вычисляется проекция на базовую кривую. + \en Calculate the point on the curve corresponding to the projection of the given point on this curve. + If a curve is trimmed then a projection to the base curve is calculated. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in, out] on - \ru Искомая точка - проекция. + \en The required point - projection. \~ + */ + void BasePointProjection( const MbCartPoint & pnt, MbCartPoint & on ) const; + + /** \brief \ru Вычислить проекцию точки на кривую. + \en Calculate the point projection to the curve. \~ + \details \ru Вычислить точку на кривой, соответствующую проекции заданной точки на эту кривую. + Дополнительно возвращает угол наклона касательной к оси 0X в точке проекции. + \en Calculate the point on the curve corresponding to the projection of the given point on this curve. + Additionally returns an inclination angle of a tangent to the axis OX at the point of projection. \~ + \param[in, out] on - \ru На входе - исходная точка. На выходе - точка-проекция на кривой. + \en Input - an initial point. Output - a projection point on a curve. \~ + \param[in, out] angle - \ru Вычисленный угол наклона касательной к оси 0X. + \en A calculated inclination angle of a curve to the axis OX. \~ + */ + void PointProjectionAndAngle( MbCartPoint & on, double & angle ) const; + + /** \brief \ru Вычислить проекцию точки на кривую. + \en Calculate the point projection to the curve. \~ + \details \ru Вычислить ближайшую точку пересечения кривой с лучом, выходящим из заданной точки pnt по направлению dir. + Рассматриваются точки, лежащие за начальной точкой луча pnt на расстоянии, превосходящем Math::paramEpsilon. + \en Calculate the nearest point of intersection between a curve and a ray from the given point 'pntp by the direction 'dir'. + We consider the points lying over the starting point pnt beam at a distance exceeding Math :: paramEpsilon. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] dir - \ru Заданное направление. + \en A given direction. \~ + \param[in, out] pp - \ru Искомая точка на кривой. + \en Required point on the curve. \~ + */ + bool DirectPointProjection( const MbCartPoint & pnt, + const MbDirection & dir, MbCartPoint & pp ) const; + + /** \brief \ru Найти ближайший перпендикуляр к кривой. + \en Find the nearest perpendicular to the curve. \~ + \details \ru Найти ближайший перпендикуляр к кривой, опущенный из заданной точки. + В этой функции не рассматриваются перпендикуляры, опущенные на продолжение кривой. + \en Find the nearest perpendicular to the curve from the given point. + In this function perpendiculars to an extension of a curve are not considered. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in, out] tProj - \ru Параметр на кривой, соответствующий точке на кривой, через которую проходит перпендикуляр. + \en Parameter on a curve, corresponding to the point on a curve, which the perpendicular is passed through. \~ + \return \ru true, если искомый перпендикуляр построен. + \en True if the required perpendicular is constructed. \~ + */ + virtual bool SmallestPerpendicular( const MbCartPoint & pnt, double & tProj ) const; + + /** \brief \ru Найти касательные к кривой. + \en Find tangents to a curve. \~ + \details \ru Найти все касательные к кривой, которые можно провести из заданной точки. + Точка может лежать на кривой. В данной функции рассматривается кривая без продолжений. + \en Find all tangents to a curve from the given point. + A point may belong to a curve. In this function a curve without extensions is considered. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in, out] tFind - \ru Массив параметров кривой, соответствующих точкам касания. + \en An array of parameters of a curve, corresponding to the tangent points. \~ + */ + virtual void TangentPoint( const MbCartPoint & pnt, SArray & tFind ) const; + + /** \brief \ru Найти перпендикуляры к кривой. + \en Find perpendiculars to a curve. \~ + \details \ru Найти все перпендикуляры к кривой, которые можно провести из заданной точки. + В данной функции рассматривается кривая без продолжений. + \en Find all perpendiculars to a curve from the given point. + In this function a curve without extensions is considered. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in, out] tFind - \ru Массив параметров кривой, соответствующих точкам на кривой, через которые проходят перпендикуляры. + \en An array of parameter on a curve, corresponding to the points on a curve, which the perpendiculars are passed through. \~ + */ + virtual void PerpendicularPoint( const MbCartPoint & pnt, SArray & tFind ) const; + + /** \brief \ru Найти пересечения кривой с горизонтальной прямой. + \en Find intersections of a curve with horizontal line. \~ + \details \ru Найти пересечения кривой с горизонтальной прямой.\n + \en Find intersections of a curve with horizontal line.\n \~ + \param[in] y - \ru Ордината точек горизонтальной прямой. + \en An ordinate of points of a horizontal line. \~ + \param[in, out] cross - \ru Массив параметров кривой, соответствующих точкам пересечения. + \en An array of parameters of a curve corresponding to the intersection points. \~ + */ + virtual void IntersectHorizontal( double y, SArray & cross ) const; + + /** \brief \ru Найти пересечения кривой с вертикальной прямой. + \en Find intersections of a curve with vertical line. \~ + \details \ru Найти пересечения кривой с вертикальной прямой.\n + \en Find intersections of a curve with vertical line.\n \~ + \param[in] x - \ru Абсцисса точек вертикальной прямой. + \en An abscissa of points of a vertical line. \~ + \param[in, out] cross - \ru Массив параметров кривой, соответствующих точкам пересечения. + \en An array of parameters of a curve corresponding to the intersection points. \~ + */ + virtual void IntersectVertical ( double x, SArray & cross ) const; + + /** \brief \ru Построить изоклины. + \en Construct isoclines. \~ + \details \ru Построить прямые, проходящие под углом к оси 0X и касательные к кривой. + \en Construct lines at an angle to the axis OX and tangent to the curve. \~ + \param[in] angle - \ru Вектор, определяющий угол наклона прямой к оси OX. + \en A vector defining an inclination angle of line to the axis OX. \~ + \param[in, out] tFind - \ru Массив параметров кривой, соответствующих точкам касания. + \en An array of parameters of a curve, corresponding to the tangent points. \~ + */ + virtual void Isoclinal( const MbVector & angle, SArray & tFind ) const; + + /** \brief \ru Построить горизонтальные изоклины. + \en Construct horizontal isoclines. \~ + \details \ru Построить горизонтальные прямые, касательные к кривой. + \en Construct horizontal lines tangent to the curve. \~ + \param[in, out] tFind - \ru Массив параметров кривой, соответствующих точкам касания. + \en An array of parameters of a curve, corresponding to the tangent points. \~ + */ + void HorzIsoclinal( SArray & tFind ) const; + + /** \brief \ru Построить вертикальные изоклины. + \en Construct vertical isoclines. \~ + \details \ru Построить вертикальные прямые, касательные к кривой. + \en Construct vertical lines tangent to the curve. \~ + \param[in, out] tFind - \ru Массив параметров кривой, соответствующих точкам касания. + \en An array of parameters of a curve, corresponding to the tangent points. \~ + */ + void VertIsoclinal( SArray & tFind ) const; + + /// \ru Найти нижнюю точку кривой и соответствующий ей параметр. \en Find the lowest point of a curve and the corresponding parameter. + void LowestPoint( MbCartPoint & lowestPoint, double & tLowest ) const; + + /** \brief \ru Найти самопересечения кривой. + \en Find self-intersections of curve. \~ + \details \ru Найти точки самопересечения кривой и соответствующие им параметры. + \en Find the points of self-intersection of a curve and the corresponding parameters. \~ + \param[in, out] crossPnt - \ru Массив точек самопересечения. + \en An array of points of self-intersection. \~ + */ + virtual void SelfIntersect( SArray &, double metricEps = Math::LengthEps ) const; + + /** \brief \ru Найти особые точки эквидистантной кривой. + \en Find the special points of an offset curve. \~ + \details \ru Особыми точками эквидистантной кривой будем считать точки, в которых радиус кривизны исходной кривой + равен величине смещения эквидистантной кривой. + \en Special points of an offset curve are the points where the curvature radius of the initial curve + equals to the value of shift of an offset curve. \~ + \param[in, out] tCusps - \ru Массив параметров особых точек. + \en An array of parameters of special points. \~ + \param[in] dist - \ru Смещение эквидистантной кривой. + \en Shift of the offset curve. \~ + */ + virtual void OffsetCuspPoint( SArray & tCusps, double dist ) const; + + /** \brief \ru Провести кривую через точку. + \en Create a curve through a point. \~ + \details \ru Изменить кривую так, чтобы она проходила через заданную точку. Изменения не должны затрагивать + всю кривую. Если у кривой присутствуют какие-либо базовые объекты, связь с ними не должна потеряться при модификации. + Если построить искомую кривую невозможно, исходная кривая не изменяется, возвращается false. + \en Change a curve such that it passes through the given point. Changes should not affect + the whole curve. If the curve has any base objects, then the connection with them should not be modified. + If the curve cannot be constructed, then the initial curve will not change, false is returned. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \return \ru true, если модификация выполнена, иначе - false. + \en True - if the modification is performed, otherwise - false. \~ + */ + virtual bool GoThroughPoint( MbCartPoint & pnt ); + + /// \ru Вычислить среднюю точку кривой. \en Calculate a middle point of a curve. + virtual bool GetMiddlePoint( MbCartPoint & ) const; + /// \ru Вычислить начальную точку кривой. \en Calculate a start point of a curve. + virtual void GetStartPoint ( MbCartPoint & ) const; + /// \ru Вычислить конечную точку кривой. \en Calculate an end point of a curve. + virtual void GetEndPoint ( MbCartPoint & ) const; + /// \ru Вычислить центр кривой. \en Calculate a center of curve. + virtual bool GetCentre ( MbCartPoint & ) const; + + /** \brief \ru Дать физический радиус скривой или ноль, если это невозможно. + \en Get the physical radius of the curve or null if it impossible. \~ + \details \ru В общем случае на запрос радиуса возвращается 0. Число, отличное от 0, можно получить лишь в том случае, + если кривая является дугой окружности или эквивалентна дуге окружности. + \en In general case 0 is returned. A value different from 0 may be obtained only in a case, + when the curve is an arc of a circle or it is equivalent to an arc of a circle. \~ + \return \ru Значение радиуса, если есть, или 0.0. + \en A value of radius, if it is existed, or 0.0. \~ + */ + virtual double GetRadius () const; + + /** \brief \ru Вычислить точку для построения оси. + \en Calculate a point to construct an axis. \~ + \details \ru Вычисляет точку для построения оси, если кривая может быть построена вращением точки вокруг некоторой оси. + \en Calculates a point to construct an axis, if a curve may be constructed by rotation of a point around an axis. \~ + \return \ru true, если такая ось существует. + \en true, if such axis exists. \~ + */ + virtual bool GetAxisPoint( MbCartPoint & p ) const; + + /// \ru Определить, подобны ли кривые для объединения (слива). \en Define whether the curves are similar for the merge. + virtual bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const; + /// \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual size_t GetCount() const; + + /// \ru Выдать n точек кривой с равными интервалами по параметру. \en Get n points of a curve with equal intervals by parameter. + void GetPointsByEvenParamDelta ( size_t n, std::vector & pnts ) const; + void GetPointsByEvenParamDelta ( size_t n, SArray & pnts ) const; // Deprecated. + /// \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of a curve with equal intervals by arc length. + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; + void GetPointsByEvenLengthDelta( size_t n, SArray & pnts ) const; // Deprecated. + + /** \brief \ru Вычислить минимальную длину кривой между двумя точками на ней. + \en Calculate minimal length of a curve between two points on it. \~ + \details \ru Если кривая не замкнутая, то длина кривой между точками определяется однозначно. + Если кривая замкнута, то из двух возможных путей выбирается самый короткий. + Для замкнутой кривой можно определить желаемую часть с помощью задания контрольной точки pc. + Тогда выбирается та часть кривой, к которой ближе находится контрольная точка. + \en If a curve is not closed, then the length between points is clearly defined. + If a curve is closed, then there is chosen the shortest path from the two possible paths. + For a closed curve the desired part may be defined by the control points pc. + In this case the such part of a curve is chosen, which is closer to a control point. \~ + \param[in] p1 - \ru Первая точка. + \en The first point. \~ + \param[in] p2 - \ru Вторая точка. + \en The second point \~ + \param[in] pc - \ru Контрольная точка. + \en A control point \~ + \return \ru Длина части кривой между точками. + \en A length of a curve between points. \~ + */ + virtual double LengthBetween2Points( MbCartPoint & p1, MbCartPoint & p2, + MbCartPoint * pc = NULL ) const; + + /// \ru Вычислить центр тяжести кривой. \en Calculate the center of gravity of a curve. + virtual bool GetWeightCentre ( MbCartPoint & ) const; + + /// \ru Проверить лежит ли точка на кривой с точностью eps. \en Check whether the point is on a curve with the tolerance eps. + bool IsPointOn( const MbCartPoint &, double eps = Math::LengthEps ) const; + /// \ru Проверить лежит ли параметр в диапазоне кривой с точностью eps. \en Check whether the parameter is inside a range with the tolerance eps. + bool IsParamOn( double t, double eps = Math::paramEpsilon ) const; + + /** \brief \ru Корректировать параметр для замкнутых кривых. + \en Correct parameter for closed curves. \~ + \details \ru Если кривая замкнута, то функция загоняет параметр t в диапазон параметров кривой. + Кроме того, если параметр t отличается от одного из граничных параметров меньше, чем на eps, + он делается равным граничному параметру. + \en If the curve is closed, then the function sets the parameter t to the range of the curve. + Besides, if t differs from one of bounding parameters by a value which is less than eps, + then it becomes equal to the bounding parameter. \~ + \param[in, out] t - \ru На входе - заданное значение параметра, на выходе - скорректированное. + \en Input - given value of parameter, output - corrected value of parameter. \~ + \param[in] eps - \ru Точность попадания на край диапазона. + \en A tolerance of getting to the bound of the range. \~ + */ + void CorrectCyclicParameter( double & t, double eps = Math::paramRegion ) const; + + /** \brief \ru Корректировать параметр. + \en Correct parameter. \~ + \details \ru Функция загоняет параметр t в диапазон параметров кривой. + \en The function sets the parameter t to the range of the curve. \~ + \param[in, out] t - \ru На входе - заданное значение параметра, на выходе - скорректированное. + \en Input - given value of parameter, output - corrected value of parameter. \~ + */ + void CorrectParameter ( double & t ) const; + + /// \ru Сделать копию с измененным направлением. \en Create a copy with changed direction. + MbCurve * InverseDuplicate() const; + /// \ru Определить, являются ли кривая инверсно такой же. \en Define whether an inversed curve is the same. + bool IsInverseSame( const MbCurve & curve, double accuracy = LENGTH_EPSILON ) const; + + /** \brief \ru Определить, является ли кривая репараметризованно такой же. + \en Define whether a reparameterized curve is the same. \~ + \details \ru Определить, является ли кривая репараметризованно такой же. + \en Define whether a reparameterized curve is the same. \~ + \param[in] curve - \ru Кривая для сравнения. + \en A curve for comparison. \~ + \param[out] factor - \ru Коэффициент сжатия параметрической области при переходе + к указанной кривой. + \en Coefficient of compression of parametric region at the time of transition + to the pointed curve. \~ + */ + virtual bool IsReparamSame( const MbCurve & curve, double & factor ) const; + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить граничную точку. \n + \en Calculate the boundary point. \n \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \return \ru Вычисленная точка. + \en A calculated point. \~ + */ + MbCartPoint GetLimitPoint( ptrdiff_t number ) const; + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить граничную точку. \n + \en Calculate the boundary point. \n \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + */ + void GetLimitPoint( ptrdiff_t number, MbCartPoint & pnt ) const; + + /** \brief \ru Вычислить касательный вектор в граничной точке. + \en Calculate a tangent vector to the boundary point. \~ + \details \ru Вычислить нормализованный касательный вектор в граничной точке. + \en Calculate a normalized tangent vector to the boundary point. \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \param[in, out] v - \ru Касательный вектор. + \en Tangent vector \~ + */ + void GetLimitTangent( ptrdiff_t number, MbVector & v ) const; + + /** \brief \ru Вычислить касательный вектор и точку на конце кривой. + \en Calculate a tangent vector and point at the end of a curve. \~ + \details \ru Вычислить нормализованный касательный вектор и точку на конце кривой. + \en Calculate a normalized tangent vector and point at the end of a curve. \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + \param[in, out] v - \ru Касательный вектор. + \en Tangent vector \~ + */ + void GetLimitPointAndTangent( ptrdiff_t number, MbCartPoint & pnt, MbVector & v ) const; + + /** \brief \ru Равны ли граничные точки? + \en Are boundary points equal? \~ + \details \ru Равны ли граничные точки кривой? + \en Are curve boundary points equal? \~ + \return \ru true, если точки равны. + \en Returns true if points are equal. \~ + */ + bool AreLimitPointsEqual() const { return GetLimitPoint( 1 ) == GetLimitPoint( 2 ); } + + /** \brief \ru Вернуть характерную точку кривой. + \en Return a specific point of a curve. \~ + \details \ru Вернуть характерную точку кривой, если расстояние от нее до заданной точки from меньше, чем dmax. + Характерными точками ограниченной кривой являются начальная точка и конечная точка. + \en Return a specific point of a curve if the distance from it to the given point is less than dmax. + Specific points of a bounded curve are its start and end points. \~ + \param[in] from - \ru Контрольная точка. + \en A control point \~ + \param[in, out] dmax - \ru На входе - максимальное расстояние для поиска характерной точки. + На выходе - расстояние от точки from до найденной характерной точки. + \en Input - maximum distance for search of specific point. + Output - a distance from the point 'from' to the found specific point. \~ + \param[in, out] pnt - \ru Касательный вектор. + \en Tangent vector. \~ + \result \ru true - если характерная точка найдена. + \en True - if the specific point is found. \~ + */ + virtual bool GetSpecificPoint( const MbCartPoint & from, double & dmax, MbCartPoint & pnt ) const; + + /// \ru Вернуть базовую кривую, если есть, или себя. \en Returns the base curve if exists or itself. + virtual const MbCurve & GetBasisCurve() const; + /// \ru Вернуть базовую кривую, если есть, или себя. \en Returns the base curve if exists or itself. + virtual MbCurve & SetBasisCurve(); + /// \ru Вернуть отступ по параметру кривой. \en Return an indent by parameter of a curve. + virtual double GetParamDelta() const; + + // \ru Геометрия подложки тождественна геометрии кривой, отлична параметризация. \en The geometry of the a substrate is identical to the geometry of a curve, a parameterization differs. + + /// \ru Выдать подложку или себя. \en Get a substrate or itself. + virtual const MbCurve & GetSubstrate() const; + /// \ru Выдать подложку или себя. \en Get a substrate or itself. + virtual MbCurve & SetSubstrate(); + /// \ru Вернуть направление подложки относительно кривой или наоборот. \en Return direction of a substrate relative to a curve or vice versa. + virtual int SubstrateCurveDirection() const; + /// \ru Преобразовать параметр подложки в параметр кривой. \en Transform a substrate parameter to the curve parameter. + virtual void SubstrateToCurve( double & ) const; + /// \ru Преобразовать параметр кривой в параметр подложки. \en Transform a curve parameter to the substrate parameter. + virtual void CurveToSubstrate( double & ) const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Длина кривой вычисляется неточно, на основе аппроксимации ломаной. + Если нужна более точно вычисленная длина кривой, надо пользоваться функцией CalculateMetricLength(). + \en The length of a curve is inaccurately calculated, by approximation of polyline. + If the more accurate curve's length is required, then use the function CalculateMetricLength(). \~ + */ + virtual double GetLengthEvaluation() const; + + /// \ru Вернуть приращение параметра, соответствующее единичной длине в пространстве. \en Return increment of parameter, corresponding to the unit length in space. + virtual double GetParamToUnit() const; + /// \ru Вернуть приращение параметра, соответствующее единичной длине в пространстве в зависимости от параметра. \en Return increment of parameter, corresponding to the unit length in space according to parameter. + virtual double GetParamToUnit( double t ) const; + /// \ru Вернуть минимально различимую величину параметра с заданной точностью. \en Return the minimal discernible value of parameter with the given tolerance. + virtual double GetTEpsilon( double epsilon ) const; + /// \ru Вернуть минимально различимую величину параметра с заданной точностью в зависимости от параметра. \en Return the minimal discernible value of parameter with the given tolerance according to parameter. + virtual double GetTEpsilon( double t, double epsilon ) const; + /// \ru Вернуть минимально различимую величину параметра с заданной точностью. \en Return the minimal discernible value of parameter with the given tolerance. + virtual double GetTRegion ( double epsilon ) const; + /// \ru Вернуть минимально различимую величину параметра с заданной точностью в зависимости от параметра. \en Return the minimal discernible value of parameter with the given tolerance according to parameter. + virtual double GetTRegion ( double t, double epsilon ) const; + + /// \ru Вернуть середину параметрического диапазона кривой. \en Return the middle of parametric range of a curve. + double GetTMid() const { return ((GetTMin() + GetTMax()) * 0.5); } + /// \ru Вернуть параметрическую длину кривой. \en Return the parametric length of a curve. + double GetTRange() const { return (GetTMax() - GetTMin()); } + /// \ru Вычислить точку на кривой. \en Calculate point on the curve. + MbCartPoint PointOn ( double & t ) const; + /// \ru Вычислить первую производную. \en Calculate first derivative. + MbVector FirstDer ( double & t ) const; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + MbDirection Tangent ( double & t ) const; + /// \ru Вычислить нормальный вектор. \en Calculate the normal vector. + MbDirection Normal ( double & t ) const; + /// \ru Вычислить длину вектора производной. \en Calculate the length of derivative vector. + double DerLength( double & t ) const; + + /** \brief \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + \details \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. \n + Функция введена для оптимизации реализации функции MbCurve3D::GetCurvatureSpecialPoints, чтобы не насчитывать точки разрыва. \n + \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \n + The function was introduced to optimize the implementation of the function MbCurve3D :: GetCurvatureSpecialPoints, so as not to calculate the break points.\n \~ + \param[out] params - \ru Точки, в которых кривизна имеет разрыв. + \en The points at which the curvature has a discontinuity. \~ + */ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + /// \ru Создать собственное свойство. \en Create a custom property. + virtual MbProperty& CreateProperty( MbePrompt name ) const; + /// \ru Выдать свойства объекта. \en Get properties of the object. + virtual void GetProperties( MbProperties & properties ) = 0; + /// \ru Записать свойства объекта. \en Set properties of the object. + virtual void SetProperties( const MbProperties & properties ) = 0; + /// \ru Выдать базовые точки кривой. \en Get the basis points of the curve. + virtual void GetBasisPoints( MbControlData & ) const = 0; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ) = 0; // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \brief \ru Непрерывна ли первая производная кривой по длине и направлению? + \en Have the first derivative of the curve the continuous length and direction? + \details \ru Отсутствуют ли разрывы первой производной кривой по длине и направлению? \n + \en Are absent any discontinuities at length or at direction of first derivative of the curve? \n \~ + \param[out] contLength - \ru Непрерывность длины (да/нет). + \en The length is continuous (true/false). \~ + \param[out] contDirect - \ru Непрерывность направления (да/нет). + \en The direction of the first derivative is continuous (true/false). \~ + \param[out] params - \ru Параметры точек, в которых происходит разрыв направления. + \en The parameters of the points at which the direction break occurs. \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; + + /** \brief \ru Устранить разрывы первых производных по длине. + \en Eliminate the discontinuities of the first derivative at length. + \details \ru Устранить разрывы производных по длине. \n + \en Eliminate the discontinuities of the first derivatives of the length. \n \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); + + /** \brief \ru Определить, близки ли две кривые метрически. + \en Check whether the two curves are metrically close. \~ + \details \ru Близость кривых определяется, исходя из равенства их конечных точек + и расстояния произвольной точки одной кривой от другой кривой. + Параметрически кривые могут отличаться. + \en The proximity of curves is defined by equality of their ends + and the distance of an arbitrary point of one curve to another curve. + Curves may differ parametrically. \~ + \param[in] curve - \ru Кривая, с которой производится сравнение. + \en A curve to compare with. \~ + \param[in] eps - \ru Максимально допустимое расстояние между ближайшими точками двух кривых. + \en The maximum allowed distance between the nearest points of two curves. \~ + \param[in] ext - \ru Флаг определяет, будет ли при необходимости продолжена кривая curve. + Если ext = true, то кривая может быть продолжена. + \en A flag defines whether the curve 'curve' may be extended when necessary. + If ext = true then the curve may be extended. \~ + \param[in] devSag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + */ + bool IsSpaceNear( const MbCurve & curve, double eps, bool ext, double devSag = 5.0*Math::deviateSag ) const; + + /** \brief \ru Определить, близки ли две кривые метрически. + \en Check whether the two curves are metrically close. \~ + \details \ru Близость кривых определяется, исходя из равенства их конечных точек + и расстояния произвольной точки одной кривой от другой кривой. + Параметрически кривые могут отличаться. + \en The proximity of curves is defined by equality of their ends + and the distance of an arbitrary point of one curve to another curve. + Curves may differ parametrically. \~ + \param[in] curve - \ru Кривая, с которой производится сравнение. + \en A curve to compare with. \~ + \param[in] xEps - \ru Точность определения проекции по оси x. + \en A tolerance of detection of the projection by x axis. \~ + \param[in] yEps - \ru Точность определения проекции по оси y. + \en A tolerance of detection of the projection by y axis. \~ + \param[in] ext - \ru Флаг определяет, будет ли при необходимости продолжена кривая curve. + Если ext = true, то кривая может быть продолжена. + \en A flag defines whether the curve 'curve' may be extended when necessary. + If ext = true then the curve may be extended. \~ + \param[in] xNear - \ru Максимально допустимое расстояние между ближайшими точками двух кривых по X. + \en The maximum allowed distance along X between the nearest points of two curves. \~ + \param[in] yNear - \ru Максимально допустимое расстояние между ближайшими точками двух кривых по Y. + \en The maximum allowed distance along Y between the nearest points of two curves. \~ + \param[in] devSag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + */ + bool IsSpaceNear( const MbCurve & curve, double xEps, double yEps, bool ext, + double xNear, double yNear, + double devSag = 5.0*Math::deviateSag ) const; + + SimpleName GetCurveName() const { return name; } ///< \ru Имя кривой. \en A curve name. + void SetCurveName( SimpleName newName ) { name = newName; } ///< \ru Установить имя кривой. \en Set a curve name. + /** \} */ + + // \ru Функции унификации объекта и вектора объектов в шаблонных функциях. \en Functions for compatibility of a object and a vector of objects in template functions. + size_t size() const { return 1; } ///< \ru Количество объектов при трактовке объекта как вектора объектов. \en Number of objects if object is interpreted as vector of objects. + const MbCurve * operator [] ( size_t ) const { return this; } ///< \ru Оператор доступа. \en An access operator. + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en Declaration without implementation of the assignment operator to prevent an assignment by default + void operator = ( const MbCurve & ); + + DECLARE_PERSISTENT_CLASS( MbCurve ) + +}; // MbCurve + +IMPL_PERSISTENT_OPS( MbCurve ) + + +//------------------------------------------------------------------------------ +// \ru Вычислить точку на кривой. \en Calculate point on the curve. +// --- +inline MbCartPoint MbCurve::PointOn( double & t ) const +{ + MbCartPoint pOn; + PointOn( t, pOn ); + return pOn; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить первую производную. \en Calculate first derivative. +// --- +inline MbVector MbCurve::FirstDer( double & t ) const +{ + MbVector der; + FirstDer( t, der ); + return der; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить длину вектора производной. \en Calculate the length of derivative vector. +// --- +inline double MbCurve::DerLength( double & t ) const +{ + MbVector der; + FirstDer( t, der ); + return der.Length(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). +// --- +inline MbDirection MbCurve::Tangent( double & t ) const +{ + MbDirection tang; + Tangent( t, tang ); + return tang; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). +// --- +inline void MbCurve::Tangent( double & t, MbVector & v ) const +{ + FirstDer( t, v ); + v.Normalize(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). +// --- +inline void MbCurve::Tangent( double & t, MbDirection & tang ) const +{ + MbVector v; + FirstDer( t, v ); + tang = v; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить нормальный вектор. \en Calculate the normal vector. +// --- +inline MbDirection MbCurve::Normal( double & t ) const { + return ~Tangent( t ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить нормальный вектор. \en Calculate the normal vector. +// --- +inline void MbCurve::Normal( double & t, MbVector & v ) const +{ + Tangent( t, v ); + v.Perpendicular(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить нормальный вектор. \en Calculate the normal vector. +// --- +inline void MbCurve::Normal( double &t, MbDirection &norm ) const { + Tangent( t, norm ); + norm.Perpendicular(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). +// --- +inline void MbCurve::_Tangent( double t, MbVector & v ) const +{ + _FirstDer( t, v ); + v.Normalize(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). +// --- +inline void MbCurve::_Tangent( double t, MbDirection & tang ) const +{ + MbVector v; + _FirstDer( t, v ); + tang = v; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. +// --- +inline void MbCurve::_Normal( double t, MbVector & v ) const +{ + _FirstDer( t, v ); + v.Perpendicular(); + v.Normalize(); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. +// --- +inline void MbCurve::_Normal( double t, MbDirection & norm ) const +{ + MbVector v; + _FirstDer( t, v ); + v.Perpendicular(); + norm = v; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить лежит ли точка на кривой с точностью eps. \en Check whether the point is on a curve with the tolerance eps. +// --- +inline bool MbCurve::IsPointOn( const MbCartPoint & pOn, double eps ) const { + return DistanceToPoint( pOn ) < eps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить лежит ли параметр в диапазоне кривой с точностью eps. \en Check whether the parameter is inside a range with the tolerance eps. +// --- +inline bool MbCurve::IsParamOn( double t, double eps ) const { + return ( GetTMin() - t < eps ) && ( t - GetTMax() < eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить проекцию точки на кривую. \en Calculate the point projection to the curve. +// --- +inline void MbCurve::PointProjection( const MbCartPoint & pnt, MbCartPoint & on ) const +{ + double t = PointProjection( pnt ); + PointOn( t, on ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить точку на кривой, соответствующую проекции заданной точки на эту кривую. \en Calculate the point on the curve corresponding to the projection of the given point on this curve. +// \ru Дополнительно возвращает угол наклона касательной к оси 0X в точке проекции. \en Additionally returns an inclination angle of a tangent to the axis OX at the point of projection. +// --- +inline void MbCurve::PointProjectionAndAngle( MbCartPoint & on, double & angle ) const +{ + double t = PointProjection( on ); + PointOn( t, on ); + MbVector fd; + FirstDer( t, fd ); + angle = fd.DirectionAngle(); // \ru Угол касательной к оси 0X \en An angle of tangent to the axis OX. +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить граничную точку. \en Calculate the boundary point. +// --- +inline MbCartPoint MbCurve::GetLimitPoint( ptrdiff_t number ) const { + double t = ( number == 1 ) ? GetTMin() : GetTMax(); + + MbCartPoint pOn; + PointOn( t, pOn ); + return pOn; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить граничную точку. \en Calculate the boundary point. +// --- +inline void MbCurve::GetLimitPoint( ptrdiff_t number, MbCartPoint & pnt ) const { + double t = ( number == 1 ) ? GetTMin() : GetTMax(); + PointOn( t, pnt ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор в граничной точке. \en Calculate a tangent vector to the boundary point. +// --- +inline void MbCurve::GetLimitTangent( ptrdiff_t number, MbVector & tang ) const { + double t = ( number == 1 ) ? GetTMin() : GetTMax(); + Tangent( t, tang ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить касательный вектор и точку на конце кривой. \en Calculate a tangent vector and point at the end of a curve. +// --- +inline void MbCurve::GetLimitPointAndTangent( ptrdiff_t number, MbCartPoint & pnt, MbVector & tang ) const { + double t = ( number == 1 ) ? GetTMin() : GetTMax(); + PointOn( t, pnt ); + Tangent( t, tang ); +} + + +//------------------------------------------------------------------------------ +// \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. \en Determine whether a curve is closed regardless of the smoothness of the closure. +// --- +inline bool MbCurve::IsTouch( double eps ) const +{ + MbCartPoint p1, p2; + _PointOn( GetTMin(), p1 ); + _PointOn( GetTMax(), p2 ); + if ( c3d::EqualPoints( p1, p2, eps ) ) { + MbCartPoint p; + _PointOn( GetTMid(), p ); + double d = p1.DistanceToPoint( p2 ); + double d1 = p.DistanceToPoint( p1 ); + double d2 = p.DistanceToPoint( p2 ); + if ( d <= d1 + d2 - EXTENT_EQUAL ) + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметры ближайших точек двух кривых. + \en Calculate parameters of the nearest points of two curves. \~ + \details \ru Вычислить параметры ближайших точек двух кривых и расстояние между этими точками. + \en Calculate parameters of the nearest points of two curves and the distance between these points. \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] ext1 - \ru Признак поиска на продолжении кривой 1. + \en An attribute of search on the extension of the curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \param[in] ext2 - \ru Признак поиска на продолжении кривой 2. + \en An attribute of search on the extension of the curve 2. \~ + \param[in] xEpsilon - \ru Погрешность по X. + \en Tolerance in X direction. \~ + \param[in] yEpsilon - \ru Погрешность по Y. + \en Tolerance in Y direction. \~ + \param[out] t1 - \ru Параметр точки кривой 1. + \en A point parameter of curve 1. \~ + \param[out] t2 - \ru Параметр точки кривой 2. + \en A point parameter of curve 2. \~ + \param[out] dmin - \ru Расстояние между точками кривых. + \en The distance between points of curves. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \return \ru Возвращает nr_Success (+1) или nr_Special(0) в случае успешного определения, в случае неудачи возвращает nr_Failure(-1). + \en Return nr_Success (+1) or nr_Special(0) in a case of successful defining, return nr_Failure(-1) in a case of failure. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (MbeNewtonResult) NearestPoints( const MbCurve & curve1, bool ext1, + const MbCurve & curve2, bool ext2, + double xEpsilon, double yEpsilon, + double & t1, double & t2, double & dmin, + VERSION version = Math::DefaultMathVersion() ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Площадь и ориентация замкнутой кривой. + \en An area and orientation of a closed curve. \~ + \details \ru Вычислить площадь замкнутой кривой. + По знаку площади определяется ориентация замкнутой кривой. + Если площадь положительна, то замкнутая кривая направлена против движения часовой стрелки. \n + Если кривая не замкнута, но установлен флаг замкнутости, + то площадь будет вычислена для кривой, замкнутой отрезком, соединяющим края. + \en Calculate an area of a closed curve. + Orientation of a closed curve is defined by the sign of an area. + If the area is positive then the closed curve is directed counterclockwise. \n + If the curve is not closed, but the flag of closedness is set, + then an area will be calculated for the curve which is closed by a section connecting bounds. \~ + \param[in] curve - \ru Исходная кривая. + \en The initial curve. \~ + \param[in] sag - \ru Угловое отклонение касательной кривой в соседних точках интегрирования, используется для расчета шага по кривой. + \en An angular deviation of a tangent curve at the neighbor integration points, is it used for the calculation of the step by a curve. \~ + \param[in] close - \ru Флаг замкнутости. + \en A flag of closedness. \~ + \return \ru Площадь замкнутой кривой со знаком (ориентацией). + \en An area of closed curve with a sign (orientation). \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (double) AreaSign( const MbCurve & curve, double sag, bool close ); + + +#endif // __CURVE_H diff --git a/C3d/Include/curve3d.h b/C3d/Include/curve3d.h new file mode 100644 index 0000000..8a4fbdd --- /dev/null +++ b/C3d/Include/curve3d.h @@ -0,0 +1,1116 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кривая в трехмерном пространстве. + \en Curve in three-dimensional space.\~ + \details \ru Кривые являются представителями семейства трёхмерных геометрических объектов. + Кривые используются для построения поверхностей, а также вспомогательных элементов геометрической модели. + В геометрическом моделировании используются кривые, которыми легко управлять. + Управление осуществляется через данные, по которым построены кривые. + Кривые строятся с помощью аналитических функций, по набору точек, на базе кривых и на базе поверхностей. + \en Curves are members of a family of three-dimensional geometric objects. + Curves are used for construction of surfaces and auxiliary elements of geometric model. + In geometric modeling there are used curves which are easy to control. + Control is performed by the data which curves constructed by. + Curves are constructed using analytical functions by a set of points on the basis of curves and on the basis of surfaces. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __CURVE3D_H +#define __CURVE3D_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbSurface; +class MATH_CLASS MbPolygon3D; +class MATH_CLASS MbNurbs3D; +class MATH_CLASS MbPlacement3D; +class MbCurveIntoNurbsInfo; +struct MbNurbsParameters; + + +class MATH_CLASS MbCurve3D; +namespace c3d // namespace C3D +{ +typedef SPtr SpaceCurveSPtr; +typedef SPtr ConstSpaceCurveSPtr; + +typedef std::vector SpaceCurvesVector; +typedef std::vector ConstSpaceCurvesVector; + +typedef std::vector SpaceCurvesSPtrVector; +typedef std::vector ConstSpaceCurvesSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая в трехмерном пространстве. + \en Curve in three-dimensional space. \~ + \details \ru Кривая в пространстве представляет собой векторную функцию скалярного параметра, + принимающего значения на конечной одномерной области. + Координаты точки кривой являются однозначными непрерывными функциями параметра кривой. + Кривая представляет собой непрерывное отображение некоторого участка числовой оси в трёхмерное пространство.\n + Кривые используются для построения поверхностей. + \en A curve in space is a vector function of a scalar parameter, + which is set on a finite one-dimensional space. + Coordinates of the point are single-valued continuous functions of curve parameter. + A curve is continuous mapping from a piece of numeric axis to the three-dimensional space.\n + Curves are used to construct surfaces. \~ + \ingroup Curves_3D +*/ +// --- +class MATH_CLASS MbCurve3D : public MbSpaceItem { +protected: + SimpleName name; ///< \ru Имя кривой. \en A curve name. + +protected : + /// \ru Конструктор по умолчанию. \en Default constructor. + MbCurve3D(); + /// \ru Конструктор копирования. \en Copy-constructor. + MbCurve3D( const MbCurve3D & other ) : MbSpaceItem(), name( other.name ) {} +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbCurve3D(); + +public : + /// \ru Реализация функции, инициирующей посещение объекта. \en Implementation of a function initializing a visit of an object. + VISITING_CLASS( MbCurve3D ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента. \en A type of element. + virtual MbeSpaceType Type() const; // \ru Групповой тип элемента. \en Group element type. + virtual MbeSpaceType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента. \en Create a copy of the element. + /// \ru Сделать копию с измененным направлением. \en Create a copy with changed direction. + virtual MbCurve3D & InverseDuplicate() const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить габарит кривой в куб. \en Add a bounding box of a curve to a cube. + /// \ru Перевести все временные (mutable) данные объекта в неопределённое (исходное) состояние. \en Translate all the time (mutable) data objects in an inconsistent (initial) state. + virtual void Refresh(); + + /** \brief \ru Рассчитать временные (mutable) данные объекта. + \en Calculate temporary (mutable) data of an object. \~ + \details \ru Рассчитать временные данные объекта в зависимости от параметра forced. + Если параметр forced равен false, рассчитываются только ещё не насчитанные данные. + Если параметр forced равен true, пересчитываются все временные данные объекта. + \en Calculate the temporary data of an object depending of the "forced" parameter. + Calculate only data that was not calculated earlier if parameter "forced" is equal false. + Recalculate all temporary data of an object if parameter "forced" is equal true. + \param[in] forced - \ru Принудительный перерасчёт. + \en Forced recalculation. \~ + */ + virtual void PrepareIntegralData( const bool forced ) const; + + /// \ru Являются ли объекты идентичными в пространстве. \en Are the objects identical in space? + virtual bool IsSpaceSame( const MbSpaceItem & item, double eps = METRIC_REGION ) const; + /** \} */ + /** \ru \name Функции описания области определения кривой + \en \name Functions for curve domain description + \{ */ + /// \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual double GetTMax() const = 0; + /// \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMin() const = 0; + + /** \brief \ru Определить, является ли кривая замкнутой. + \en Define whether the curve is closed. \~ + \details \ru Определить, является ли кривая замкнутой.\n + Замкнутой считается кривая, если она циклична:\n + - начальная и конечная точка кривой совпадают,\n + - производные в начальной и конечной точке совпадают; \n + если по своей природе кривая допускает изломы (контур, ломаная), + то допускается не совпадение производных; + у кривой Безье производные должны совпадать по направлению, + но могут не совпадать по модулю. + \en Define whether the curve is closed.\n + A curve is considered as closed if it is cyclic:\n + - start point is coincident with end point,\n + - derivatives in start point and end point coincide, \n + if there are breaks at curve (in cases when a curve is contour or polyline), + then derivatives may not coincide; + in Bezier curve derivatives should coincide by direction, + but they may differ by absolute value. \~ + \return \ru true, если кривая замкнута. + \en True if a curve is closed. \~ + \ingroup Curves_3D + */ + virtual bool IsClosed() const = 0; + + /// \ru Вернуть период. Если кривая непериодическая, то 0. \en Return period. If a curve is not periodic then 0. + virtual double GetPeriod() const; + /// \ru Определить, является ли замкнутая кривая периодической. \en Define whether the curve is periodic. + virtual bool IsPeriodic() const; + + /** \brief \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. + \en Determine whether a curve is closed regardless of the smoothness of the closure. \~ + \details \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. + \en Determine whether a curve is actually closed regardless of the smoothness of the closure. \~ + */ + bool IsTouch( double eps = Math::metricPrecision ) const; + + /** \} */ + + /** \ru \name Функции для работы в области определения кривой\n + функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр + при выходе его за пределы области определения параметра. + Исключение составляет MbLine3D (прямая). + \en \name Functions for working in the curve's domain.\n + functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter + when it is out of domain bounds. + The exception is MbLine3D (line). + \{ */ + + /** \brief \ru Вычислить точку на кривой. + \en Calculate a point on the curve. \~ + \details \ru Скорректировать параметры при выходе их за пределы области определения и вычислить точку на кривой. + \en Correct parameter when getting out of domain bounds and calculate a point on the curve. \~ + \param[in] t - \ru Параметр curve. + \en Curve parameter. \~ + \param[out] p - \ru Вычисленная точка на кривой. + \en A point on the curve. \~ + \ingroup Curves_3D + */ + virtual void PointOn ( double & t, MbCartPoint3D & p ) const = 0; + /// \ru Вычислить первую производную. \en Calculate first derivative. + virtual void FirstDer ( double & t, MbVector3D & ) const = 0; + /// \ru Вычислить вторую производную. \en Calculate second derivative. + virtual void SecondDer( double & t, MbVector3D & ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const = 0; + /// \ru Вычислить касательный вектор (нормализованный). \en Calculate tangent vector (normalized). + virtual void Tangent ( double & t, MbVector3D & ) const; + /// \ru Вычислить вектор главной нормали. \en Calculate main normal vector. + virtual void Normal ( double & t, MbVector3D & ) const; + /// \ru Вычислить вектор бинормали. \en Calculate binormal vector. + virtual void BNormal ( double & t, MbVector3D & ) const; + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения кривой\n + функции _PointOn, _FirstDer, _SecondDer, _ThirdDer,... не корректируют параметр + при выходе за пределы области определения. + \en \name Functions for working inside and outside the curve's domain\n + functions _PointOn, _FirstDer, _SecondDer, _ThirdDer,... do not correct parameter + when it is out of domain bounds. + \{ */ + + /** \brief \ru Вычислить точку на кривой и её продолжении. + \en Calculate point at curve and its extension. \~ + \details \ru Вычислить точку на кривой в том числе и за пределами области определения параметрa. + \en Calculate a point on the curve including the outside area determination parameter. \~ + \param[in] t - \ru Параметр curve. + \en Curve parameter. \~ + \param[out] p - \ru Вычисленная точка на кривой. + \en A point on the curve. \~ + \ingroup Curves_3D + */ + virtual void _PointOn ( double t, MbCartPoint3D & p ) const; + /// \ru Вычислить первую производную на кривой и её продолжении. \en Calculate first derivative at curve and its extension. + virtual void _FirstDer ( double t, MbVector3D & ) const; + /// \ru Вычислить вторую производную на кривой и её продолжении. \en Calculate second derivative at curve and its extension. + virtual void _SecondDer( double t, MbVector3D & ) const; + /// \ru Вычислить третью производную на кривой и её продолжении. \en Calculate third derivative at curve and its extension. + virtual void _ThirdDer ( double t, MbVector3D & ) const; + /// \ru Вычислить касательный вектор (нормализованный) на кривой и её продолжении. \en Calculate tangent vector (normalized) at curve and its extension. + virtual void _Tangent ( double t, MbVector3D & ) const; + /// \ru Вычислить вектор главной нормали (нормализованный) на кривой и её продолжении. \en Calculate main normal vector (normalized) at curve and its extension. + virtual void _Normal ( double t, MbVector3D & ) const; + /// \ru Вычислить вектор бинормали (нормализованный) на кривой и её продолжении. \en Calculate binormal vector (normalized) at curve and its extension. + virtual void _BNormal ( double t, MbVector3D & ) const; + + /** \brief \ru Вычислить значения точки и производных для заданного параметра. + \en Calculate point and derivatives of object for given parameter. \~ + \details \ru Значения точки и производных вычисляются в пределах области определения и на расширенной кривой. + \en Values of point and derivatives are calculated on parameter area and on extended curve. \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[in] ext - \ru В пределах области определения (false), на расширенной кривой (true). + \en On parameters area (false), on extended curve (true). \~ + \param[out] pnt - \ru Точка. + \en Point. \~ + \param[out] fir - \ru Производная. + \en Derivative with respect to t. \~ + \param[out] sec - \ru Вторая производная по t, если не ноль. + \en Second derivative with respect to t, if not NULL. \~ + \param[out] thir - \ru Третья производная по t, если не ноль. + \en Third derivative with respect to t, if not NULL. \~ + \ingroup Curves_3D + */ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + /** \brief \ru Вычислить точку и производные на кривой. + \en Calculate point and derivatives on the curve. \~ + \details \ru Функция перегружена у MbSurfaceIntersectionCurve и MbSilhouetteCurve для приближённого быстрого вычисления точки и производных. + В остальных поверхностях эквивалентна функции Explore(t,false,pnt,fir,sec,NULL). + \en The function is overloaded in MbSurfaceIntersectionCurve and MbSilhouetteCurve for the fast approximated calculation of a point and derivatives. + In other surfaces it is equivalent to the function Explore(t,false,pnt,fir,sec,NULL). \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + \param[out] fir - \ru Производная. + \en Derivative with respect to t. \~ + \param[out] sec - \ru Вторая производная по t, если не ноль. + \en Second derivative with respect to t, if not NULL. \~ + \ingroup Curves_3D + */ + virtual void FastApproxExplore( double & t, MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec ) const; + /** \} */ + + /** \ru \name Функции движения по кривой + \en \name Function of moving by curve + \{ */ + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой по величине прогиба кривой. + Вычисление шага проходит с учетом радиуса кривизны. + Шаг аппроксимации кривой выбирается таким образом, + чтобы отклонение кривой от ее полигона не превышало заданную величину прогиба. + \en Calculate parameter step for the curve's approximation by its sag value. + Calculation of the step is performed with consideration of curvature radius. + A step of curve's approximation is chosen in such way, + that the deviation from its polygon does not exceed the given value of sag. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] sag - \ru Максимально допустимая величина прогиба. + \en Maximum feasible sag value. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Curves_3D + */ + virtual double Step( double t, double sag ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой по углу отклонения касательной. + Шаг аппроксимации кривой выбирается таким образом, + чтобы угловое отклонение касательной кривой в следующей точке + не превышало заданную величину ang. + \en Calculate parameter step for the curve's approximation by the deviation angle of the tangent vector. + A step of curve's approximation is chosen in such way, + that angular deviation of the tangent curve at the next point + does not exceed the given value ang. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] ang - \ru Максимально допустимый угол отклонения касательной. + \en The maximum feasible deviation angle of tangent. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Curves_3D + */ + virtual double DeviationStep( double t, double ang ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой по заданной метрической длине шага вдоль кривой. + \en Calculate the parameter step for approximation of a curve by the given metric length of a step along a curve. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] len - \ru Максимальная метрическая длина шага вдоль кривой. + \en Maximum metric length of a step along a curve. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Curves_3D + */ + virtual double MetricStep ( double t, double length ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации кривой или по угловому отклонению касательной, или по величине прогиба, или по метрической длине. + \en Calculate parameter step for the curve approximation: by diviation sngle; or by its sag value; or by the metric length. \~ + \param[in] t - \ru Параметр, определяющий точку на кривой, в которой надо вычислить шаг. + \en A parameter defining the point on a curve, at which a step should be calculated. \~ + \param[in] stepData - \ru Данные для вычисления шага. + \en Data for step calculation. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Curves_3D + */ + double CurveStep( const double & t, const MbStepData & stepData ) const; + + /** \} */ + /** \ru \name Общие функции кривой + \en \name Common function of curve. + \{ */ + /// \ru Сбросить текущее значение параметра. \en Reset the current value of parameter. + virtual void ResetTCalc() const; + /// \ru Изменить направление кривой. \en Change direction of a curve. + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; + /// \ru Вернуть базовую кривую, если есть, или себя \en Returns the base curve if exists or itself + virtual const MbCurve3D & GetBasisCurve() const; + /// \ru Вернуть базовую кривую, если есть, или себя \en Returns the base curve if exists or itself + virtual MbCurve3D & SetBasisCurve(); + /// \ru Вычислить кривизну кривой. \en Calculate curvature of curve. + virtual double Curvature( double t ) const; + /// \ru Вычислить вторую производную касательной. \en Calculate second derivative of tangent. + virtual void ThirdMetricDer( double t, MbVector3D & vect ) const; + + // \ru Построить NURBS копию кривой. \en Construct a NURBS copy of a curve. + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую заданную. По возможности, строит точную кривую, возможно с кратными узлами. + Количество узлов для NURBS определяется в зависимости от кривой. + \en Constructs a NURBS copy which approximates a given curve. If it is possible, constructs the accurate curve, perhaps with multiple knots. + The number of knots for NURBS is defined depending on the curve. \~ + \param[in] nInfo - \ru Параметры преобразования кривой в NURBS. + \en Parameters of conversion of a curve to NURBS. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo * nInfo = NULL ) const; + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую заданную в диапазоне параметров [t1, t2] с заданным направлением. + По возможности, строит точную кривую, возможно с кратными узлами. + Количеством узлов для NURBS определяется в зависимости от кривой. + \en Constructs a NURBS curve which approximates a given curve inside the range [t1, t2]. with a given direction. + If it is possible, constructs the accurate curve, perhaps with multiple knots. + The number of knots for NURBS is defined depending on the curve. \~ + \param[in] t1 - \ru Параметр, соответствующий началу аппроксимируемой части кривой. + \en Parameter corresponding to start of approximated part of a curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу аппроксимируемой части кривой. + \en Parameter corresponding to end of approximated part of a curve. \~ + \param[in] sense - \ru Совпадает ли направление возрастания параметра вдоль NURBS кривой с направлением на исходной кривой. + sense > 0 - направление совпадает. + \en Does the direction of parameter increasing along the NURBS curve coincide with direction of the initial curve. + 'sense' > 0 - direction coincide. \~ + \param[in] nInfo - \ru Параметры преобразования кривой в NURBS. + \en Parameters of conversion of a curve to NURBS. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + virtual MbNurbs3D * NurbsCurve( const MbCurveIntoNurbsInfo & nInfo ) const; + + /** \brief \ru Построить NURBS копию кривой. + \en Construct a NURBS copy of a curve. \~ + \details \ru Строит NURBS кривую, аппроксимирующую исходную с заданными параметрами. + В параметрах можно задать степень и количество узлов сплайна, диапазон изменения параметра кривой. + Если в параметрах не задан флаг точной аппроксимации, то строит NURBS без кратных узлов. + \en Constructs a NURBS curve which approximates a given curve with the given parameters. + In parameters the degree and the number of knots of a spline and the range of curve's parameters changing may be set. + If the flag of accurate approximation is not set in parameters then NURBS without multiple knots is constructed. \~ + \param[in] tParameters - \ru Параметры построения NURBS копии кривой. + \en Parameters for the construction of a NURBS copy of the curve. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + \ingroup Curves_3D + */ + virtual MbCurve3D * NurbsCurve( const MbNurbsParameters & tParameters ) const; + + /** \brief \ru Определить число узлов NURBS кривой, нужное для аппроксимации кривой с заданной точностью. + \en Define the number of knots of a NURBS curve which is required to approximate the curve with the given tolerance. \~ + \details \ru Определить число узлов NURBS кривой, нужное для аппроксимации кривой с заданной точностью. \n + \en Define the number of knots of a NURBS curve which is required to approximate the curve with the given tolerance. \n \~ + \param[in] tParameters - \ru Параметры построения NURBS копии кривой. + \en Parameters for the construction of a NURBS copy of the curve. \~ + \param[in] epsilon - \ru Точность аппроксимации. + \en The tolerance of approximation. \~ + \result \ru Построенная NURBS кривая или NULL при неуспешном построении. + \en The constructed NURBS curve or NULL in a case of failure. \~ + */ + virtual size_t NurbsCurveMinPoints( const MbNurbsParameters & tParameters, double epsilon = c3d::METRIC_DELTA ) const; + + /** \brief \ru Построить усеченную кривую. + \en Construct a trimmed curve. \~ + \details \ru Строит усеченную кривую, начало которой соответствует точке с параметром t1 и + конец - точке с параметром t2. + Можно изменить направление полученной кривой относительно исходной с помощью параметра sense. + Если кривая замкнута, можно получить усеченную кривую, проходящую через + начало кривой.\n + В случае замкнутой или периодической кривой три параметра sense, t1 и t2 однозначно + определяют результат. + В случае разомкнутой кривой параметр sense и параметрами усечения должны соответствовать друг другу:\n + 1) если sense == 1, то t1 < t2,\n + 2) если sense == -1, то t1 > t2.\n + Если есть несоответствие между sense и параметрами усечения, то + приоритетным параметром считается sense. + Если параметры t1 и t2 равны и кривая замкнута, в результате должны получить замкнутую кривую. + \en Constructs a trimmed curve, a start point of which corresponds to a point with parameter t1 and + an end point corresponds to a point with parameter t2. + Direction of the constructed curve relative to the initial curve may be changed by the parameter 'sense'. + If the curve is closed, then there may be obtained a trimmed curve, passing through + the start of a curve.\n + In a case of closed or periodic curve three parameters 'sense', t1 and t2 clearly + define the result. + In a case of unclosed curve the parameter 'sense' and parameter of trimming should correspond each other:\n + 1) if sense == 1, then t1 < t2,\n + 2) if sense == -1, then t1 > t2,\n + If there is a discrepancy between 'sense' and parameters of trimming, then + 'sense' parameter has higher priority. + If parameters t1 and t2 are equal and the curve is closed, then in result a closed curve should be obtained. \~ + \param[in] t1 - \ru Параметр, соответствующий началу усеченной кривой. + \en Parameter corresponding to start of a trimmed curve. \~ + \param[in] t2 - \ru Параметр, соответствующий концу усеченной кривой. + \en Parameter corresponding to end of a trimmed curve. \~ + \param[in] sense - \ru Направление усеченной кривой относительно исходной.\n + sense = 1 - направление кривой сохраняется. + sense = -1 - направление кривой меняется на обратное. + \en Direction of a trimmed curve in relation to an initial curve. + sense = 1 - direction does not change. + sense = -1 - direction changes to the opposite value. \~ + \result \ru Построенная усеченная кривая. + \en A constructed trimmed curve. \~ + \ingroup Curves_3D + */ + virtual MbCurve3D * Trimmed( double t1, double t2, int sense ) const; // \ru Создание усеченной кривой. \en Creation of trimmed curve. + + /// \ru Вернуть параметрическую длину кривой. \en Return the parametric length of a curve. + double GetParamLength () const { return GetTMax() - GetTMin(); } + + // \ru Функции с расчетом метрической длины перегружать все сразу, чтобы не было рассогласования \en Functions with calculation of metric length, they should be overloaded simultaneously to avoid mismatches + /// \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double GetMetricLength() const; + /// \ru Вычислить метрическую длину кривой. \en Calculate the metric length of a curve. + virtual double CalculateMetricLength() const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Вычислить метрическую длину разомкнутой кривой от параметра t1 до t2. + Должно выполнятся условие t1 < t2. + \en Calculate the metric length of unclosed curve from parameter t1 to parameter t2. + The condition t1 < t2 should satisfied. \~ + \param[in] t1 - \ru Начальный параметр отрезка кривой. + \en Start parameter of a curve section. \~ + \param[in] t2 - \ru Конечный параметр отрезка кривой. + \en End parameter of a curve section. \~ + \return \ru Длина кривой. + \en Length of a curve. \~ + \ingroup Curves_3D + */ + virtual double CalculateLength( double t1, double t2 ) const; + + /** \brief \ru Сдвинуть параметр вдоль кривой. + \en Translate parameter along the curve. \~ + \details \ru Сдвинуть параметр вдоль кривой на заданное расстояние в заданном направлении. + Новое значение параметра сохраняется в переменной t. Если кривая не замкнута и длина ее части от точки с параметром t до конца в заданном направлении + меньше, чем нужное смещение, то вычисления происходят на продолжении кривой, если можно построить продолжение. + \en Translate parameter along the curve by the given distance at the given direction. + The new value of parameter is saved in the variable t. If the curve is not closed and the length of its part from the point with parameter t to the end at the given direction + is less than the required shift, then calculations are performed on extension of the curve, if it possible to construct such extension. \~ + \param[in, out] t - \ru На входе - исходное значение параметра. На выходе - новое значение параметра. + \en Input - the initial value of parameter. Output - the new value of parameter. \~ + \param[in] len - \ru Величина смещения вдоль кривой. + \en The value of shift along the curve. \~ + \param[in] curveDir - \ru Направление смещения. Если curveDir - неотрицательно, то смещение направлено в сторону увеличения параметра. + Иначе - в сторону уменьшения параметра. + \en The offset direction. If curveDir is non-negative, then the shift is directed to the side of increasing of parameter. + Otherwise - to the side of decreasing of parameter. \~ + \param[in] eps - \ru Точность вычислений. + \en Computational tolerance. \~ + \return \ru true - если операция выполнена успешно, иначе false. + \en True - if the operation is performed successfully, otherwise false. \~ + \ingroup Curves_3D + */ + virtual bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::metricPrecision, + VERSION version = Math::DefaultMathVersion() ) const; + + /** \brief \ru Вычислить метрическую длину кривой. + \en Calculate the metric length of a curve. \~ + \details \ru Длина кривой вычисляется неточно, на основе аппроксимации ломаной. + Если нужна более точно вычисленная длина кривой, надо пользоваться функцией CalculateMetricLength(). + \en The length of a curve is inaccurately calculated, by approximation of polyline. + If the more accurate curve's length is required, then use the function CalculateMetricLength(). \~ + */ + virtual double GetLengthEvaluation() const; // \ru Оценка метрической длины кривой. \en Estimation of the metric length of a curve. + + /// \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual void CalculateGabarit( MbCube & cube ) const; + // \ru Вычислить габарит в локальной системе координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; + + /// \ru Проверить вырожденная ли кривая. \en Check whether the curve is degenerated.calculate. + virtual bool IsDegenerate( double eps = METRIC_PRECISION ) const; + /// \ru Является ли линия прямолинейной? \en Whether the line is straight? + virtual bool IsStraight () const; + /// \ru Является ли кривая плоской? \en Is a curve planar? + virtual bool IsPlanar () const; + /// \ru Являются ли стыки контура/кривой гладкими? \en Are joints of contour/curve smooth? + virtual bool IsSmoothConnected( double angleEps ) const; + /// \ru Изменить носитель. Для поверхностных кривых. \en Change the carrier. For surface curves. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); + + /** \brief \ru Изменить носитель. + \en Change the carrier. \~ + \details \ru Для поверхностных кривых. Заменяет текущий носитель item на новый, если возможно. + Трансформирует носимый элемент по заданной матрице. + \en For surface curves. Replaces the current carrier 'item' by a new one, if this is possible. + Transforms a carried element by the given matrix. \~ + \param[in] item - \ru Исходный носитель. + \en An initial carrier. \~ + \param[in] init - \ru Новый носитель. + \en A new carrier. \~ + \param[in] matr - \ru Матрица для трансформации носимого элемента. + \en A matrix for transformation of a carried element. \~ + \return \ru true - если операция выполнена успешно, иначе false. + \en True - if the operation is performed successfully, otherwise false. \~ + \ingroup Curves_3D + */ + virtual bool ChangeCarrierBorne( const MbSpaceItem & item, MbSpaceItem & init, const MbMatrix & matr ); // \ru Изменение носителя. \en Changing of carrier. + + virtual MbProperty & CreateProperty( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + /** \brief \ru Рассчитать массив точек для отрисовки. + \en Calculate an array of points for drawing. \~ + \details \ru Выдать массив отрисовочных точек с заданной стрелкой прогиба. + Если кривая представляет собой контур, то узловые точки контура дублируются. + \en Get an array of drawn points with a given sag. + If the cure is a contour then knots of a contour are duplicated. \~ + \param[in] sag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \param[in, out] poligon - \ru Полигон рассчитанных точек на кривой. + \en A polygon of calculated points on a curve. \~ + \ingroup Curves_3D + */ + virtual void CalculatePolygon( const MbStepData & stepData, MbPolygon3D & poligon ) const; // \ru Рассчитать полигон. \en Calculate a polygon. + void CalculatePolygon( double sag, MbPolygon3D & poligon ) const; // The method deprecated. It will be removed at 2018. Use CalculatePolygon( MbStepData(ist_SpaceStep,sag), poligon ); \~ + + /// \ru Выдать центр кривой. \en Give the curve center. + virtual void GetCentre ( MbCartPoint3D & c ) const; + /// \ru Выдать центр тяжести кривой. \en Give the gravity center of a curve. + virtual void GetWeightCentre( MbCartPoint3D & wc ) const; + + // \ru Проекция точки на кривую (метод Ньютона). \en Point projection on a curve (the Newton method). + /** \brief \ru Найти проекцию точки на кривую. + \en Find the point projection to the curve. \~ + \details \ru Найти проекцию точки на кривую или ее продолжение методом Ньютона по заданному начальному приближению. + \en Find the point projection to the curve or its extension by the Newton method with the given initial approximation. \~ + \param[in] p - \ru Заданная точка. + \en A given point. \~ + \param[in] iterLimit - \ru Максимальное количество итераций. + \en The maximum number of iterations. \~ + \param[out] t - \ru На входе - начальное приближение, на выходе - параметр кривой, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a curve corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \result \ru Результат выполнения итерационного метода. + \en The result of the iterative method. \~ + \ingroup Curves_3D + */ + virtual MbeNewtonResult PointProjectionNewton( const MbCartPoint3D & p, size_t iterLimit, double & t, bool ext ) const; + + // \ru Ближайшая проекция точки на кривую. \en The nearest projection of a point onto the curve. + /** \brief \ru Найти проекцию точки на кривую. + \en Find the point projection to the curve. \~ + \details \ru Найти ближайшую проекцию точки на кривую или ее продолжение по заданному начальному приближению. + Если задан диапазон изменения параметра tRange - то надо найти проекцию в заданном диапазоне. + Диапазон параметра может выходить за область определения параметра кривой. + Используется метод Ньютона. + \en Find the nearest point projection to the curve or its by the given initial approximation. + If the range of parameter changing 'tRange' is set, then find a projection in the given range. + A range of parameter may not belong to the domain of a curve. + The Newton method is used. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in,out] t - \ru На входе - начальное приближение, на выходе - параметр кривой, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a curve corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \param[in] tRange - \ru Диапазон изменения параметра, в котором надо найти решение. + \en A range of parameter changing in which the solution should be found. \~ + \result \ru true - если найдена проекция, удовлетворяющая всем входным условиям. + \en True - if there is found a projection which satisfies to all input conditions. \~ + \ingroup Curves_3D + */ + virtual bool NearPointProjection ( const MbCartPoint3D &pnt, double & t, bool ext, MbRect1D * tRange = NULL ) const; + + // \ru Изоклины кривой (метод Ньютона). \en Isoclines of a curve (Newton method). + /** \brief \ru Найти изоклины кривой. + \en Find isoclines of a curve. \~ + \details \ru Найти точку на кривой, в которой касательная параллельна некоторой плоскости, + имеющей нормаль dir. + \en Find the point on a curve where the tangent is parallel to a plane + having a normal dir. \~ + \param[in] dir - \ru Вектор, задающий плоскость. + \en A vector which defines a plane. \~ + \param[in] iterLimit - \ru Максимальное количество итераций. + \en The maximum number of iterations. \~ + \param[in,out] t - \ru На входе - начальное приближение, на выходе - параметр точки с искомой касательной. + \en Input - initial approximation, output - parameter of a point of the required tangent. \~ + \result \ru Результат выполнения итерационного метода. + \en The result of the iterative method. \~ + \ingroup Curves_3D + */ + virtual MbeNewtonResult IsoclinalNewton( const MbVector3D & dir, size_t iterLimit, double & t ) const; + + // \ru Определение точек касания изоклины. \en Defining the tangent points of isocline. + /** \brief \ru Найти все изоклины кривой. + \en Find all isoclines of a curve. \~ + \details \ru Найти точки на кривой, в которых касательная параллельна некоторой плоскости, + имеющей нормаль nor. + \en Find the points on a curve where the tangent is parallel to a plane + having a normal nor. \~ + \param[in] nor - \ru Вектор, задающий плоскость. + \en A vector which defines a plane. \~ + \param[out] tIso - \ru Массив параметров точек с искомой касательной. + \en An array of parameters of points for the required tangent. \~ + \ingroup Curves_3D + */ + virtual void GetIsoclinal ( const MbVector3D & nor, SArray & tIso ) const; + + /// \ru Вычислить ближайшее расстояние до кривой. \en Calculate the nearest distance to a curve. + virtual double DistanceToCurve( const MbCurve3D & curve2, double & t1, double & t2 ) const; + /// \ru Ближайшая точка кривой к плейсменту. \en The nearest point of a curve by the placement. + virtual double DistanceToPlace( const MbPlacement3D & place, double & t0, double & angle ) const; + + /** \brief \ru Дать физический радиус кривой или ноль, если это невозможно. + \en Get the physical radius of the curve or null if it impossible. \~ + \details \ru В общем случае на запрос радиуса возвращается 0. Число, отличное от 0, можно получить лишь в том случае, + если кривая является дугой окружности или эквивалентна дуге окружности. + \en In general case 0 is returned. A value different from 0 may be obtained only in a case, + when the curve is an arc of a circle or it is equivalent to an arc of a circle. \~ + \return \ru Значение радиуса, если есть, или 0.0. + \en A value of radius, if it is existed, or 0.0. \~ + */ + virtual double GetRadius() const; + + /** \brief \ru Дать ось окружности, геометрически совпадающей с данной кривой + \en Get an axis of a circle which is geometrically coincident to the given curve. \~ + \details \ru Дать ось окружности, геометрически совпадающей с данной кривой + \en Get an axis of a circle which is geometrically coincident to the given curve. \~ + \param[out] axis - \ru Ось с началом в центре окружности и направлением вдоль нормали плоскости окружности + \en An axis with the origin at circle's center and direction along the normal of circle's plane. \~ + */ + virtual bool GetCircleAxis( MbAxis3D & axis ) const; + + /** \brief \ru Построить плоскую проекцию некоторой части пространственной кривой. + \en Construct a planar projection of a piece of a space curve. \~ + \details \ru Построить плоскую проекцию некоторой части пространственной кривой. + \en Construct a planar projection of a piece of a space curve. \~ + \param[in] into - \ru Матрица преобразования из глобальной системы координат в видовую плоскость. + \en The transformation matrix from the global coordinate system into a plane of view. \~ + \param[in] pRegion - \ru Отображаемая часть кривой (paramRegion.x = t1, paramRegion.y = t2), по умолчанию - вся кривая. + \en A mapped piece of a curve (paramRegion.x = t1, paramRegion.y = t2), by default - the whole curve.. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + \param[in, out] coincParams - \ru Флаг совпадения параметризации исходной кривой и ее проекции \n + если coincParams != NULL, функция попытается сделать проекцию с совпадающей параметризацией \n + если в результате *coincParams = true, у проекции параметризация совпадает с параметрицацией исходной кривой. + \en A flag of coincidence between parameterization of initial curve and its projection \n + if coincParams != NULL then the function tries to create a projection with coincident parameterization \n + if *coincParams = true then parameterization of projection coincides with parameterization of initial curve. \~ + \return \ru Двумерная проекция кривой. + \en Two-dimensional projection of a curve \~ + \ingroup Curves_3D + */ + virtual MbCurve * GetMap( const MbMatrix3D & into, MbRect1D * pRegion = NULL, + VERSION version = Math::DefaultMathVersion(), bool * coincParams = NULL ) const; + + /** \brief \ru Построить плоскую проекцию некоторой части пространственной кривой. + \en Construct a planar projection of a piece of a space curve. \~ + \details \ru Построить плоскую проекцию некоторой части пространственной кривой для перспективного отображения. + \en Construct a planar projection of a piece of a space curve for the perspective visualization. \~ + \param[in] into - \ru Матрица преобразования из глобальной системы координат в видовую плоскость. + \en The transformation matrix from the global coordinate system into a plane of view. \~ + \param[in] zNear - \ru Параметр перспективного отображения, равный расстоянию точки наблюдения от видовой плоскости (отрицательный) + \en The parameter of the perspective visualization which is equal to the distance between the observation point and the plane of view (negative). \~ + \param[in] pRegion - \ru Отображаемая часть кривой (paramRegion.x = t1, paramRegion.y = t2), по умолчанию - вся кривая. + \en A mapped piece of a curve (paramRegion.x = t1, paramRegion.y = t2), by default - the whole curve.. \~ + \return \ru Двумерная проекция кривой. + \en Two-dimensional projection of a curve \~ + \ingroup Curves_3D + */ + virtual MbCurve * GetMapPsp( const MbMatrix3D & into, double zNear, + MbRect1D * pRegion = NULL ) const; + + /** \brief \ru Построить плоскую проекцию пространственной кривой на плоскость. + \en Construct a planar projection of a space curve to a plane. \~ + \details \ru Построить плоскую проекцию пространственной кривой на плоскость. \n + \en Construct a planar projection of a space curve to a plane. \n \~ + \param[in] place - \ru Плоскость. + \en A plane. \~ + \param[in] version - \ru Версия математики. + \en The version of mathematics. \~ + \return \ru Двумерная проекция кривой. + \en Two-dimensional projection of a curve \~ + \ingroup Curves_3D + */ + virtual MbCurve * GetProjection( const MbPlacement3D & place, VERSION version ) const; + + /// \ru Определить количество разбиений для прохода в операциях. \en Define the number of splittings for one passage in operations. + virtual size_t GetCount() const; + + /// \ru Выдать n точек кривой с равными интервалами по параметру. \en Get n points of a curve with equal intervals by parameter. + void GetPointsByEvenParamDelta ( size_t n, std::vector & pnts ) const; + void GetPointsByEvenParamDelta ( size_t n, SArray & pnts ) const; // Deprecated. + /// \ru Выдать n точек кривой с равными интервалами по длине дуги. \en Get n points of a curve with equal intervals by arc length. + virtual void GetPointsByEvenLengthDelta( size_t n, std::vector & pnts ) const; + void GetPointsByEvenLengthDelta( size_t n, SArray & pnts ) const; // Deprecated. + + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \brief \ru Непрерывна ли первая производная кривой по длине и направлению? + \en Have the first derivative of the curve the continuous length and direction? + \details \ru Отсутствуют ли разрывы первой производной кривой по длине и направлению? \n + \en Are absent any discontinuities at length or at direction of first derivative of the curve? \n \~ + \param[out] contLength - \ru Непрерывность длины (да/нет). + \en The length is continuous (true/false). \~ + \param[out] contDirect - \ru Непрерывность направления (да/нет). + \en The direction of the first derivative is continuous (true/false). \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = NULL, double epsilon = EPSILON ) const; + + /** \brief \ru Устранить разрывы первых производных по длине. + \en Eliminate the discontinuities of the first derivative at length. + \details \ru Устранить разрывы производных по длине. \n + \en Eliminate the discontinuities of the first derivatives of the length. \n \~ + \param[in] epsilon - \ru Погрешность вычисления. + \en The accuracy of the calculation. \~ + */ + virtual bool SetContinuousDerivativeLength( double epsilon = EPSILON ); + + /** \brief \ru Определить, близки ли две кривые метрически. + \en Check whether the two curves are metrically close. \~ + \details \ru Близость кривых определяется, исходя из равенства их конечных точек + и расстояния произвольной точки одной кривой от другой кривой. + Параметрически кривые могут отличаться. + \en The proximity of curves is defined by equality of their ends + and the distance of an arbitrary point of one curve to another curve. + Curves may differ parametrically. \~ + \param[in] curve - \ru Кривая, с которой производится сравнение. + \en A curve to compare with. \~ + \param[in] eps - \ru Максимально допустимое расстояние между ближайшими точками двух кривых. + \en The maximum allowed distance between the nearest points of two curves. \~ + \param[in] ext - \ru Флаг определяет, будет ли при необходимости продолжена кривая curve. + Если ext = true, то кривая может быть продолжена. + \en A flag defines whether the curve 'curve' may be extended when necessary. + If ext = true then the curve may be extended. \~ + \param[in] devSag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \return \ru true - если кривые метрически близки. + \en True - if curves are metrically close. \~ + \ingroup Curves_3D + */ + bool IsSpaceNear( const MbCurve3D & curve, double eps, bool ext, double devSag = 5.0*Math::deviateSag ) const; + + /// \ru Проверить, лежит ли точка на кривой. \en Check whether a point is on a curve or not. + bool IsPointOn( const MbCartPoint3D &, double eps = METRIC_PRECISION ) const; + /// \ru Вернуть середину параметрического диапазона кривой. \en Return the middle of parametric range of a curve. + double GetTMid() const { return ((GetTMin() + GetTMax()) * 0.5); } + /// \ru Вернуть параметрическую длину кривой. \en Return the parametric length of a curve. + double GetTRange() const { return (GetTMax() - GetTMin()); } + + /// \ru Вычислить точку на кривой. \en Calculate point on the curve. + MbCartPoint3D PointOn ( double & t ) const; + /// \ru Вычислить первую производную. \en Calculate first derivative. + MbVector3D FirstDer ( double & t ) const; + /// \ru Вычислить вторую производную. \en Calculate second derivative. + MbVector3D SecondDer ( double & t ) const; + /// \ru Вычислить третью производную. \en Calculate third derivative. + MbVector3D ThirdDer ( double & t ) const; + + /** \brief \ru Найти все особые точки функции кривизны кривой. + \en Find all the special points of the curvature function of the curve. \~ + \details \ru Найти все экстремумы, точки разрыва и точки перегиба функции кривизны кривой. \n + \en Find all extrema, discontinuity points and inflection points of the curvature function of the curve. \n \~ + \param[out] points - \ru Массив найденных особых точек функции кривизны.\n + Первое поле каждого элемента содержит параметр найденной точки.\n + Второе поле каждого элемента содержит значения кривизн в найденных точках.\n + Данные значения могут быть следующих видов: \n + 1) = 0.0 - точка перегиба;\n + 2) < 0.0 - значение кривизны в точке минимума;\n + 3) > 0.0 - значение кривизны в точке максимума;\n + На разрыве кривизны вставляются две точки, слева и справа от разрыва. Точка с большей кривизной \n + вставляется со знаком плюс, точка с меньшей кривизной вставляется со знаком минус.\n + \en The array of the found special points of the curvature function. \n + The first field of each element contains the parameter of the found point. \n + The second field of each element contains the curvature values at the found points. + These values can be of the following types: + 1) = 0.0 - inflection point; \ n + 2) < 0.0 - curvature value at the minimum point; \ n + 3) > 0.0 - the curvature value at the maximum point; \ n + Two points are inserted at the curvature discontinuity, to the left and to the right of the discontinuity. \n + Point with greater curvature is inserted with a plus sign, a point with a lower curvature is inserted with a minus sign. \n + \ingroup Curves_3D + */ + virtual void GetCurvatureSpecialPoints( std::vector & points ) const; + + /** \brief \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. + \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \~ + \details \ru Получить границы участков кривой, на которых сохраняется непрерывность кривизны. \n + Функция введена для оптимизации реализации функции MbCurve3D::GetCurvatureSpecialPoints, чтобы не насчитывать точки разрыва. \n + \en Get the boundaries of the sections of the curve on which the continuity of curvature is preserved. \n + The function was introduced to optimize the implementation of the function MbCurve3D::GetCurvatureSpecialPoints, so as not to calculate the break points.\n \~ + \param[out] params - \ru Точки, в которых кривизна имеет разрыв. + \en The points at which the curvature has a discontinuity. \~ + \ingroup Curves_3D + */ + virtual void GetCurvatureContinuityBounds( std::vector & params ) const; + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить граничную точку. \n + \en Calculate the boundary point. \n \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \return \ru Вычисленная точка. + \en A calculated point. \~ + \ingroup Curves_3D + */ + MbCartPoint3D GetLimitPoint( ptrdiff_t number ) const; // \ru number <= 1 : в начале, инача - в конце \en Number <= 1 : at start, otherwise - at end + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить граничную точку. \n + \en Calculate the boundary point. \n \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + \ingroup Curves_3D + */ + void GetLimitPoint( ptrdiff_t number, MbCartPoint3D & pnt ) const; + + /** \brief \ru Вычислить касательный вектор в граничной точке. + \en Calculate a tangent vector to the boundary point. \~ + \details \ru Вычислить нормализованный касательный вектор в граничной точке. + \en Calculate a normalized tangent vector to the boundary point. \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \return \ru Касательный вектор. + \en Tangent vector. \~ + */ + MbVector3D GetLimitTangent( ptrdiff_t number ) const; + + /** \brief \ru Вычислить касательный вектор в граничной точке. + \en Calculate a tangent vector to the boundary point. \~ + \details \ru Вычислить нормализованный касательный вектор в граничной точке. + \en Calculate a normalized tangent vector to the boundary point. \~ + \param[in] number - \ru Номер граничной точки. Значение 1 соответствует начальной точке кривой, 2 - конечной. + \en A number of a boundary point. The value 1 corresponds to the start point of a curve, 2 - to the end point. \~ + \param[in, out] v - \ru Касательный вектор. + \en Tangent vector. \~ + */ + void GetLimitTangent( ptrdiff_t number, MbVector3D & v ) const; + + /** \brief \ru Равны ли граничные точки. + \en Are boundary points equal? \~ + \details \ru Равны ли граничные точки кривой. + \en Are curve boundary points equal? \~ + \return \ru true, если точки равны. + \en Returns true if points are equal. \~ + */ + bool AreLimitPointsEqual() const { return GetLimitPoint( 1 ) == GetLimitPoint( 2 ); } + + /// \ru Загнать в параметрическую область. \en Move to the parametric region. + bool SetInParamRegion( double & t ) const; + /// \ru Проверить, что параметр в диапазоне кривой. \en Check whether a parameter is in the range of the curve. + bool IsParamOn( double t, double eps ) const { return ( GetTMin()-eps<=t && t<=GetTMax()+eps ); } + /// \ru Являются ли кривая инверсно такой же? \en Whether an inversed curve is the same. + bool IsInverseSame( const MbCurve3D & curve, double accuracy = LENGTH_EPSILON ) const; + + /** \brief \ru Определить, является ли кривая репараметризованно такой же. + \en Define whether a reparameterized curve is the same. \~ + \details \ru Определить, является ли кривая репараметризованно такой же. + \en Define whether a reparameterized curve is the same. \~ + \param[in] curve - \ru Кривая для сравнения. + \en A curve for comparison. \~ + \param[out] factor - \ru Коэффициент сжатия параметрической области при переходе + к указанной кривой. + \en Coefficient of compression of parametric region at the time of transition + to the pointed curve. \~ + */ + virtual bool IsReparamSame( const MbCurve3D & curve, double & factor ) const; + + /// \ru Дать приращение параметра, осреднённо соответствующее единичной длине в пространстве. \en Get increment of parameter, corresponding to the unit length in space. + virtual double GetParamToUnit() const; + /// \ru Дать приращение параметра, соответствующее единичной длине в пространстве. \en Get increment of parameter, corresponding to the unit length in space. + virtual double GetParamToUnit( double t ) const; + /// \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + double GetTEpsilon() const; + /// \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + double GetTEpsilon( double t ) const; + /// \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + double GetTRegion() const; + /// \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + double GetTRegion( double t ) const; + + // \ru Геометрия подложки тождественна геометрии кривой, но отлична параметризация. \en The geometry of the a substrate is identical to the geometry of a curve, but parameterization differs. + /// \ru Выдать подложку или себя. \en Get a substrate or itself. + virtual const MbCurve3D & GetSubstrate() const; + /// \ru Выдать подложку или себя. \en Get a substrate or itself. + virtual MbCurve3D & SetSubstrate(); + /// \ru Направление подложки относительно кривой или наоборот. \en Direction of a substrate relative to a curve or vice versa. + virtual int SubstrateCurveDirection() const; + /// \ru Преобразовать параметр подложки в параметр кривой. \en Transform a substrate parameter to the curve parameter. + virtual void SubstrateToCurve( double & ) const; + /// \ru Преобразовать параметр кривой в параметр подложки. \en Transform a curve parameter to the substrate parameter. + virtual void CurveToSubstrate( double & ) const; + + /// \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get planar curve and placement if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + virtual bool GetPlaneCurve( MbCurve *& curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get planar curve and placement if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + bool GetPlaneCurve( SPtr & curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать плоскую кривую и плейсмент, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерную кривую). \en Get planar curve and placement if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + bool GetPlaneCurve( SPtr & curve2d, MbPlacement3D & place, bool saveParams, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get surface curve if the space curve is surface (after the using call DeleteItem for arguments) + virtual bool GetSurfaceCurve( MbCurve *& curve2d, MbSurface *& surface, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get surface curve if the space curve is surface (after the using call DeleteItem for arguments) + bool GetSurfaceCurve( SPtr & curve2d, SPtr & surface, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Дать поверхностную кривую, если пространственная кривая поверхностная (после использования вызывать DeleteItem на аргументы). \en Get surface curve if the space curve is surface (after the using call DeleteItem for arguments) + bool GetSurfaceCurve( SPtr & curve2d, SPtr & surface, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Заполнить плейсемент, если кривая плоская. \en Fill the placement if a curve is planar. + virtual bool GetPlacement( MbPlacement3D & place, VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Является ли объект смещением. \en Is the object is a shift? + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + /// \ru Подобные ли кривые для объединения (слива). \en Whether the curves to union (joining) are similar. + virtual bool IsSimilarToCurve( const MbCurve3D & other, double precision = METRIC_PRECISION ) const; + /// \ru Аппроксимация кривой плоскогранной трубкой радиуса radius. \en Approximation of a curve by the flat tube with the given radius. + void CalculateGrid( double radius, const MbStepData & stepData, MbMesh & mesh ) const; + + SimpleName GetCurveName() const { return name; } ///< \ru Имя кривой. \en A curve name. + void SetCurveName( SimpleName newName ) { name = newName; } ///< \ru Установить имя кривой. \en Set a curve name. + /** \} */ + + // \ru Функции унификации кривой и вектора кривых в шаблонных функциях. \en Functions for compatibility of a curve and a vector of curves in template functions. + size_t size() const { return 1; } ///< \ru Размер кривой трактуемой как в виде вектора кривых. \en Size of curve interpreted as vector of curves. + const MbCurve3D * operator [] ( size_t ) const { return this; } ///< \ru Оператор доступа. \en An access operator. + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en Declaration without implementation of the assignment operator to prevent an assignment by default + MbCurve3D & operator = ( const MbCurve3D & ); + + DECLARE_PERSISTENT_CLASS( MbCurve3D ) +}; + +IMPL_PERSISTENT_OPS( MbCurve3D ) + + +//------------------------------------------------------------------------------ +// \ru Определить, замкнута ли кривая фактически независимо от гладкости замыкания. \en Determine whether a curve is closed regardless of the smoothness of the closure. +// --- +inline bool MbCurve3D::IsTouch( double eps ) const +{ + MbCartPoint3D p1, p2; + _PointOn( GetTMin(), p1 ); + _PointOn( GetTMax(), p2 ); + if ( c3d::EqualPoints( p1, p2, eps ) ) { + MbCartPoint3D p; + _PointOn( GetTMid(), p ); + double d = p1.DistanceToPoint( p2 ); + double d1 = p.DistanceToPoint( p1 ); + double d2 = p.DistanceToPoint( p2 ); + if ( d <= d1 + d2 - EXTENT_EQUAL ) + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметры ближайших точек двух кривых. + \en Calculate parameters of the nearest points of two curves. \~ + \details \ru Вычислить параметры ближайших точек двух кривых и расстояние между этими точками. \n + \en Calculate parameters of the nearest points of two curves and the distance between these points. \n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] ext1 - \ru Признак поиска на продолжении кривой 1. + \en An attribute of search on the extension of the curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \param[in] ext2 - \ru Признак поиска на продолжении кривой 2. + \en An attribute of search on the extension of the curve 2. \~ + \param[in] t1 - \ru Параметр точки кривой 1. + \en A point parameter of curve 1. \~ + \param[in] t2 - \ru Параметр точки кривой 2. + \en A point parameter of curve 2. \~ + \param[in] dmin - \ru Расстояние между точками кривых. + \en The distance between points of curves. \~ + \return \ru Возвращает nr_Success (+1) или nr_Special(0) в случае успешного определения, в случае неудачи возвращает nr_Failure(-1). + \en Return nr_Success (+1) or nr_Special(0) in a case of successful defining, return nr_Failure(-1) in a case of failure. \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (MbeNewtonResult) NearestPoints( const MbCurve3D & curve1, bool ext1, // \ru Признак поиска на продолжении объекта \en An attribute of search at the extension of an object. + const MbCurve3D & curve2, bool ext2, // \ru Признак поиска на продолжении объекта \en An attribute of search at the extension of an object. + double & t1, double & t2, double & dmin ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Oпределение параметров ближайших точек кривых. + \en Definition of parameters of the nearest points of curves. \~ + \details \ru Итерационное определение параметров ближайших точек кривых + путём решения уравнений методом Ньютона при заданных начальных приближениях. + Если кривые пересекаются и начальные приближения близки к точке пересечения, + то будут найдены параметры точки пересечения. \n + Если в области начальных приближений параметров кривые не пересекаются, + то будут найдены параметры точек кривых, касательные в которых ортогональны отрезку, + соединяющему найденные точки. \n + \en Iterative definition of parameters of the nearest points of curves + by solving an equation by the Newton method with given initial approximations. + If curves intersect and initial approximations are close to the intersection point, + then parameters of the intersection point will be found. \n + If curves do not intersect in the region of initial approximations, + then there will be found parameters of curves points where tangents to the curves are orthogonal to the segment + which connects the found points. \n \~ + \param[in] curve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] ext1 - \ru Признак поиска на продолжении кривой 1. + \en An attribute of search on the extension of the curve 1. \~ + \param[in] curve2 - \ru Кривая 2. + \en Curve 2. \~ + \param[in] ext2 - \ru Признак поиска на продолжении кривой 2. + \en An attribute of search on the extension of the curve 2. \~ + \param[in] funcEpsilon - \ru Максимальная погрешность расстояния между точками пересечения кривых. + \en The minimal tolerance of the distance between curves intersection points. \~ + \param[in] iterLimit - \ru Максимальное число итераций. + \en The maximum number of iterations. \~ + \param[in, out] t1 - \ru Параметр кривой 1 для точки пересечения (начальное приближение на входе). + \en Parameter of the curve 1 for the intersection point (the initial approximation at input). \~ + \param[in, out] t2 - \ru Параметр кривой 2 для точки пересечения (начальное приближение на входе). + \en Parameter of the curve 2 for the intersection point (the initial approximation at input). \~ + \return \ru Код ошибки: случае успешного определения nr_Success (+1), nr_Special(0) или nr_Failure(-1) - в случае неудачи. + \en Error code: in a case of successful defining nr_Success (+1), nr_Special(0) or nr_Failure(-1) - in a case of failure. \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (MbeNewtonResult) CurveCrossNewton( const MbCurve3D & curve1, bool ext1, + const MbCurve3D & curve2, bool ext2, + double funcEpsilon, size_t iterLimit, + double & t1, double & t2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить точки полигона кривой в общем случае. + \en Calculate polygon points of curve. \~ + \details \ru Вычислить точки полигона кривой в общем случае. \n + \en Calculate polygon points of curve. \n \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[in] sag - \ru Максимальная величина прогиба. + \en Maximal value of sag. \~ + \param[out] paramPoints - \ru Массив параметров и точек. + \en Array of parameters and points. \~ + \ingroup Curves_3D +*/ +// --- +MATH_FUNC (void) CalculatePolygon( const MbCurve3D & curve, const MbStepData & stepData, std::vector< std::pair > & paramPoints ); +DEPRECATE_DECLARE MATH_FUNC (void) CalculatePolygon( const MbCurve3D & curve, double sag, std::vector< std::pair > & paramPoints ); // The method deprecated. It will be removed at 2018. Use ::CalculatePolygon( curve, MbStepData(ist_SpaceStep,sag), paramPoints ); \~ + + +#endif // __CURVE3D_H diff --git a/C3d/Include/dxf_converter.h b/C3d/Include/dxf_converter.h new file mode 100644 index 0000000..7f16a81 --- /dev/null +++ b/C3d/Include/dxf_converter.h @@ -0,0 +1,463 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru DXF - конвертер. + \en DXF - converter. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __DXF_CONVERTER_H +#define __DXF_CONVERTER_H + +#include +#include +#include +#include +#include + + +class IConvertorProperty3D; +class IProgressIndicator; +class ColorProperties; +class ItModelInstanceProperties; +class ItModelDocument; +class ItModelInstance; +class DXFConverter; +class DXFCompositeRef; +class MbGrid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Уникальный (в пределах документа) идентификатор объекта. + \en Unique (in the document) object identifier. \~ + \ingroup DXF_Exchange +*/ +class CONV_CLASS DXFHandle { + +private: + int64 thisId; ///< \ru Уникальное 64-битное число, соответствующее модельному объекту. \en Unique 64-bit number corresponding to the model object. + +public: + DXFHandle ( ); + DXFHandle ( int64 & id ); + DXFHandle ( const unsigned char id[8] ); + ~DXFHandle(); + + const DXFHandle & operator = ( const DXFHandle & id ); + + bool IsDefined() const { return thisId != -1 ; } + + // \ru операторы сравнения \en compare operators + friend bool operator > ( const DXFHandle & left, const DXFHandle & right ); + friend bool operator == ( const DXFHandle & left, const DXFHandle & right ); +}; + + +//------------------------------------------------------------------------------ +/// \ru Сравнение thisId. \en Comparison of thisId. +//--- +inline +bool operator > ( const DXFHandle & left, const DXFHandle & right ) { + return left.thisId > right.thisId; +} + + +//------------------------------------------------------------------------------ +/// \ru Равенство thisId. \en Equality of thisId. +//--- +inline +bool operator ==( const DXFHandle & left, const DXFHandle & right ) { + return left.IsDefined() && right.IsDefined() && left.thisId == right.thisId; +} + + +/** + \addtogroup DXF_Exchange + \{ +*/ + + +//------------------------------------------------------------------------------ +// \ru Тело. \en A solid. +//--- +class CONV_CLASS DXFSolidBody { +private: + MbPlacement3D placement; ///< \ru Локальная система координат. \en Local coordinate system. + std::vector > solids; ///< \ru Тела. \en Solids. + std::vector< SPtr > faces; ///< \ru Грани. \en Faces. + +public: + DXFSolidBody( MbPlacement3D & placement ); + DXFSolidBody( const DXFSolidBody &); + ~DXFSolidBody(); + +public: + bool IsEmpty () const; + + bool IsSingle () const; + MbPlacement3D GetPlacement() const; + + void MakePlacementIdentical( const MbPlacement3D& ownComponentLocation = MbPlacement3D::global ); + void FillSolids ( std::vector > & solids ) const; + void Flush (); + void AddSolids ( const std::vector > & mSolids ); + void AddFaces ( const std::vector< SPtr > & mFaces ); + void SetPlacement ( const MbPlacement3D & place ); + + size_t GetSolidsCount() const { return solids.size(); } + void GetSolids ( std::vector > & mSolids ) const; + + size_t GetFacesCount () const { return faces.size(); } + void GetFaces ( std::vector< SPtr > & mFaces ) const; +private: + //DXFSolidBody ( const DXFSolidBody & ); // \ru не реализовано \en not implemented + DXFSolidBody & operator = ( const DXFSolidBody & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +// +// --- +inline +void DXFSolidBody::SetPlacement( const MbPlacement3D & place ) { + placement = place; +} + + +//------------------------------------------------------------------------------ +// \ru Поверхность. \en The surface. +//--- +class CONV_CLASS DXFSurfaceBody { +private: + MbPlacement3D placement; ///< \ru Локальная система координат. \en Local coordinate system. + std::vector< SRef > faces; ///< \ru Грани. \en Faces. + SPtr mesh; + +public: + DXFSurfaceBody(); + DXFSurfaceBody( MbPlacement3D & placement ); + ~DXFSurfaceBody(); + +public: + bool IsEmpty () const; + bool IsSingle () const; + MbPlacement3D GetPlacement() const; + + void Flush(); + void AddFace ( MbFace & face ); + void AddGrid ( MbGrid & grid ); + void AddFaces( const std::vector< SPtr > & mFaces ); + + size_t GetFacesCount() const { return faces.size(); } + +private: + void FillFaces( RPArray & faces ) const; + void GetFaces( std::vector< SPtr > & mFaces ) const; +public: + + SPtr GetMesh(); + + std::vector > GenerateItems( bool stitch ); + +private: + + + DXFSurfaceBody ( const DXFSurfaceBody & ); // \ru не реализовано \en not implemented + DXFSurfaceBody & operator = ( const DXFSurfaceBody & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойства блока. + \en Block properties. \~ +\ingroup DXF_Exchange +*/ +class CONV_CLASS DXFCompositeData { +private: + DXFHandle thisId; ///< \ru Идентификатор блока. \en Block identifier. + MbVector3D m_scalesId; ///< \ru Масштабы блока по осям координат, (нужны только для идентификация блока с thisId); связано с отказом от использования левых плейсментов в подсборках (err. 56646). \en Block scales by coordinate axes, (they are necessary only for the identification of the block with thisId); this is related with the decision not to use left placements in subassemblies (err. 56646). 56646). + c3d::string_t name; ///< \ru Имя блока. \en Block name. + MbVector3D scales; ///< \ru Масштабы блока по осям координат (нужны при создании сборки). \en Scales of block by coordinate axes (they are necessary for assembly creation). + + MbMatrix3D m_TranslateRotate; ///< \ru Преобразование блока для текущей вставки блока, но без учета масштабных коэффициентов самой вставки блока. \en Transformation of a block for the current block insertion without taking into account the scale factors of this block insertion. + MbMatrix3D m_sumTransform; ///< \ru Преобразование всех внешних блоков. \en Transformation of all external blocks. + +public: + DXFCompositeData(); + DXFCompositeData( const DXFHandle & chandle, const TCHAR * cname ); + DXFCompositeData( const DXFHandle & chandle, const TCHAR * cname, + const MbVector3D &, + const MbMatrix3D & tr, + const MbMatrix3D & sumTr ); + // DXFCompositeData( const TCHAR * cname ); + DXFCompositeData( const DXFCompositeData & cname ); + ~DXFCompositeData(); + +public: + const TCHAR * GetName() const { return name.c_str(); } + std::string Name() const { return c3d::ToSTDstring( name ); } + c3d::string_t NamePath() const { return c3d::string_t( name.c_str() ); } + const DXFHandle & ThisId () const { return thisId; } + const MbVector3D & Scales () const { return scales; } + MbVector3D & Scales () { return scales; } + size_t NameLength() const { return name.length(); } + MbVector3D & ScalesId() { return m_scalesId; } + MbVector3D GetScalesId()const { return m_scalesId; } + const MbMatrix3D & GetTranslateRotate() const { return m_TranslateRotate; } + const MbMatrix3D & GetSumTransform () const { return m_sumTransform; } + + /// \ru Cравнение с другими данными. \en Comparison with other data. + bool operator == ( const DXFCompositeData & ) const ; + + DXFCompositeData & operator=( const DXFCompositeData & ) { C3D_ASSERT_UNCONDITIONAL( false ); return *this; } +}; + + +//------------------------------------------------------------------------------ +/// \ru Cравнение с другими данными по thisId. \en Comparison with other data by thisId. +//---- +inline +bool DXFCompositeData::operator == ( const DXFCompositeData & comp ) const { + // \ru для различения блока используется идентификационный номер и масштабный коэффициент \en an identification number and a scale factor are used to distinguish the block + return thisId == comp.thisId && m_scalesId == comp.m_scalesId; + // return thisId == comp.thisId && scales == comp.scales; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +/** + \ingroup DXF_Exchange + */ +// +/////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Блок \en Block +//--- +class CONV_CLASS DXFComposite : public MbRefItem { +private: + PArray composites; ///< \ru Составляющие. \en Components. + PArray solid_bodies; ///< \ru Тела. \en Solids. + std::vector< SPtr > space_curves; ///< \ru Кривые. \en Curves. + DXFSurfaceBody surface_body; ///< \ru Поверхностное тело. \en Surface solid. + DXFCompositeData data; ///< \ru Данные для слива блока. \en Data of the block for union. + SPtr insert; ///< \ru Готовая вставка блока в модельный документ. \en Prepared insert of the block to the model document. + +public: + DXFComposite(); + DXFComposite( const DXFCompositeData & data ); + ~DXFComposite(); + +public: + bool IsEmpty () const; + void Complete ( DXFConverter & converter ); + void AddComposite ( DXFCompositeRef * composite ); + ptrdiff_t GetObjectsCount (); + void FlushSolidBodies (); + + void AddFace ( MbFace & m_face ); + void AddGrid ( MbGrid & m_grid ); + void AddSpaceCurve ( MbCurve3D & space_curves ); + void AddSolidBody ( MbPlacement3D & placement, const std::vector > & m_solids, + const std::vector< SPtr > & m_faces ); + + size_t GetSolidBodiesCount() const { return solid_bodies.Count(); } + const DXFSolidBody * GetSolidBody( size_t k ) const { return ((k < solid_bodies.Count()) ? solid_bodies[k] : NULL); } + DXFSolidBody * SetSolidBody( size_t k ) { return ((k < solid_bodies.Count()) ? solid_bodies[k] : NULL); } + + const DXFCompositeData & GetData() const { return data;} + + bool SetToModel( const MbPlacement3D & where, + ItModelInstance & instance ); + /// \ru Высвободить и обнулить вставку. \en Free the insert and set it to null. + void ReleaseInsert(); + + /// \ru Добавить геометрию (solid_bodies и surface_body) из ob. \en Add to geometry (solid_bodies and surface_body) from ob. + void AddGeometryFrom( const DXFComposite & ob ); +private: + friend class DXFConverter; + friend class DXFCompositeRef; + void CompleteDocument ( ItModelDocument & model_document, DXFConverter & converter ); + void CompleteInstance ( ItModelInstance & model_instance, DXFConverter & converter, + MbPlacement3D * place, MbVector3D & scales ); + + void CompleteComponent( const MbPlacement3D & place, + ItModelInstance & model_instance, + DXFConverter & converter, const MbVector3D& scalesBase ); + + DXFComposite * FindObj( const DXFCompositeData & ); + void CheckPlacementsByGabarits( MbPlacement3D & ); + + void CheckIdenticalBaserSurfaces(); // Контроль одинаковых поверхностей в гранях. + void CollectOwnItems( std::vector >& ownItems ); // Собрать собственные элементы комопнента +private: + DXFComposite ( const DXFComposite & ); // \ru не реализовано \en not implemented + DXFComposite & operator = ( const DXFComposite & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +// \ru Ссылка на блок \en Reference to a block +//--- +class CONV_CLASS DXFCompositeRef { +private: + MbPlacement3D place; ///< \ru Локальная система координат. \en Local coordinate system. + DXFComposite * composite; ///< \ru Блок. \en Block. +public: + DXFCompositeRef ( ); + DXFCompositeRef ( DXFComposite & composite , const MbPlacement3D & cplace ); + DXFCompositeRef ( DXFComposite & composite ); + ~DXFCompositeRef( ); + + /// \ru Заполнить документ модели. \en Fill the model document. + void CompleteInstance ( ItModelInstance & model_instance, + DXFConverter & converter, + MbVector3D & overallScales ); + /// \ru Создать документ \en Create a document + void CompleteDocument ( ItModelDocument & model_document, DXFConverter & converter ); + + const MbPlacement3D & GetPlacement() const { return place; } + void SetPlacement( const MbPlacement3D & pl ) { place = pl; } + DXFComposite * operator->() { return composite; } + DXFComposite * operator* () { return composite; } + + /// \ru Для явной записи. \en For explicit record. + DXFComposite * GetComposite() const { return composite; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru DXF-конвертер. + \en DXF - converter. \~ +*/ +class CONV_CLASS DXFConverter { +private: + PArray composites; ///< \ru Составляющие блок подблоки, тела, поверхности. \en Subblocks, solids, surfaces forming the block. + DXFCompositeRef * model_space; ///< \ru Корневой блок. \en Root block. + PArraySort readComposites; ///< \ru Идентификаторы прочтенных блоков. \en Identifiers of read blocks. + IConvertorProperty3D * property; ///< \ru Свойства конвертера. \en Converter properties. + int stitch; ///< \ru Нет информации. \en No information. + double factor; ///< \ru Нет информации. \en No information. + IProgressIndicator * indicator; ///< \ru Индикатор хода процесса преобразования. \en Transformation progress indicator. + ptrdiff_t indicator_delta; ///< \ru Приращение индикатора на одну условную операцию. \en Increment of the indicator by one unit operation. + ptrdiff_t indicator_count; ///< \ru Значение счётчика индикатора. \en Value of the indicator counter. + +#ifdef C3D_DEBUG + uint32 prev_mili_sec; + uint32 current_mili_sec; + uint32 delta_mili_sec; +#endif // C3D_DEBUG + +public: + DXFConverter(); + ~DXFConverter(); + + /// \ru Задать признак сшивки. \en Set a flag of stitching. + void SetStitch ( bool stitch ); + /// \ru Получить признак сшивки. \en Get flag of stitching. + bool IsStitch () const; + /// \ru Задать значение множителя. \en Set a value of multiplier. + void SetFactor ( double factor ); + /// \ru Получить значение множителя. \en Get value of multiplier. + double GetFactor () const; + /// \ru Задать свойства конвертера. \en Specify converter properties. + void SetProperty ( IConvertorProperty3D * property ); + /// \ru Получить свойства конвертера. \en Get converter properties. + IConvertorProperty3D * GetProperty (); + /// \ru Инициировать пустой блок. \en Initialize an empty block. + void BeginComposite (); + /**\brief \ru Инициировать блок с данными. + \en Initialize block with data. \~ + \param[in] matr - \ru Матрица, преобразующая данные блока к СК объемлющего блока. + \en Matrix transforming block data to coordinate system of the enclosing block. \~ + \param[in] data - \ru Данные самого блока. + \en Data of the block. \~ + */ + bool BeginComposite ( MbMatrix3D &matr, const DXFCompositeData & data ); + + /** \brief \ru Завершить создание составного элемента. + \en Complete creation of a composite element. \~ + \details \ru Если у последнего составного элемента:\n + - нет идентификатора;\n + - внутри нет вставок,\n + то это признак того, что этот блок создан только для сшивки геометрии. + В этом случае последний блок объединяется с предпоследним: + в предпоследний переносится геометрия, последний удаляется. + \en If the last composite element has:\n + - no identifier;\n + - no inserts,\n + then it is a creterion that the block is created only for stitching the geometry. + In this case the last block is united with the last but one: + the geometry is moved to the last but one, the last one is deleted. \~ + */ + bool EndComposite (); + /// \ru Очистить конвертер. \en Clear the converter. + void Reset (); + /// \ru Отобразить текующее состояние хода операции. \en Show the current state of operation progress. + bool Indicate ( ptrdiff_t count ); + + /** \brief \ru Завершить создание документа. + \en Complete the document creation. \~ + */ + void CompleteDocument ( ItModelDocument & model_document, + IProgressIndicator * indicator = NULL ); + + /// \ru Отобразить текующее состояние хода операции. \en Show the current state of operation progress. + void ConvertLastComposite( uint32 defaultColor ); + + /// \ru Добавить модельную грань. \en Add the model face. + void AddFace ( MbFace & m_face ); + + /// \ru Добавить модельную грань. \en Add the model face. + void AddGrid ( MbGrid & m_grid ); + + /**\brief \ru Добавить тело. + \en Add a solid. \~ + \param[in] placement - \ru Положение тела в ЛСК. + \en Position of the solid in LCS. \~ + \param[in] model_solids - \ru Модельные тела. + \en Model solids. \~ + \param[in] model_faces - \ru Модельные грани. + \en Model solids. \~ + */ + void AddSolidBody ( MbPlacement3D & placement, + const std::vector > & m_solids, + const std::vector< SPtr > & m_faces ); + /// \ru Добавить пространственную кривую. \en Add a spatial curves. + void AddSpaceCurve ( MbCurve3D & spaceCurve ); + /// \ru Удалить значение из списка прочитанных идентификатров. \en Delete a value from the list of read identifiers. + void RemoveData ( const DXFCompositeData & data ); + +private: + /**\brief \ru Cоздать модельные грани по свойствам старых модельных тел. + \en Create model faces from properties of old model solids. \~ + \param[in] solids - \ru Положение тела в ЛСК. + \en Position of the solid in LCS. \~ + \param[in] stitchedSolids - \ru Модельные тела. + \en Model solids. \~ + \param[in] defaultColor - \ru Цвет по умолчанию. + \en Default color. \~ + \param[in] model_faces - \ru Модельные грани. + \en Model solids. \~ + */ + void CreateModelFacesFromOldSolids( const std::vector > & solids, + const std::vector< SPtr > & stitchedSolids, + uint32 defaultColor, + std::vector< SPtr > & modelFaces ) ; + private: + DXFConverter ( const DXFConverter & ); // \ru не реализовано \en not implemented + DXFConverter & operator = ( const DXFConverter & ); // \ru не реализовано \en not implemented + +}; + + +/** \} */ + + +#endif // __DXF_CONVERTER_H \ No newline at end of file diff --git a/C3d/Include/dxf_data.h b/C3d/Include/dxf_data.h new file mode 100644 index 0000000..3f5f03d --- /dev/null +++ b/C3d/Include/dxf_data.h @@ -0,0 +1,339 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru DXF - конвертер. + \en DXF - converter. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __DXF_DATA_H +#define __DXF_DATA_H + +#include +#include +#include +#include +#include +#include +#include + + +class MbCartPoint; +class MbCurve; +class MbCartPoint3D; +class MbVector3D; +class MbPlacement3D; +class MbCurve3D; +class MbSolid; +class MbFace; +class MbGrid; +class DXFConverter; + + +//------------------------------------------------------------------------------ +/** \brief \ru Объект формата DXF. + \en Object of DXF format. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFEntity { +protected: + MbAttributeContainer attributes; ///< \ru Атрибуты. \en Attributes. + +protected: + // \ru Конструктор. \en Constructor. + DXFEntity(); + // \ru Деструктор. \en Destructor. + virtual ~DXFEntity(); + +public: + /// \ru Установить цветовые атрибуты. \en Set color attributes. + void SetAttributes( MbAttributeContainer & attribs ); + virtual bool Convert ( DXFConverter & converter ) = 0; + +private: + DXFEntity ( const DXFEntity & ); // \ru не реализовано \en not implemented + DXFEntity & operator = ( const DXFEntity & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Анализатор потока SAT. + \en SAT stream analyzer. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFModelerGeometry : public DXFEntity { +private: + std::iostream & out; ///< \ru анализируемый поток. \en stream being analyzed. + +public: + DXFModelerGeometry( std::iostream & out ); + virtual ~DXFModelerGeometry(); + + virtual bool Convert( DXFConverter & converter ); + +private: + DXFModelerGeometry ( const DXFModelerGeometry & ); // \ru не реализовано \en not implemented + DXFModelerGeometry & operator = ( const DXFModelerGeometry & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Грань. + \en Face. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFFace : public DXFEntity { +private: + /** \brief \ru Цикл. + \en Loop. \~ + \details \ru Цикл объявлен внутри DXFFace. + \en The Loop is declared inside DXFFace. \~ + \ingroup DXF_Exchange +*/ + class CONV_CLASS DXFLoop { + public: + SArray points; ///< \ru Набор точек. \en Point set. + + public: + DXFLoop( const SArray & points ); + ~DXFLoop(); + + private: + DXFLoop ( const DXFLoop & ); // \ru не реализовано \en not implemented + DXFLoop & operator = ( const DXFLoop & ); // \ru не реализовано \en not implemented + + }; + +private: + PArray loops; ///< \ru Набор циклов. \en Loop set. + +public: + DXFFace( const SArray & points ); + virtual ~DXFFace(); + + virtual bool Convert ( DXFConverter & converter ); + MbFace * MakeFace( ) const; + MbGrid* MakeGrid( ) const; + void AddHole ( const SArray & points ); + void Scale ( double factor ); + +private: + DXFFace ( const DXFFace & ); // \ru не реализовано \en not implemented + DXFFace & operator = ( const DXFFace & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сеть на основе граней. + \en Mesh on the base of faces. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFPolyfaceMesh : public DXFEntity { +private: + const PArray & faces; ///< \ru Набор граней. \en Face set. + +public: + DXFPolyfaceMesh( const PArray & faces ); + virtual ~DXFPolyfaceMesh(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFPolyfaceMesh ( const DXFPolyfaceMesh & ); // \ru не реализовано \en not implemented + DXFPolyfaceMesh & operator = ( const DXFPolyfaceMesh & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сеть на основе вершин DXF. + \en Mesh on the base of DXF vertices. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFPolygonMesh : public DXFEntity { +private: + Array2 & points; ///< \ru Набор вершин. \en Vertex set. + bool uclosed; ///< \ru Признак замкнутости по u. \en Flag of closedness by u. + bool vclosed; ///< \ru Признак замкнутости по v. \en Flag of closedness by v. + +public: + DXFPolygonMesh( Array2 & points, bool uclosed, bool vclosed ); + virtual ~DXFPolygonMesh(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFPolygonMesh ( const DXFPolygonMesh & ); // \ru не реализовано \en not implemented + DXFPolygonMesh & operator = ( const DXFPolygonMesh & ); // \ru не реализовано \en not implemented +}; + + +//------------------------------------------------------------------------------ +/**\brief \ru Составная кривая. + \en Polyline. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFPolyline : public DXFEntity { +public: + /**\brief \ru Сегмент составной кривой. + \en Polyline segment. \~ + \details \ru Класс объявлен внутри DXFPolyline; + \en The class is declared inside DXFPolyline; \~ + \ingroup DXF_Exchange +*/ + class CONV_CLASS DXFSegment { + private: + MbCurve & curve; ///< \ru Кривая. \en A curve. + double width1; ///< \ru Толщина. \en The thickness. + double width2; ///< \ru Толщина. \en The thickness. + + mutable SPtr left; + mutable SPtr right; + mutable SPtr top; + mutable SPtr bottom; + + public: + DXFSegment( MbCurve & _curve, double _width1, double _width2 ); + ~DXFSegment(); + + const MbCurve & Curve () const { return curve; } + double Width1 () const { return width1; } + double Width2 () const { return width2; } + bool IsWidth1Zero() const { return (width1 < NULL_EPSILON); } + bool IsWidth2Zero() const { return (width2 < NULL_EPSILON); } + void ChangeLeft ( MbCurve & left ) const; + void ChangeRight ( MbCurve & right ) const; + void ChangeTop ( MbCurve & top ) const; + void ChangeBottom( MbCurve & bottom ) const; + const MbCurve * GetLeft () const { return left; } + const MbCurve * GetRight () const { return right; } + const MbCurve * GetTop () const { return top; } + const MbCurve * GetBottom () const { return bottom; } + void MakeContours( std::vector< SPtr > & contours ) const; + + private: + DXFSegment ( const DXFSegment & ); // \ru не реализовано \en not implemented + DXFSegment & operator = ( const DXFSegment & ); // \ru не реализовано \en not implemented + + }; + +private: + const PArray & segments; ///< \ru Сегменты. \en Segments. + bool closed; ///< \ru Признак замкнутости. \en Flag of closedness. + MbPlacement3D placement; ///< \ru Локальная система координат. \en Local coordinate system. + MbVector3D direction; ///< \ru Направление. \en Direction. + +public: + DXFPolyline( const PArray & _segments, bool _closed, const MbPlacement3D & _placement, const MbVector3D & _direction ); + virtual ~DXFPolyline(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFPolyline ( const DXFPolyline & ); // \ru не реализовано \en not implemented + DXFPolyline & operator = ( const DXFPolyline & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая. + \en A curve. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFCurve : public DXFEntity { +private: + MbCurve3D & curve; ///< \ru Кривая. \en A curve. + MbVector3D direction; ///< \ru Направление. \en Direction. + +public: + DXFCurve( MbCurve3D & _curve, const MbVector3D & _direction ); + virtual ~DXFCurve(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFCurve ( const DXFCurve & ); // \ru не реализовано \en not implemented + DXFCurve & operator = ( const DXFCurve & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Пространственная кривая. + \en A space curve. \~ + \details \ru Используется для передачи каркасных моделей. + \en Used for wireframe models transfer. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFCurve3D : public DXFEntity { +private: + MbCurve3D & curve; ///< \ru Кривая. \en A curve. + +public: + DXFCurve3D( MbCurve3D & _curve ); + virtual ~DXFCurve3D(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFCurve3D ( const DXFCurve3D & ); // \ru не реализовано \en not implemented + DXFCurve3D & operator = ( const DXFCurve3D & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Точка. + \en Point. \~ + \ingroup DXF_Exchange +*/ +// --- +class CONV_CLASS DXFPoint : public DXFEntity { +private: + MbCartPoint3D point; ///< \ru Точка. \en A point. + MbVector3D direction; ///< \ru Направление. \en Direction. + +public: + DXFPoint( const MbCartPoint3D & _point, const MbVector3D & _direction ); + virtual ~DXFPoint(); + + virtual bool Convert( DXFConverter & converter ); + void Scale ( double factor ); + +private: + DXFPoint ( const DXFPoint & ); // \ru не реализовано \en not implemented + DXFPoint & operator = ( const DXFPoint & ); // \ru не реализовано \en not implemented + +}; + + +//------------------------------------------------------------------------------ +// +// --- +void StitchFacesAndCreateSolids( const RPArray & faces, std::vector< SPtr > & solids ); + + +//------------------------------------------------------------------------------ +// +// --- +void UnStitchFacesAndCreateSolids( const RPArray & faces, std::vector< SPtr > & solids ); + + +#endif // __DXF_DATA_H \ No newline at end of file diff --git a/C3d/Include/func_analytical_function.h b/C3d/Include/func_analytical_function.h new file mode 100644 index 0000000..4bc8804 --- /dev/null +++ b/C3d/Include/func_analytical_function.h @@ -0,0 +1,199 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Символьные (пользовательские) функции. + \en Symbolic (user) functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_ANLYTICAL_FUNCTION_H +#define __FUNC_ANLYTICAL_FUNCTION_H + + +#include +#include +#include +#include +#include + + +class MbMathematicalNode; // \ru Математический узел \en The mathematical node +class MbListVars; // \ru Список переменных \en The list of variables +class MbUserFunc; // \ru Пользовательская функция \en Th user function + + +//------------------------------------------------------------------------------ +/** \brief \ru Скалярная функция, заданная символьной строкой. + \en The symbolic function. \~ + \details \ru Скалярная функция, заданная символьной строкой. \n + \en The symbolic function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MdCharacterFunction : public MbFunction, public MbSyncItem { +private : + const MbMathematicalNode * expression; ///< \ru Выражение функции в виде дерева. \en An expression of a function as tree. + const MbListVars * variables; ///< \ru Аргументы функции в виде списка. \en Arguments of a function as list + c3d::string_t data; ///< \ru Выражение функции в виде строки. \en An expression of a function as string. + c3d::string_t argument; ///< \ru Аргументы функции в виде строки. \en Arguments of a function as string. + double tmin; ///< \ru Начальный параметр. \en Start parameter. + double tmax; ///< \ru Конечный параметр. \en End parameter. + bool sense; ///< \ru Направление. \en Direction. + +public : + /// \ru Конструктор. \en Constructor. + MdCharacterFunction( const MbMathematicalNode & expression_, const MbListVars & vars, + const c3d::string_t & data_, const c3d::string_t & argument_, + double tmin_, double tmax_, bool sense_ ); + virtual ~MdCharacterFunction(); + +private: + MdCharacterFunction( const MdCharacterFunction & ); + +public : + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of object + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed () const; // \ru Замкнутость кривой \en A curve closeness + virtual void SetClosed ( bool cl ); // \ru Замкнутость функции \en A function closeness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step ( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + virtual bool IsConst () const; + virtual bool IsLine () const; + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + +private: + void Translate (); + void CheckParam ( double & t ) const; +private: + void operator = ( const MdCharacterFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MdCharacterFunction ) +}; + +IMPL_PERSISTENT_OPS( MdCharacterFunction ) + +//------------------------------------------------------------------------------ +/** \brief \ru Скалярная функция, заданная аналитическим выражением. + \en The analytical function. \~ + \details \ru Скалярная функция, заданная аналитическим выражением. \n + \en The analytical function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MdAnalyticalFunction : public MbFunction +{ +private: + MbUserFunc * expression; // \ru Пользовательская функция. \en The user function. + double tmin; // \ru Начальный параметр. \en Start parameter. + double tmax; // \ru Конечный параметр. \en End parameter. + bool sense; // \ru Направление. \en Direction. +private: + struct DerivateData : public AuxiliaryData { + double tCur; // \ru Параметр для которого рассчитаны производные \en. The parameter where the derivatives have been calculated. + double derivatives[cdt_CountDer]; // \ru Рассчитанные значения производных. \en The calculated values of derivatives. + + DerivateData(); + DerivateData( const DerivateData & data ); + }; + mutable CacheManager cache; + +public : + // \ru Конструктор. \en Constructor. + MdAnalyticalFunction( MbUserFunc & ufunc, double tmin_, double tmax_, bool sense_ = true ); +public: + virtual ~MdAnalyticalFunction(); + +private: + MdAnalyticalFunction( const MdAnalyticalFunction & ); + +public : + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual bool IsClosed () const; // \ru Замкнутость кривой \en A curve closeness + virtual void SetClosed ( bool cl ); // \ru Замкнутость функции \en A function closeness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step ( double t, double sag ) const; + virtual double DeviationStep ( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + virtual bool IsConst () const; + virtual bool IsLine () const; + + virtual void SetOffsetFunc ( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam ( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue ( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitValue ( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + + virtual void GetCharacteristicParams( std::vector & tVec, double t1, double t2 ) const; // \ru Дать параметры особого поведения(для cos это Pi*n) \en Get parameters of special behavior (for cos it is Pi*n) + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + + virtual bool IsCos ( double &a, double& b ) const; ///< \ru Имеет ли функция вид a * cos() + b. \en Function looks like a * cos() + b. + + +private: + /// \ru Производные по параметру: параметр, значение, первая, вторая и третья производные \en Derivatives with respect to the parameter: parameter, value, first, second and third derivatives + void Derivates ( double & t, DerivateData* data ) const; + void CheckParam( double & t ) const; + void ResetTCalc() const; // \ru Сбросить временные данные \en Reset temporary data + void operator = ( const MdAnalyticalFunction & ); // \ru Не реализовано. \en NOT ALLOWED !!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MdAnalyticalFunction ) +}; + +IMPL_PERSISTENT_OPS( MdAnalyticalFunction ) + +#endif // __FUNC_ANLYTICAL_FUNCTION_H diff --git a/C3d/Include/func_const_function.h b/C3d/Include/func_const_function.h new file mode 100644 index 0000000..559a468 --- /dev/null +++ b/C3d/Include/func_const_function.h @@ -0,0 +1,94 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Линейная функция. + \en Linear function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_CONST_FUNCTION_H +#define __FUNC_CONST_FUNCTION_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Постоянная функция. + \en Constant function. \~ + \details \ru Постоянная функция. \n + \en Constant function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbConstFunction : public MbFunction { +public : + double value; ///< \ru Значение функции. \en The value of function. + +public : + MbConstFunction( double v ); ///< \ru Конструктор по значению. \en Constructor by the value. +private: + MbConstFunction( const MbConstFunction & ); +public : + virtual ~MbConstFunction(); +public: + void Init ( double v ); ///< \ru Инициализация по значению. \en Initialization by the value. +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate () const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed () const; // \ru Замкнутость кривой \en A curve closedness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closedness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse ( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + +private: + void operator = ( const MbConstFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbConstFunction ) +}; + +IMPL_PERSISTENT_OPS( MbConstFunction ) + +#endif // __FUNC_CONST_FUNCTION_H diff --git a/C3d/Include/func_cubic_function.h b/C3d/Include/func_cubic_function.h new file mode 100644 index 0000000..14a14d5 --- /dev/null +++ b/C3d/Include/func_cubic_function.h @@ -0,0 +1,242 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кубическая функция Эрмита. + \en Cubic Hermite function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_CUBIC_FUNCTION_H +#define __FUNC_CUBIC_FUNCTION_H + + +#include +#include + + +#define FUNC_NUMB 4 ///< \ru Количество элементов расчетного массива кубической функции Эрмита. \en The number of elements of calculation array of a cubic Hermite function. + + +//------------------------------------------------------------------------------ +/** \brief \ru Кубическая функция Эрмита. + \en Cubic Hermite function. \~ + \details \ru Кубическая функция Эрмита. \n + \en Cubic Hermite function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbCubicFunction : public MbFunction { +protected: + SArray valueList; ///< \ru Характерные точки. \en The control points. + SArray firstList; ///< \ru Производные в контрольных точках. \en The derivatives in control points. + SArray tList; ///< \ru Значения параметров на кривой, которую моделирует кубический сплайн. \en The values of parameters on a curve which is modeled by a cubic spline. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + ptrdiff_t uppIndex; ///< \ru Количество интервалов (число точек - 1). \en The number of intervals (a number of points - 1). + +public : + /// \ru Конструктор по точкам и признаку замкнутости. \en Constructor by points and an attribute of closedness. + MbCubicFunction( const SArray & values, bool cls ); + /// \ru Конструктор по точкам, параметрам и признаку замкнутости. \en Constructor by points, parameters and an attribute of closedness. + MbCubicFunction( const SArray & values, const SArray & params, bool cls ); + /// \ru Конструктор по точкам, производным, параметрам и признаку замкнутости. \en Constructor by points, derivatives, parameters and an attribute of closedness. + MbCubicFunction( const SArray & values, const SArray & firsts, const SArray & params, bool cls ); + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbCubicFunction( double value1, double value2 ); + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbCubicFunction( double value1, double derive1, double t1, double value2, double derive2, double t2 ); +private: + MbCubicFunction( const MbCubicFunction & ); +public : + virtual ~MbCubicFunction(); + +public: + /// \ru Инициализация по точкам, параметрам и признаку замкнутости. \en Initialization by points, parameters and an attribute of closedness. + void Init( const SArray & values, + const SArray & params, bool cls ); +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA () const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed () const; // \ru Замкнутость кривой \en A curve closedness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closedness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer ( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + virtual void SetLimitDerive( size_t n, double newValue, double dt ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitDerive( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + virtual bool InsertValue( double t, double newValue ); // \ru Установить значение для параметра t. \en Set the value for the pdrdmeter t. + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + MbFunction * Break( double t1, double t2 ) const; ///< \ru Выделить часть функции. \en Select a part of a function. + // \ru В указанной точке t установить заданное поведение, изменив функцию на интервале, не превышающем tDelta. \en Set a given behavior at point t by modifying the function of an interval not exceeding tDelta. + void SetFunctionValue( double t, const double & val, double tDelta, const double & der, double eps ); + + size_t GetValuesCount() const; // \ru Выдать количество опорных точек \en Get the number of control points + double GetParam( size_t index ) const; // \ru Дать значение параметра точки по номеру \en Get the value of point parameter by its number + double GetValue( size_t index ) const; // \ru Дать значение точки по номеру \en Get the value of point by its number + +private: + bool CalculateDerivatives(); // \ru Расчет производных. \en Calculation of derivatives + inline bool LocalCoordinate( double & t, ptrdiff_t & j1, ptrdiff_t & j2, + double & y1, double & y2, double & t1, double & t2 ) const; + ptrdiff_t GetIndex ( double t ) const; + void ParamPoint ( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamFirst ( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamSecond( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamThird ( double t1, double t2, double * tLoft ) const; + bool SetCorrection( size_t ind, double tDelta ); // \ru Скорректировать функцию по индексу. \en Function correction by index. + void CalculateValues( size_t i1, size_t i2 ); // \ru Скорректировать функцию на интервале i1-i2. \en Function correction on the interval i1-i2. + + +private: + void operator = ( const MbCubicFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCubicFunction ) +}; + +IMPL_PERSISTENT_OPS( MbCubicFunction ) + +//------------------------------------------------------------------------------ +// \ru Определение местных координат области поверхности \en Definition of local coordinates in a surface region +// --- +inline bool MbCubicFunction::LocalCoordinate( double & t, ptrdiff_t & j1, ptrdiff_t & j2, + double & y1, double & y2, + double & t1, double & t2 ) const +{ + bool result = true; + ptrdiff_t listInd = tList.MaxIndex(); + double tmin = tList[0]; + double tmax = tList[listInd]; + if ( t < tmin ) { + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t - tmin) / tmp) * tmp; + } + else { + t = tmin; + result = false; + } + } + else + if ( t > tmax ) { + if ( closed ) { + double tmp = tmax - tmin; + t -= ::floor((t - tmin) / tmp) * tmp; + } + else { + t = tmax; + result = false; + } + } + + j1 = 0; + j2 = listInd; + + ptrdiff_t ind, delta = j2; // \ru Диапазон \en A range + + // \ru Поиск половинным делением \en Search by bisection + while ( delta > 1 ) { + ind = j1 + ( delta / (ptrdiff_t)2 ); // \ru Индекс в середине \en The index in the middle + if ( t < tList[ind] ) // \ru Если v меньше серединного параметра \en If v is less than the middle parameter + j2 = ind; // \ru Изменить правую границу \en Change the right bound + else + j1 = ind; // \ru Изменить левую границу \en Change the left bound + delta = j2 - j1; // \ru Диапазон \en A range + } + + t1 = tList[j1]; + t2 = tList[j2]; + y1 = (t-t2) / (t1-t2); + y2 = (t-t1) / (t2-t1); + + return result; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa точки \en Definition of array of degrees of point parameter +// --- +inline void MbCubicFunction::ParamPoint( double y1, double y2, double t1, double t2, double * tLoft ) const { + tLoft[0] = 3*y1*y1 - 2*y1*y1*y1; + tLoft[1] = 3*y2*y2 - 2*y2*y2*y2; + tLoft[2] = (y1*y1*y1 - y1*y1) * (t1-t2); + tLoft[3] = (y2*y2*y2 - y2*y2) * (t2-t1); +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa производной \en Definition of array of degrees of derivative parameter +// --- +inline void MbCubicFunction::ParamFirst( double y1, double y2, double t1, double t2, double * tLoft ) const { + tLoft[0] = (6*y1 - 6*y1*y1) / (t1-t2); + tLoft[1] = (6*y2 - 6*y2*y2) / (t2-t1); + tLoft[2] = (3*y1*y1 - 2*y1); + tLoft[3] = (3*y2*y2 - 2*y2); +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa второй производной \en Definition of array of degrees of second derivative parameter +// --- +inline void MbCubicFunction::ParamSecond( double y1, double y2, double t1, double t2, double * tLoft ) const { + double d1 = 1 / (t1-t2); + double d2 = -d1; + tLoft[0] = (6 - 12*y1) * d1*d1; + tLoft[1] = (6 - 12*y2) * d2*d2; + tLoft[2] = (6*y1 - 2) * d1; + tLoft[3] = (6*y2 - 2) * d2; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa третьей производной \en Definition of array of degrees of third derivative parameter +// --- +inline void MbCubicFunction::ParamThird( double t1, double t2, double * tLoft ) const { + double d1 = 1 / (t1-t2); + double d2 = -d1; + tLoft[0] = -12*d1*d1*d1; + tLoft[1] = -12*d2*d2*d2; + tLoft[2] = 6*d1*d1; + tLoft[3] = 6*d2*d2; +} + + +#endif // __FUNC_CUBIC_FUNCTION_H diff --git a/C3d/Include/func_cubic_spline_function.h b/C3d/Include/func_cubic_spline_function.h new file mode 100644 index 0000000..efd89b7 --- /dev/null +++ b/C3d/Include/func_cubic_spline_function.h @@ -0,0 +1,115 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кубический сплайн функция. + \en Cubic spline function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_CUBIC_SPLINE_FUNCTION_H +#define __FUNC_CUBIC_SPLINE_FUNCTION_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Кубический сплайн функция. + \en Cubic spline function. \~ + \details \ru Кубический сплайн функция. \n + \en Cubic spline function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbCubicSplineFunction : public MbFunction { +protected: + SArray valueList; ///< \ru Характерные точки. \en The control points. + SArray secondList; ///< \ru Вторые производные в контрольных точках. \en Second derivatives in control points. + SArray tList; ///< \ru Значение параметров на кривой, которую моделирует кубический сплайн. \en The values of parameters on a curve which is modeled by a cubic spline. + bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closeness. + ptrdiff_t uppIndex; ///< \ru Количество интервалов (число точек - 1). \en The number of intervals (a number of points - 1). + +public : + /// \ru Конструктор по точкам и признаку замкнутости. \en Constructor by points and an attribute of closeness. + MbCubicSplineFunction( const SArray & values, bool cls ); + /// \ru Конструктор по точкам, параметрам и признаку замкнутости. \en Constructor by points, parameters and an attribute of closeness. + MbCubicSplineFunction( const SArray & values, const SArray & params, bool cls ); +private: + MbCubicSplineFunction( const MbCubicSplineFunction & ); +public : + virtual ~MbCubicSplineFunction(); + +public: + /// \ru Инициализация по точкам, параметрам и признаку замкнутости. \en Initialization by points, parameters and an attribute of closeness. + void Init( const SArray & values, // \ru Инициализация переменных \en Initialization of variables + const SArray & params, bool cls ); +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA () const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of object + + virtual double GetTMax () const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin () const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed () const; // \ru Замкнутость кривой \en A curve closeness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closeness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer ( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point) + virtual bool InsertValue( double t, double newValue ); // \ru Установить значение для параметра t. \en Set the value for the pdrdmeter t. + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + MbFunction * Break( double t1, double t2 ) const; ///< \ru Выделить часть функции. \en Select a part of a function. + +private: + double Value ( double t, size_t num ) const; // \ru Точка на кривой \en The point on the curve + double FirstDer( double t, size_t num ) const; // \ru Первая производная \en First derivative + ptrdiff_t GetIndex( double t ) const; + bool CalcSecondDerives (); // \ru Расчет вторых производных \en Calculation of second derivatives + bool CalcClosedSpline (); // \ru Расчет вторых производных в узлах для замкнутой кривой \en Calculation of second derivatives in nodes of closed curve + bool CalcUnClosedSpline(); // \ru Расчет вторых производных в узлах для разомкнутой кривой \en Calculation of second derivatives in nodes of unclosed curve + bool DefineIntervalPar( double & t, size_t & num ) const; // \ru Определение принадлежности интервалу параметров \en Check belonging to interval of parameters +private: + void operator = ( const MbCubicSplineFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCubicSplineFunction ) +}; + +IMPL_PERSISTENT_OPS( MbCubicSplineFunction ) + +#endif // __FUNC_CUBIC_SPLINE_FUNCTION_H diff --git a/C3d/Include/func_line_function.h b/C3d/Include/func_line_function.h new file mode 100644 index 0000000..ad9432c --- /dev/null +++ b/C3d/Include/func_line_function.h @@ -0,0 +1,98 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Линейная функция. + \en Linear function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_LINE_FUNCTION_H +#define __FUNC_LINE_FUNCTION_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Линейная функция. + \en Linear function. \~ + \details \ru Линейная функция. \n + \en Linear function. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbLineFunction : public MbFunction { +public : + double value1; ///< \ru Значение функции в начале области определения. \en A value of function in the beginning of its domain. + double value2; ///< \ru Значение функции в конце области определения. \en A value of function in the ending of its domain. + double tmin; ///< \ru Начало области определения. \en Beginning of domain. + double tmax; ///< \ru Конец области определения. \en Ending of domain. + +public : + ///< \ru Конструктор по значениям и параметрам. \en Constructor by values and parameters. + MbLineFunction( double v1, double v2, double t1, double t2 ); +private: + MbLineFunction( const MbLineFunction & ); +public : + virtual ~MbLineFunction(); +public: + void Init( double v1, double v2, double t1, double t2 ); ///< \ru Инициализация по значениям и параметрам. \en Initialization by values and parameters. +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closedness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closedness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer ( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + virtual bool SetLimitParam( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at beginning, 2 - at ending) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at beginning, 2 - at ending) + +private: + void operator = ( const MbLineFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLineFunction ) +}; + +IMPL_PERSISTENT_OPS( MbLineFunction ) + +#endif // __FUNC_LINE_FUNCTION_H diff --git a/C3d/Include/func_power_function.h b/C3d/Include/func_power_function.h new file mode 100644 index 0000000..c00ee31 --- /dev/null +++ b/C3d/Include/func_power_function.h @@ -0,0 +1,100 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Степенная функция. + \en Power function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_POWER_FUNCTION_H +#define __FUNC_POWER_FUNCTION_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Степенная функция. + \en Power function. \~ + \details \ru Степенная функция f(t) = origin + scale* (t - shift)**exponent. \n + \en Power function f(t) = origin + scale* (t - shift)**exponent. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbPowerFunction : public MbFunction { +public : + double origin; ///< \ru Начальное значение. \en Start value. + double scale; ///< \ru Коэффициент усиления. \en Scale gain. + double shift; ///< \ru Сдвиг параметра. \en Parameter shift. + double exponent; ///< \ru Степень возведения. \en Exponent parameter. + double tmin; ///< \ru Начало области определения. \en Beginning of domain. + double tmax; ///< \ru Конец области определения. \en Ending of domain. + +public : + ///< \ru Конструктор по значениям и параметрам. \en Constructor by values and parameters. + MbPowerFunction( double orig, double scal, double shif, double expo, double t1, double t2 ); +private: + MbPowerFunction( const MbPowerFunction & ); +public : + virtual ~MbPowerFunction(); +public: + void Init( double orig, double scal, double shif, double expo, double t1, double t2 ); ///< \ru Инициализация по значениям и параметрам. \en Initialization by values and parameters. +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closedness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closedness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer ( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + bool SetLimit( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at beginning, 2 - at ending) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at beginning, 2 - at ending) + +private: + void operator = ( const MbPowerFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPowerFunction ) +}; + +IMPL_PERSISTENT_OPS( MbPowerFunction ) + +#endif // __FUNC_POWER_FUNCTION_H diff --git a/C3d/Include/func_sinus_function.h b/C3d/Include/func_sinus_function.h new file mode 100644 index 0000000..2a93ef0 --- /dev/null +++ b/C3d/Include/func_sinus_function.h @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Синус функция. + \en Sinus function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNC_SINUS_FUNCTION_H +#define __FUNC_SINUS_FUNCTION_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Синус функция. + \en Sinus function. \~ + \details \ru Синус функция f(t) = origin + amplitude* sin((t - shift) / frequency). \n + \en Sinus function f(t) = origin + amplitude* sin((t - shift) / frequency). \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbSinusFunction : public MbFunction { +public : + double origin; ///< \ru Начальное значение. \en Start value. + double amplitude; ///< \ru Амплитуда. \en Amplitude. + double shift; ///< \ru Сдвиг параметра. \en Parameter shift. + double frequency; ///< \ru Циклическая частота. \en Frequency. + double tmin; ///< \ru Начало области определения. \en Beginning of domain. + double tmax; ///< \ru Конец области определения. \en Ending of domain. + +public : + ///< \ru Конструктор по значениям и параметрам. \en Constructor by values and parameters. + MbSinusFunction( double orig, double ampl, double shif, double freq, double t1, double t2 ); +private: + MbSinusFunction( const MbSinusFunction & ); +public : + virtual ~MbSinusFunction(); +public: + void Init( double orig, double ampl, double shif, double freq, double t1, double t2 ); ///< \ru Инициализация по значениям и параметрам. \en Initialization by values and parameters. +public: + // \ru Общие функции математического объекта \en Common functions of mathematical object + virtual MbeFunctionType IsA() const; // \ru Тип элемента \en A type of element + virtual MbFunction & Duplicate() const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbFunction & ); // \ru Сделать равным \en Make equal + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter + virtual bool IsClosed() const; // \ru Замкнутость кривой \en A curve closeness + virtual void SetClosed( bool cl ); // \ru Замкнутость функции \en A function closeness + + virtual double Value ( double & t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double FirstDer ( double & t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double SecondDer ( double & t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double ThirdDer ( double & t ) const; // \ru Третья производная по t \en The third derivative with respect to t + + virtual double _Value ( double t ) const; // \ru Значение функции для t \en The value of function for a given t + virtual double _FirstDer ( double t ) const; // \ru Первая производная по t \en The first derivative with respect to t + virtual double _SecondDer ( double t ) const; // \ru Вторая производная по t \en The second derivative with respect to t + virtual double _ThirdDer ( double t ) const; // \ru Третья производная по t \en The third derivative with respect to t + // \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление \en Change direction + virtual double Step( double t, double sag ) const; + virtual double DeviationStep( double t, double angle ) const; + + virtual double MinValue ( double & t ) const; // \ru Минимальное значение функции \en The minimum value of function + virtual double MaxValue ( double & t ) const; // \ru Максимальное значение функции \en The maximum value of function + virtual double MidValue () const; // \ru Среднее значение функции \en The middle value of function + virtual bool IsGood () const; // \ru Корректность функции \en Correctness of function + + virtual bool IsConst() const; + virtual bool IsLine () const; + + // \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const; + // \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ); + + virtual void SetOffsetFunc( double distOld, double distNew ); // \ru Сместить функцию \en Shift a function + bool SetLimit( double newTMin, double newTMax ); // \ru Установить область изменения параметра \en Set range of parameter + virtual void SetLimitValue( size_t n, double newValue ); // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at beginning, 2 - at ending) + virtual double GetLimitValue( size_t n ) const; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at beginning, 2 - at ending) + +private: + void operator = ( const MbSinusFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSinusFunction ) +}; + + +IMPL_PERSISTENT_OPS( MbSinusFunction ) + + +#endif // __FUNC_SINUS_FUNCTION_H diff --git a/C3d/Include/function.h b/C3d/Include/function.h new file mode 100644 index 0000000..4a46e7c --- /dev/null +++ b/C3d/Include/function.h @@ -0,0 +1,203 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Скалярная функция параметра. + \en Scalar function of parameter. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNCTION_H +#define __FUNCTION_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbProperties; +class MATH_CLASS MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы скалярных функций. + \en Types of scalar functions. \~ + \details \ru Скалярные функции можно рассматривать как кривые в одномерном пространстве. \n + \en Scalar functions may be considered as curves in one-dimensional space. \n \~ + \ingroup Functions + */ +// --- +enum MbeFunctionType { + + ft_Undefined = 0, ///< \ru Неизвестный объект. \en Unknown object. + + ft_Function = 1, ///< \ru Функция. \en A function. + ft_ConstFunction = 2, ///< \ru Постоянная функция. \en A constant function. + ft_LineFunction = 3, ///< \ru Линейная функция. \en A linear function. + ft_CubicFunction = 4, ///< \ru Кубическая функция Эрмита. \en A cubic Hermite function. + ft_CubicSplineFunction = 5, ///< \ru Кубическая сплайновая функция. \en A cubic spline function. + ft_PowerFunction = 6, ///< \ru Степенная функция. \en Power function. + ft_SinusFunction = 7, ///< \ru Синусоидальная функция. \en Sinusoidal function. + + ft_CharacterFunction = 101, ///< \ru Символьная функция. \en A symbolic function. + ft_AnalyticalFunction = 102, ///< \ru Символьная функция на модельном выражении. \en A symbolic function in model expression. + + ft_FreeItem = 600, ///< \ru Тип для объектов, созданных пользователем. \en Type for the user-defined objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Скалярная функция параметра. + \en Scalar function of parameter. \~ + \details \ru Скалярная функция параметра. \n + \en Scalar function of parameter. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbFunction : public MbRefItem, public TapeBase { + +protected : + MbFunction(); +private: + MbFunction( const MbFunction & ); +public : + virtual ~MbFunction(); +public: + /** \ru \name Общие функции математического объекта + \en \name Common functions of mathematical object + \{ */ + /// \ru Тип элемента. \en A type of element. + virtual MbeFunctionType IsA() const = 0; + /// \ru Сделать копию элемента. \en Create a copy of the element. + virtual MbFunction & Duplicate() const = 0; + /// \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const = 0; + /// \ru Являются ли объекты подобными. \en Determine whether objects are similar. + virtual bool IsSimilar( const MbFunction & ) const; + /// \ru Сделать равным. \en Make equal. + virtual bool SetEqual ( const MbFunction & ) = 0; + /// \ru Выдать свойства объекта. \en Get properties of the object. + virtual void GetProperties( MbProperties & ) = 0; + /// \ru Записать свойства объекта. \en Set properties of the object. + virtual void SetProperties( const MbProperties & ) = 0; + /** \} */ + /** \ru \name Общие функции + \en \name Common functions + \{ */ + /// \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual double GetTMax() const = 0; + /// \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMin() const = 0; + /// \ru Получить замкнутость функции. \en Get the closeness of a function. + virtual bool IsClosed() const = 0; + /// \ru Установить замкнутость функции. \en Set the closeness of a function. + virtual void SetClosed( bool cl ) = 0; + /// \ru Периодичность замкнутой кривой. \en Periodicity of a closed curve. + virtual bool IsPeriodic() const; + + /// \ru Значение функции для t. \en The value of function for a given t. + virtual double Value ( double & t ) const = 0; + /// \ru Первая производная по t. \en The first derivative with respect to t. + virtual double FirstDer ( double & t ) const = 0; + /// \ru Вторая производная по t. \en The second derivative with respect to t. + virtual double SecondDer( double & t ) const = 0; + /// \ru Третья производная по t. \en The third derivative with respect to t. + virtual double ThirdDer ( double & t ) const = 0; + + /// \ru Значение расширенной функции для t. \en The value of extended function for a given t. + virtual double _Value ( double t ) const; + /// \ru Первая производная расширенной функции по t. \en The first derivative of extended function with respect to t. + virtual double _FirstDer ( double t ) const; + /// \ru Вторая производная расширенной функции по t. \en The second derivative of extended function with respect to t. + virtual double _SecondDer( double t ) const; + /// \ru Третья производная расширенной функции по t. \en The third derivative of extended function with respect to t. + virtual double _ThirdDer ( double t ) const; + + /** \brief \ru Вычислить значение и производные для заданного параметра. + \en Calculate value and derivatives of object for given parameter. \~ + \details \ru Значение и производных вычисляются в пределах области определения и на расширенной оси. + \en Values of point and derivatives are calculated on parameter area and on extended axis. \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[in] ext - \ru В пределах области определения (false), на расширенной оси (true). + \en On parameters area (false), on extended axis (true). \~ + \param[out] val - \ru Значение. + \en Value. \~ + \param[out] fir - \ru Производная. + \en Derivative with respect to t. \~ + \param[out] sec - \ru Вторая производная по t, если не ноль. + \en Second derivative with respect to t, if not NULL. \~ + \param[out] thr - \ru Третья производная по t, если не ноль. + \en Third derivative with respect to t, if not NULL. \~ + \ingroup Curves_3D + */ + virtual void Explore( double & t, bool ext, + double & val, double & fir, double * sec, double * thr ) const; + + /// \ru Изменить направление. \en Change direction. + virtual void Inverse( MbRegTransform * iReg = NULL ) = 0; + /// \ru Вычислить шаг по прогибу для заданного параметра t. \en Calculate a step by the sag for a given parameter t. + virtual double Step( double t, double sag ) const = 0; + /// \ru Вычислить шаг по угловому отклонению для заданного параметра t. \en Calculate a step by the angular deviation for a given parameter t. + virtual double DeviationStep( double t, double angle ) const = 0; + + /// \ru Минимальное значение функции. \en The minimum value of function. + virtual double MinValue( double & t ) const = 0; + /// \ru Максимальное значение функции. \en The maximum value of function. + virtual double MaxValue( double & t ) const = 0; + /// \ru Среднее значение функции. \en The middle value of function. + virtual double MidValue() const = 0; + /// \ru Корректность функции. \en Correctness of function. + virtual bool IsGood () const = 0; + + virtual bool IsConst() const = 0; ///< \ru Является ли функция константной. \en Whether the function is constant. + virtual bool IsLine () const = 0; ///< \ru Является ли функция линейной. \en Whether the function is linear. + + /// \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction. + virtual MbFunction * Trimmed( double t1, double t2, int sense ) const = 0; + /// \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть: beg == true - соранить начальную половину, beg == false - соранить конечную половину. + /// \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half. + virtual MbFunction * BreakFunction( double t, bool beg ) = 0; + /// \ru Разбить функцию параметрами: beg == true - соранить начальную половину, beg == false - соранить конечную половину. + /// \en Function break by the parameters: begs == true - save the initial half, beg == false - save the final half. + bool CuttingFunction( SArray & params, bool beginSafe, double eps, RPArray & cutted ); + + /// \ru Наличие полюса функции. \en Existence of a function pole. + virtual bool IsPole( double t ) const; + /// \ru Сместить функцию. \en Shift a function. + virtual void SetOffsetFunc( double distOld, double distNew ) = 0; + /// \ru Установить область изменения параметра. \en Set the range of parameter. + virtual bool SetLimitParam( double newTMin, double newTMax ); + /// \ru Установить значение на конце ( 1 - в начале, 2 - в конце). \en Set the value at the end (1 - at start point, 2 - at end point). + virtual void SetLimitValue( size_t n, double newValue ) = 0; + /// \ru Дать значение на конце ( 1 - в начале, 2 - в конце). \en Get the value at the end (1 - at start point, 2 - at end point). + virtual double GetLimitValue( size_t n ) const = 0; + /// \ru Установить значение производной на конце ( 1 - в начале, 2 - в конце). \en Set the value of derivative at the end (1 - at start point, 2 - at end point). + virtual void SetLimitDerive( size_t n, double newValue, double dt ); + /// \ru Дать значение производной на конце ( 1 - в начале, 2 - в конце). \en Get the value of derivative at the end (1 - at start point, 2 - at end point). + virtual double GetLimitDerive( size_t n ) const; + /// \ru Установить значение для параметра t. \en Set the value for the parameter t. + virtual bool InsertValue( double t, double newValue ); + /// \ru Получить параметры особого поведения в интервале от t1 до t2 (для cos это Pi*n). \en Get the parameters of special behaviour on the interval from t1 to t2 (for cos it is Pi*n). + virtual void GetCharacteristicParams( std::vector & tSpecific, double t1, double t2 ); + + /** \} */ + /// \ru Параметрическая длина. \en The parametric length. + double GetParamLength () const { return GetTMax()-GetTMin(); } + /// \ru Находится ли параметр в области определения функции. \en Whether the parameter belongs to the function domain. + bool IsParamOn( double t, double eps ) const { return ( GetTMin()-eps <= t && t <= GetTMax()+eps ); } + /// \ru Подготовить к записи регистрируемый объект. \en Prepare for writing the registered object. + void PrepareWrite() { SetRegistrable( (GetUseCount() > 1) ? registrable : noRegistrable ); } + +private: + void operator = ( const MbFunction & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS( MbFunction ) +}; + +IMPL_PERSISTENT_OPS( MbFunction ) + +#endif // __FUNCTION_H diff --git a/C3d/Include/function_factory.h b/C3d/Include/function_factory.h new file mode 100644 index 0000000..74f757f --- /dev/null +++ b/C3d/Include/function_factory.h @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Создание скалярных функций. + \en Creation of scalar functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __FUNCTION_FACTORY_H +#define __FUNCTION_FACTORY_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbFunction; +class MATH_CLASS MbListVars; +class MATH_CLASS MbMathematicalNode; + + +//------------------------------------------------------------------------------ +/** \brief \ru Фабрика функций. + \en Factory of functions. \~ + \details \ru Фабрика функций. \n + \en Factory of functions. \n \~ + \ingroup Functions +*/ +// --- +class MATH_CLASS MbFunctionFactory { +private: + mutable MbResultType status; ///< \ru Результат создания. \en The result of creation. + +public : + /// \ru Конструктор. \en Constructor. + MbFunctionFactory(); + virtual ~MbFunctionFactory(); + +public: + MbResultType Status() const; ///< \ru Получить статус создания. \en Get the state of creation. + +public: + /// \ru Создать символьную функцию. \en Create a symbolic function. + MbFunction * CreateAnalyticalFunction ( const c3d::string_t & data, MbListVars & vars, + const MbMathematicalNode & root, + const c3d::string_t & argument, + double tmin, double tmax ) const; + /// \ru Создать символьную функцию. \en Create a symbolic function. + MbFunction * CreateAnalyticalFunction ( const c3d::string_t & data, + const c3d::string_t & argument, + double tmin, double tmax ) const; + /// \ru Создать постоянную функцию. \en Create a constant function. + MbFunction * CreateConstFunction ( double value ) const; + /// \ru Создать линейную функцию. \en Create a linear function. + MbFunction * CreateLineFunction ( double v1, double v2, double t1, double t2 ) const; + /// \ru Создать кубическую функцию. \en Create a cubic function. + MbFunction * CreateCubicFunction ( const SArray & values, bool closed ) const; + /// \ru Создать кубическую функцию. \en Create a cubic function. + MbFunction * CreateCubicFunction ( const SArray & values, + const SArray & params, bool closed ) const; + /// \ru Создать кубическую функцию. \en Create a cubic function. + MbFunction * CreateCubicFunction ( const SArray & values, + const SArray & firsts, + const SArray & params, bool closed ) const; + /* + MbFunction * CreateCubicSplineFunction( const SArray & values, bool closed ) const; + MbFunction * CreateCubicSplineFunction( const SArray & values, + const SArray & params, bool closed ) const; + */ + +OBVIOUS_PRIVATE_COPY( MbFunctionFactory ) +}; + + +//------------------------------------------------------------------------------ +// \ru Найти в строке переменные \en Find variables in string +// --- +const MbMathematicalNode * GetVarListForAnalyticalFunc( const c3d::string_t & data, MbListVars & vars ); + + +#endif // __FUNCTION_FACTORY_H diff --git a/C3d/Include/gc_api.h b/C3d/Include/gc_api.h new file mode 100644 index 0000000..26df62d --- /dev/null +++ b/C3d/Include/gc_api.h @@ -0,0 +1,339 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Тестовый программный интерфейс геометрического решателя C3D Solver. + \en Testing program interface of C3D Solver. + \~ + + \details \ru Данный файл содержит типы данных и вызовы, предназначенные для тестирования + и отладки, поэтому могут быть изменены или удалены из API C3D Solver + в будущих версиях. Для применения решателя двухмерных ограничений рекомендуется + использовать только интерфейс, объявленный в заголовочных файлах gce_api.h и gce_types.h. + + \en This file contains data types and calls for testing and debugging, so they + can be modified or removed from the C3D Solver API in future versions. To use + the 2D constraint solver, it is recommended to use only the interface declared + in the header files gce_api.h and gce_types.h. + \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GC_API_H +#define __GC_API_H + +#include +// +#include +#include + +template class SArray; + +//---------------------------------------------------------------------------------------- +// \ru Дескрипция координаты геометрического примитива. \en Description of geometric primitive coordinate. +//--- +template +struct geom_coord +{ + Geom geom; + coord_name crdName; + + geom_coord( Geom g, coord_name cName ) : geom(g), crdName(cName) {} + geom_coord( const geom_coord & crd ) + { + geom = crd.geom; + crdName = crd.crdName; + } + geom_coord & operator = ( const geom_coord & crd ) + { + geom = crd.geom; + crdName = crd.crdName; + return *this; + } + +private: + geom_coord(); +}; + +//---------------------------------------------------------------------------------------- +/* + Deprecated data type. Use GCE_ConstraintStatus instead this. + 2019.07.02 +*/ +//--- +enum GcConState +{ + cst_None, + cst_Satisfied, + cst_Not_Satisfied, + cst_Redundant, + cst_Overconstraining, + cst_Unsolvable, +}; + +/** + \addtogroup Constraints2D_API + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Состояние определенности системы геометрических ограничений. + \en State of geometric constraints system. +*/ +//--- +typedef enum +{ + GCE_STATE_Unknown = 0 ///< \ru О состоянии ничего не известно. \en State is unknown. + , GCE_STATE_WellConstrained ///< \ru Полностью определенная система - не имеет степеней свобод. \en Well-constrained system - does not have degrees of freedom. + , GCE_STATE_UnderConstrained ///< \ru Недоопределенная система - имеются степени свободы. \en Underconstrained system - there are degrees of freedom. + , GCE_STATE_OverConstrained ///< \ru Переопределенная система - система ограничений несовместна. \en Overconstrained system - the system of constraints is inconsistent (there are contradictions). + /* + \ru Идентификаторы не менять (возможна запись в файлы)! + \en Don't change identifiers (record to files is possible)! + */ +} GCE_s_state; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Проверка: Останется ли система удовлетворенной, если изменить координаты точки. + \en Check: Whether the system remains satisfied if the point coordinates are changed. + \details + \ru Функция работает корректно, если на момент её вызова система ограничений решена. При проверке + не происходит пробного перерешивания системы, а оценивается лишь удовлетворенность + смежных ограничений при новом параметре (px,py). Функция может быть применена для оценки области значений(окрестность + некоторой погрешности) точки, в которой система остается удовлетворенной. + \en The function works correctly if the system is in resolved state, during the check + a test resolving of the system is not performed, only satisfaction of adjacent constraints + with a new parameter (px,py) is estimated. + The function can be applied for estimation of domain (neighborhood of some tolerance) + of the point in which the system remains satisfied. \~ +*/ +//--- +GCE_FUNC(bool) GCE_CheckPointSatisfaction( GCE_system gSys, geom_item pnt, point_type cp, double px, double py ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Выдать состояние системы ограничений. + \en Get constraint system state. + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \return \ru Одно из состояний, перечисленного набором: "Система недоопределена", + "Полностью определена" или "Переопределена". + \en One of the states enumerated by a set: Under-defined, Well-defined and Over-defined. \~ + \note \ru Сложность выполнения функции эквивалентна запросу GCE_PointDOF. + \en Function complexity is equivalent to request GCE_PointDOF. +*/ +//--- +GCE_FUNC(GCE_s_state) GCE_StateOfSystem( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +/// \ru Проверить, удовлетворена ли система ограничений. \en To check the satisfaction of constraints. +/** + For internal use only! + \param \ru gSys - Контекст решателя. + \en gSys - Solver state. \~ + \param \ru c3dVer - Версия ядра c3d. + \en c3dVer - Mathematical kernel version. \~ + \return \ru Код результата вычислений. + \en Calculation result code. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_CheckSatisfaction( GCE_system gSys, VERSION c3dVer = GetCurrentMathFileVersion() ); + +//---------------------------------------------------------------------------------------- +/// \ru Выдать координаты переменных геометрической модели, \en Get coordinates of variables of geometric models +/// \ru значения которых не зависят от изменения входных переменных in_coords; \en which do not depend on changes of input variables in_coords; +// --- +GCE_FUNC(bool) GCE_GetOutVarCoordinates( GCE_system gcContext, + const SArray & in_coords, + const SArray & drvCons, + SArray & outCoords ); + +//---------------------------------------------------------------------------------------- +/// \ru Задать фиксацию координаты параметрического объекта \en Specify fixation of a parametric object coordinate +//--- +GCE_FUNC(constraint_item) GCE_FixCoordinate( GCE_system gSys, geom_item g, coord_name crd ); + +//---------------------------------------------------------------------------------------- +/// \ru Задать ограничение "Радиальный размер" \en Specify "Radial dimension" constraint +/** + \param cir - \ru окружность или дуга + \en a circle or an arc \~ + \param diam - \ru признак диаметрального размера + \en flag of diametral dimension \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_FormCirDimension( GCE_system gcContext, geom_item cir, GCE_dim_pars dPars, bool diam ); + +//---------------------------------------------------------------------------------------- +/// \ru Отменить режим драггинга \en Cancel dragging mode +// --- +GCE_FUNC(void) GCE_ResetMovingMode( GCE_system ); + +/** + \} + Constraints2D_API +*/ + +/* + Deprecated functions +*/ + +//---------------------------------------------------------------------------------------- +// \ru Выдать состояние ограничения \en Get the state of constraint +/* + The call is deprecated (2019). Use GCE_ConstraintStatus instead this. +*/ +//--- +GCE_FUNC(GcConState) GCE_GetConstraintState( GCE_system, constraint_item ); + +//---------------------------------------------------------------------------------------- +// \ru Собрать плохо-обусловленную часть системы ограничений. \en Collect ill-conditioned part of the constraint system. +/* + It is planned to use GCE_ConstraintStatus instead this call. +*/ +// --- +GCE_FUNC(bool) GCE_CollectLinearDependedConstrains( GCE_system, SArray & ); + +//---------------------------------------------------------------------------------------- +// +//--- +GCE_FUNC(GCE_s_state) GCE_GetConstraintStatus( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Рекомендуется использовать #GCE_AddSymmetry. + \en The function is obsolete. It is recommended to use #GCE_AddSymmetry. \~ + */ +//--- +GCE_FUNC(constraint_item) GCE_FormPointSymmetry( GCE_system gcContext, geom_item pnt[2], geom_item curve, int8 ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Рекомендуется использовать #GCE_AddIncidence. + \en The function is obsolete. It is recommended to use #GCE_AddIncidence. \~ +*/ +GCE_FUNC(constraint_item) GCE_FormPointOnCurve( GCE_system, geom_item, geom_item ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + Вместо неё используйте #GCE_PrepareMovingGeoms. + \en An obsolete function. The call will be removed in one of the next versions. + Use #GCE_PrepareMovingGeoms instead. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareMovingOfGeoms( GCE_system, SArray &, double, double ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Вместо неё применять #GCE_CoordDOF. + \en The function is deprecated. Use #GCE_CoordDOF instead. \~ +*/ +//-2017-- +GCE_FUNC(ptrdiff_t) GCE_GetCoordinateDOF( GCE_system, geom_coord<> ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Вместо неё применять #GCE_AddFixedLength. + \en The function is obsolete Use #GCE_AddFixedLength instead. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_FormFixedLength( GCE_system, geom_item ); + +//---------------------------------------------------------------------------------------- +/* + \attention \ru Функция устарела. Вместо неё применять #GCE_FixCoordinate. + \en The function is obsolete Use #GCE_FixCoordinate instead. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_FormFixedCoordinate( GCE_system, geom_coord<> ); + +/* + Deprecated typenames and constants (2019.06) +*/ +typedef GCE_s_state GcConstraintStatus; +const GCE_s_state tcs_Unknown = GCE_STATE_Unknown; +const GCE_s_state tcs_WellConstrained = GCE_STATE_WellConstrained; +const GCE_s_state tcs_UnderConstrained= GCE_STATE_UnderConstrained; +const GCE_s_state tcs_OverConstrained = GCE_STATE_OverConstrained; + +//---------------------------------------------------------------------------------------- +/* + Internal use only +*/ +//--- +GCE_FUNC(GCE_system) GCE_RestoreFromJournal( const char * fName ); + +//---------------------------------------------------------------------------------------- +/** + \note Used only for testing +*/ +//--- +GCE_FUNC(const GCE_diagnostic_pars &) GCE_DiagnosticPars( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +// Measure a dimension value (it used for testing purposes only) +//--- +GCE_FUNC(double) GCT_Measure( GCE_system gSys, constraint_type cType, geom_item g1, geom_item g2 ); + +struct GCT_auto_c_query; + +//---------------------------------------------------------------------------------------- +// Функция обратного вызова для подтверждения автоограничения +// Callback function to confirm auto-constraint +//--- +typedef double ( *GCT_auto_c_weight )( GCT_auto_c_query *, constraint_type cType + , geom_item g1, geom_item g2 ); + +//---------------------------------------------------------------------------------------- +// Событийная функция: регистрация нового авто-ограничения в системе +// Event function: a new auto-constraint is registered in the system. +//--- +typedef void ( *GCT_auto_c_registered )( GCT_auto_c_query *, GCE_system gSys, constraint_item cItem ); + +//---------------------------------------------------------------------------------------- +// It always returns 1.0 +//--- +inline double _DefaultWeight( GCT_auto_c_query *, constraint_type + , geom_item, geom_item ) { return 1.0; } + +//---------------------------------------------------------------------------------------- +// Структура запроса автоограничений +// Data structure of a query to autoconstrain +//--- +struct GCT_auto_c_query +{ + std::vector geoms; ///< \ru Множество объектов автоограничивания. \en Set of objects of auto-constraining. + GCT_auto_c_weight wFunc; + GCT_auto_c_query() : geoms(), wFunc( _DefaultWeight ) {} + +private: + GCT_auto_c_query( const GCT_auto_c_query & ); + GCT_auto_c_query & operator = ( const GCT_auto_c_query & ); +}; + +//---------------------------------------------------------------------------------------- +// +//--- +enum GCT_auto_c_result +{ + GCE_AUTO_C_DONE + , GCE_NO_AUTO_CONSTRAINT +}; + +//---------------------------------------------------------------------------------------- +// Задать автоматическое ограничение для данной пары объектов. +// Set automatic constraint for the given pair of geometric objects. +//--- +GCE_FUNC(constraint_item) GCT_AutoConstrain( GCE_system gSys, geom_item g1, geom_item g2, GCT_auto_c_query * ); + +//---------------------------------------------------------------------------------------- +// Автоматическая генерация ограничений. +// Automatically generate constraints. +//--- +GCE_FUNC(GCT_auto_c_result) GCT_AutoConstrain( GCE_system gSys, GCT_auto_c_query * ); + + +#endif + +// eof diff --git a/C3d/Include/gce_api.h b/C3d/Include/gce_api.h new file mode 100644 index 0000000..8a90053 --- /dev/null +++ b/C3d/Include/gce_api.h @@ -0,0 +1,1877 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Программный интерфейс решателя геометрических ограничений. + \en Program interface of geometric constraints solver. \~ + \details \ru Программный интерфейс геометрического решателя представляет + собой набор типов данных и функций, необходимых для решения + задачи геометрических ограничений. Предметная область решателя + предусматривает такие типы, как "геометрический объект", + "геометрическое ограничение", "система ограничений". Базовые типы + решателя объявлены в заголовочном файле . Вызовы функций + и их аргументы подобраны таким образом, что бы наиболее удобно + осуществлять формулировку задачи для решателя в терминах объектов + и ограничений. Названия многих типов данных и вызовов API начинаются + префиксом GCE, сокращенно Geometric Constraint Engine. \n + + Функции API решателя можно подразделить на такие группы: + 1) Функции #GCE_CreateSystem, #GCE_ClearSystem, #GCE_RemoveSystem + позволяют создавать и удалять систему ограничений в целом + (должны вызываться в однопоточном режиме);\n + 2) С помощью функций вида GCE_Add_XXXXXXX осуществляется формулировка + задачи ограничений, с их помощью в систему добавляются объекты и + ограничения (могут использоваться в параллельном режиме);\n + 3) Функции вида GCE_Change_XXXXXXX, GCE_Set_XXXXXXX позволяют менять + размеры и состояние объектов (могут использоваться в параллельном режиме);\n + 4) Функции для запросов такие, как GCE_Get_XXXXXXX, #GCE_SplinePoint, + GCE_IsXXXXX, #GCE_PointDOF и т.д. позволяют осуществлять запросы + о состоянии объектов или их свойств, узнать степень свободы объектов + и прочие характеристики (могут использоваться в параллельном режиме);\n + 5) Метод #GCE_Evaluate вычисляет состояния системы ограничений, в котором + все ограничения удовлетворены, или возвращает код ошибки при невозможности + найти решение (должна вызываться в однопоточном режиме).\n + 6) Другая группа вызовов отвечает за способы управления недоопределенной + системой ограничений. Вызовы #GCE_PrepareDraggingPoint, #GCE_MovePoint + обеспечивают интерактивную манипуляцию объектами чертежа/эскиза.\n + + \en A program interface of geometric solver represents + a set of data types and functions necessary for solution + of a problem of geometric constraints. Subject area of the solver + provides such types as "geometric object", "geometric constraint", + "constraint system". Base types of the solver are declared in the header + file . Calls of functions and their arguments are chosen + in such way that the formulation of the problem for the solver in terms + of objects and constraints could be performed by the most convenient way. + The names of many data types and API calls begins with a prefix 'GCE', + abbreviation for Geometric Constraint Engine. \n + + API functions of solver can be subdivided into the following groups: + 1) Functions #GCE_CreateSystem, GCE_ClearSystem, GCE_RemoveSystem + allow to create and delete the system of constraints in general + (should be called in sequential code);\n + 2) The problems of constraints are formulated with a function of a kind GCE_Add_XXXXXXX, + by using them the objects and constraints are added to the system + (could be called in multi-threaded mode);\n + 3) Functions of a kind GCE_Change_XXXXXXX, GCE_Set_XXXXXXX allow to change dimensions + and objects states (could be called in multi-threaded mode);\n + 4) Functions for requests, such as #GCE_Get_XXXXXXX, #GCE_SplinePoint, + #GCE_IsXXXXX, #GCE_PointDOF etc, allow to perform requests + about the states of objects or their properties, find the objects degree of freedom + and other characteristics could be called in multi-threaded mode;\n + 5) The method #GCE_Evaluate calculates the state of the constraint system, where + all constraints are satisfied or returns an error code if it is not possible + to find a solution (should be called in sequential code). \n + 6) Other group of calls responses for the ways of control of underdetermined + system of constraints. Calls of #GCE_PrepareDraggingPoint, #GCE_MovePoint + provide interactive manipulation with objects of drawing/sketch.\n \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_API_H +#define __GCE_API_H + +#include +#include +#include + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbCurve; + +/** + \addtogroup Constraints2D_API + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Создать пустую систему ограничений. + \en Create a simple constraint system. \~ + \details \ru Вызов создает пустую систему ограничений. Кроме того, в памяти + создаются внутренние структуры данных геометрического решателя, обслуживающего + систему ограничений. Функция возвращает специальный дескриптор, по которому + система ограничений доступна для различных манипуляций: добавление или удаление + геометрических объектов, ограничений, варьирование размеров, драггинг недоопределенных + объектов и т.д. + \en The call creates a simple constraint system. Besides, inside the memory + there are created internal data structures of geometric solver maintaining + the system of constraints. The functions returns a special descriptor by which + the constraint system is available for various manipulations: addition and deletion + of geometric objects, constraints, variation of sizes, dragging underconstrained objects + etc. \~ + + \return \ru Дескриптор системы ограничений. + \en Descriptor of constraint system. \~ +*/ +//--- +GCE_FUNC(GCE_system) GCE_CreateSystem(); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Сделать систему ограничений пустой. + \en Make the constraint system empty. \~ + \details \ru Данный метод делает систему ограничений пустой при этом + дескриптор gSys остается действительным, т.е. можно осуществлять дальнейшую + работу с системой ограничений. + \en This method makes the constraint system empty while + the descriptor gSys remains valid, i.e. it is possible to perform the further + work with the constraint system. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \sa #GCE_RemoveSystem +*/ +//--- +GCE_FUNC(void) GCE_ClearSystem( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить систему ограничений. + \en Delete system of constraints. \~ + \details \ru Данный метод делает систему ограничений недействительной. + Осуществляется освобождение ОЗУ от внутренних структур данных, обслуживающих + систему ограничений. + \en This method makes the constraint system invalid. + Deallocation of RAM from the internal data structures maintaining + the system of constraints is performed. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \sa #GCE_ClearSystem +*/ +//--- +GCE_FUNC(void) GCE_RemoveSystem( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений точку. + \en Add point to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pVal - \ru Координаты точки. + \en Point coordinates. \~ + \return \ru Дескриптор зарегистрированной точки. + \en Descriptor of registered point. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddPoint( GCE_system gSys, GCE_point pVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений прямую. + \en Add line to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] lVal - \ru Координаты прямой. + \en Line coordinates. \~ + \return \ru Дескриптор зарегистрированной прямой. + \en Descriptor of registered line. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddLine( GCE_system gSys, const GCE_line & lVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений отрезок прямой, заданный парой концевых точек. + \en Add a line segment specified by pair of end points to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] p - \ru Дескрипторы конечных точек отрезка. + \en Descriptors of end points of the line segment. \~ + \return \ru Дескриптор зарегистрированного отрезка. + \en Descriptor of registered segment. \~ + \details \ru Для отрезка, созданного через данный вызов, действительны все типы + ограничений, которые применимы для прямой, создаваемой вызовом GCE_AddLine. + \en All types of constraints which are applicable to the line created by GCE_AddLine + are valid for the segment created by this call. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddLineSeg( GCE_system gSys, geom_item p[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений окружность. + \en Add circle to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cVal - \ru Координаты окружности. + \en Coordinates of a circle. \~ + \return \ru Дескриптор зарегистрированной окружности. + \en Descriptor of the registered circle. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddCircle( GCE_system gSys, const GCE_circle & cVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений эллипс. + \en Add ellipse to the constraint system. \~ + \param[in] \ru gSys Система ограничений. + \en gSys System of constraints. \~ + \param[in] \ru eVal Координаты эллипса. + \en eVal Ellipse coordinates. \~ + \return \ru Дескриптор зарегистрированного эллипса. + \en Descriptor of registered ellipse. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddEllipse( GCE_system gSys, const GCE_ellipse & eVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений сплайн (NURBS) + \en Add spline (NURBS) to the constraint system \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] spl - \ru Координаты сплайна. + \en Spline coordinates. \~ + \return \ru Дескриптор зарегистрированного сплайна. + \en Descriptor of registered spline. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddSpline( GCE_system gSys, const GCE_spline & spl ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений параметрическую кривую. + \en Add parametric curve to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] crv - \ru Математическое описание параметрической кривой. + \en Mathematical description of parametric curve. \~ + \return \ru Дескриптор зарегистрированной параметрической кривой. + \en Descriptor of registered parametric curve. \~ + \attention \ru Время жизни экземпляра класса crv опирается на счетчик ссылок, т.е. + решатель его увеличивает при добавлении параметрической кривой и + декрементирует при удалении кривой из решателя. + \en The lifetime of the instance of the class 'crv' is based on the reference counter, i.e. + the solver increases it when adding a parametric curve and + decreases when deleting a curve from the solver. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddParametricCurve( GCE_system gSys, const MbCurve & crv ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему граничную кривую, ограниченную парой точек. + \en Add a curve bounded by a pair of points to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] crv - \ru Дескриптор базовой геометрической кривой. Базовой кривой может + быть только кривая одного из следующих типов: прямая, окружность, + эллипс, сплайн или параметрическая кривая. + \en Descriptor of base geometric curve. Base curve may + be only one curve from the following types: line, circle, + ellipse, spline or parametric curve. \~ + \param[in] p - \ru Пара дескрипторов начальной и конечной точек участка кривой. + \en A pair of descriptors of the beginning and ending points of curve piece. \~ + \return \ru Дескриптор зарегистрированной ограниченной кривой. + \en Descriptor of registered bounded curve. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_AddBoundedCurve( GCE_system gSys, geom_item curve, geom_item p[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему жёсткое множество геометрических объектов. + \en Add a rigid set of geometric objects to the system. \~ + \details \ru Жёсткое множество - это массив геометрических объектов, зафиксированных друг относительно друга. + Жёсткое множество представляет собой геометрический объект, для которого доступен весь функционал + работы с геометрическими объектами. Например, у него можно спросить тип (#GCE_GeomType -> GCE_SET) или запросить + положение. С помощью вызовов #GCE_GetPoint и #GCE_GetCoordValue можно получить начало координат и направление оси OX + ЛСК жёсткого множества. Чтобы удалить жёсткое множество, надо, как и для любого другого геометрического объекта, + вызвать функцию #GCE_RemoveGeom. При этом составляющие жёсткое множество объекты (geoms) при удалении жёсткого + множества не удаляются и могут далее быть использованы в решателе. С геометрическими объектами, образующими + жёсткое множество, нужно работать точно так же, как и до их добавления в жёсткое множество. Например, для наложения + ограничения между элементом жёсткого множества и любым другим геометрическим объектом необходимо в + качестве аргумента ограничения указывать не дескриптор жёсткого множества, которому данный объект принадлежит, а + дескриптор самого геометрического объекта из массива geoms, на который накладывается ограничение. + \en A rigid set is an array of geometric objects which are fixed relative to each other. It is considered as a + geometric object and hence all the functionality for working with geometric objects is available for it. For + example, it's possible to request its type (#GCE_GeomType -> GCE_SET) or get its position invoking #GCE_GetPoint + and #GCE_GetCoordValue to get the origin and the direction of the OX axis of the LCS of the rigid set. To remove + a rigid set it's necessary to call the function #GCE_RemoveGeom. Geometric objects (geoms) are not deleted together + with a rigid set and can be used in the solver after it will be deleted. With geometric objects that have been + included in a rigid set it is necessary to continue to work just as before adding them to a rigid set. For + instance, to specify a constraint between an element of a rigid set and any other geometric object, it is necessary + to specify as the constraint argument not the descriptor of the rigid set to which the object belongs but the + descriptor of the geometric object from the geoms array on which the constraint is specified.\~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] geoms - \ru Массив дескрипторов геометрических объектов, образующих жёсткое множество. + \en \~ + \return \ru Дескриптор зарегистрированного жёсткого множества объектов. + \en Descriptor of registered bounded curve. \~ +*/ +// --- +GCE_FUNC(geom_item) GCE_AddRigidSet( GCE_system gSys, const std::vector & geoms ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений переменную. + \en Add a variable to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] val - \ru Начальное значение переменной. + \en A start value of the variable. \~ + \return \ru Дескриптор зарегистрированной переменной. + \en Descriptor of registered variable. \~ +*/ +//--- +GCE_FUNC(var_item) GCE_AddVariable( GCE_system gSys, double val ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Тип геометрического объекта. + \en A type of geometric object. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \return \ru Тип геометрического объекта. + \en A type of geometric object. \~ +*/ +//--- +GCE_FUNC(geom_type) GCE_GeomType( GCE_system gSys, geom_item g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Тип геометрической кривой. + \en A type of geometric curve. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор кривой. + \en Descriptor of curve \~ + \return \ru Тип геометрического объекта. + \en A type of geometric object. \~ + \details \ru The function returns geometric type of a curve 'crv' or type + of a base curve if 'crv' has type #GCE_BOUNDED_CURVE. + \en Функция вернет геометрический тип кривой 'crv' либо тип базовой кривой, + если 'crv' имеет тип #GCE_BOUNDED_CURVE. \~ +*/ +//--- +GCE_FUNC(geom_type) GCE_BaseCurveType( GCE_system gSys, geom_item crv ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить переменную из системы ограничений. + \en Delete variable from the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] var - \ru Дескриптор переменной. + \en Descriptor of variable. \~ + \return \ru true, если переменная var действительно удалена. + \en it equals true if the variable var is actually deleted. \~ +*/ +//--- +GCE_FUNC(bool) GCE_RemoveVariable( GCE_system gSys, var_item var ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить геометрический объект из системы ограничений. + \en Delete geometric object from the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \return \ru true, если геометрический объект g действительно удален. + \en it equals true if the geometric object g is actually deleted. \~ +*/ +//--- +GCE_FUNC(bool) GCE_RemoveGeom( GCE_system gSys, geom_item g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить ограничение из системы. + \en Delete a constraint from the system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] con - \ru Дескриптор ограничения. + \en Descriptor of constraint. \~ + \return \ru true, если ограничение con действительно удалено. + \en it equals true if the constraint con is actually deleted. \~ +*/ +//--- +GCE_FUNC(bool) GCE_RemoveConstraint( GCE_system gSys, constraint_item con ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запросить дескриптор контрольной точки объекта. + \en Request of the object control point descriptor. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор объекта. + \en Descriptor of object. \~ + \param[in] pnt - \ru Имя контрольной точки объекта. + \en Name of the object control point. \~ + \return \ru Дескриптор контрольной точки объекта. + \en Descriptor of the object control point. \~ + + \details \ru Дескриптор, полученный по значению этой функции, имеет автоматическое + время жизни, т.е. нет необходимости вызывать для него метод #GCE_RemoveGeom. + \en Descriptor obtained by the value of this function, it has automatical + lifetime, i.e. there is no reason to call the method #GCE_RemoveGeom for it. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_PointOf( GCE_system gSys, geom_item g, point_type pnt ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Дескриптор контрольной точки сплайна по индексу. + \en Descriptor of spline control point by index \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] spl - \ru Дескриптор сплайна. + \en Descriptor of spline. \~ + \param[in] pntIdx - \ru Индекс контрольной точки. + \en A control point index. \~ + \return \ru Дескриптор контрольной точки сплайна. + \en Descriptor of spline control point. \~ + + \details \ru Дескриптор, полученный по значению этой функции, имеет автоматическое + время жизни, т.е. нет необходимости вызывать для него метод #GCE_RemoveGeom. + \en Descriptor obtained by the value of this function, it has automatical + lifetime, i.e. there is no reason to call the method #GCE_RemoveGeom for it. \~ +*/ +//--- +GCE_FUNC(geom_item) GCE_SplinePoint( GCE_system gSys, geom_item spl, size_t pntIdx ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить текущие координаты вектора. + \en Get the current coordinates of vector. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор вектора или иного геометрического объекта. + \en Descriptor of vector or other geometric object. \~ + \param[in] vType - \ru Идентификатор вектора, принадлежащего объекту (в настоящий момент равен или GCE_DIRECTION, или GCE_ORIENTATION). + GCE_DIRECTION возвращает направляющую прямой, отрезка или главной полуоси эллипса. + \en Identifier of vector belonging to the object (currently it equals GCE_DIRECTION or GCE_ORIENTATION). + In case of GCE_DIRECTION function returns direction vector for line, line segment or ellipse major axis.\~ + \return \ru Координаты вектора. + \en Vector coordinates. \~ +*/ +//--- +GCE_FUNC(GCE_vec2d) GCE_GetVectorValue( GCE_system gSys, geom_item g, query_geom_type vType ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить текущие координаты точки. + \en Get the current coordinates of point. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор точки или иного геометрического объекта. + \en Descriptor of point or other geometric object. \~ + \param[in] pName - \ru Идентификатор точки, принадлежащей объекту. + \en Identifier of a point belonging to the object. \~ + \return \ru Координаты точки. + \en Point coordinates \~ +*/ +//--- +GCE_FUNC(GCE_point) GCE_GetPointXY( GCE_system gSys, geom_item g, point_type pName = GCE_PROPER_POINT ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить текущее значение координаты геометрического объекта. + \en Get the current value of geometric object's coordinate. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор объекта. + \en Descriptor of object. \~ + \param[in] cName - \ru Обозначение параметра объекта. + \en Denotation of object parameter. \~ + \return \ru Координаты точки. + \en Point coordinates \~ + \details \ru Получить текущее значение координаты геометрического объекта. Например, + с помощью данной функции можно узнать текущее значение большой или малой + полуоси эллипса, радиус окружности и т.д. + \en Get the current value of geometric object's coordinate. For example, + by using this function one can find the current value of the major or the minor + semi-axis of ellipse, circle radius etc. \~ +*/ +//--- +GCE_FUNC(double) GCE_GetCoordValue( GCE_system gSys, geom_item g, coord_name cName ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить текущее значение переменной. + \en Get the current value of variable. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] var - \ru Дескриптор переменной. + \en Descriptor of variable. \~ + \return \ru Значение переменной. + \en A value of variable. \~ +*/ +//--- +GCE_FUNC(double) GCE_GetVarValue( GCE_system gSys, var_item var ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать текущие координаты точки. + \en Set the current coordinates of point. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор точки или иного геометрического объекта. + \en Descriptor of point or other geometric object. \~ + \param[in] pName - \ru Идентификатор точки, принадлежащей объекту. + \en Identifier of a point belonging to the object. \~ + \param[in] xyVal - \ru Новое значение координат точки. + \en New value of point coordinates. \~ + \return \ru true, если операция выполнена успешно. + \en true if operation succeeded. \~ + + \details \ru Метод присваивает точке или контрольной точке объекта g c + атрибутом pName новое состояние координат (параметр xyVal). Следует учитывать, + что вызов #GCE_SetPointXY не решает системы ограничений, а только меняет состояние + геометрического объекта. При этом система ограничений может стать неудовлетворенной. + Состояние точки, присвоенное вызовом GCE_SetPointXY не обязано сохранятся после + вызова #GCE_Evaluate, если точка не фиксированная или не замороженная. + \en The method assigns to the point or the control point of the object g with + the attribute pName a new state of coordinates (the parameter xyVal). It should be taken into account + that the call of #GCE_SetPointXY doesn't solve the constraint system but only changes the state + of geometric object. At the same time the constraint system may become unsatisfied. + The state of a point assigned by the call of GCE_SetPointXY should not be saved after + the call of #GCE_Evaluate if the point is not fixed or not frozen. \~ +*/ +//--- +GCE_FUNC(bool) GCE_SetPointXY( GCE_system gSys, geom_item g, point_type pName, GCE_point xyVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать текущее значение координаты геометрического объекта. + \en Set the current value of geometric object's coordinate. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор объекта. + \en Descriptor of object. \~ + \param[in] cName - \ru Обозначение параметра объекта. + \en Denotation of object parameter. \~ + \param[in] crdVal - \ru Новое значение координаты. + \en New value of coordinate. \~ + \return \ru true, если операция выполнена успешно. + \en true if operation succeeded. \~ + + \details \ru Метод присваивает координате объекта g c атрибутом cName новое значение. + Следует учитывать, что вызов #GCE_SetCoordValue не решает системы ограничений, + а только меняет состояние геометрического объекта. При этом система ограничений + может стать неудовлетворенной. Состояние координаты, присвоенное этим методом + не обязано сохранятся после вызова #GCE_Evaluate, если точка не фиксированная + или не замороженная. + \en The method assigns a new value to the coordinate of the object g with the attribute cName. + It should be taken into account that the call of #GCE_SetCoordValue doesn't solve the constraint system + but only changes the state of geometric object. At the same time the constraint system + may become unsatisfied. The state of coordinate assigned by this method + should not be saved after the call of #GCE_Evaluate if the point is not fixed + or not frozen. \~ +*/ +//--- +GCE_FUNC(bool) GCE_SetCoordValue( GCE_system gSys, geom_item g, coord_name cName, double crdVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать текущее значение переменной. + \en Set the current value of variable. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] var - \ru Дескриптор переменной. + \en Descriptor of variable. \~ + \param[in] val - \ru Новое значение переменной. + \en New value of variable. \~ + \return \ru true, если операция выполнена успешно. + \en true if operation succeeded. \~ +*/ +//--- +GCE_FUNC(bool) GCE_SetVarValue( GCE_system gSys, var_item var, double val ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Заморозить геометрический объект. + \en Freeze geometric object. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Геометрический объект. + \en Geometric object. \~ + \return \ru true, если операция выполнена успешно. + \en true if operation succeeded. \~ + + \details + + \ru Функция лишает объект всей степени свободы. Отдельно можно заметить, что + функция GCE_IsConstrainedGeom для замороженного объекта вернет false, если + объект не был связан другими ограничениями. Т.е. заморозка не считается + ограничением.\n + Решатель не может менять замороженную геометрию, но её может поменять + клиентское приложение методами GCE_SetCoordValue или GCE_SetPointXY. + Замороженные объекты следует рассматривать в качестве независимых входных + параметров системы ограничений. + + \en The function deprives the object of all degrees of freedom. Note that + the function GCE_IsConstrainedGeom returns false for the frozen object if + the object was not connected with other constraints. I.e. the freezing is not considered + as a constraint.\n + The solver cannot change the frozen geometry but the user application can change it + with the methods GCE_SetCoordValue or GCE_SetPointXY. Frozen objects should be + considered as independent input parameters of constraint system. \~ + + \note + \ru Обычно на стороне САПР эта команда применяется для фиксации проекционной геометрии + в ассоциативных чертежах или в эскизах с проекциями трехмерных объектов. + \en Usually, in CAD applications this command is used only for fixation of projection + geometry in associative drawings or sketches with projections of 3D-objects. \~ +*/ +//--- +GCE_FUNC(bool) GCE_FreezeGeom( GCE_system gSys, geom_item g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Функция отвечает на вопрос: Связан ли геометрический объект ограничениями? + \en The function answers the question: Is geometric object connected with constraints? \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object. \~ + \return \ru true, если для объекта g задано хотя бы одно ограничение. + \en true if at least one constraint is set for the object g. \~ + \sa GCE_RemoveGeom, GCE_RemoveConstraint +*/ +//--- +GCE_FUNC(bool) GCE_IsConstrainedGeom( GCE_system gSys, geom_item g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выполнить проверку удовлетворенности ограничения. + \en Perform a check that a constraint is satisfied. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cItem - \ru Дескриптор ограничения. + \en Descriptor of constraint. \~ + \return \ru true, если ограничение удовлетворено. + \en true if a constraint is satisfied. \~ +*/ +//--- +GCE_FUNC(bool) GCE_IsSatisfied( GCE_system gSys, constraint_item cItem ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Статус ограничения в системе. + \en Status of constraint inn the system. + \details + \ru Вызов показывает результат диагностики, которая выделяет в системе ограничений + хорошо-обусловленные части и части, содержащие переопределения и противоречия. В результате + диагностики или попытки решения каждое ограничение помечается одним из статусов, + перечисленных в наборе GCE_c_status. + + \en The call shows the result of the diagnostic, which highlights the constraint system + well-conditioned parts and parts containing redundancies and inconsistencies. As a result + diagnosing or evaluating each constraint is marked with one of the statuses enumerated by + GCE_c_status enum. + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cItem - \ru Дескриптор ограничения. + \en Descriptor of constraint. \~ + \return \ru Статус ограничения в результате диагностики на противоречия или переопределения. + \en The status of the constraint as a result of diagnostics on inconsistence and overdefining. \~ + +*/ +// --- +GCE_FUNC(GCE_c_status) GCE_ConstraintStatus( GCE_system gSys, constraint_item cItem ); + +//---------------------------------------------------------------------------------------- +/** + brief \ru Выполнить диагностику геометрических объектов. + \en Diagnose geometry. \~ + \details + \ru Если в ходе решения системы ограничений вырождаются какие-то геометрические объекты + (функция #GCE_Evaluate возвращает GCE_RESULT_InvalidGeometry ), то данная функция возвращает + массив индексов, под которыми эти объекты зарегистрированы в решателе. + Если вырождающихся объектов нет, то функция вернет пустой массив. + \en If some geometrical objects are degenerate in the course of solving the system of constraints + (function #GCE_Evaluate returns GCE_RESULT_InvalidGeometry ), this function returns an array of indices + by which these geometric objects are registered in the solver. + If geometrical objects do not degenerate, then the function returns an empty array. \~ + \param[in] gcSys - \ru Система ограничений. + \en System of constraints. \~ + \return \ru Вектор индексов объектов с вырожденной геометрией. + \en Vector of indices of objects with invalid geometry. \~ +*/// --- +GCE_FUNC(std::vector) GCE_DiagnoseGeometry( GCE_system gcSys ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Вычислить степень свободы точки. + \en Calculate point's degree of freedom. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \param[in] cp - \ru Код контрольной точки объекта g. + \en The code of control point of the object g. \~ + \param[out] dofDir- \ru Угловое направление свободы перемещения точки в радианах. + \en Angular direction of point moving freedom in radians. \~ + \return \ru Функция возвращает степень свободы точки; Если возвращается значение < 0, + то вычислить степень свободы не удалось. + \en The function returns degree of freedom of the point; If a negative value is returned, + then it is failed to calculate the degree of freedom. \~ + + \details \ru Данная функция возвращает степень свободы точки и может принимать + одно из следующих значений:\n + (-1) - Означает, что функция не определила степень свободы;\n + 0 - Означает, что точка неподвижна в системе ограничений;\n + 1 - Означает, что точка имеет свободу перемещения вдоль некоторой траектории, причем + через параметр dofDir возвращается направление тангенциального вектора перемещения + точки;\n + 2 - Означает, что точка имеет свободу перемещения в некоторой 2D-области.\n + Если направление перемещения определить не удалось, то dofDir принимает значение < 0. + + \en This function returns the point's degree of freedom and may take + one of the following values:\n + (-1) - It means that the function didn't determine the degree of freedom;\n + 0 - It means that the point is fixed in constraint system. + 1 - It means that the point has a freedom of movement along some trajectory, besides + the direction of point movement tangent vector is returned via the parameter dotDir;\n + 2 - It means that the point has a movement freedom inside some two-dimensional region.\n + If the direction of movement was not determined, then dotDir takes a negative value. \~ +*/ +//-- +GCE_FUNC(ptrdiff_t) GCE_GetPointDOF( GCE_system gSys, geom_item g, point_type cp, double & dofDir ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Вычислить степень свободы точки. + \en Calculate point's degree of freedom. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pnt - \ru Дескриптор точки. + \en Descriptor of point \~ + \param[out] dofDir- \ru Угловое направление свободы перемещения точки в радианах. + \en Angular direction of point moving freedom in radians. \~ + \return \ru Функция возвращает структуру #GCE_point_dof, которая описывает + степень свободы точки, её целочисленное значение и вектор перемещения. + Если возвращается значение dof < 0, то вычислить степень свободы не удалось. + \en The function returns a structure #GCE_point_dof, which describes degree + of freedom of the point, namely its integral value (dof) and direction + vector of point moving freedom (dir). If a negative value (dof) is returned, + then it is failed to calculate the degree of freedom. \~ + + \details \ru Данная функция возвращает степень свободы точки и может принимать + одно из следующих значений:\n + dof = (-1) - Означает, что функция не определила степень свободы;\n + dof = 0 - Означает, что точка неподвижна в системе ограничений;\n + dof = 1 - Означает, что точка имеет свободу перемещения вдоль некоторой траектории, + причем через параметр "dir" (в структуре #GCE_point_dof ) возвращается направление + тангенциального вектора перемещения точки;\n + dof = 2 - Означает, что точка имеет свободу перемещения в некоторой 2D-области.\n + Если направление перемещения определить не удалось, то "dof" принимает значение < 0. + + \en This function returns the point's degree of freedom and may take + one of the following values:\n + dof = (-1) - It means that the function didn't determine the degree of freedom;\n + dof = 0 - It means that the point is fixed in constraint system. + dof = 1 - It means that the point has a freedom of movement along some trajectory, besides + the direction of point movement tangent vector is returned via the parameter "dir" + of data structure #GCE_point_dof;\n + dof = 2 - It means that the point has a movement freedom inside some two-dimensional region.\n + If the direction of movement was not determined, then "dof" takes a negative value. \~ +*/ +//-- +GCE_FUNC(GCE_point_dof) GCE_PointDOF( GCE_system gSys, geom_item pnt ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать степень свободы геометрической координаты. + \en Get the degree of freedom of geometric coordinate. + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of a geometric object. \~ + \param[in] cName - \ru Обозначение геометрической координаты. + \en Denotation of geometric coordinate. \~ + \return \ru Степень свободы координаты: 1-для недоопределенной координаты, 0-для полно-заданной координаты. + \en Degree of freedom: 1 for underdefined coordinate, 0 for well-defined coordinate.\~ + + \details + \ru Функция возвращает степень свободы координаты, а именно одно из возможных + значений: 1, 0 и -1. Если возвращается значение < 0, то вычислить степень + свободы не удалось. + \en The function returns degree of freedom of the coordinate, namely one of the + possible values: 1, 0 and -1. If a negative value is returned, then it is + failed to calculate the degree of freedom. \~ + +*/ +//--- +GCE_FUNC(int) GCE_CoordDOF( GCE_system gSys, geom_item g, coord_name cName ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение для одного объекта (унарное ограничение). + \en Set a constraint on single object (unary constraint). \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cType - \ru Значение одного из следующих типов ограничений: GCE_FIX_GEOM; GCE_VERTICAL; GCE_HORIZONTAL; GCE_ANGLE_OX; GCE_LENGTH. + \en The value of one of the following types of constraints: GCE_FIX_GEOM; GCE_VERTICAL; GCE_HORIZONTAL; GCE_ANGLE_OX; GCE_LENGTH. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details + \ru Функция задает унарное ограничение, а именно ограничение, относящееся к одному из типов, + действительных для одного геометрического объекта. + \en The function specifies an unary constraint, namely constraint which has one of types + that are valid for single geometric object. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddUnaryConstraint( GCE_system gSys, constraint_type cType, geom_item geom ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Совпадение". + \en Set the constraint "Coincidence". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары геометрических объектов. + \en Descriptors of geom objects pair. \~ + \details + \ru Если ограничение совпадение задано для точки и кривой, то предполагается, что точка + лежит на кривой. Если совпадение задано для геометрических объектов одного и того + же типа, то совпадение подразумевает, что они равны. + \en If a coincident constraint is defined between a point and a curve then this implies + that the point lies on the curve. A coincident constraint defined between two + geometries of the same type implies that they are equal. + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \attention + \ru В текущей версии решателя применение этого ограничения возможно + только для двух точек либо для точки и кривой. На будущее планируется расширить + его применения для других типов. + \en In the current version of solver using of this constraint is possible only for + two points either for a point and a curve. It is planned to extend its application + area for other types. \~ +*/ +// --- +GCE_FUNC(constraint_item) GCE_AddCoincidence( GCE_system gSys, geom_item g[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Ограничение "Точка на участке кривой по коэффициенту его параметрической длины". + \en The constraint "Point on a piece of a curve by the coefficient of its parametric range". \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curve - \ru Дескриптор кривой. + \en Descriptor of a curve. \~ + \param[in] pnt - \ru Дескрипторы точек: две крайние точки участка и точка между. + \en Descriptors of points: two boundary points of a piece and a point between. \~ + \param[in] k - \ru Долевой коэффициент от параметрической длины участка. + \en Coefficient for a part of parametric range of piece. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \details \ru Предполагается, что для кривой curve и точек pnt[0], pnt[1], обеспечивается + инцидентность другими ограничениями, зарегистрированными в решателе, или эти + точки априори принадлежат кривой. Для точки pnt[2] инцидентность с кривой задавать + не требуется, т.к. данное ограничение уже обеспечивает это. Если pnt[0] = pnt[1] = GCE_NULL_G, то участок + кривой, для которого исчисляется процент k, совпадает со всей параметрической + областью кривой. Например, для окружности параметрическая область равна + интервалу [-PI ... PI]. Область значений k из интервала от 0 до 1 отображается + на параметрическую область участка кривой, соответственно k = 0 прикрепит точку + pnt[2] к началу участка, а k = 1.0 к концу участка. + + \en It is assumed that for the curve 'curve' and the points pnt[0], pnt[1] an incidence + is provided with the other constraints registered in solver or these + points a priori belong to a curve. An incidence between pnt[2] and 'curve' is not required because + this constraint already provides an incidence. If pnt[0] = pnt[1] = GCE_NULL_G, then the piece + of a curve for which the percentage k is calculated coincides with the whole parametric + region of a curve. For example, in a case of circle the parametric range is equal + to the interval [-PI ... PI]. The range of values of k from the interval from 0 to 1 is mapped + to the parametric region of curve's piece, k = 0 attaches the point + pnt[2] to the beginning of the piece and k = 1.0 - to the end of the piece. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddPointOnPercent( GCE_system gSys, geom_item curve, geom_item pnt[3], double k ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Ограничение "Точка на участке кривой по коэффициенту его длины". + \en The constraint "Point on a piece of a curve by the coefficient of its length". \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curve - \ru Дескриптор кривой. + \en Descriptor of a curve. \~ + \param[in] pnt - \ru Дескрипторы точек: две крайние и точка между ними. + \en Descriptors of points: two boundary points and a point between them. \~ + \param[in] k - \ru Значение доли от метрической длины между заданными точками. + \en Value of a part (proportion) of the arc length between the two points. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \details \ru Метод создает в системе ограничение, задающее положение точки на + участке кривой, заданное коэффициентом от его длины. Предполагается, + что для кривой curve и точек pnt[0], pnt[1], обеспечивается инцидентность другими, + зарегистрированными в решателе, ограничениями или эти точки априори принадлежат + кривой. Если pnt[0] = pnt[1] = GCE_NULL_G, то участок кривой, для которого + исчисляется процент k, совпадает со всей параметрической областью кривой. + Например, для окружности параметрическая область равна интервалу [-PI ... PI]. + Если k = 0, то ограничение прикрепит точку pnt[2] к началу участка, если k = 1.0, + то ограничение прикрепит точку pnt[2] к концу участка. + + \en The method creates a constraint specifying the point location on + a piece of a curve which is set by the coefficient (proportional) of its arc length. + It is assumed that for the curve 'curve' and the points pnt[0], pnt[1] an incidence + is provided with the other constraints registered in the solver or these points belong to + the curve a priori. If pnt[0] = pnt[1] = GCE_NULL_G, then the piece of a curve for which + the percentage k is calculated coincides with the whole parametric region of a curve. + For example, in a case of circle the parametric range is equal to the interval [-PI ... PI]. + If k = 0, then the constraint attaches the point pnt[2] to the beginning of the piece, if k = 1.0, + then the constraint attaches the point pnt[2] to the end of the piece. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddPointByMetricPercent( GCE_system gSys, geom_item curve, geom_item pnt[3], double k ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Фиксация положения точки, лежащей на кривой". + \en Set the constraint "Fixation of location of the point lying on a curve". \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curve - \ru Дескриптор кривой. + \en Descriptor of a curve. \~ + \param[in] pnt - \ru Дескрипторы точки. + \en Descriptors of a point. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \details \ru Данная функция создает ограничение, прикрепляющее точку к кривой в текущем + месте. Точка локализуется, опираясь на параметрическое представление кривой, с помощью + параметра вдоль кривой, где она расположена. Требуется, что бы к моменту вызова функции, + точка лежала на кривой, а для точки и кривой curve должна обеспечиваться инцидентность + с помощью других ограничений или эта точка априори должна принадлежать кривой. + \en This function creates a constraint attaching a point to the curve in the current + location. The point is localized according to the parametric representation of a curve with a help of + parameter along a curve where it is located. It is required that at the moment when the function is called + the point is lying on the curve, and coincidence between the point and the curve should be provided + by other constraints or this point should belong to the curve a priori. \~ + + \attention \ru В Cad-системе КОМПАС данная функция применяется только для фиксации концов + участка (bounded curve) параметрической кривой, полученной проецированием из 3D-модели. + Для таких ограничений, как "средняя точка" рекомендуется применять более + нативную функцию #GCE_AddMiddlePoint. + \en In CAD system KOMPAS this function is used only for fixation of ends of + a piece ('bounded curve') of a parametric curve obtained by projecting from 3D model. + It is recommended to apply the more native function + #GCE_AddMiddlePoint for such constraints as "middle point". \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddFixCurvePoint( GCE_system gSys, geom_item curve, geom_item pnt ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Точка на параметрическом эллипсе". + \en Set the constraint "Point on parametric ellipse". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pnt - \ru Дескриптор точки. + \en Descriptor of a point. \~ + \param[in] ellipse - \ru Дескриптор эллипса. + \en Descriptor of ellipse. \~ + \param[in] \ru t Значение параметра на эллипсе из области [-PI,PI]. + \en t The value of parameter on ellipse from the region [-PI,PI]. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Данная функция действительна только для кривых, относящихся типу + "эллипс", функция создает ограничение, обеспечивающее совпадение точки pnt с + точкой эллипса, заданной параметром t из параметрической области эллипса, + равной интервалу [-PI,PI]. + \en This function is valid only for curves of the type + "ellipse", the function creates a constraint which provides coincidence between the point pnt and + the ellipse point set by the parameter t from the ellipse parametric region + which is equal to the interval [-PI,PI]. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddPointOnParEllipse( GCE_system gSys, geom_item pnt, geom_item ellipse, double t ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Точка на кривой по параметру". + \en Specify a constraint "Point on curve at a given parameter". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pnt - \ru Дескриптор точки. + \en Descriptor of a point. \~ + \param[in] curve - \ru Дескриптор кривой. + \en Descriptor of a curve. \~ + \param[in] t - \ru Дескриптор параметра кривой. + \en Descriptor of a curve parameter. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Функция отличается от #GCE_AddCoincidence тем, что позволяет связать точку с параметрической + кривой через значение параметра и управлять её положением на кривой через этот параметр. + Ограничение доступно для следующих типов кривой: #GCE_ELLIPSE, #GCE_SPLINE, + #GCE_PARAMETRIC_CURVE и #GCE_BOUNDED_CURVE, основанной на кривой одного из перечисленных + типов. + \en This function differs from #GCE_AddCoincidence in that it allows to link a point with a + parametric curve through a parameter value and control its position on the curve through this + parameter. The constraint is available for the following curve types: #GCE_ELLIPSE, + #GCE_SPLINE, #GCE_PARAMETRIC_CURVE and #GCE_BOUNDED_CURVE, based on the curve of one of the + listed types. +*/ +// --- +GCE_FUNC(constraint_item) GCE_AddParPointOnCurve( GCE_system gSys, geom_item pnt, geom_item curve, var_item t ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Выравнивание точек вдоль заданного направления". + \en Set the constraint "Alignment of points along the given direction". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] p - \ru Дескрипторы пары точек. + \en Descriptors of point pair. \~ + \param[in] ang - \ru Угол, задающий направление выравнивания, радианы. + \en An angle specifying alignment direction, in radians. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddAlignPoints( GCE_system gSys, geom_item p[2], double ang ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Угловой размер между двумя прямыми". + \en Set the constraint "Angular dimension between two lines". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] l1 - \ru Дескриптор первого линейного геометрического объекта. + \en Descriptor of the first linear geometric object. \~ + \param[in] l2 - \ru Дескриптор второго линейного геометрического объекта. + \en Descriptor of the second linear geometric object. \~ + \param[in] dPars - \ru Параметры углового размера (подробности см.#GCE_adim_pars). + \en Parameters of angular dimension (see #GCE_adim_pars). \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Угловой размер для пары линейных геометрических объектов. Аргументами + ограничения могут быть объекты, принадлежащие типам: "прямая", "отрезок" или + "Bounded curve", основанной на прямой. + \en Angular dimension for a pair of linear geometric objects. Arguments + of constraint are objects of the following types: "line", "segment" or + "Bounded curve" based on line. \~ + +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddAngle( GCE_system gSys, geom_item l1, geom_item l2 + , const GCE_adim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Биссектриса". + \en Set the constraint "Bisector of angle". \~ + \param[in] \ru gSys Система ограничений. + \en gSys System of constraints. \~ + \param[in] \ru bl отрезок, биссектриса между двумя прямыми. + \en bl a segment, bisector of angle between two lines. \~ + \param[in] \ru l1, l2 прямые или отрезки, между которыми устанавливается биссектриса. + \en l1, l2 lines or segments a bisector of angle is set between. \~ + \param[in] \ru variant вариант решения для биссектрисы. + \en variant variant of solution for bisector of angle. \~ + \return \ru дескриптор нового ограничения. + \en descriptor of new constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddAngleBisector( GCE_system gSys + , geom_item l1, geom_item l2 + , geom_item bl + , GCE_bisec_variant variant ); + +//---------------------------------------------------------------------------------------- +/// \ru Задать угловой размер для четырех точек. \en Specify angular dimension for four points. +/**\ru Конструируется угловой размер для двух отрезков с точками p1-p2, p3-p4. + \en Angular dimension is constructed for two segments with points p1-p2, p3-p4. \~ + \param[in] \ru gSys - Система ограничений. + \en gSys - System of constraints. \~ + \param[in] \ru fPair - Первая пара точек (первый отрезок). + \en sPair - First pair of points (first segment).\~ + \\param[in] \ru fPair - Вторая пара точек (второй отрезок). + \en sPair - Second pair of points (second segment).\~ + \param[in] dPars - \ru Параметры углового размера (подробности см.#GCE_adim_pars). + \en Parameters of angular dimension (see #GCE_adim_pars). \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddAngle4P( GCE_system gSys, geom_item fPair[2] + , geom_item sPair[2], const GCE_adim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Коллинеарность". + \en Set the constraint "Colinearity". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары линейных объектов. + \en Descriptors of a pair of linear objects. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Ограничение делает пару объектов, принадлежащими общей прямой, применяется + для прямых или отрезков. + \en Constraint makes a pair of objects belonging to the common line, it is used + for lines or segments. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddColinear( GCE_system gSys, geom_item g[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Коллинеарность трех точек". + \en Set the constraint "Colinearity of three points". \~ + \details \ru Задать для трех точек отношение, такое что точки лежат на одной прямой. + \en Set such a constraint for three points that points should lie on the same line. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pnt - \ru Тройка точек, лежащих на одной прямой. + \en A triplet of points lying on the same line. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddColinear3Points( GCE_system gcSys, geom_item pnt[3] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Равенство длин" для отрезков. + \en Set the constraint "Equality of lengths" for segments. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] ls1 - \ru Дескриптор первого отрезка. + \en Descriptor of the first segment. \~ + \param[in] ls2 - \ru Дескриптор второго отрезка. + \en Descriptor of the second segment. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Ограничение применимо для отрезков или участков прямых, созданных с помощью + функции #GCE_AddBoundedCurve или #GCE_AddLineSeg. + \en The constraint is applicable for segments or line pieces created by + the function #GCE_AddBoundedCurve or #GCE_AddLineSeg. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddEqualLength( GCE_system gSys, geom_item ls1, geom_item ls2 ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Равенство радиусов" для двух окружностей (дуг) + \en Set the constraint "Equality of radii" for two circles (arcs) \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] c1 - \ru Дескриптор первой окружности. + \en Descriptor of the first circle. \~ + \param[in] c2 - \ru Дескриптор второй окружности. + \en Descriptor of the second circle. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddEqualRadius( GCE_system gSys, geom_item c1, geom_item c2 ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Равенство кривизны двух кривых в заданных точках". + \en Specify a constraint "Equality of curvature of two curves at given points". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curves - \ru Дескрипторы пары кривых. + \en Descriptors of a pair of curves. \~ + \param[in] tPars - \ru Дескрипторы параметров параметрических кривых, в которых должно выполняется + равенство кривизны. + \en Descriptors of parameters of parametric curves in which the equality of curvature + must be satisfied. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \note \ru Если тип кривой #GCE_CIRCLE или #GCE_BOUNDED_CURVE, базовой кривой которой является окружность, + то соответствующее этой кривой значение tPars[i] может равняться #GCE_NULL_V, т.к. кривизна + окружности одинакова во всех её точках. + \en If curve has a type #GCE_CIRCLE or #GCE_BOUNDED_CURVE which is based on circle then the + corresponding value of tPars[i] may be equal to #GCE_NULL_V because the curvature of circle + is the same in all its points. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddEqualCurvature( GCE_system gSys, geom_item curves[2], var_item tPars[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Радиусный размер". + \en Specify a "Radius dimension" constraint. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cir - \ru Дескриптор окружности. + \en Descriptor of circle. \~ + \param[in] dPar - \ru Параметры линейного размера (подробности см.#GCE_dim_pars). + \en Parameters of linear dimension (see #GCE_dim_pars). \~ + + \return \ru Дескриптор радиусного ограничения. + \en Descriptor of radius constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddRadiusDimension( GCE_system gSys, geom_item cir, GCE_dim_pars dPar ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Диаметральный размер". + \en Specify a "Diameter dimension" constraint. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cir - \ru Дескриптор окружности. + \en Descriptor of circle. \~ + \param[in] dPar - \ru Параметры линейного размера (подробности см.#GCE_dim_pars). + \en Parameters of linear dimension (see #GCE_dim_pars). \~ + + \return \ru Дескриптор диаметрального ограничения. + \en Descriptor of diameter constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDiameter( GCE_system gSys, geom_item cir, GCE_dim_pars dPar ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Управляющий параметр" или "Фиксация переменной" + \en Set the constraint "Driving parameter" or "Fixation of variable" \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] var - \ru Дескриптор переменной. + \en Descriptor of variable. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \note \ru Созданное с помощью этой функции, ограничение может управляться + через вызов GCE_ChangeDrivingDimension. + \en A constraint created with this function can be driven + via the call of GCE_ChangeDrivingDimension. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_FixVariable( GCE_system gSys, var_item var ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Задать ограничение "Фиксация геометрического объекта". + \en Set the constraint "Fixation of geom" \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +// --- +GCE_FUNC(constraint_item) GCE_FixGeom( GCE_system gSys, geom_item g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Фиксированная длина отрезка" + \en Set the constraint "Fixation of segment length" \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] ls - \ru Дескриптор отрезка. + \en Descriptor of segment. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Ограничение применимо пока только для отрезков. + \en The constraint is applicable only for segments so far. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_FixLength( GCE_system gSys, geom_item ls ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Задать ограничение "Фиксированный радиус". + \en Set the constraint "Fixation of radius" \~ + \details \ru Ограничение применимо для фиксации радиуса окружности или полуоси эллипса. + \en The constraint is applicable to fix radius of circle or semiaxis of ellipse. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] circ - \ru Дескриптор окружности или эллипса. + \en Descriptor of circle or ellipse. \~ + \param[in] cName- \ru Тип фиксируемой координаты. Может быть радиус, большая или малая полуось эллипса. + \en Type of fixed coordinate. It can be #GCE_RADIUS, + #GCE_MAJOR_RADIUS or #GCE_MINOR_RADIUS.\~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +// --- +GCE_FUNC(constraint_item) GCE_FixRadius( GCE_system gSys, geom_item circ, coord_name cName = GCE_RADIUS ); + +//---------------------------------------------------------------------------------------- +/** + \brief + \ru Задать ограничение "Зафиксировать производную сплайна в заданной точке". + \en Set the constraint "Fixation of derivative vector of the spline at a given point". \~ + \param[in] gSys - \ru Система ограничений. \en System of constraints. \~ + \param[in] spline - \ru Дескриптор сплайна. \en Descriptor of spline. \~ + \param[in] par - \ru Значение параметра, в котором надо зафиксировать производную. + \ \en Parameter value in which it is necessary to record a derivative. \~ + \param[in] derOrder - \ru Порядок производной, которую надо зафиксировать. \en Order of the derivative which must be fixed. \~ + \param[in] fixVal - \ru Значение, к которому надо приравнять производную. \en The value to which it is necessary to equate the derivative. \~ + \return \ru Дескриптор нового ограничения. \en Descriptor of a new constraint. \~ + \details + \ru Точка фиксации задается через значение параметра, соответствующего ей. \n + Порядок фиксируемой производной может равняться 0 (фиксация точки), 1, 2 или 3. \n + Если fixVal равен NULL, будет зафиксировано текущее значение производной, + иначе фиксируемой производной будет присвоено значение fixVal. + \en + Fixation point is specified via the parameter value corresponding to it. \n + The order of a fixed derivative can be equal 0 (point fixing), 1, 2 or 3. \n + If fixVal is NULL current value of the derivative vector will be fixed. + Otherwise the derivative vector will be fixed at fixVal value. \~ + */ +//--- +GCE_FUNC(constraint_item) GCE_FixSplineDerivative( GCE_system gSys, geom_item spline + , double par, uint derOrder, GCE_vec2d * fixVal = NULL ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Средняя точка". + \en Set the constraint "Middle point". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pnt - \ru Дескрипторы трех точек. + \en Descriptors of point triplet. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Для данных трех точек, задать отношение, связывающее тройку точек, + так, что третья точка лежит на середине отрезка между pnt[0] и pnt[1]. + \en For the given three points set the relation connecting the point triplet + in such way that the third point lies in the middle of points pnt[0] and pnt[1]. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddMiddlePoint( GCE_system gcSys, geom_item pnt[3] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Параллельность". + \en Set the constraint "Parallelism". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары линейных объектов. + \en Descriptors of a pair of linear objects. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Ограничение применяется для прямых или отрезков. + \en The constraint is used for lines or segments. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddParallel( GCE_system gSys, geom_item g[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Перпендикулярность". + \en Set the constraint "Perpendicularity". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары линейных объектов. + \en Descriptors of a pair of linear objects. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Ограничение применяется для прямых или отрезков. + \en The constraint is used for lines or segments. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddPerpendicular( GCE_system gSys, geom_item g[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Симметрия относительно линейного объекта". + \en Set the constraint "Symmetry relative to the linear object". \~ + + \param[in] gSys - \ru Система ограничений. + gSys - \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары симметричных объектов. + g - \en Descriptors pair of symmetrical objects.. \~ + \param[in] lObj - \ru Дескриптор оси симметрии. + lObj - \en Descriptor of the axis of symmetry. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + + \attention \ru В настоящий момент данное ограничение применимо только для симметрии точек. + \en Currently, this restriction only applies to the symmetry of the points. \~ + */ +//--- +GCE_FUNC(constraint_item) GCE_AddSymmetry( GCE_system gSys, geom_item g[2], geom_item lObj ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Касание двух кривых". + \en Set the constraint "Tangency of two curves". \~ + \param[in] \ru gSys Система ограничений. + \en gSys System of constraints. \~ + \param[in] \ru g Дескрипторы пары кривых или прямых. + \en g Descriptors of a pair of curves or lines. \~ + \param[in] \ru tPar Дескрипторы параметров касания для параметрических кривых. + \en tPar Descriptors of parameters of tangency for parametric curves. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details + \par \ru Вспомогательные параметры касания + \en Help parameters of tangency + \ru Дескрипторы переменных tPar[0] и tPar[1] задают вспомогательные значения, параметризующие + точку касания на первой и второй кривой. Одна или обе tPar могут быть равными GCE_NULL_V, + если соответствующая кривая не является сплайном или параметрической кривой, либо + пользователь согласен, что точка касания будет локализована автоматически по ближайшему решению. + + \en Variable descriptors tPar[0], tPar[1] specify help values parametrizing a tangent point + on the first and the second curve. One of both tPar can be equal GCE_NULL_V. + + \note \ru tPar[0] или tPar[1] могут быть равными GCE_NULL_V, если параметры + касания не предусмотрены или кривые не имеют параметрического представления. + Параметрическое представление имеют пока только два типа: + GCE_SPLINE и GCE_PARAMETRIC_CURVE. + \en tPar[0] or tPar[1] may be equal to GCE_NULL_V if parameters + of tangency are not provided or curves have no parametric representation. + There are only two types having parametric representation: + GCE_SPLINE and GCE_PARAMETRIC_CURVE. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddTangent( GCE_system gSys, geom_item g[2], var_item tPar[2] ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать размерное ограничение "Расстояние между объектами". + \en Set the dimensional constraint "Distance between objects". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескрипторы пары геометрических объектов. + \en Descriptors of a pair of geometric objects. \~ + \param[in] dPars - \ru Параметры линейного размера (подробности см.#GCE_ldim_pars). + \en Parameters of linear dimension (see #GCE_adim_ldim). \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Задать линейный размер для пары геометрических объектов. + \en Set linear dimension for a pair of geometric objects. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDistance( GCE_system gSys, geom_item g[2], const GCE_ldim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Расстояние между точками". + \en Set the constraint "Distance between points". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] p - \ru Дескрипторы пары точек. + \en Descriptors of point pair. \~ + \param[in] dPars - \ru Параметры размерного ограничения. + \en Parameters of dimensional constraint. \~ + + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDistance2P( GCE_system gSys, geom_item p[2], const GCE_dim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Расстояние от точки до отрезка". + \en Set the constraint "Distance from a point to a segment". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] p - \ru Дескрипторы тройки точек. + \en Descriptors of point triplet. \~ + \param[in] dPars - \ru Параметры размерного ограничения. + \en Parameters of dimensional constraint. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Линейный размер от точки p1 до отрезка . Размер чувствителен к знаку + величины размера. + \en Linear dimension from the point p1 to the segment . + The dimension is sensitive to a sign of its value. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDistancePLs( GCE_system gSys, geom_item p[3] + , const GCE_dim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Ориентированное расстояние между точками". + \en Set the constraint "Directed distance between points". \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] p - \ru Дескрипторы пары точек. + \en Descriptors of point pair. \~ + \param[in] dPars - \ru Параметры размерного ограничения. + \en Parameters of dimensional constraint. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Параметр dPars.dirAngle задает направление размера в радианах. + Управляя dPars.dirAngle, можно задать вертикальный или + горизонтальный размеры. Так размер параметром dPars.dirAngle = 0 + создаст "горизонтальный размер", а dPars.dirAngle, равный PI/2 радиан + будет соответствовать "вертикальному" размеру. + + \en The constraint represents the dimension type that dimensions the + distance between two points in plane when they are projected onto a line + at an angle specified by parameter dPars dirAngle, which sets the direction + of dimension in radians. With driving dPars.dirAngle it is possible to + set the vertical or the horizontal dimension. So a dimension with an angle + equal to 0 radians specifies a "horizontal". The angle equal to PI/2 radians + corresponds to "vertical" dimension. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDirectedDistance( GCE_system gSys, geom_item p[2] + , const GCE_ldim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать линейное уравнение. + \en Set the linear equation. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] a - \ru Вектор коэффициентов линейного уравнения. + \en Vector of coefficients of linear equation. \~ + \param[in] v - \ru Дескрипторы переменных уравнения. + \en Descriptors of variables of equation. \~ + \param[in] n - \ru Количество переменных. + \en Quantity of variables.\~ + \param[in] c - \ru Коэффициент без переменной. + \en Free coefficient. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details \ru Задать линейное уравнение в виде a1*v1 + a2*v2 + .. + an*vn + c = 0. + \en Set a linear equation in form of a1*v1 + a2*v2 + .. + an*vn + c = 0. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddLinearEquation( GCE_system gSys, const double * a + , const var_item * v, size_t n, double c ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Изменить значение управляющего размера. + \en Change the value of driving dimension. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] dItem - \ru Дескриптор размерного ограничения. + \en Descriptor of dimensional constraint. \~ + \param[in] dVal - \ru Требуемое значение размера. + \en Required value of constraint. \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \details \ru Функция применяется только для управляющих размеров или управляющих параметров. + Если управляющий размер или параметр является угловым, то параметр dVal задается в радианах.\n + Следует учитывать, что настоящая функция не осуществляет вычислений, а только + подготавливает изменение размера. Что бы изменения вступили в силу, необходимо вызвать + функцию #GCE_Evaluate. + \en The function is used only for driving dimensions or driving parameters. + If the driving dimension or parameter is angular, then the parameter dVal is specified in radians. \n + It should be taken into account that the function doesn't perform computations but only + prepares the changing of dimension. For the changes to take effect it is required + to call the function #GCE_Evaluate. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_ChangeDrivingDimension( GCE_system gSys, constraint_item dItem, double dVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Отклонить ограничение от точки решения. + \en Deviate the constraint from the point of solution. \~ + \param[in] dItem - \ru Дескриптор геометрического ограничения. + \en Descriptor of geometric constraint. \~ + \param[in] delta - \ru Величина отклонения. + \en Deviation value. \~ + \return errCode - \ru Результат решения системы ограничений. + \en Solution of constraint system. \~ + + \details \ru Функция применяется для диагностики избыточности ограничения, основанной + на отклонении области решений ограничения. Работает только для размерных ограничений + и некоторых типов геометрических ограничений, таких как "Выравнивание точек", + "Горизонтальность" и т.д. Применимость к тому или иному типу не задокументирована и + определяется опытным путем. + Если было возвращено значение GCE_RESULT_None, то ограничение не отклонялось. + \en The function is used for the diagnostics of constraints redundancy based + on the deviation of the region of solution of the constraint. It works only for dimensional constraints + and other types of geometric constraints such as "Points alignment", + "Horizontality" etc. The applicability to a certain type was not documented and + it is defined only empirically. + If GCE_RESULT_None is returned, the constraint wasn't deviated. \~ +*/ +// --- +GCE_FUNC(GCE_result) GCE_DeviateDimension( GCE_system gSys, constraint_item dItem, double delta ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Тест избыточности ограничения, основанный на отклонении его от точки решения. + \en Test for redundancy of constraint based on the deviation the constraint from the point of solution. \~ + \param[in] dItem - \ru Дескриптор геометрического ограничения. + \en Descriptor of geometric constraint. \~ + \param[in] delta - \ru Величина отклонения. + \en Deviation value. \~ + \return - \ru Результат решения системы ограничений. + \en Solution of constraint system. \~ + + \details \ru Функция применяется для диагностики избыточности ограничения, основанной + на отклонении области решений ограничения. Работает только для размерных ограничений + и некоторых типов геометрических ограничений, таких как "Выравнивание точек", + "Горизонтальность" и т.д. Применимость к тому или иному типу (кроме размерных) не + задокументирована и определяется опытным путем. + Если было возвращено значение GCE_RESULT_None, то ограничение не отклонялось. + \en The function is used for the diagnostics of constraints redundancy based + on the deviation of the region of solution of the constraint. It works only for dimensional constraints + and other types of geometric constraints such as "Points alignment", + "Horizontality" etc. The applicability to a certain type (for non dimensional) + was not documented and it is defined only empirically. + If GCE_RESULT_None is returned, the constraint wasn't deviated. \~ + + \note \ru В отличии от #GCE_DeviateDimension не меняется состояние системы ограничений. + \en Unlike #GCE_DeviateDimension this function does not change state of geometric constraint system. +*/ +// --- +GCE_FUNC(GCE_result) GCE_DeviationTest( GCE_system gSys, constraint_item dItem, double delta ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Текущее значение размерного параметра. + \en A current value of the dimension parameter. + \details \ru Функция выдает текущее значение размерного параметра ограничения. Если + ограничение не размерное, то функция вернет GCE_UNDEFINED_DBL. Для управляющих размеров + будет выдано значение управляющего параметра, которое было задано при создании размера + или последним вызовом GCE_ChangeDrivingDimension. + \en The function returns a value of dimension parameter of the constraint. + If the constraint is a driving dimension, the function returns a value of dimension + parameter specified when creating the constraint or last call of #GCE_ChangeDrivingDimension. +*/ +//--- +GCE_FUNC(double) GCE_DimensionParameter( GCE_system gSys, constraint_item dItem ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вычислить систему ограничений. + \en Calculate the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \return \ru Код результата вычислений. + \en Calculation result code. \~ + \details \ru Функция решает задачу ограничений. Задача ограничений формулируется + функциями API геометрического решателя; функции вида GCE_Add_XXXXXXX добавляют новые + объекты, функции вида GCE_Change_XXXXXXX, GCE_Set_XXXXXXX изменяют состояние + объектов. Таким образом, что бы все такие изменения вступили в силу, нужно + вызвать метод #GCE_Evaluate.\n + Алгоритмы GCE_Evaluate учитывают удовлетворенность систем ограничений; если + все ограничения уже решены, то функция не тратит время на вычисления, а + состояние геометрических объектов остается неизменным. + \en The function solves problem of constraints. The problem of constraint is formulated + by API functions of geometric solver; the functions of a kind GCE_Add_XXXXXXX add a new + object, the functions of kinds GCE_Change_XXXXXXX and GCE_Set_XXXXXXX change a state + of objects. Thus, for all changes to take effect it is necessary + to call the method #GCE_Evaluate.\n + The algorithms GCE_Evaluate take into account whether constraint systems are satisfied, if + all constraints have been already solved, then the function doesn't spend time for calculations, and + the state of geometric objects remains unchanged. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_Evaluate( GCE_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Инициализировать режим драггинга контрольной точки объекта. + \en Initialize the dragging mode of the object control point. \~ + \param[in] \ru gSys Система ограничений. + \en gSys System of constraints. \~ + \param[in] \ru obj Геометрический объект. + \en obj Geometric object. \~ + \param[in] \ru pntId Обозначение передвигаемой контрольной точки объекта. + \en pntId Denotation of the dragged control point of the object. \~ + \param[in] \ru curXY Координаты курсора, куда следует перемещаемая точка. + \en curXY Coordinates of cursor where the moving point follows. \~ + \return \ru Код ошибки. Вернет код GCE_RESULT_Ok, если подготовка режима драггина прошла успешна. + \en Error code. Returns GCE_RESULT_Ok if preparing the dragging mode was successful.\~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareMovingOfPoint( GCE_system gSys, geom_item obj + , point_type pntId, GCE_point curXY ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Инициализировать режим драггинга контрольной точки объекта. + \en Initialize the dragging mode of the object control point. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] drgPnt - \ru Контрольная точка объекта. + \en A geom control point. \~ + \param[in] curXY - \ru Координаты точки драггинга. + \en Coordinates of dragging point. \~ + \return \ru Код ошибки. Вернет код GCE_RESULT_Ok, если подготовка режима драггина прошла успешна. + \en Error code. Returns GCE_RESULT_Ok if preparing the dragging mode was successful.\~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareDraggingPoint( GCE_system gSys, GCE_dragging_point drgPnt + , GCE_point curXY ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Инициализировать режим драггинга контрольной точки множества объектов. + \en Initialize the dragging mode of the control point of object set. \~ + \details \ru Этот метод предназначен для группового редактирования (драггинг) + нескольких объектов с "общей" hot-точкой. Под "общей" hot-точкой подразумевается + не обязательно одна точка (с одним дескриптором), а множество точек с разными + дескрипторами, но имеющих одинаковые координаты. + \en This method is intended for the group dragging of few objects with + the "common" hot-point. A "common" hot-point is not necessarily the only point + (with the only descriptor), but a set of points with different descriptors but + with equal coordinates. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cPntArr - \ru Множество геометрически одинаковых контрольных точек. + \en A set of geometrically equal control points. \~ + \param[in] curXY - \ru Координаты точки драггинга. + \en Coordinates of dragging point. \~ + \return \ru Код ошибки. Вернет код GCE_RESULT_Ok, если подготовка режима драггина прошла успешна. + \en Error code. Returns GCE_RESULT_Ok if preparing the dragging mode was successful.\~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareDraggingPoint( GCE_system gSys + , const std::vector & cPntArr + , GCE_point curXY ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Инициализировать режим перетаскивания множества объектов. + \en Initialize mode of moving a set of objects. + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param geoms - \ru Множество геометрических объектов. + \en Set of geometric objects. \~ + \param curXY - \ru Координаты точки драггинга. + \en Coordinates of dragging point. \~ + \return \ru Код ошибки. Вернет код GCE_RESULT_Ok, если подготовка режима драггина прошла успешна. + \en Error code. Returns GCE_RESULT_Ok if preparing the dragging mode was successful.\~ + +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareMovingGeoms( GCE_system gSys + , std::vector & geoms + , GCE_point curXY ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Переместить точку драггинга. + \en Move a dragging point. \~ + \param[in] gcSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curXY - \ru Текущие координаты курсора. + \en Current coordinates of cursor. \~ + \return \ru Код ошибки. Вернет код GCE_RESULT_Ok, если подготовка режима драггина прошла успешна. + \en Error code. Returns GCE_RESULT_Ok if preparing the dragging mode was successful.\~ + + \details \ru Процедура обслуживает режим драггинга, с ее помощью геометрический решатель + отслеживает положение курсора. Этот вызов позволяет осуществлять двух-координатное + управление не доопределенной моделью. Если функция возвращает код ошибки, + не равный #GCE_RESULT_Ok, то гарантируется, что состояние геометрических объектов + останется неизменным. Если функция вернула #GCE_RESULT_Ok, то решатель содержит + новое состояние геометрических объектов, удовлетворяющее всем ранее наложенным + ограничениям (новое решение). В этом случае вызывать #GCE_Evaluate для приведения + объектов в решенное состояние не требуется. + \en The procedure services the dragging mode, with a help of it a geometric solver + tracks the cursor location. This call allows to perform a two-coordinate + control of an underdetermined model. If the function returns an error code, + which is not #GCE_RESULT_Ok, then it is guaranteed that the state of geometric objects + will remain the same. If the function returned #GCE_RESULT_Ok, then the solver contains + a new state of geometric objects satisfying to all the constraints created before + (a new solution). In this case it not required to call #GCE_Evaluate for the conversion + of objects to the solved state. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_MovePoint( GCE_system gcSys, GCE_point curXY ); + +//---------------------------------------------------------------------------------------- +/** + brief \ru Трансформировать геометрические объекты согласно заданной матрице. + \en Transform geometric objects according to a given matrix. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] geoms - \ru Множество геометрических объектов. + \en Set of geometric objects. \~ + \param[in] mat - \ru Матрица преобразования. + \en Transformation matrix. \~ + \return \ru Код ошибки. \en Error code. \~ +*/// --- +GCE_FUNC(GCE_result) GCE_DynamicTransform( GCE_system gSys, const std::vector & geoms, const MbMatrix & mat ); + +//---------------------------------------------------------------------------------------- +/** + brief \ru Трансформировать геометрию системы ограничений согласно заданной матрице. + \en Transform the geometry of the constraints system according to a given matrix. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] mat - \ru Матрица преобразования. + \en Transformation matrix. \~ + \return \ru Код ошибки. \en Error code. \~ +*/// --- +GCE_FUNC(GCE_result) GCE_Transform( GCE_system gSys, const MbMatrix & mat ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Включить журналирование и назначить файл для записи журнала вызовов API. + \en Switch on the journalling and specify the file for recording a journal of GCE API calls. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] fName - \ru Имя файла назначения с полным путем. + \en Name of destination file with a full path. \~ + \return true, if journalling has been successfully switched on. + \attention + \ru Файл журнала будет записан только после завершения сеанса работы с системой + ограничений, а именно сразу после вызова GCE_RemoveSystem. + \en The journal file will be written only when a session of work with the + constraint system is finished, i.e. immediately after calling the + GCE_RemoveSystem method. +*/ +//--- +GCE_FUNC(bool) GCE_SetJournal( GCE_system gSys, const char * fName ); + +#define FB_NULL_GEOM 0 + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + Рекомендуется использовать новую функцию: #GCE_DeviateDimension( GCE_system gSys, constraint_item dItem, double delta ) + \en An obsolete function. The call will be removed in one of the next versions. + It's recommended to use new version of this function: #GCE_DeviateDimension( GCE_system gSys, constraint_item dItem, double delta )\~ + */ +// --- +GCE_FUNC(bool) GCE_DeviateDimension( GCE_system gSys, constraint_item dItem + , double delta, GCE_result & errCode ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + Рекомендуется использовать новую функцию: #GCE_DeviationTest( GCE_system gSys, constraint_item dItem, double delta ) + \en An obsolete function. The call will be removed in one of the next versions. + It's recommended to use new version of this function: #GCE_DeviationTest( GCE_system gSys, constraint_item dItem, double delta )\~ + */ +// --- +GCE_FUNC(bool) GCE_DeviationTest( GCE_system gSys, constraint_item dItem + , double delta, GCE_result & errCode ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + \en An obsolete function. The call will be removed in one of the next versions. \~ + + \attention \ru Время жизни экземпляра класса crv опирается на счетчик ссылок, т.е. + решатель его увеличивает при добавлении кривой и декрементирует при удалении кривой из решателя. + \en The lifetime of the instance of the class 'crv' is based on the reference counter, i.e. + the solver increases it when adding a curve and decreases when deleting a curve from the solver. \~ +*/ +//--- +class MbPolyCurve; +GCE_FUNC(geom_item) GCE_AddSpline( GCE_system gSys, const MbPolyCurve & crv ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + \en An obsolete function. The call will be removed in one of the next versions. \~ +*/ +//--- +inline geom_item GCE_AddPoint( GCE_system gSys, GCE_point pVal, int ) +{ + return GCE_AddPoint( gSys, pVal ); +} + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + \en An obsolete function. The call will be removed in one of the next versions. \~ +*/ +//--- +GCE_FUNC(GCE_system) GCE_CreateSystem( void * ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий (2016). + \en An obsolete function. The call will be removed in one of the next versions (2016). \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddDirectedDistance2P( GCE_system gSys, geom_item p[2] + , const GCE_ldim_pars & dPars ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + \en An obsolete function. The call will be removed in one of the next versions. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddAlignPoints( GCE_system gSys, geom_item p[2], bool hor ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Вместо неё применять #GCE_FixLength. + \en The function is obsolete. Use #GCE_FixLength instead. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddFixedLength( GCE_system, geom_item ); + +//---------------------------------------------------------------------------------------- +/** + \attention \ru Функция устарела. Вместо неё применять #GCE_FixVariable. + \en The function is obsolete. Use #GCE_FixVariable instead. \~ +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddFixVariable( GCE_system, var_item ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение "Точка на кривой". + \en Set the constraint "Point on curve". \~ + \attention This call is deprecated. Call #GCE_AddCoincidence instead. +*/ +//--- +GCE_FUNC(constraint_item) GCE_AddIncidence( GCE_system, geom_item, geom_item ); + +//---------------------------------------------------------------------------------------- +/** + \attention + \ru Устаревшая функция. Вызов будет удален в одной из следующих версий. + Используйте #GCE_PrepareMovingOfPoint( GCE_system gSys, const std::vector & cPntArr, GCE_point curXY ) + взамен. + \en An obsolete function. The call will be removed in one of the next versions. + Use GCE_PrepareDraggingPoint( GCE_system gSys, const std::vector & cPntArr, GCE_point curXY ) instead of this. \~ +*/ +//--- +GCE_FUNC(GCE_result) GCE_PrepareMovingOfPoint( GCE_system gSys + , const std::vector & cPntArr + , GCE_point curXY ); + +/** \} */ + +#endif // __GCE_API_H + +// eof diff --git a/C3d/Include/gce_callback.h b/C3d/Include/gce_callback.h new file mode 100644 index 0000000..e994b3b --- /dev/null +++ b/C3d/Include/gce_callback.h @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции и типы данных для обратных вызовов двухмерного геометрического решателя. + \en Functions and data types for callbacks of the 2D-solver. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_CALLBACK_H +#define __GCE_CALLBACK_H + +#include + +/** + \addtogroup Constraints2D_API + \{ +*/ + +/* + Application data types for callback queries +*/ +typedef void* GCE_app_geom; ///< Geometric object of the application using the solver +//typedef void* GCE_app_client; +const GCE_app_geom GCE_NOGEOM = 0; ///< \en Specifies an undefined object of the user's app. \ru Означает неопределенный объект пользовательского приложения. + +/* + Callback enquiries +*/ +typedef void ( *GCE_geom_registered )( GCE_app_geom ag ); ///< Application geom was registered in the solver. +typedef void ( *GCE_geom_unregistered )( GCE_app_geom ag ); +typedef bool ( *GCE_allow_zero_radius )( GCE_app_geom ag ); ///< +typedef bool ( *GCE_abort )(); ///< Query to interrupt calculations + +//---------------------------------------------------------------------------------------- +/** \brief \ru Структура, объединяющая обратные вызовы двухмерного решателя. + \en The structure uniting 2D-solver callbacks. + \details \ru Таблица функций, определяемых на стороне пользовательского приложения + для "тонкой настройки" решателя. + \en Table of user-defined callbacks tuning the 2D-solver. \~ +*/ +//--- +typedef struct +{ + /* + General system callbacks; + */ + GCE_geom_registered gRegister; + GCE_geom_unregistered gUnregister; + GCE_abort abortFunc; + + /* + Geometry properties + */ + GCE_allow_zero_radius allowZeroRadius; ///< Permit circle to have zero radius. +} GCE_callback_table; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Установить и вернуть структуру с функциями обратного вызова по умолчанию. + \en Set and return default callback functions. \~ + \details \ru GCE_callback_table - простая структура в стиле C, не имеющая конструктора. + Функция GCE_InitCallbacks позволяет придать структуре начальное значение + что бы избежать некорректных значений в памяти. + \en GCE_callback_table is a plain old data structure with no constructor. + The function is able to set an initial value of the structure to avoid + incorrect work with memory. +*/ +//--- +GCE_FUNC(GCE_callback_table&) GCE_InitCallbacks( GCE_callback_table & ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Зарегистрировать таблицу обратных вызовов для новой системы ограничений. + \en Register callback table for new constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en Constraint system. \~ + \param[in] cbTable - \ru Таблица обратных вызовов. + \en Table of callbacks. \~ + \return \ru Вернет GCE_RESULT_Ok, если регистрация выполнена. + \en Returns GCE_RESULT_Ok if the registration fulfilled. \~ + +*/ +//--- +GCE_FUNC(GCE_result) GCE_Register( GCE_system gSys, const GCE_callback_table & cbTable ); + +//---------------------------------------------------------------------------------------- +/// Associate an application geometry and a solver's descriptor. +//--- +GCE_FUNC(void) GCE_Bind( GCE_system, geom_item, GCE_app_geom ); + +/** + \} + Constraints2D_API +*/ + +#endif // __GCE_CALLBACK_H + +// eof \ No newline at end of file diff --git a/C3d/Include/gce_geom.h b/C3d/Include/gce_geom.h new file mode 100644 index 0000000..6665a79 --- /dev/null +++ b/C3d/Include/gce_geom.h @@ -0,0 +1,329 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Программный интерфейс для системы КОМПАС + \en Program interface for KOMPAS system. \~ + \details \ru Данный файл содержит классы и методы, ориентированные на типы + данных CAD-системы КОМПАС. Для других приложений это API может оказаться + не удобным, а его методы могут быть удалены или изменены в будущих + версиях. Рекомендуется применять эту часть API решателя, только если + не удасться найти требуемую функциональность в заголовочных файлах + gce_api.h или gce_types.h. + \en This file contains classes and methods oriented to + data types of CAD-system KOMPAS. For other applications this API can be + inconvenient and its methods can be deleted or modified in future + versions. It is recommended to apply this part of solver API only if + the required functionality is not found in header files + gce_api.h or gce_types.h. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_GEOM_H +#define __GCE_GEOM_H +// +#include +#include +#include +// +#include "gce_types.h" + + +class MATH_CLASS MbPolyCurve; +struct IfGeomPoint2d; + +//---------------------------------------------------------------------------------------- +// \ru Перечисление параметрических объектов \en Enumeration of parametric objects. +//--- +enum GcGeomType +{ + vt_NULL, ///< \ru Несуществующий тип. \en Nonexistent type. + gt_Point2d, ///< \ru Точка. \en Point. + gt_Line2d, ///< \ru Прямая. \en Line. + gt_LineSegment2d, ///< \ru Отрезок. \en Segment. + gt_Circle2d, ///< \ru Окружность. \en Circle. + gt_Arc2d, ///< \ru Дуга. \en Arc. + gt_Ellipse2d, ///< \ru Эллипс. \en Ellipse. + gt_EllipseArc2d, ///< \ru Дуга эллипса. \en Ellipse arc. + // gt_ViewPointerArrow, ///< \ru Отрезок. \en Segment. +}; + +//---------------------------------------------------------------------------------------- +// \ru Макросы \en Macros +// --- +#define CAST_PTR(T) IfGeom2dPtr // \ru Указатель с функцией приведения типов \en Pointer with function of type conversion +#define GEOM_PTR(T) IfGeom2dPtr // \ru Указатель с функцией приведения типов \en Pointer with function of type conversion +#define CAST2PTR(T,arg) (arg) != NULL ? (T*)((arg)->GetInterfacingGeom(iidr_ ## T)) : NULL // \ru Привести к другому типу \en Convert to another type + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Координата геометрического объекта или переменной \en Coordinate of a geometric object or a variable +////////////////////////////////////////////////////////////////////////////////////////// +struct ItGeomCoord : public ItCoord +{ + virtual refcount_t AddRef() const = 0; + virtual refcount_t Release() const = 0; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +/*\ru Надкласс примитивных геометрических объектов решателя + Внимание: Применяется только для САПР КОМПАС. Рекомендуется вместо него использовать вызовы API из gce_api.h + объектом IfSomething. Вместо макроса IFPTR применять GEOM_PTR.\n + После того, как MdViewObj будет наконец-то, освобождать память по правилам + IfSomething, нужно:\n + 1) Все слова IfSomethingGeom2d заменить на IfSomething;\n + 2) Все слова GetInterfacingGeom заменить на QueryInterface;\n + 3) Удалить этот класс;\n + 4) Компилятор сам подскажет, какие места нужно доправить;\n + + \en Used while there is no correct work with MdViewObj in 2D model + as with object IfSomething. GEOM_PTR is to be applied instead of macro IFPTR.\n + After MdViewObj has been implemented it is required to free memory by rules IfSomething, + it is necessary to:\n + 1) All words IfSomethingGeom2d replace by IfSomething;\n + 2) All words GetInterfacingGeom replace by QueryInterface;\n + 3) Delete this class;\n + 4) Compiler will prompt which places are to be corrected;\n \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// +struct IfSomethingGeom2d +{ + virtual IfSomethingGeom2d * GetInterfacingGeom( unsigned int iid ) = 0; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Геометрический объект параметризации \en Geometric object of parametrization +/*\ru Этот тип и его подтипы соответствуют словарю типов решателя, а не типам пользователя. + \en This type and its subtypes correspond to the dictionary of types of the solver but not to the user types. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// +struct IfGeom2d: public IfSomethingGeom2d +{ + virtual GcGeomType GetGeomType() const = 0; + /// \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual point_type IdentCtrlPoint( const IfGeomPoint2d & ) const = 0; + /// \ru Выдать обозначение координаты, принадлежащей объекту \en Get notation of coordinate belonging to the object + virtual coord_name IdentCoord( const ItGeomCoord & ) const = 0; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Точка на плоскости \en Point on the plane +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomPoint2d: public IfGeom2d +{ + virtual GcGeomType GetGeomType() const { return gt_Point2d; } + virtual ItGeomCoord * GetXCoord() const = 0; + virtual ItGeomCoord * GetYCoord() const = 0; + /// \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual coord_name IdentCoord( const ItGeomCoord & ) const; + +public: + inline MbCartPoint GetValue() const; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// Deprecated (2017). Use GCE_AddLine instead this. +/* + КОМПАС отвязан от этого интерфейса. +*/ +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomLine2d: public IfGeom2d +{ + virtual GcGeomType GetGeomType() const { return gt_Line2d; } + virtual ItGeomCoord * GetACoord() = 0; ///< \ru Выдать угол нормали прямой \en Get angle of line normal + virtual ItGeomCoord * GetDCoord() = 0; ///< \ru Выдать расстояние до начала СК в направлении нормали \en Get distance to the coordinate system origin in the normal direction + /// \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual coord_name IdentCoord( const ItGeomCoord & ) const; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Отрезок на плоскости \en Segment on the plane +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomLineSeg2d: public IfGeom2d +{ + virtual GcGeomType GetGeomType() const { return gt_LineSegment2d; } + virtual IfGeomPoint2d * GetEnd( int nb ) = 0; ///< \ru Выдать конец отрезка 1,2 \en Get end of segment 1,2 + virtual bool IsFixedLength() = 0; ///< \ru Признак отрезка постоянной длины (для стрелки взгляда) \en Flag of segment of constant length (for the view vector) + // \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual coord_name IdentCoord( const ItGeomCoord & ) const { return GCE_NULL_CRD; } + inline GCE_point EndPoint( int nb ); ///< \ru Выдать конец отрезка 1,2 \en Get end of segment 1,2 +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// Deprecated (2017). Use GCE_AddCircle instead this. +/* + КОМПАС отвязан от этого интерфейса. +*/ +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomCircle2d: public IfGeom2d +{ + virtual GcGeomType GetGeomType() const { return gt_Circle2d; } + virtual IfGeomPoint2d * GetCentre() = 0; + virtual ItGeomCoord * GetRadius() = 0; + // \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual coord_name IdentCoord( const ItGeomCoord & ) const; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Эллипс на плоскости \en Ellipse on the plane +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomEllipse2d: public IfGeom2d +{ + virtual GcGeomType GetGeomType() const { return gt_Ellipse2d; } + virtual IfGeomPoint2d * GetCentre() = 0; // \ru Выдать центр эллипса \en Get ellipse center + virtual ItGeomCoord * GetACoord() = 0; // \ru Выдать размер полуоси а \en Get size of semiaxis a + virtual ItGeomCoord * GetBCoord() = 0; // \ru Выдать размер полуоси b \en Get size of semiaxis b + virtual ItGeomCoord * GetPhiCoord() = 0; // \ru Выдать угол оси a \en Get angle of axis a + virtual coord_name IdentCoord( const ItGeomCoord & ) const; // \ru Выдать обозначение контрольной точки, принадлежащей объекту \en Get notation of the control point belonging to the object + virtual bool IsClockwise() const = 0; // \ru Вернет true, усли параметризация эллипса по часовой стрелке. \en Returns true if the ellipse parametrization is directed clockwise. +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Дуга эллипса на плоскости \en Elliptical arc on the plane +////////////////////////////////////////////////////////////////////////////////////////// +struct GCE_CLASS IfGeomEllipseArc2d: public IfGeomEllipse2d +{ + virtual GcGeomType GetGeomType() const { return gt_EllipseArc2d; } + virtual IfGeomPoint2d * GetEnd( int nb ) = 0; + inline MbCartPoint GetEndValue( int nb ) + { + if ( const IfGeomPoint2d * bnd = GetEnd(nb) ) + { + return bnd->GetValue(); + } + return MbCartPoint(); + } +}; + +//---------------------------------------------------------------------------------------- +// \ru Выдать true, если оба указателя представляют одну и ту же точку параметрическую точку \en Return true if both pointers represent the same parametric point +/*\ru Поведение соответствует ParPoint::IsEqual + \en Behavior corresponds to ParPoint::IsEqual \~ +*/ +//--- +inline bool SamePoints( const IfGeomPoint2d * p1, const IfGeomPoint2d * p2 ) +{ + if ( p2 == p1 ) + { + return true; + } + if ( p1 && p2 ) + { + if ( p1->GetXCoord() == p2->GetXCoord() ) + { + return true; + } + } + + return false; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline MbCartPoint IfGeomPoint2d::GetValue() const +{ + MbCartPoint val; + if ( const ItGeomCoord * x = GetXCoord() ) + { + if ( const ItGeomCoord * y = GetYCoord() ) + { + val.Init( x->GetValue(), y->GetValue() ); + } + } + return val; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline GCE_point IfGeomLineSeg2d::EndPoint( int nb ) +{ + GCE_point val; + if ( IfGeomPoint2d * pnt = GetEnd(nb) ) + { + const MbCartPoint xy = pnt->GetValue(); + val.x = xy.x; + val.y = xy.y; + } + return val; +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// \ru Аналог IfPtr без работы со счетчиком ссылок \en Analog of IfPtr without working with reference counter +/*\ru Указатель с сервисом приведения типов + \en Pointer with type conversion service \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +template +class IfGeom2dPtr +{ + T * m_pI; + +public: + IfGeom2dPtr() : m_pI(0) {} + IfGeom2dPtr( T * pI ): m_pI(pI) {} + IfGeom2dPtr( IfSomethingGeom2d * pI ) : m_pI(0) { if ( pI != 0 ) m_pI = (T*)pI->GetInterfacingGeom(iid); } + IfGeom2dPtr( const IfGeom2dPtr & o ) : m_pI( o.m_pI ) {} + +public: + unsigned int GetIid() const { return iid; } + operator T*() const { return m_pI; } + T& operator *() { C3D_ASSERT(m_pI != 0); return *m_pI; } + T** operator &() { C3D_ASSERT(m_pI == 0); return &m_pI; } + T* operator->() { C3D_ASSERT(m_pI != 0); return m_pI; } + T* operator->() const { C3D_ASSERT(m_pI != 0); return m_pI; } + T* Get() const { return m_pI; } + T* operator= ( T* pI ) { m_pI = pI; } + T* operator= ( const IfGeom2dPtr & o ) { return operator=(o.m_pI); } + T* operator= ( IfSomethingGeom2d * pI ); +}; + +//---------------------------------------------------------------------------------------- +// \ru Присвоить другой интерфейс \en Assign another interface +// --- +template +inline T* IfGeom2dPtr::operator = ( IfSomethingGeom2d * pI ) { + T * pOld = m_pI; + m_pI = 0; + if ( pI != 0 ) + m_pI = (T*)pI->GetInterfacingGeom( iid ); + + return m_pI; +} + +//---------------------------------------------------------------------------------------- +// \ru Идентификаторы интерфейсов решателя сопряжений \en Identifiers of constraint solver interfaces +//--- +typedef enum +{ + // \ru Геометрические объекты \en Geometrical objects + iidr_IfSomethingGeom2d, + iidr_IfGeom2d, ///< \ru Плоский геометрический объект \en Planar geometric object + iidr_IfGeomPoint2d, + iidr_IfGeomLine2d, + iidr_IfGeomLineSeg2d, + iidr_IfGeomCircle2d, + iidr_IfGeomArc2d, + iidr_IfGeomEllipse2d, + iidr_IfGeomEllipseArc2d, + iidr_ParSolvingObj, ///< \ru Интерфейс неизвестного чертежного объекта, не обязательно примитивного, \en Interface of unknown drawing object, not necessary primitive +} EIfIDRolesMathGC; + +////////////////////////////////////////////////////////////////////////////////////////// +// Deprecated (2016). Use GCE_AddBoundedCurve with GCE_AddCircle instead this. +/* + КОМПАС отвязан от этого интерфейса. +*/ +////////////////////////////////////////////////////////////////////////////////////////// +struct IfGeomArc2d: public IfGeomCircle2d +{ +private: + virtual GcGeomType GetGeomType() const { return gt_Arc2d; } + virtual bool GetClockwise() const = 0; + virtual IfGeomPoint2d * GetEnd( int nb ) = 0; +}; + +#endif + +// eof \ No newline at end of file diff --git a/C3d/Include/gce_kompas_interface.h b/C3d/Include/gce_kompas_interface.h new file mode 100644 index 0000000..67ceef8 --- /dev/null +++ b/C3d/Include/gce_kompas_interface.h @@ -0,0 +1,148 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Программный интерфейс для системы КОМПАС + \en Program interface for KOMPAS system. \~ + \details \ru Данный файл содержит классы и методы, ориентированные на типы + данных CAD-системы КОМПАС. Для других приложений это API может оказаться + не удобным, а его методы могут быть удалены или изменены в будущих + версиях. Рекомендуется применять эту часть API решателя, только если + не удасться найти требуемую функциональность в заголовочных файлах + gce_api.h или gce_types.h. + \en This file contains classes and methods oriented to + data types of CAD-system KOMPAS. For other applications this API can be + inconvenient and its methods can be deleted or modified in future + versions. It is recommended to apply this part of solver API only if + the required functionality is not found in header files + gce_api.h or gce_types.h. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_KOMPAS_INTERFACE_H +#define __GCE_KOMPAS_INTERFACE_H + +#include +#include +#include +// +#include "gce_geom.h" +#include + +class MtVectorN; +template class RPArray; + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Ограничение для подмножества координат \en Constraint for subset of coordinates +/**\ru Как правило, это алгебраические уравнение общего вида f(x1,x2,..,xn) = g(x1,x2,..,xn) + явно-выраженной форме: x1 = g(x2,x3,..,xn). + \en As a rule, it is an algebraic equation of a general form f(x1,x2,..,xn) = g(x1,x2,..,xn) + or, as a special case, it is an equation in explicit form: x1 = g(x2,x3,..,xn). \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +struct ItAlgebraicConstraint +{ + /// \ru Выдать координату с индексом crdIdx. \en Get coordinate with crdIdx index. + virtual ItGeomCoord * GetCoord( ptrdiff_t crdIdx ) const = 0; + /// \ru Количество координат, связанных с уравнением. \en Count of coordinates connected with the equation. + virtual ptrdiff_t GetCoordCount() const = 0; + /// \ru Вычисление первой производной по координате и значений функции. \en The first derivative by coordinate and the function values calculation. + virtual bool CalcDerive( ItGeomCoord &, const std::vector & /*argLine*/, double & /*fd*/, double & /*f*/ ) const { return false; } + /// \ru Выдать координату зависимой переменной (для уравнений заданных в явно-выраженной форме). \en Get the coordinate of dependent variable (for explicit equations). + virtual ptrdiff_t GetDependedCoordIdx() const = 0; + /// \ru Признак уравнения, заданного в форме присвоения, по правилам КОМПАС-3D V12. \en Flag of equation specified in form of assignment, by the rules of KOMPAS-3D V12. + /**\ru Уравнения, заданные в явно выраженной форме, считающиеся присвоением выражения зависимой переменной: x1 = g(x2,x3,..,xn). + Такие уравнения стремимся вычислять иерархическим способом, сверху-вниз. + \en Equations specified explicitly, considered to be the assignment of dependent variable: x1 = g(x2,x3,..,xn). + It is preferred to compute such equations by hierarchical top-down method. \~ + */ + virtual bool IsAssignmentForm() const = 0; + + virtual refcount_t AddRef() const = 0; + virtual refcount_t Release() const = 0; + +private: + // It will be removed + virtual bool CalcDerive( ItGeomCoord &, const MtVectorN &, double &, double & ) const { return false; } + +protected: + ~ItAlgebraicConstraint() {} +}; + +/** + \addtogroup Constraints2D_API + \{ +*/ + +//---------------------------------------------------------------------------------------- +/// \ru Задать ограничение, реализуемое на стороне клиента \en Specify a constraint implemented by the user +/** + \param \ru gSys контекст решателя + \en gSys the solver context \~ + \param \ru iEqu интерфейс уравнения, заданного пользователем + \en iEqu interface of the equation specified by the user \~ + \param \ru varsCount количество переменных + \en varsCount count of variables \~ + \param \ru varsVector вектор переменных + \en varsVector vector of variables \~ + \return \ru дескриптор нового ограничения + \en descriptor of a new constraint \~ +*/ +// --- +GCE_FUNC(constraint_item) GCE_AddEquation( GCE_system gSys + , ItAlgebraicConstraint & iEqu + , size_t varsCount + , const var_item * varsVector ); + +//---------------------------------------------------------------------------------------- +/// \ru Определить смежные ли это ограничение и геометрический объект \en Determine whether the constraint and the geometric object are adjacent +//--- +GCE_FUNC(bool) GCE_IsAdjacentConstraint( GCE_system gSys + , geom_item g + , constraint_item c ); + +//---------------------------------------------------------------------------------------- +/// \ru Получить текущие координаты точки \en Get the current coordinates of point +/** + \param \ru gSys контекст решателя + \en gSys the solver context \~ + \param \ru g дескриптор точки или иного геометрического объекта + \en g descriptor of a point or other geometric object \~ + \param \ru pName идентификатор точки, принадлежащей объекту + \en pName identifier of a point belonging to the object \~ + \return \ru координаты точки + \en point coordinates \~ +*/ +//--- +GCE_FUNC(MbCartPoint) GCE_GetPoint( GCE_system gSys + , geom_item g + , point_type pName = GCE_PROPER_POINT ); + +/** + \} + Constraints2D_API +*/ + +//---------------------------------------------------------------------------------------- +/* + \brief \ru Добавить геометрический объект. \en Add a geometric object. \~ + \details \ru Регистрирует объект пользователя в контексе решателя. + Пользователь отвечает за время жизни этого объекта в контексте + решателя и обязан в нужный момент также и удалить (разрегистрировать) + объект (см. #GCE_RemoveGeom). + \en Register a user object in the solver context. + The user is responsible for the object life time in the context + of the solver and must delete (unregister) it at the appropriate time + object (see #GCE_RemoveGeom). \~ +*/ +/** + \attention \ru Устаревшая функция. Вызов будет удален в одной из следующих версий (2016). + \en An obsolete function. The call will be removed in one of the next versions. \~ +*/ +GCE_FUNC(geom_item) GCE_AddGeom( GCE_system gSys, IfGeom2d & ); + + +#endif // __GCE_KOMPAS_INTERFACE_H + +// eof \ No newline at end of file diff --git a/C3d/Include/gce_precision.h b/C3d/Include/gce_precision.h new file mode 100644 index 0000000..1866082 --- /dev/null +++ b/C3d/Include/gce_precision.h @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Набор констант и величин погрешности для решения задач двумерных ограничений. + \en Set of constants and tolerance values to solve two-dimensional constraint problems. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GC_PRECISION_H +#define __GC_PRECISION_H + +#include +#include + +#define GC_GOLDEN_SECTION 0.381966011250105 // \ru Золотое сечение. \en Golden ratio. + +/** + \addtogroup Constraints2D_API + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Допуски для оценки точности геометрии. + \en Tolerances to test the accuracy of geometry. +*/ +// +//--- +struct MbGeomTol +{ + double lenTol; /// \ru Абсолютная погрешность в единицах длины. \en Linear resolution (in length units). + double angTol; /// \ru Абсолютная погрешность в радианах. \en Angular resolution (radians). + + MbGeomTol( double lenEps, double angEps ) : lenTol(lenEps), angTol(angEps) {} + MbGeomTol( double tol ) : lenTol(tol), angTol(tol) {} +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// +/** \brief \ru Фиксированные точности решения задач двумерной параметризации и иные константы. + \en Fixed tolerances of two-dimensional parametrization problems solving and other constants \~ + \details \ru Класс инкапсулирует все точности и прочие константы, распространяющиеся на задачи + двумерной параметризации. + \n + 1. При проверке метрических величин или инцидентности точек в 2D-пространстве + используется точность GcPrecision::lengthRegion. Т.е. любые две точки, + не совпадающие с погрешностью GcPrecision::lengthRegion считаютя разными.\n + 2. Для итерационных решателей используется точность параметра GcPrecision::newtonEpsilon, + эта величина на 1-2 порядка выше, чем неразличимая область (lengthRegion, angleRegion).\n + 3. Любое угловое, метрическое или параметрическое значение меньшее + GcPrecision::tolerance считается нулем.\n + 4. Величина newtonEpsilon всегда меньше либо равна lengthEpsilon и angleEpsilon.\n + 5. Любой элемент матрицы меньший по модулю, чем GcPrecision::m_null - считается + нулем. Барьер GcPrecision::m_null влияет на быстродействие и точность разложения + и перемножения матриц. Чем выше m_null, тем быстрее может работать разложение, в ущерб + вычислительной устойчивости.\n + \en The class encapsulates all tolerances and other constants related to + two-dimensional parametrization problems. + \n + 1. For check of metric values or points coincidence in 2D space + tolerance GcPrecision::lengthRegion is used. I.e. any two points + which are not coincident with tolerance GcPrecision::lengthRegion are considered to be different.\n + 2. For iterative solvers tolerance of parameter GcPrecision::newtonEpsilon is used. + This value is 1-2 orders higher than undistinguishable domain (lengthRegion, angleRegion).\n + 3. Any angular,metric or parametric value less than + GcPrecision::tolerance is considered to be zero.\n + 4. Value newtonEpsilon is always less or equal to lengthEpsilon and angleEpsilon.\n + 5. Any element of matrix less than GcPrecision::m_null by absolute value is considered + to be zero. Threshold GcPrecision::m_null influences on performance and accuracy of decomposition + and multiplication of matrices. The higher m_null the faster the decomposition can work, to the prejudice of + computational stability.\n \~ + \nosubgrouping +*/ +// +////////////////////////////////////////////////////////////////////////////////////////// + +struct GCE_CLASS GcPrecision +{ + /** + \ru \name Точности + \en \name Tolerances + \{ + */ + + const static double m_null; ///< \ru Абсолютная точность, с которой определяется четкий нуль в матрице; \en Absolute tolerance with which the clear zero is determined in matrix; + const static double grshTol; ///< \ru Относительная точность для оценки линейной зависимости при ортогонализации (Грамм-Шмидт) \en Relative tolerance for estimation of linear dependence during orthogonalizaiton (Gram-Schmidt) + const static double tolerance; ///< \ru Точность для проверки на нуль вещественного числа (углового или метрического); \en Tolerance for checking a real number (angular or metric) for zero; + const static double degMetricEps; ///< \ru Метрическая точность для проверки вырожденной геометрии; \en Metric tolerance for checking the geometry for degeneracy; + const static double lengthEpsilon; ///< \ru Вычислительная точность итерационных решателей и конструирования локусов пересечения ( линейная ); \en Computational tolerance of iterative solvers and intersection loci construction (linear); + const static double angleEpsilon; ///< \ru Вычислительная точность итерационных решателей и конструирования локусов пересечения ( угловая ); \en Computational tolerance of iterative solvers and intersection loci construction (angular); + const static double lengthRegion; ///< \ru Неразличимая метрическая область (проверочная точность). \en Indistinguishable metric domain (satisfactory tolerance). + const static double angleRegion; ///< \ru Неразличимая угловая область (проверочная точность). \en Indistinguishable angular domain (satisfactory tolerance). + const static double newtonEpsilon; ///< \ru Целевая точность итерационного решателя. \en Target accuracy of the iterative solver. + const static double newtonRegion; ///< \ru Удовлетворительная точность итерационного решения. \en Satisfactory accuracy of the iterative solution. + const static double paramRegion; ///< \ru Проверочная точность параметра \en Parameter checking tolerance + const static double maxRadius; ///< \ru Максимально возможный радиус для 2d-эскиза \en Maximal possible radius for cutting of 2d-sketch + const static MbGeomTol satisfying; ///< \ru Точность удовлетворенных ограничений; \en Satisfactory accuracy; + const static MbGeomTol newtonTol; ///< \ru Точность решения системы уравнений итерационными методами; \en Tolerance of solving the equation system by iterative methods; + + /** + \} + \ru \name Другие константы + \en \name Other constants + \{ + */ + + const static double pi2; ///< 2*M_PI (6.18...) + const static double lastReal; ///< \ru "Самое большое" число с плавающей точкой \en "The greatest" float number + const static int iterLimitCount; ///< \ru Предельное количество итераций в численном методе Ньютона \en Limit of iterations in numerical Newton's method + const static int wellIterLimit; ///< \ru Предельное количество итераций в хорошо-сходящихся процессах. \en Limit number of iterations in well-convergent processes. + static TCHAR buff_512[512]; ///< \ru Текстовый буфер размером в 512 байт \en Text buffer of 512 bytes + /** + \} + */ +}; + +//---------------------------------------------------------------------------------------- +/// \ru Число из дисткретного множества {-1,0,1}. \en A number from discrete set {-1,0,1}. +//--- +typedef int8 sign_t; + +/*! @} */ + +#endif + +// eof diff --git a/C3d/Include/gce_res_code.h b/C3d/Include/gce_res_code.h new file mode 100644 index 0000000..5e2ac59 --- /dev/null +++ b/C3d/Include/gce_res_code.h @@ -0,0 +1,14 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль устарел + \en The module is deprecated +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_RES_CODE_H +#define __GCE_RES_CODE_H + +#endif // __GCE_RES_CODE_H + +// eof \ No newline at end of file diff --git a/C3d/Include/gce_types.h b/C3d/Include/gce_types.h new file mode 100644 index 0000000..39f0c4d --- /dev/null +++ b/C3d/Include/gce_types.h @@ -0,0 +1,686 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Типы данных двумерного геометрического решателя. + \en Data types of the two-dimensional geometric solver. \~ + \details \ru Этот файл представляет собой набор типов данных, необходимых для + взаимодействия геометрического решателя с клиентским приложением. + \en This file contains set of data types necessary for interaction + of the geometrical solver with user application. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCE_TYPES_H +#define __GCE_TYPES_H + +#include +#include +#include +#include +#include +#include +#ifndef C3D_WINDOWS //_MSC_VER +#include +#endif //C3D_WINDOWS + +class MATH_CLASS MbNurbs; + +/** + \addtogroup Constraints2D_API + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Система геометрических ограничений. + \en Geometric constraints system. \~ + \details \ru GCE_system является типом данных, который обозначает систему ограничений, + которая создается с помощью вызова #GCE_CreateSystem. Реально, этот тип является + указателем на внутреннюю структуру данных, где содержится система ограничений и различные + рабочие данные, определяющие её внутреннее состояние. Время жизни системы ограничений + заканчивается только, когда к ней будет применен вызов API #GCE_RemoveSystem, после чего + значение GCE_system становится недействительным. + \en GCE_system is data type which denotes a system of constraints created by + call #GCE_CreateSystem. Actually this type is a pointer to an internal data structure with + a system of constraints and various working data determining its internal state. Lifetime + of the constraint system finishes only when a call of API #GCE_RemoveSystem + is applied to it, thereafter the value of GCE_system becomes invalid. \~ +*/ +typedef void * GCE_system; + +//---------------------------------------------------------------------------------------- +// \ru Типы данных. \en Data types. +//--- +/// \ru Дескриптор геометрического объекта, зарегистрированного в контексте решателя. \en Descriptor of geometrical object registered in the solver context. +typedef size_t geom_item; +/// \ru Дескриптор ограничения, зарегистрированного в решателе. \en Descriptor of a constraint registered in the solver. +typedef size_t constraint_item; +/// \ru Дескриптор переменной, зарегистрированной в решателе. \en Descriptor of a variable registered in the solver. +typedef size_t var_item; + +//---------------------------------------------------------------------------------------- +// \ru Константы. \en Constants. +//--- +/// \ru Неопределенное значение дескриптора или пустого объекта. \en Undefined value of descriptor or an empty object. +const size_t GCE_NULL = SYS_MAX_T; +/// \ru Неопределенное значение дескриптора типа #geom_item. \en Undefined value of #geom_item type. +const geom_item GCE_NULL_G = GCE_NULL; +/// \ru Неопределенное значение дескриптора типа #var_item. \en Undefined value of #var_item type. +const var_item GCE_NULL_V = GCE_NULL; +/// \ru Неопределенное значение дескриптора типа #constraint_item. \en Undefined value of #constraint_item type. +const constraint_item GCE_NULL_C = GCE_NULL; +/// \ru Не определенное значение числа double. \en An undefined value of double. +const double GCE_UNDEFINED_DBL = UNDEFINED_DBL; + +//---------------------------------------------------------------------------------------- +/// \ru Словарь типов геометрических примитивов. \en Dictionary of geometric primitives types. +//--- +typedef enum +{ + GCE_ANY_GEOM, ///< \ru Неизвестный тип. \en Unknown type. + + // \ru Основные типы. \en Basic types. + GCE_POINT, ///< \ru Точка на плоскости. \en Point on plane. + GCE_LINE, ///< \ru Прямая на плоскости. \en Line on plane. + GCE_CIRCLE, ///< \ru Окружность на плоскости. \en Circle on plane. + GCE_ELLIPSE, ///< \ru Эллипс на плоскости. \en Ellipse on plane. + GCE_SPLINE, ///< \ru Сплайн на плоскости. \en Spline on plane. + GCE_PARAMETRIC_CURVE, ///< \ru Параметрическая кривая на плоскости. \en Parametric curve on plane. + GCE_BOUNDED_CURVE, ///< \ru Ограниченная двумя точками, кривая. \en Curve bounded by two points. + + // \ru Дополнительные типы. \en Additional types. + GCE_LINE_SEGMENT, ///< \ru Отрезок прямой. \en Line segment. + GCE_SET, ///< \ru Подмножество геометрических объектов. \en Subset of geometric objects. +} geom_type; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Варианты контрольных точек, запрашиваемых у геометрического объекта. + \en Variants of control point requested from a geometric object. + \details \ru Это перечисление применяется для запроса дескриптора характерных точке объекта, + таких как центр окружности, концевая точка кривой и т.д... + \en This enum is used to request a descriptor of control point of an object, + such as center of circle, bounding point of a curve etc... + \see #GCE_PointOf +*/ +//--- +typedef enum +{ + /* + (!) Don't change the integer values of these names. It may be written to a file permanently. + */ + GCE_FIRST_PTYPE = 0 ///< \ru Значение начинающее последовательность вариантов. \en The value of beginning of the sequence. + , GCE_IMPROPER_POINT = 0 ///< \ru Точка, не принадлежащая объекту. \en Point not belonging to the object. + , GCE_FIRST_END ///< \ru Первый конец ограниченной кривой. \en The first end of bounded curve. + , GCE_SECOND_END ///< \ru Второй конец ограниченной кривой. \en The second end of bounded curve. + , GCE_CENTRE ///< \ru Центр окружности (дуги) или эллипса. \en Center of circle (arc) or ellipse. + , GCE_PROPER_POINT ///< \ru Собственно точка. \en Proper point. + , GCE_Q1 ///< \ru Квадрантная точка эллипса (3 часа). \en Quadrant point of ellipse (3 o'clock). + , GCE_Q2 ///< \ru Квадрантная точка эллипса (12 часов). \en Quadrant point of ellipse (12 o'clock). + , GCE_Q3 ///< \ru Квадрантная точка эллипса (6 часов). \en Quadrant point of ellipse (6 o'clock). + , GCE_Q4 ///< \ru Квадрантная точка эллипса (9 часов). \en Quadrant point of ellipse (9 o'clock). + , GCE_LOCATION_POINT ///< \ru Точка размещения геометрического объекта. \en Location point of geometric object. + , GCE_LAST_PTYPE ///< \ru Значение завершающее последовательность вариантов. \en The value of variants completes the sequence. + /* + The values below are used only within the solver. + */ + , GCE_DIRECTION ///< \ru Направляющий вектор эллипса (направление "большой" полуоси ). \en Vector of ellipse direction (direction of "major" semiaxis). + /** \brief \ru Единичный вектор ориентации: Нормаль прямой, направление "большой" полуоси эллипса. + \en Unit vector of orientation: Normal of a line, direction of "major" semiaxis of ellipse. \~ + */ + , GCE_ORIENTATION + +} query_geom_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Тип запрашиваемой точки (используется, как подмножество значений query_geom_type). + \en Type of the requested point (used as subset of values query_geom_type). +*/ +//--- +typedef query_geom_type point_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Перечисление координат геометрических объектов. + \en Enumeration of geom's coordinates. +*/ +//--- +typedef enum +{ + GCE_X, GCE_Y ///< \ru Координаты точки или вектора. \en Coordinates of a point or a vector. + , GCE_ACRD ///< \ru Угол нормали прямой, угол наклона эллипса. \en Angle of line normal, slope angle of ellipse. + , GCE_DCRD ///< \ru Координата смещения прямой, расстояние от начала координат до прямой. \en Coordinate of line shift, distance from CS origin to line. + , GCE_RADIUS ///< \ru Радиус окружности. \en Circle radius. + , GCE_MAJOR_RADIUS ///< \ru "Главная" полуось эллипса. \en "Major" semiaxis of ellipse. + , GCE_MINOR_RADIUS ///< \ru "Малая" полуось эллипса. \en "Minor" semiaxis of ellipse. + , GCE_NULL_CRD ///< \ru Пустая (несуществующая) координата. \en Empty (nonexistent) coordinate. +} coord_name; + +typedef coord_name coord_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Идентификатор типа 2D ограничения. + \en Identifier of 2D constraint type. \~ + \attention \ru На самом деле решатель поддерживает другие ограничения, кроме перечисленных. + См. вызовы API в 'gce_api.h' + \en Actually, the solver provides more constraint types than is given in the enum. + See the API calls in 'gce_api.h' \~ +*/ +typedef enum +{ + // \ru Унарные геометрические ограничения: \en Unary geometric constraints: + GCE_FIX_GEOM + , GCE_HORIZONTAL ///< \ru Горизонтальность прямой или отрезка. \en Horizontality of a linear object. + , GCE_VERTICAL ///< \ru Вертикальность прямой или отрезка. \en Verticality of a linear object. + , GCE_LENGTH ///< \ru Фиксация длины отрезка. \en Fixation of length of a line segment. + , GCE_ANGLE_OX + + // \ru Бинарные геометрические ограничения: "constr( geom1, geom2 )" \en Binary geometric constraints: "constr( geom1, geom2 )" + , GCE_COINCIDENT ///< \ru Совпадение пары геометрических объектов. \en Coincidence of a pair of geometric objects. + , GCE_EQUAL_LENGTH ///< \ru Равенство длин пары отрезков. \en Equality of two segments lengths. + , GCE_EQUAL_RADIUS ///< \ru Равенство радиусов пары окружностей. \en Equality of two circles lengths. + , GCE_PARALLEL ///< \ru Параллельность пары прямых или отрезков. \en Parallelism of two lines or segments. + , GCE_PERPENDICULAR ///< \ru Перпендикулярность пары прямых или отрезков. \en Perpendicularity of two lines or segments. + , GCE_TANGENT ///< \ru Касание пары кривых. \en Tangency of two curves. + , GCE_COLINEAR ///< \ru Коллинеарность пары прямых или отрезков. \en Collinearity of a pair of lines or segments. + , GCE_ALIGN_2P ///< \ru Выравнивание пары точек вдоль направления. \en Alignment of a pair of points along the direction. + , GCE_CURVATURE_EQUALITY ///< \ru Равенство кривизны кривых в точках. \en Equality of curves curvature in given points. + + // \ru Тернарные геометрические ограничения. \en Ternary geometric constraints. + , GCE_ANGLE_BISECTOR ///< \ru Биссектриса угла. \en Bisector of angle. + , GCE_MIDDLE_POINT ///< \ru Средняя точка. \en Middle point. + , GCE_COLINEAR_3P ///< \ru Коллинеарность тройки точек. \en Collinearity of a point triple. + , GCE_SYMMETRIC ///< \ru Симметричность. \en Symmetry. + + , GCE_PERCENT_POINT ///< \ru \en + , GCE_EQUATION ///< \ru Уравнение. \en Equation. + // \ru Размерные геометрические ограничения \en Dimensional geometric constraints + , GCE_DISTANCE + , GCE_RADIUS_DIM + , GCE_DIAMETER + , GCE_ANGLE + , GCE_CONSTRAINTS_COUNT ///< \ru Количество типов. \en Number of types. + , GCE_UNKNOWN = GCE_CONSTRAINTS_COUNT ///< \ru Неизвестный тип ограничения. \en Unknown constraint type. + , GCE_UNKNOWN_CON = GCE_UNKNOWN +} constraint_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Диагностические коды выполнения функций геометрического решателя. + \en Diagnostic codes of the geometric solver functions execution. \~ +*/ +//--- +typedef enum +{ + GCE_RESULT_None = 0, ///< \ru Нет результата (пустое сообщение). \en No result (empty message). + GCE_RESULT_Ok = 1, ///< \ru Успешный результат. \en Successful result. + GCE_RESULT_Satisfied = 1, ///< \ru Ограничение удовлетворено. \en The constraint is satisfied. + GCE_RESULT_Not_Satisfied = 2, ///< \ru Система ограничений не решена. \en The system of constraints is not solved. + GCE_RESULT_Overconstrained = 3, ///< \ru Переопределенная (несовместная) система ограничений. \en Overdetermined (inconsistent) system of constraints. + GCE_RESULT_InvalidGeometry = 4, ///< \ru Решение привело в нарушению геометрии. \en Solution leaded to violation of geometry. + GCE_RESULT_MovingOfFixedGeom = 5, ///< \ru Попытка перемещения фиксированного объекта. \en Attempt of a fixed object translation. + GCE_RESULT_Unregistered = 6, ///< \ru Обращение к недействительному объекту. \en Access to invalid object. + GCE_RESULT_SystemError = 7, ///< \ru Внутренняя системная ошибка. \en Internal system error. + GCE_RESULT_NullSystem = 8, ///< \ru Обращение к недействительной системе ограничений. \en Access to invalid system of constraints. + GCE_RESULT_CircleCantStretched = 9, ///< \ru Окружность не может быть масштабирована с разными коэффициентами по осям (растяжение). \en The circle can't be scaled with different scaling factors for each axis (stretching). + GCE_RESULT_SingularMatrix = 10, ///< \ru Прислали вырожденную матрицу трансформации. \en A singular transform matrix was received. + GCE_RESULT_DegenerateScalingFactor = 11, ///< \ru Вырожденный коэффициент масштабирования. \en Degenerate scaling factor. + GCE_RESULT_InvalidDimensionTransform = 12, ///< \ru Неудачное преобразование размера. \en Invalid dimension transformation. + GCE_RESULT_Aborted = 13, ///< \ru Процесс вычислений был прерван по запросу приложения. \en The evaluation process aborted by the application. \~ + GCE_RESULT_IsNotDrivingDimension = 14, ///< \ru Данное ограничение должно быть управляющим размером. \en Given constraint should be a driving dimension. + GCE_RESULT_UnsupportedConstraint = 15, ///< \ru На геометрические объекты было наложено невозможное ограничение. \en An impossible constraint was set on geometric objects. + GCE_RESULT_NonUnitScalingFactor = 16, ///< \ru Неединичный коэффициент масштабирования. \en Non unit scaling factor. +} GCE_result; + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Статус геометрического ограничения. + \en Status of a geometric constraint. + \details + \ru Статус ограничения подразумевает деление системы ограничения на подмножества, + которые маркируются следующим образом:\n + Ограничения, помеченые GCE_STATUS_WellTreated и GCE_STATUS_WellConditioned образуют + хорошо-обрабатываемую решателем часть системы ограничений, не содержащую переопределений + и обычно вычисляемую без противоречий.\n + Ограничения, помеченные статусами GCE_STATUS_WellConditioned и GCE_STATUS_IllConditioned + вместе образуют группу взаимосвязанных ограничений, которые обычно решаются без противоречий, + но потенциально могут противоречить друг другу при участии размеров. + Те из них, что помечены GCE_STATUS_IllConditioned создают условия для решаемости хуже, + чем GCE_STATUS_WellConditioned.\n + Статусом GCE_STATUS_Redundant решатель помечает лишние ограничения, которые можно удалить + из системы ограничений. Обычно такие ограничения исполняются за счет других ограничений + или создают ситуацию переопределенности (несовместная система ограничений).\n + Статусом GCE_STATUS_OverConstrained помечаются те из ограничений, которые остались не + решенными по причине несовместной переопределенности. Ограничения со статусами + GCE_STATUS_Redundant и GCE_STATUS_OverConstrained могут находится в противоречии с другими + ограничениями кроме тех, что помечены GCE_STATUS_WellTreated. + + The status of a constraint implies the division of the system into subsets, which are + labeled as follows: \n + Constraints marked with the GCE_STATUS_WellConditioned and GCE_STATUS_IllConditioned + statuses together form a group of interrelated constraints, which are usually resolved + without contradiction, but can potentially contradict each other with the presence of + dimensions. \n + Constraints marked with GCE_STATUS_WellConditioned and GCE_STATUS_IllConditioned statuses + together form a group of interrelated constraints that are usually resolved without + contradiction, but potentially contradictory with dimensions. + Those that are labeled GCE_STATUS_IllConditioned make conditions for evaluating worse, + than GCE_STATUS_WellConditioned. \n + The status of GCE_STATUS_Redundant solver marks the extra constraints that can be removed. + from the constraint system. Usually such constraints are enforced by other constraints. + or create an overdefined situation (incompatible constraint system). \n + The status GCE_STATUS_OverConstrained marks those of constraints that was not solved + due to inconsistent overdefining. Constraints with GCE_STATUS_Redundant and + GCE_STATUS_OverConstrained statuses may conflict with other constraints except those + marked with GCE_STATUS_WellTreated. +*/ +//--- +typedef enum +{ + GCE_STATUS_Undefined = 0 + /* + Statuses indicating which of constraints belong to well-treated + or redundancy parts of the constraint system. + */ + , GCE_STATUS_WellTreated = 1 // Ограничение принадлежит рабочей части системы ограничений без переопределений. + , GCE_STATUS_WellConditioned = 2 // Ограничение принадлежит хорошо-обусловленной части уравнений. + , GCE_STATUS_IllConditioned = 3 ///< /ru Ограничения из плохо-обусловленной части. /en A constraint of ill-condition + , GCE_STATUS_Redundant = 4 ///< /ru Ограничение игнорируется решателем по причине избыточности. // en A constraint is ignored by the solving process beacause of the redundancy. + + /* + Statuses resulting the evaluation (call GCE_Evaluate). + */ + , GCE_STATUS_Solved // Ограничение решено + , GCE_STATUS_NotSolved // Не решено по каким-то причинам + , GCE_STATUS_NotConsistent // Не решено из-за противоречия с другими ограничениями. + , GCE_STATUS_OverConstrained // Не решено избыточное ограничение, противоречащее другим. + +} GCE_c_status; + +//---------------------------------------------------------------------------------------- +/// \ru Вернет 'true' в случае успешного результата. \en Return true, if the result code is successful. +// --- +inline bool OK( GCE_result resCode ) +{ + return resCode == GCE_RESULT_Ok; +} + +//---------------------------------------------------------------------------------------- +/// \ru Вариант решения биссектрисы для двух прямых. \en Variant of a bisector for two lines. +/* + \ru Идентификаторы не менять (возможна запись в файлы)! + \en Don't change identifiers (record to files is possible)! +*/ +//--- +typedef enum +{ + GCE_BISEC_CLOSEST = 0 ///< \ru Неопределенное направление (ближайшее решение). \en Undefined direction (nearest solution). + , GCE_BISEC_MINUS = 1 ///< \ru Биссектриса вдоль суммы направлений прямых/отрезков. \en Bisector along the difference of directions of lines/segments. + , GCE_BISEC_PLUS = 2 ///< \ru Биссектриса вдоль разности нормалей прямых/отрезков. \en Bisector along sum of directions of lines/segments. + +} GCE_bisec_variant; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты вектора. \en Vector coordinates. +//--- +struct GCE_vec2d +{ + double x, y; + GCE_vec2d() { x = y = 0; } +}; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты вектора n-й размерности. \en Coordinates of n-dimensional vector. +//--- +struct GCE_vecNd +{ + size_t size; + double * arg; + GCE_vecNd(): arg(0), size(0) {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты точки на плоскости. \en Coordinates of a point on plane. +//--- +struct GCE_point +{ + double x, y; ///< \ru Декартовы координаты на плоскости \en Cartesian coordinates on the plane + GCE_point() { x = y = 0; } +}; + +//---------------------------------------------------------------------------------------- +/// \ru Степень свободы точки. \en Degree of freedom of a point. +//--- +struct GCE_point_dof +{ + int dof; ///< Degree of freedom of the point. + GCE_vec2d dir; ///< Direction of point moving freedom. + GCE_point_dof(): dof(-1), dir() {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты прямой на плоскости. \en Coordinate of a line on the plane. +//--- +struct GCE_line +{ + GCE_point p; + GCE_vec2d norm; + GCE_line() : p(), norm() {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты окружности. \en Coordinates of a circle. +//--- +struct GCE_circle +{ + GCE_point centre; ///< \ru Центр окружности. \en Circle center. + double radius; ///< \ru Радиус окружности. \en Circle radius. + GCE_circle() : centre(), radius( 0.0 ) {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты эллипса. \en Coordinates of a ellipse. +//--- +struct GCE_ellipse +{ + GCE_point centre; ///< \ru Центр эллипса. \en Ellipse center. + GCE_vec2d direct; ///< \ru Направляющий вектор главной полуоси. \en Vector of the major semiaxis direction. + double majorR; ///< \ru Главная полуось. \en Major semiaxis. + double minorR; ///< \ru Вторая полуось. \en Second semiaxis. + + GCE_ellipse() + : centre() + , direct() + , majorR( 0.0 ) + , minorR( 0.0 ) + {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Координаты и характеристики сплайна. + \en Coordinates and characteristics of a spline.\~ + \details \ru + Сплайн можно задавать тремя способами: \n + 1) По уже существующему объекту MbNurbs. \n + 2) По уже существующему объекту MbNurbs и набору интерполяционных точек. \n + 3) По набору интерполяционных точек, соответствующих им параметров, порядку и признаку замкнутости. + \en + The spline can be specified in three ways: \n + 1) Using already existing object of MbNurbs. \n + 2) Using already existing object of MbNurbs and a set of interpolation points. \n + 3) Using a set of interpolation points, corresponding parameters, order and closedness attribute.\~ + \ingroup Constraints2D_API +*/ +// --- +struct GCE_CLASS GCE_spline +{ + size_t degree; ///< \ru Порядок В-сплайна. \en Order of B-spline. + bool isClosed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness. + std::vector controlPoints; ///< \ru Множество контрольных точек. \en Set of control points. + std::vector controlWeights; ///< \ru Множество весов контрольных точек. \en Set of weights of the control points. + std::vector controlKnots; ///< \ru Узловой вектор. \en Knot vector. + std::vector interpPoints; ///< \ru Множество интерполяционных точек. \en Set of interpolation points. + std::vector interpParams; ///< \ru Множество значений параметров, соответствующих интерполяционным точкам. \en Set of the parameter values corresponding to interpolation points. + MbeNurbsCurveForm form; ///< \ru Форма кривой. \en Form of curve. + + GCE_spline() + : degree( Math::curveDegree ) + , isClosed( false ) + , controlPoints() + , controlWeights() + , controlKnots() + , interpPoints() + , interpParams() + , form( ncf_Unspecified ) + {} + explicit GCE_spline( const MbNurbs & nurbs ); + GCE_spline( const MbNurbs & nurbs, const std::vector & interp ); + GCE_spline( size_t deg, bool cls, const std::vector & interp, const std::vector & pars ); + +private: + GCE_spline( const GCE_spline & ); + GCE_spline & operator = ( const GCE_spline & ); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Параметры размерного ограничения. + \en Parameters of dimensional constraint. \~ + \details + \ru Все размерные ограничения задаются над геометрическими объектами; кроме них + размер определяется дополнительными параметрами, которые передаются через + структуру #GCE_dim_pars. + \en All dimensional constraints are specified on geometrical objects; in addition + dimension is specified by additional parameters which are passed via + the structure #GCE_dim_pars. \~ + + \par + \ru Функции, в которые GCE_dim_pars передается в качестве аргумента: + #GCE_AddDistance, #GCE_AddDistance2P, #GCE_AddDistancePLs, #GCE_AddDistancePLs, + #GCE_AddDirectedDistance, #GCE_FormCirDimension. + \en Functions into which GCE_dim_pars is passed as argument: + #GCE_AddDistance, #GCE_AddDistance2P, #GCE_AddDistancePLs, #GCE_AddDistancePLs, + #GCE_AddDirectedDistance, #GCE_FormCirDimension. \~ + + \par \ru Размеры + + Размер - это числовая функция, аргументами которой являются геометрические объекты, + а возвращаемым значением является число. На основе размеров определяются + 'размерные ограничения'. Все 'размерные ограничения' связывают геометрические + объекты с числом, называемым значением размера. Если ограничение удовлетворено, + то его числовой параметр равен значению размера. Числовой параметр размера + задается либо фиксированным числом (константой), либо числовой переменной.\n + Решатель ограничений обрабатывает два типа размеров: Управляющие и вариационные.\n + + \en Dimensions + + Dimension is a numerical function which arguments are geometric + objects and return value is a number. 'Dimensional constraints' are defined + on the base of dimensions. All 'dimensional constraints' associate geometric + objects with a number called a value of dimension. If the constraint is satisfied, + then its numerical parameter is equal to the value of dimension. Numerical parameter of the dimension + is specified by a fixed number (a constant) or by a numerical variable.\n + The solver of constraints treats two types of dimensions: Driving and variational.\n \~ + + + \par \ru Виды размеров + + "Управляющий" размер - это размерное ограничение, задающее положение + геометрическим объектам согласно константного значения размера;\n + "Вариационный" размер - это ограничение, связывающее геометрические + объекты и переменную, равную значению размера. Под воздействием вариационного + размера может меняться и геометрия и переменная размера.\n + Размеры могу быть направленные, например, расстояние между + точками по горизонтали или по вертикали (функция #GCE_AddDirectedDistance). + + \en Kinds of dimension + + "Driving" dimension is a dimensional constraint specifying position of + geometric objects subject to a constant value of dimension;\n + "Variational" dimension is a constraint associating geometric + objects and a variable which is equal to the dimension value. Both geometry and variable of dimension + can vary under the influence of variational dimension.\n + Dimensions can be directed, for instance, horizontal or vertical distance between + points(function #GCE_AddDirectedDistance). \~ + + + \par \ru Параметры + var - дескриптор переменной, задающей значение размера (градусы, если размер угловой); \n + dimValue - параметр, задающий значение размера; \n + + Если var != GCE_NULL_V, это означает, что размер "вариационный". + Если var == GCE_NULL_V, то значение размера = dimValue, иначе значение размера + тождественно равно числовой переменной 'var', т.е. размер управляющий. + + \en Parameters + + var - descriptor of variable specifying the value of dimension (degrees if the dimension is angular); \n + dimValue - parameter specifying the value of dimension; \n + + If var != GCE_NULL_V, it means that the dimension is "variational" + If var == GCE_NULL_V, then the value of dimension equals dimValue, else the value of dimension + is identically equal to a numerical variable 'var', i.e. the dimension is driving; \~ +*/ +//--- +struct GCE_dim_pars +{ + var_item var; ///< \ru Значение размера, заданное переменной. \en Value of dimension specified by the variable. + double dimValue; ///< \ru Значение размера. \en Value of dimension. + + GCE_dim_pars() + : dimValue( 0.0 ) + , var( GCE_NULL_V ) + {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Параметры углового размерного ограничения. + \en Parameters of angular dimensional constraint. + + \details \ru Структура данных передает настройки для создания угловых размеров. Помимо + общих настроек, передаваемых через структуру #GCE_dim_pars, здесь добавлен флаг + типа угла и множитель пересчета угла в переменную. \n + + factor - множитель для пересчета из присланного угла в переменную. + Используется для создания кратных углов, например двойного.\n + adjacent - смежный угол. Соответствует углу (M_PI - a), где 'a' - угол + между векторами, задающими направление линейного объекта.\n + + Угловой размер можно задать для любых комбинаций линейных объектов. + + \en The data structure passes settings for creation of angular dimensions. + In addition to the general settings passed via structure #GCE_dim_pars there is a flag + of angle type and factor of conversion of angle to variable here. \n + + 'factor' is a factor for converting from a given angle to variable. + It is used for creation of multiple angles, for instance, double angle.\n + 'adjacent' - adjacent angle. It corresponds to angle (M_PI - a), where 'a' is an angle + between vectors specifying the direction of a linear object.\n + + Angular dimension can be specified for any combination of linear objects. \~ +*/ +//--- +struct GCE_adim_pars +{ + GCE_dim_pars dPars; ///< \ru Общие настройки размера. \en General settings of dimension. + double factor; ///< \ru Множитель для пересчета из угла в переменную. \en Factor for converting from angle to variable. + bool adjacent; ///< \ru Смежный угол. \en Adjacent angle. + + GCE_adim_pars() : dPars(), factor( 1.0 ), adjacent( false ) + {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Параметры линейного размерного ограничения. + \en Parameters of distance constraint. + + \details + \ru dirAngle - значение угла в радианах, задающее направление ориентируемых размеров. Пока + используется только для #GCE_AddDirectedDistance2P. \n + \en dirAngle - value of angle in radians specifying the direction of oriented dimensions. + Now it is used only for #GCE_AddDirectedDistance2P. \n \~ +*/ +//--- +struct GCE_ldim_pars +{ + GCE_dim_pars dPars; ///< \ru Числовое значение размера, заданное переменной или числом double. \en Numeric value of dimension specified as a variable or simple double. + double dirAngle; ///< \ru Направление измерения (Используется только для ориентируемых размеров) \en Direction of dimension (It is used for oriented dimensions only) + geom_item hp[2]; ///< \ru Пара дескрипторов вспомогательных точек размера. \en A pair of descriptors of help points of dimension. + + GCE_ldim_pars() : dPars(), dirAngle( 0.0 ) + { + hp[0] = hp[1] = GCE_NULL_G; + } +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Контрольная точка драггинга. + \en Control point of the dragging. + \details + \ru GCE_dragging_point::geom - Дескриптор геометрического объекта, выбранного для воздействия + с помощью функции драггинга ( #GCE_PrepareDraggingPoint).\n + GCE_dragging_point::point - Дескриптор контрольной точки геометрического объекта драггинга. + + \en GCE_dragging_point::geom - Descriptor of a geometric object chosen to interact through + a dragging function (#GCE_PrepareDraggingPoint).\n + GCE_dragging_point::point - Descriptor of control point of the dragging geometric object. + \~ + \see #GCE_PrepareDraggingPoint, #GCE_MovePoint. +*/ +//--- +struct GCE_dragging_point +{ + geom_item geom; ///< \ru Дескриптор геометрического объекта. \en Descriptor of the geometric object. + geom_item point; ///< \ru Дескриптор контрольной точки геометрического объекта. \en Descriptor of the geometric object control point. + GCE_dragging_point() : geom( GCE_NULL ), point( GCE_NULL ) {} + GCE_dragging_point( geom_item g, geom_item pnt ) : geom( g ), point( pnt ) {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Диагностические характеристики системы ограничений. + \en Diagnostic characteristics of constraint system. \~ + \note Used only for testing +*/ +//--- +struct GCE_diagnostic_pars +{ + size_t consCount; // A number of registered constraints. + size_t inConsCount; // A number of internal constraints. + double reductCoef; // Reduction ration of decomposition methods [percentage]. + GCE_diagnostic_pars() : consCount( 0 ), inConsCount( 0 ), reductCoef( .0 ) {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Диагностические характеристики системы ограничений. + \en Diagnostic characteristics of constraint system. \~ + \note Used only for testing +*/ +//--- +struct GCT_diagnostic_pars +{ + size_t consCount; // A number of registered constraints. + size_t inConsCount; // A number of internal constraints. + double reductCoef; // Reduction ratio of decomposition methods [percentage]. + size_t dof; // Degree of freedom of a constraint system. + GCT_diagnostic_pars() + : consCount(0) + , inConsCount(0) + , reductCoef(0) + , dof(0) + {} +}; + +/** + \} + Constraints2D_API +*/ + +//---------------------------------------------------------------------------------------- +// \ru Дескриптор контрольной точки объекта. \en Descriptor of the object control point. +/* + The data structure is deprecated. +*/ +//--- +struct geom_point +{ + geom_item geom; ///< \ru Дескриптор геометрического объекта \en Descriptor of the geometric object + point_type pntName; ///< \ru Имя контрольной точки геометрического объекта \en Name of the geometric object control point + geom_point() : geom( GCE_NULL ), pntName( GCE_IMPROPER_POINT ) {} + geom_point( geom_item g, point_type pnt ) : geom( g ), pntName( pnt ) {} +}; + +/* + The values below will be deleted (deprecated names). +*/ +const constraint_type GCE_INCIDENT = GCE_COINCIDENT; +const geom_type GCE_ARC = GCE_ANY_GEOM; +const geom_type GCE_ELLIPSE_ARC = GCE_ANY_GEOM; + +/* + The values below are deprecated. +*/ + +const query_geom_type GCE_EllipseQ1 = GCE_Q1; +const query_geom_type GCE_EllipseQ2 = GCE_Q2; +const query_geom_type GCE_EllipseQ3 = GCE_Q3; +const query_geom_type GCE_EllipseQ4 = GCE_Q4; + +#endif // __GCE_TYPES_H + +// eof diff --git a/C3d/Include/gcm_api.h b/C3d/Include/gcm_api.h new file mode 100644 index 0000000..c59948a --- /dev/null +++ b/C3d/Include/gcm_api.h @@ -0,0 +1,1085 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Программный интерфейс 3D решателя геометрических ограничений. + \en Program interface of three-dimensional geometric constraints solver. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_API_H +#define __GCM_API_H + +#include +// +#include +#include +#include + +class reader; +class writer; + +/** + \addtogroup GCM_3D_API + \{ +*/ + +/* + Constructing and deleting a constraint system +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Создать пустую систему ограничений. + \en Create a simple constraint system. \~ + \details \ru Вызов создает пустую систему ограничений. Кроме того, в памяти создаются + внутренние структуры данных геометрического решателя, обслуживающего систему ограничений. + Функция возвращает специальный дескриптор, по которому система ограничений доступна для + различных манипуляций: добавление или удаление геометрических объектов, ограничений, + варьирование размеров, драггинг недоопределенных объектов и т.д. + \en The call creates a simple constraint system. Besides, there are created + internal data structures of geometric solver maintaining the system of constraints. + The function returns a special descriptor by which the constraint system is available + for various manipulations: addition and deletion of geometric objects, constraints, + variation of sizes, dragging underconstrained objects etc. \~ + + \return \ru Дескриптор системы ограничений. + \en Descriptor of constraint system. \~ +*/ +//--- +GCM_FUNC(GCM_system) GCM_CreateSystem(); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Сделать систему ограничений пустой. + \en Make the constraint system empty. \~ + \details \ru Данный метод делает систему ограничений пустой при этом дескриптор gSys + остается действительным, т.е. можно осуществлять дальнейшую работу с системой ограничений. + \en This method makes the constraint system empty while the descriptor gSys + remains valid, i.e. it is possible to perform the further work with the constraint system. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \sa #GCM_RemoveSystem +*/ +//--- +GCM_FUNC(void) GCM_ClearSystem( GCM_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить систему ограничений. + \en Delete system of constraints. \~ + \details \ru Данный метод делает систему ограничений недействительной. Осуществляется + освобождение ОЗУ от внутренних структур данных, обслуживающих систему ограничений. + \en This method makes the constraint system invalid. Deallocation of RAM + from the internal data structures maintaining the system of constraints is performed. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \sa #GCM_ClearSystem +*/ +//--- +GCM_FUNC(void) GCM_RemoveSystem( GCM_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Читать систему ограничений из потока + \en Read constraint system from stream. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] in - \ru Поток для чтения. + \en Stream for reading. \~ +*/ +//--- +GCM_FUNC(bool) GCM_ReadSystem( GCM_system gSys, reader & in ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запись системы ограничений в поток + \en Write constraint system to stream. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] out - \ru Поток для записи. + \en Stream for writing. \~ +*/ +//--- +GCM_FUNC(bool) GCM_WriteSystem( GCM_system gSys, writer & out ); + +//---------------------------------------------------------------------------------------- +/// Query to interrupt calculations +//--- +typedef bool ( *GCM_abort )(); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Назначить функцию прерывания вычислений + \en Set a callback to interrupt the calculations. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cbFunc - \ru Функция обратного вызова для прерывания операций. + \en A callback to interrupt the calculation. \~ +*/ +//--- +GCM_FUNC(void) GCM_SetCallback( GCM_system gSys, GCM_abort cbFunc ); + + +/* + Specifying geometry data structures (GCM_g_record) +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать запись пустого геометрического объекта. + \en Give the record of empty geometric object. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_NullGeom(); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать запись точки из типа MbCartPoint3D в типе GCM_g_record. + \en Get a record of point from the type MbCartPoint3D to the type GCM_g_record. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Point( const MbCartPoint3D & ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запись прямой, заданной её точкой и направляющим вектором. + \en Record of line specified by the point and direction vector. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Line( const MbCartPoint3D & org + , const MbVector3D & axisZ ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запись плоскости, заданной точкой и нормалью. + \en Record of plane specified by the point and normal vector. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Plane( const MbCartPoint3D & org, const MbVector3D & axisZ ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись конуса по заданному набору параметров. + \en Get data record of cone for the given set of parameters. \~ + \param[in] centre - \ru Центр окружности-основания конуса. + \en Center of base circle of the cone. \~ + \param[in] axis - \ru Направляющий вектор оси конуса. + \en Direction vector of the cone axis. \~ + \param[in] radiusA - \ru Радиус основания конуса. + \en Radius of the base circle. \~ + \param[in] radiusB - \ru Радиус сечения конуса ("малый" радиус). + \en Radius of section of circle ("minor" radius). \~ + \return \ru Запись конуса. + \en Record of cone. \~ + + \details \ru Предполагается, что параметры конуса описывают воображаемый усеченный конус, + высота которого всегда равна единице длины. При этом radiusA - это радиус + основания конуса, а radiusB - радиус его сечения. + \en It is assumed that the parameters describe the imaginary cone frustum, + whose height is always unit of length. In this radiusA - is the radius of + the base of the cone, and radiusB - the radius of its cross-section. +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Cone( const MbCartPoint3D & centre, const MbVector3D & axis + , double radiusA, double radiusB ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись цилиндра по заданному набору параметров. + \en Get data record of cylinder for the given set of parameters. \~ + \param[in] centre - \ru Центр окружности-основания цилиндра. + \en Center of base circle of the cylinder. \~ + \param[in] axis - \ru Направляющий вектор оси цилиндра. + \en Direction vector of the cylinder axis. \~ + \param[in] radius - \ru Радиус основания цилиндра. + \en Radius of the base circle. \~ + \return \ru Запись цилиндра. + \en Record of cylinder. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Cylinder( const MbCartPoint3D & centre, const MbVector3D & axis + , double radius ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись окружности, заданной набором параметров. + \en Get record of circle specified by the set of parameters. \~ + \param[in] centre - \ru Центр окружности. + \en Center of the circle. \~ + \param[in] axis - \ru Направляющий вектор оси окружности. + \en Direction vector of the circle axis. \~ + \param[in] radius - \ru Радиус окружности. + \en Radius of the circle. \~ + \return \ru Запись данных об окружности. + \en Data record of the circle. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Circle( const MbCartPoint3D & centre, const MbVector3D & axis, double radius ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись тороида по заданному набору параметров. + \en Get data record of torus for the given set of parameters. \~ + \param[in] centre - \ru Центр тора. + \en Center of torus. \~ + \param[in] axis - \ru Направляющий вектор оси вращения. + \en Direction vector of the rotation axis. \~ + \param[in] majorR - \ru "Большой" радиус тора - радиус окружности, описывающей вращение центра сечения. + \en "Major" radius is the radius of circle sweeping center of the rotating section. + \~ + \param[in] minorR - \ru Радиус окружности вращения ("малый" радиус). + \en Radius of section of circle ("minor" radius). \~ + + \details \ru Таким образом предполагается, что тор это воображаемая поверхность вращения, образованная + вращением окружности с радиусом minorR, лежащей в одной плоскости с осью вращения и центром, + расположенном на расстоянии majorR от оси тора. + \en Thus, it is assumed that the torus is an imaginary surface formed by + rotation of a circle of "minor radius" lying in the same plane as the axis + of rotation and the center located at a distance of majorR from the axis. +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Torus( const MbCartPoint3D & centre, const MbVector3D & axis + , double majorR, double minorR ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись данных о сфере, заданной центром и радиусом. + \en Get data record of sphere specified by center and radius. \~ + \param[in] centre - \ru Центр сферы. + \en Center of the sphere. \~ + \param[in] radius - \ru Радиус сферы. + \en Radius of the sphere. \~ + \return \ru Запись данных о сфере. + \en Data record of the sphere. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_Sphere( const MbCartPoint3D & centre, double radius ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись данных твердого тела, заданной началом координат и осями Z, X. + \en Get a data record of solid specified by its origin of coordinates, Z-axis and X-axis. \~ + \details + \ru Результат, который возвращает данная функция, используется для задания + в системе ограничений твердого тела (кластера) с помощью вызовов + GCM_AddGeom или #GCM_SubGeom. + \en The result, which returns this function, is used to specify a rigid body + (cluster) in the system by calling #GCM_AddGeom or #GCM_SubGeom. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_SolidLCS( const MbCartPoint3D & org + , const MbVector3D & axisZ = MbVector3D::zAxis + , const MbVector3D & axisX = MbVector3D::xAxis ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись данных системы координат твердого тела. + \en Get a data record of the solid coordinate system by its placement. \~ + \details + \ru Результат, который возвращает данная функция, используется для задания + в системе ограничений твердого тела (кластера) с помощью вызовов + GCM_AddGeom или GCM_SubGeom. + \en The result, which returns this function, is used to specify a rigid body + (cluster) in the system by calling #GCM_AddGeom or #GCM_SubGeom. \~ +*/ +//--- +GCM_FUNC(GCM_g_record) GCM_SolidLCS( const MbPlacement3D & ); + +/* + Defining geometry of constraint system +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений точку. + \en Add point to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] pVal - \ru Координаты точки. + \en Coordinates of a point. \~ + \return \ru Дескриптор зарегистрированной точки. + \en Descriptor of registered point. \~ +*/ +//--- +GCM_FUNC(GCM_geom) GCM_AddPoint( GCM_system gSys, const MbCartPoint3D & pVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений геометрический объект. + \en Add geometric object to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] gRec - \ru Запись геометрического объекта. + \en Record of geometric record. \~ + \return \ru Дескриптор зарегистрированного объекта. + \en Descriptor of registered object. \~ +*/ +//--- +GCM_FUNC(GCM_geom) GCM_AddGeom( GCM_system gSys, const GCM_g_record & gRec ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в систему ограничений геометрический объект. + \en Add geometric object to the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] gType - \ru Тип геометрического объекта. + \en Type of geometric object. \~ + \param[in] gMat - \ru Прямая матрица ЛСК объекта. + \en Direct matrix of geometric object. \~ + \param[in] radiusA - \ru Радиус окружности, цилиндра, сферы, а также "мажорный" радиус конуса и тора. + \en Radius of circle, cylinder, sphere, also "major" radius of cone and torus. \~ + \param[in] radiusB - \ru "Минорный" радиус конуса или тора. + \en "Minor" radius of cone and torus. \~ + \return \ru Дескриптор зарегистрированного объекта. + \en Descriptor of registered object. \~ +*/ +//-- +GCM_FUNC(GCM_geom) GCM_AddGeom( GCM_system gSys, GCM_g_type gType + , const MbMatrix3D & gMat + , double radiusA, double radiusB ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить в подсистему твердого тела (кластера) подчиненный геометрический объект. + \en Include a geometric sub-object to the subsystem of a solid (rigid cluster). \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] sol - \ru Твердое тело или кластер. + \en Solid or rigid cluster. \~ + \param[in] gRec - \ru Запись геометрического подчиненного объекта, заданного в ЛСК тела. + \en Record of geometric sub-object, which is given in LCS of the solid. \~ + \return \ru Дескриптор подчиненного объекта из подмножества тела. + \en Descriptor of sub-object in subset of the solid. \~ +*/ +//--- +GCM_FUNC(GCM_geom) GCM_SubGeom( GCM_system gSys, GCM_geom sol, const GCM_g_record & gRec ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать кластер (тело), в который включен данный геометрический объект. + \en Give a cluster (solid) in which a geometric object is included. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] subGeom -\ru Геометрический объект, принадлежащий кластеру. + \en A geometric object belonging to the cluster.. \~ + \return \ru Дескриптор кластера, которому принадлежит данный геометрический объект. + \en Descriptor of the cluster that owns this geometric object. \~ +*/ +//--- +GCM_FUNC(GCM_geom) GCM_Parent( GCM_system gSys, GCM_geom subGeom ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Тип геометрического объекта. + \en A type of geometric object. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \return \ru Геометрический тип объекта. + \en Geometric type of an object. \~ +*/ +//--- +GCM_FUNC(GCM_g_type) GCM_GeomType( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить геометрический объект из системы ограничений. + \en Delete a geometric object from the constraint system. \~ + \param gSys - \ru Система ограничений. + \en System of constraints. \~ + \param g - \ru Дескриптор геометрического объекта. + \en Descriptor of geometric object \~ + \details \ru После применения этой функции дескриптор объекта становится недействительным. + Надо заметить, что удаляемый геометрический объект может все еще участвовать в других + объектах и ограничениях. В этом случае удаляемый объект, хотя и считается удаленным, + фактически продолжает действовать до тех пор, пока другие объекты, связанные с ним, + не будут удалены. + \en After using this function the object descriptor 'g' will be invalidated. + It should be noted that the removed geometric object can still involved in other + objects and constraints. In this case, the object to be deleted, although it is considered + removed actually remains in effect until other objects connected with will be deleted. +*/ +//--- +GCE_FUNC(void) GCM_RemoveGeom( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вернет true, если объект все еще действительный. + \en Returns true if the object is still valid. \~ +*/ +//--- +//GCE_FUNC(bool) GCM_IsValid( GCM_system gSys, GCM_geom g ); + +/* + Defining a system of constraints +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать бинарное ограничение для пары геометрических объектов. + \en Set a binary constraint for two geometric objects. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g1 - \ru Дескриптор первого объекта. + \en Descriptors of first object. \~ + \param[in] g2 - \ru Дескриптор второго объекта. + \en Descriptors of second object. \~ + \param[in] aVal - \ru Опция выравнивания. + \en Alignment option. \~ + \param[in] tVar - \ru Вариант касания для ограничения c типом 'GCM_TANGENT'. + \en Variant of tangency for constraint of type 'GCM_TANGENT'. \~ + + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details + \ru Эта функция применяется для задания в системе бинарного ограничения любого + типа кроме размерных, а именно ограничения следующих типов: GCM_COINCIDENT, GCM_PARALLEL, + GCM_PERPENDICULAR, GCM_TANGENT, GCM_CONCENTRIC, GCM_IN_PLACE. В случае неудавшегося вызова, + функция вернет дескриптор пустого объекта GCM_NULL. + + \en The function is used to set a binary constraint of any type except + dimensional constraints, namely one of the following types: GCM_COINCIDENT, GCM_PARALLEL, + GCM_PERPENDICULAR, GCM_TANGENT, GCM_CONCENTRIC, GCM_IN_PLACE. In a case of failure, + the function returns a handle to an empty object GCM_NULL. \~ +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_AddBinConstraint( GCM_system gSys, GCM_c_type cType + , GCM_geom g1, GCM_geom g2, GCM_alignment aVal = GCM_CLOSEST + , GCM_tan_choice tVar = GCM_TAN_POINT ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение, устанавливающее расстояние между парой геометрических объектов. + \en Set a constraint which specifies distance between a pair of geometric objects. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g1 - \ru Дескриптор первого объекта. + \en Descriptors of first object. \~ + \param[in] g2 - \ru Дескриптор второго объекта. + \en Descriptors of second object. \~ + \param[in] dVal - \ru Значение размера. + \en The value of dimension. \~ + \param[in] aVal - \ru Опция выравнивания. + \en Alignment option. \~ + \return \ru Дескриптор нового ограничения c типом GCM_DISTANCE. + \en Descriptor of the created constraint of type GCM_DISTANCE. \~ + + \details \ru Эта функция создает в системе размерное ограничение с типом GCM_DISTANCE, + которое задает линейный размер между двумя геометрическими объектами. + В случае неудачного вызова, функция вернет дескриптор пустого объекта GCM_NULL. + \en The function creates a dimensional constraint of type GCM_DISTANCE, which + specifies linear dimension between two geometric objects. + In a failed call, the function returns a handle to an empty object GCM_NULL.\~ + + \note \ru Значение dVal может быть знакопеременным для ориентируемых объектов. + \en Value of dVal can be positive as well as negative for oriented objects. \~ +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_AddDistance( GCM_system gSys, GCM_geom g1, GCM_geom g2 + , double dVal, GCM_alignment aVal = GCM_CLOSEST ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение, устанавливающее угол между двумя геометрическими объектами. + \en Set a constraint which specifies angle between a pair of geometric objects. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g1 - \ru Дескриптор первого объекта. + \en Descriptors of first object. \~ + \param[in] g2 - \ru Дескриптор второго объекта. + \en Descriptors of second object. \~ + \param[in] axis - \ru Дескриптор объекта, задающего ось вращения угла. Может быть = GCM_NULL. + \en Descriptor of an object that specifying the rotation axis of angle. It can be GCM_NULL. \~ + \param[in] dVal - \ru Значение размера (радианы). + \en The value of dimension (radians). \~ + \return \ru Дескриптор нового ограничения c типом GCM_ANGLE. + \en Descriptor of the created constraint of type GCM_ANGLE. \~ + + \details \ru Эта функция создает в системе размерное ограничение с типом GCM_ANGLE, + которое задает угол между направлениями двух геометрических объектов. + Если ось вращения axis задана (т.е. != GCM_NULL), то угол имеет планарный + способ измерения (0 ... 2пи). В этом случае направления 'g1' и 'g2' обязаны + лежать в плоскости с нормалью заданной осью axis (оба направления перпендикулярны оси). + В случае неудавшегося вызова, функция вернет дескриптор пустого объекта GCM_NULL. + \en The function creates a dimensional constraint of type GCM_ANGLE, which + specifies angle between the directions of two geometric objects. + If the rotational axis is specified (i.e. != GCM_NULL), the angle has an + planar method of measurement (0 ... 2пи). In this case directions of + 'g1' and 'g2' must lie on a plane which has a normal specified by + the 'axis' parameter (both directions perpendicular to the axis ). + In a failed call, the function returns a handle to an empty object GCM_NULL. \~ +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_AddAngle( GCM_system gSys, GCM_geom g1, GCM_geom g2, GCM_geom axis, double dVal ); +GCM_FUNC(GCM_constraint) GCM_AddAngle( GCM_system gSys, GCM_geom g1, GCM_geom g2, double dVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение, устанавливающее радиус геометрического объекта. + \en To create a constraint which specifies a radius of geometric objects. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g1 - \ru Дескриптор геометрического объекта, обладающего ненулевым радиусом. + \en Descriptor of the first object which has nonzero radius. \~ + \return \ru Дескриптор нового ограничения c типом GCM_RADIUS. + \en Descriptor of the created constraint which has a type GCM_RADIUS. \~ + + \details \ru Эта функция позволяет задать радиус геометрического объекта. Изменить величину + радиуса можно с помощью функции #GCM_ChangeDrivingDimension. Удаляется + радиальный размер вызовом функции #GCM_RemoveConstraint. + В случае неудачного вызова, функция вернет дескриптор пустого объекта GCM_NULL. + \en This function allows to specify a radius of the geometric object. To change + radius value use the function #GCM_ChangeDrivingDimension. To remove limitation + on radius of the geometric object use the function #GCM_RemoveConstraint. + In a case of failure, the function returns a handle to an empty object GCM_NULL. \~ +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_FixRadius( GCM_system gSys, GCM_geom g1 ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать управляющий планарный угол между двумя геометрическими объектами. + \en Set a driving planar angle between a pair of geometric objects. \~ + \details \ru Функция аналогична вызову GCM_AddAngle, однако требует ось 'axis', + задающую плоскость откладывания угла. + \en This is the same call GCM_AddAngle, but requires an axis, which defines + a plane in which the angle is measured. \~ +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_AddPlanarAngle( GCM_system gSys, GCM_geom g1, GCM_geom g2 + , GCM_geom axis, double dVal ); + +//---------------------------------------------------------------------------------------- +// Not yet documented +//--- +GCM_FUNC(GCM_constraint) GCM_AddSymmeric( GCM_system gSys, GCM_geom g1, GCM_geom g2 + , GCM_geom plane, GCM_alignment aVal = GCM_NO_ALIGNMENT ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать линейный паттерн. + \en Create a linear pattern constraint. \~ + \details \ru Ограничение "Линейный Паттерн" задаёт закон, согласно которому группа + геометрических объектов, добавленных в этот паттерн с помощью функции + #GCM_AddGeomToPattern, располагается на заданной прямой. Кроме направляющей + прямой, для создания Линейного Паттерна требуется задать геометрический объект, + называемый образцом. Этот объект определяет начало координат (нулевую точку) + направляющей прямой. Таким образом в системе координат направляющей прямой + Линейного Паттерна образец всегда остаётся неподвижным относительно любых + трансляций, поворотов и деформаций. Положение любого добавляемого в паттерн + объекта (копии) определяется его положением на прямой, направленной вдоль + заданной оси, началом координат которой является начало координат ЛСК образца. + \en The Linear Pattern constraint defines the law under which geometric objects + added to this pattern using #GCM_AddGeomToPattern function are located on the + given line (guide line). In addition to the guide line to create a Linear + Pattern constraint it's necessary to specify a geometric object called a + Sample. This object defines the starting point of the guide line of the Linear + Pattern. Thus, Sample always remains stationary relative to any translations, + rotations and deformations in the coordinate system of the Linear Pattern guide + line. The position of any object (called a Copy) to be added to the pattern is + determined by its position on the guide line with the origin coinciding with the + origin of the LCS of the Sample.\~ + \par \ru Порядок удаления + Чтобы удалить Линейный Паттерн целиком нужно воспользоваться функцией + #GCM_RemoveConstraint. При этом не требуется удалять ограничения, созданные при + добавлении новых элементов в паттерн с помощью функции #GCM_AddGeomToPattern: + они будут удалены автоматически. + \en Removal procedure + To remove the Linear Pattern completely It's necessary to use the + #GCM_RemoveConstraint function. There is no need to remove constraints that were + created by the addition of new Copies to the pattern using the function + #GCM_AddGeomToPattern. They will be deleted automatically. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g1 - \ru Дескриптор образца. + \en Descriptor of the sample. \~ + \param[in] g2 - \ru Дескриптор направляющей оси линейного паттерна. + \en Descriptor of the direction axis of the Linear Pattern. \~ + \param[in] align - \ru Опция выравнивания образца относительно направляющей оси. Если задана + опция GCM_ALIGN_WITH_AXIAL_GEOM, то образец g1 будет лежать на направлеющей + прямой(оси) линейного паттерна. + \en Option of alignment of a sample g1 relative to the direction axis. If the + option #GCM_ALIGN_WITH_AXIAL_GEOM is given the sample g1 will be coincident + with the direction line(axis). \~ + \return \ru Дескриптор нового ограничения c типом GCM_LINEAR_PATTERN. + \en Descriptor of the created constraint which has a type GCM_LINEAR_PATTERN. \~ +*/ +// --- +GCM_FUNC(GCM_pattern) GCM_AddLinearPattern( GCM_system gSys, GCM_geom g1, GCM_geom g2, GCM_alignment align=GCM_NO_ALIGNMENT ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать угловой паттерн. + \en Create an angular pattern constraint. \~ + \details \ru Ограничение "Угловой Паттерн" задаёт закон, согласно которому группа + геометрических объектов, добавленных в этот паттерн с помощью функции + #GCM_AddGeomToPattern, располагается на некоторой окружности. Окружность эта + лежит в плоскости перпендикулярной заданной оси, а центр окружности лежит на + этой оси. Кроме оси вращения для создания Углового Паттерна требуется задать + геометрический объект, называемый образцом. Этот объект определяет нулевой угол + и начальный радиус окружности. Таким образом положение любого добавляемого в + паттерн объекта (копии) определяется вращением вокруг заданной оси, начиная от + образца. При этом радиус окружности (расстояние от копии или образца до оси) не + не является константой и может варьироваться (изменяться) в ходе решения. + \en The Angular Pattern constraint defines the law under which geometric objects + added to this pattern using #GCM_AddGeomToPattern function are located on the + given circle. This circle lies in a plane that is perpendicular to the given + axis, and the center of this circle lies on this axis. In addition to the axis + to create an Angular Pattern constraint it's necessary to specify a geometric + object called a Sample. This object defines the zero angle and the initial + radius of the circle for the Angular Pattern. The position of any object (called + a Copy) to be added to the pattern is determined by the rotation around the + given axis, starting from the Sample. The radius of the circle (the distance + from the Copy or the Sample to the axis) is not constant and can vary in the + process of solving the system of equations. \~ + + \par \ru Порядок удаления + Чтобы удалить Угловой Паттерн целиком нужно воспользоваться функцией + #GCM_RemoveConstraint. При этом не требуется удалять ограничения, созданные при + добавлении новых элементов в паттерн с помощью #GCM_AddGeomToPattern: они будут + удалены автоматически. + \en Removal procedure + To remove the Angular Pattern completely It's necessary to use the + #GCM_RemoveConstraint function. There is no need to remove constraints that were + created by the addition of new Copies to the pattern using the function + #GCM_AddGeomToPattern. They will be deleted automatically. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] smp - \ru Дескриптор образца. + \en Descriptor of the sample. \~ + \param[in] axial - \ru Дескриптор оси вращения углового паттерна. + \en Descriptor of the rotation axis of the Angular Pattern. \~ + \param[in] align - \ru Опция выравнивания образца относительно направляющей оси. Если задана + опция GCM_ALIGN_WITH_AXIAL_GEOM, то образец 'smp' будет лежать в плоскости + XY направляющего обекта (оси вращения), и если направляющий объект имеет + радиус (например, это окружность), то расстояние от объектов Углового + Паттерна до оси вращения будет равно радиусу направляющего объекта + (например, радиусу окружности). + \en Option of alignment of a sample relative to the direction axis. + If the GCM_ALIGN_WITH_AXIAL_GEOM option is specified sample g1 will lie in + the XY plane of the direction axis object (rotation axis) and if the + direction axis object has a radius (for example, this is a circle) the + distance from the Angle Pattern objects to the rotation axis will be equal + to the radius of the direction axis object (for example, radius of a circle). \~ + \return \ru Дескриптор нового ограничения c типом GCM_ANGULAR_PATTERN. + \en Descriptor of the created constraint which has a type GCM_ANGULAR_PATTERN. \~ +*/ +// --- +GCM_FUNC(GCM_pattern) GCM_AddAngularPattern( GCM_system gSys, GCM_geom smp, GCM_geom axial, GCM_alignment align=GCM_NO_ALIGNMENT ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Добавить геометрический объект в паттерн. + \en Add geometric object to the pattern. \~ + \details \ru Объект, добавляемый в паттерн, назовём копией. + Если копия добавляется в Линейный Паттерн, то требуется указать расстояние от + копии до образца. Оно может быть положительным или отрицательным и определяется + требуемым положением копии относительно образца с учётом направляющей оси. Так + же можно опционально задать выравнивание ЛСК копии относительно ЛСК образца. + Если копия добавляется в Угловой Паттерн, то требуется указать угол поворота + копии относительно образца, вокруг оси вращения паттерна. Так же можно + опционально задать выравнивание копии относительно образца. Возможны 2 типа + выравнивания: GCM_ALIGNED - выравнивание ЛСК копии и образца и GCM_ROTATED - + выравнивание ЛСК копии с ЛСК образца, повёрнутого вокруг оси вращения на тот же + угол, что и копия. + Расстояние (или угол поворота) от образца до копии по умолчанию фиксировано, + но может быть варьируемым при задании соответствующей опции #GCM_scale. + \en Let's call a Copy the object that is added to the pattern. + If the Copy is added to the Linear Pattern it's necessary to specify the + distance from the Copy to the Sample. It can be positive or negative and is + determined by the required position of the Copy relative to the Sample taking + into account the guide axis. It's optionally possible to specify alignment of + the Copy LCS relative to the Sample LCS. + If the Copy is added to the Angular Pattern it's necessary to specify the + angle of rotation of the Copy relative to the Sample around the pattern rotation + axis. It's optionally possible to specify alignment of the Copy relative to the + Sample. There are 2 types of alignment: GCM_ALIGNED - alignment of the local + coordinate systems of the Copy and the Sample, GCM_ROTATED - the alignment of + the local coordinate system of the Copy with the local coordinate system of the + Sample that is rotated around the axis of rotation at the same angle as the Copy. + The distance (or angle of rotation) from the sample to the copy is fixed by default, +                 but can be varied by specifying the appropriate #GCM_scale option.\~ + + \par \ru Порядок удаления. + Чтобы удалить копию из паттерна используйте функцию #GCM_RemoveConstraint. Если + же вам надо удалить паттерн целиком, то вам не требуется удалять каждую копию из + паттерна, просто удалите паттерн. + \en Removal procedure + To remove a Copy from the pattern use the function #GCM_RemoveConstraint. If + it's necessary to remove the pattern completely there is no need to remove each + copy from the pattern. Just remove the pattern constraint. \~ + + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] ptrn - \ru Дескриптор паттерна, в который добавляем копию. + \en Descriptor of the pattern. \~ + \param[in] geom - \ru Дескриптор добавляемого геометрического объекта (копии). + \en Descriptor of the copy. \~ + \param[in] position - \ru Переменная, задающая положение добавляемой копии в паттерне (расстояние или угол). + \en Variable that specifies the position of the copy in the pattern (distance or angle). \~ + \param[in] align - \ru Опция, задающая выравнивание копии по отношению к образцу. + \en Option that specifies the alignment of copy relative to the sample. \~ + \param[in] scale - \ru Тип масштабирования элемента паттерна. + \en Scaling type of pattern element. \~ + \return \ru Дескриптор нового ограничения c типом GCM_PATTERNED. + \en Descriptor of the created constraint which has a type GCM_PATTERNED. \~ +*/ +// --- +GCM_FUNC(GCM_constraint) GCM_AddGeomToPattern( GCM_system gSys, GCM_pattern ptrn, GCM_geom geom, double position, + GCM_alignment align = GCM_NO_ALIGNMENT, GCM_scale scale = GCM_RIGID ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать ограничение. + \en Set a constraint. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cRec - \ru Унифицированная запись ограничения. + \en Uniform record of a constraint. \~ + \return \ru Дескриптор нового ограничения. + \en Descriptor of a new constraint. \~ + \details + \ru Эта функция применяется только для автоматического тестирования решателя, + поэтому подробно не документировалась. + \en This function is used only for the automated testing of the solver therefore not documented. +*/ +//--- +GCM_FUNC(GCM_constraint) GCM_AddConstraint( GCM_system gSys, const GCM_c_record & cRec ); + +//---------------------------------------------------------------------------------------- +// Not yet documented +//--- +GCM_FUNC(GCM_geom) GCM_SetDependent( GCM_system gSys, GCM_constraint con, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Удалить ограничение из системы. + \en Delete a constraint from the system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] con - \ru Дескриптор ограничения. + \en Descriptor of constraint. \~ +*/ +//--- +GCE_FUNC(void) GCM_RemoveConstraint( GCM_system gSys, GCM_constraint con ); + + +/* + Fixation and freeing of a geometry +*/ + +//---------------------------------------------------------------------------------------- +// Create fixing constraint of the geom +//--- +GCM_FUNC(GCM_constraint) GCM_FixGeom_( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Сделать геометрический объект неподвижным. + \en Set a geometric object fixed. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Дескриптор геометрического объекта. + \en Descriptors of geometric object. \~ + + \details + \ru Эта функция делает объект неподвижным лишая его всех степеней свобод. Если геометрический + объект является суб-объектом тела (кластера), то объект замораживается только в рамках кластера, + однако в глобальной системе координат объект имеет такую же свободу как и кластер, + которому он принадлежит. + \en Thе function makes the object fixed depriving it of all degrees of freedom. If the geometric object + is a sub geom of a solid (cluster), the object is frozen only in the framework of the cluster, + but in the global coordinate system the object has the same freedom as the cluster + to which it belongs. + \~ + \note \ru На будущее планируется, что данная функция будет возвращать дескриптор ограничения. + \en In the future this function will be returning a descriptor of constraint, i.e. will create a fixing constraint. \~ + \sa GCM_FreeGeom +*/ +//--- +GCM_FUNC(bool) GCM_FreezeGeom( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Освободить объект, зафиксированный методом GCM_FreezeGeom. + \en Set free geometric object fixed by GCM_FreezeGeom call. \~ + \sa GCM_FreezeGeom +*/ +//--- +GCM_FUNC(void) GCM_FreeGeom( GCM_system gSys, GCM_geom g ); + +/* + Evaluating methods +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вычислить систему ограничений. + \en Calculate the constraint system. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \return \ru Код результата вычислений. + \en Calculation result code. \~ + \details \ru Функция решает задачу ограничений. Задача ограничений формулируется + функциями API геометрического решателя; функции вида GCM_Add_XXXXXXX добавляют новые + объекты, функции вида GCM_Change_XXXXXXX, GCM_Set_XXXXXXX изменяют состояние объектов. + Таким образом, что бы все такие изменения вступили в силу, нужно вызвать + метод #GCM_Evaluate.\n + Алгоритмы GCM_Evaluate учитывают удовлетворенность систем ограничений; если + все ограничения уже решены, то функция не тратит время на вычисления, а + состояние геометрических объектов остается неизменным. + \en The function solves problem of constraints. The problem of constraint is + formulated by API functions of geometric solver; the functions of a kind GCM_Add_XXXXXXX + add a new object, the functions of kinds GCM_Change_XXXXXXX and GCM_Set_XXXXXXX change + a state of objects. Thus, for all changes to take effect it is necessary to call the + method #GCM_Evaluate.\n + The algorithms GCM_Evaluate take into account whether constraint systems are satisfied, + if all constraints have been already solved, then the function does not spend time + for calculations, and the state of geometric objects remains unchanged. \~ +*/ +//--- +GCM_FUNC(GCM_result) GCM_Evaluate( GCM_system gSys ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить код результата вычисления ограничения. + \en Get result code of the evaluation of constraint. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cItem - \ru Дескриптор ограничения, принадлежащего системе gSys. + \en Descriptor of constraint belonging to the system gSys. \~ + \note \ru Если система еще не вычислялась, то функция вернет код GCM_RESULT_None. + \en If the system has not yet been evaluated then the function will return + the code GCM_RESULT_None. \~ + \return \ru Диагностический код хранящийся в системе после последней вызова GCM_Evaluate. + \en Diagnostic code stored in the system after the last call GCM_Evaluate. \~ +*/ +//--- +GCM_FUNC(GCM_result) GCM_EvaluationResult( GCM_system gSys, GCM_constraint cItem ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выполнить проверку удовлетворенности ограничения. + \en Perform a check that a constraint is satisfied. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] cItem - \ru Дескриптор ограничения. + \en Descriptor of constraint. \~ + \return \ru true, если ограничение удовлетворено. + \en true if a constraint is satisfied. \~ +*/ +//--- +GCM_FUNC(bool) GCM_IsSatisfied( GCM_system gSys, GCM_constraint cItem ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать текущее положение (решение) геометрического объекта. + \en Get current placement (solution) of the geometric object. +*/ +//--- +GCM_FUNC(MbPlacement3D) GCM_Placement( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать начало СК геометрического объекта. + \en Get an LCS origin of the geometric object. + \details \ru Функция вернет координаты начала ЛСК объекта. Данный вызов может быть + использован для любых типов геометрии. Например, для окружности данный вызов вернет ее + центр, для плоскости - точку, лежащую на плоскости, для цилиндра - центр основания + цилиндра и т.д. + \en The function returns coordinates of the origin of the LCS. The call can be applied + to any type of geometry. For example, for a circle the call will return its center, + for a plane - it is a point laying on the plane, + for a cylinder - it is a center of its foundation circle and so on. + +*/ +//--- +GCM_FUNC(MbCartPoint3D) GCM_Origin( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Текущее значение радиуса геометрического объекта. + \en Current radius value of the geometric object. +*/ +//--- +GCM_FUNC(double) GCM_Radius( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Текущее значение "большого" радиуса тора или конуса. + \en Current "major" radius value of torus or cone. +*/ +//--- +GCM_FUNC(double) GCM_RadiusA( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Текущее значение "малого" радиуса тора или конуса. + \en Current "minor" radius value of torus or cone. +*/ +//--- +GCM_FUNC(double) GCM_RadiusB( GCM_system gSys, GCM_geom g ); + +/* + Changing methods +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Изменить значение управляющего размера. + \en Change the value of driving dimension. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] dItem - \ru Дескриптор размерного ограничения. + \en Descriptor of dimensional constraint. \~ + \param[in] dVal - \ru Требуемое значение размера. + \en Required value of constraint. \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \details \ru Функция применяется только для управляющих размеров. Если управляющий размер + является угловым, то параметр dVal задается в радианах.\n + Следует учитывать, что настоящая функция не осуществляет вычислений, а только подготавливает + изменение размера. Что бы изменения вступили в силу, необходимо вызвать функцию #GCE_Evaluate. + \en The function is used only for driving dimensions. If the driving dimension + is angular, then the parameter dVal is specified in radians. \n + It should be noted that the function doesn't perform computations but only prepares + the changing of dimension. For the changes to take effect it is required to call + the function #GCM_Evaluate. \~ +*/ +//--- +GCM_FUNC(GCM_result) GCM_ChangeDrivingDimension( GCM_system gSys, GCM_constraint dItem, double dVal ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Задать текущее положение геометрического объекта. + \en Set current placement of the geometric object. + \note \ru Эта функция только придает объекту новое состояние без переоценки системы + ограничений. Вызов GCM_Evaluate может поменять заданное состояние, если + имеются не удовлетворенные ограничения. + \en The function only impart new state of the object without the revaluation + of constraints. Call GCM_Evaluate can change the given state to satisfy + constraints of this object. \~ +*/ +//--- +GCM_FUNC(void) GCM_SetPlacement( GCM_system gSys, GCM_geom g, const MbPlacement3D & place ); + + +/* + Dragging functions +*/ + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Инициализировать режим перетаскивания объектов в плоскости экрана. + \en Initialize mode of object moving in the screen plane. + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] movGeom - \ru Компонент, деталь, которой манипулируют. + \en Component, part which is manipulated. \~ + \param[in] projPlane - \ru Плоскость экрана, заданная в ГСК сборки. + \en Plane of the screen given in the WCS of assembly. \~ + \param[in] curPnt - \ru Точка, принадлежащая компоненту, которая проецируется на плоскость + экрана в положение курсора, и за которую осуществляется 'перетаскивание'. + curPnt задана в ЛСК геом.объекта movGeom. + \en Point of the component which is projected onto plane of the screen to + cursor position and is 'dragging'. curPnt given in the LCS of + the geometric object movGeom; \~ + \return \ru Код результата. \en Result code. \~ + + \details + \ru Функция запускается однократно перед входом в режим перетаскивания компонент, который управляется + (по движению мыши) через команду #GCM_SolveReposition(GCM_system, const MbCartPoint3D &). Режим + прекращается вызовом любой иной команды, кроме #GCM_PrepareReposition. Также есть специальная + функция для выхода из режима "перетаскивания" - #GCM_FinishReposition, для явного сбрасывания + режима перемещения. + \en The function runs once to start the dragging mode of components, which is controlled + (by movement of the mouse) by the command #GCM_SolveReposition(GCM_system, const MbCartPoint3D &). + Mode is stopped by the calling any other command except #GCM_PrepareReposition. There is also + the special function to exit from the dragging mode explicitly - #GCM_FinishReposition. \~ +*/ +//--- +GCM_FUNC(GCM_result) GCM_PrepareReposition( GCM_system gSys, GCM_geom movGeom + , const MbPlacement3D & projPlane, const MbCartPoint3D & curPnt ); + +/** \brief \ru Инициализировать режим вращения компонента вокруг фиксированной оси. + \en To initialize the rotation mode of the component around a fixed axis. +*/ +GCM_FUNC(GCM_result) GCM_PrepareReposition( GCM_system gSys, GCM_geom rotGeom, const MbCartPoint3D & org, const MbVector3D & axis ); + +/// \ru Завершить режим "перетаскивания". \en Finish the dragging mode. +GCM_FUNC(void) GCM_FinishReposition( GCM_system gSys ); + +/** \brief \ru Выдать объект манипуляции, с которым работает решатель, находясь в режиме вращения/перемещения объектом (драггинг). + \en Get manipulation object with which the Solver works when being in the dragging mode (rotating or moving). +*/ +GCM_FUNC(GCM_geom) GCM_GetMovingGeom( GCM_system gSys ); + +/** + \brief \ru Решить систему для произвольного изменения положения одного тела. + \en Solve the system for an arbitrary change of position of one solid. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] g - \ru Тело, положение которого меняется. + \en Solid, the position of which is changed. \~ + \param[in] newPos - \ru Новое пололожение тела. + \en New position of a solid. \~ + \param[in] movType - \ru Код желаемого поведения + \en Code of the desired behavior \~ + \return \ru Код результата. \en Result code. \~ + + \note \ru Эта функция не позволяет вывести систему сопряжений из состояния решаемости, + кроме случаев, когда до вызова функции система уже находилась в нерешенном + состоянии. Если новое положение 'newPos' не позволяет удовлетворять системе сопряжений, + то новое положение тела окажется наиболее близким к newPos (при сохранении решаемости). + \en This function doesn't allow to take out constraint system from decided state, + except when before call of function the system was already unsolved. If new position + 'newPos' doesn't allow to satisfy the system of constraints, then new position of solid + will be the most nearest to newPos (while preserving solvability). \~ +*/ +GCM_FUNC(GCM_result) GCM_SolveReposition( GCM_system gSys, GCM_geom g + , const MbPlacement3D & newPos, GCM_reposition movType ); + +/** + \brief \ru Решить систему сопряжений для новой позиции курсора в режиме драггинга. + \en Solve the system of constraints for new position of cursor in the dragging mode. + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] curPos - \ru Текущее положение курсора в ГСК. + \en Current position of a cursor in the WCS. \~ + \return \ru Код результата. \en Result code. \~ + + \details \ru Процедура, управляющая режимом перетаскивания, который прекращается вызовом любой иной команды. + \en Procedure that controls dragging mode which are stopped after calling any other command. \~ +*/ +GCM_FUNC(GCM_result) GCM_SolveReposition( GCM_system gSys, const MbCartPoint3D & curPos ); + +/** + \brief \ru Решить систему в режиме драггинга с одно-параметрическим управлением. + \en Solve the system under one-parametric driving in the dragging mode. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] alpha - \ru Управляющий параметр (зачастую задается в радианах). + \en Driving parameter (this is ussualy an angle given in radians). \~ + \return \ru Код результата. \en Result code. \~ + + \details \ru Это функция, управляющая режимом динамического перепозиционирования + (см. #GCM_PrepareReposition), в котором положение тела управляется изменением одной + координаты, например, угла вращения вокруг оси. Режим прекращается вызовом + #GCM_FinishReposition или любой иной командой, меняющей состояние решетеля, например, + #GCM_AddConstraint. + \en This function controls dynamic reposition mode (see #GCM_PrepareReposition), + in which the position of the solid is driven by changing one coordinate. For example + the angle of rotation around an axis. Mode is stopped by calling #GCM_FinishReposition + or any other command, which is changes state of the Solver, for example #GCM_AddConstraint. + \~ +*/ +GCM_FUNC(GCM_result) GCM_SolveReposition( GCM_system gSys, double alpha ); + +/* + Journaling functions +*/ + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Включить журналирование и назначить файл для записи журнала вызовов API. + \en Switch on the journaling and specify the file for recording a journal of GCE API calls. \~ + \param[in] gSys - \ru Система ограничений. + \en System of constraints. \~ + \param[in] fName - \ru Имя файла назначения с полным путем. + \en Name of destination file with a full path. \~ + \return true, if journaling has been successfully switched on. + + \attention + \ru Файл журнала будет записан только после завершения сеанса работы с системой + ограничений, а именно сразу после вызова GCM_RemoveSystem. + \en The journal file will be written only when a session of work with the + constraint system is finished, i.e. immediately after calling the + GCM_RemoveSystem method. + \ru Добавление записей в журнал из параллельного кода не происходит. + \en Adding records to the journal from parallel code does not occur. +*/ +//--- +GCE_FUNC(bool) GCM_SetJournal( GCM_system gSys, const char * fName ); + + +/** \} */ // GCM_3D_API + +struct GCT_diagnostic_pars; +//---------------------------------------------------------------------------------------- +/* + It's used for testing purposes only. +*/ +//--- +GCM_FUNC(const GCT_diagnostic_pars &) GCM_DiagnosticPars( GCM_system gSys ); + +//---------------------------------------------------------------------------------------- +// Use GCM_FreezeGeom instead this (2019). +//--- +GCM_FUNC(void) GCM_FixGeom( GCM_system gSys, GCM_geom g ); + +//---------------------------------------------------------------------------------------- +// Deprecated +//--- +GCM_FUNC(bool) GCM_IsFixed( GCM_system gSys, GCM_geom g ); + + +#endif // __GCM_API_H + +// eof diff --git a/C3d/Include/gcm_blackbox.h b/C3d/Include/gcm_blackbox.h new file mode 100644 index 0000000..52ad5a6 --- /dev/null +++ b/C3d/Include/gcm_blackbox.h @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief Абстрактный интерфейс для чёрного ящика +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_BLACKBOX_H +#define __GCM_BLACKBOX_H + +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------- +/** \brief \ru Чёрный ящик. + \en Blackbox. \~ + \details + \ru Черный ящик реализует закон позиционирования геометрических объектов, зависящих + от позиции других объектов. Интерфейс #ItGCBlackbox реализуется обычно на стороне + клиентского приложения и передается геометрическому решателю для исполнения через метод + #MtGeomSolver::AddBlackbox. например, в системе КОМПАС-3D черный ящик применяется для + моделирования массивов тел (паттерны), которые родились путем тиражирования детали + по закону определенному на стороне приложения. + Черный ящик может применяться не только для организации паттернов, но и для задания на + стороне клиентского приложения различных однонаправленных зависимостей, с определенным + законом позиционирования тел. Объекты, которые рассматриваются, как входящие для черного + ящика, называются независимыми. Объекты, которые рассматриваются, как исходящие для + черного ящика, называются зависимыми. + \en Blackbox implements a law of positioning of geometric objects which are + dependent on positions of other objects. Interface #ItGCBlackbox is usually implemented + on the side of application and it is transferred from the application to the solver + by method #MtGeomSolver::AddBlackbox. The functionality of blackboxes can be used to + the organization of patterns in assembly structures, when the elements of the pattern + are copies of the same part replicated according to a law specified my the application. \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +struct ItGCBlackbox +{ + /// \ru Выдать независимые геометрические объекты. \en The function collects in the array independent geoms of a blackbox. + virtual void CollectMyInGeoms( IFC_Array & ) const = 0; + /// \ru Выдать зависимые геометрические объекты. \en The function collects in the array dependent geoms of a blackbox. + virtual void CollectMyOutGeoms( IFC_Array & ) const = 0; + /** \brief \ru Рассчитать положение зависимого объекта. + \en Calculate position of a dependent geometric object. \~ + \param[in] inPlaces - \ru Позиции независимых объектов, получаемых методом #ItGCBlackbox::CollectMyInGeoms. + \en Positions of independed geoms, which are got by #ItGCBlackbox::CollectMyInGeoms.\~ + \param[in] depGeom - \ru Зависимый геометрический объект. + \en Depended geometric object.\~ + \param[out] depPlace - \ru Вычисленное положение для объекта outGeom. + \en Calculated position for a dependent geom 'outGeom'\~ + \return \ru true, если функция корректно исполнена. + \en true if the function performed succeeded. \~ + */ + virtual bool Calculate( const SArray & inPlaces + , const ItGeom & depGeom + , MbPlacement3D & depPlace ) const = 0; + /// \ru Является ли данный объект зависимым для черного ящика? \en Check if the given geometric item is dependent + virtual bool IsMyOutGeom( const ItGeom & ) const = 0; + /** + \brief \ru Сформулировать ограничения для зависимого геометрического объекта. + \en Formulate constraints for the dependent geometric object. \~ + \details \ru Функция позволяет задать положение зависимого объекта относительно управляющих в явном виде с помощью + интерфейса #MtGeomSolver (#MtGeomSolver::AddConstraint, #MtGeomSolver::AddConstraintItem, + #MtGeomSolver::AddPattren). Данный механизм является альтернативой вызову #ItGCBlackbox::Calculatе. + Его использование сообщает решателю не только о наличии зависимости (как в случае с + #ItGCBlackbox::Calculatе), но и о ее характере. Данное знание позволяет расширить класс разрешимых + задач, но в некоторых случаях может привести к ухудшению производительности. + \en The function allows to set the position of the dependent object relative to it's governing objects + explicitly using the interface #MtGeomSolver (#MtGeomSolver::AddConstraint, + #MtGeomSolver::AddConstraintItem, #MtGeomSolver::AddPattren). This mechanism is an alternative to calling + #ItGCBlackbox::Calculate. Using this mechanism provides an information about the dependency character. + This information allows to extend the class of solvable problems but in some cases can lead to + performance degradation. + \param[in, out] solver - \ru Система ограничений. + \en System of constraints. \~ + \param[in] outGeom - \ru Зависимый геометрический объект. + \en Depended geometric object.\~ + \return \ru Должна возвращать true, если положение зависимого объекта было задано в явном виде через задание в + решателе нужных для этого ограничений; если же положение зависимого объекта должно вычисляться с помощью + метода #ItGCBlackbox::Calculate, функция должна возвращать false. + \en The function should return true, if the position of the dependent object was formulated in the + constraints solver explicitly using #MtGeomSolver::AddConstraint, #MtGeomSolver::AddConstraintItem or + #MtGeomSolver::AddPattren methods. + If the position of the dependent object must be calculated using the method #ItGCBlackbox::Calculate, + the function should return false. + */ + virtual bool FormulateOutGeom( MtGeomSolver & solver, ItGeomPtr outGeom ); + /** + \brief \ru Завершить работу с черным ящиком. \en To finish work with the black box. \~ + \details \ru Функция предоставляет возможность пользователю данного интерфейса корректно завершить работу с черным + ящиком в тот момент, когда он удаляется в решателе. + \en The function allows the user of this interface correctly to complete work with the black box when + it is removing from the solver. \~ + */ + virtual void FinishBlackBox() {} + +public: + virtual refcount_t AddRef() const = 0; + virtual refcount_t Release() const = 0; +}; + +//---------------------------------------------------------------------------------------- +// \ru Сформулировать ограничения для зависимого геометрического объекта. \en Formulate constraints for the dependent geometric object. \~ +// --- +inline bool ItGCBlackbox::FormulateOutGeom( MtGeomSolver & /*solver*/, ItGeomPtr /*outGeom*/ ) +{ + return false; +} + +#endif // __GCM_BLACKBOX_H + +// eof diff --git a/C3d/Include/gcm_constraint.h b/C3d/Include/gcm_constraint.h new file mode 100644 index 0000000..f6e01d2 --- /dev/null +++ b/C3d/Include/gcm_constraint.h @@ -0,0 +1,490 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file \brief \ru Интерфейс для геометрического ограничения в 3D. + \en Interface for geometric constraint in 3D. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_CONSTRAINT_H +#define __GCM_CONSTRAINT_H + +#include +#include +#include +#include + +class MbTopologyItem; +class MtConstraintNode; + +/** + \addtogroup GCM_3D_ObjectAPI + \{ +*/ + +//---------------------------------------------------------------------------------------- +/// \ru Ось планарного угла. \en Axis of a planar angle. +//--- +struct GCM_geom_axis +{ + MbVector3D axis; ///< \ru Направляющий вектор оси планарного угла (задана в ЛСК тела geomPtr). \en Vector of planar angle axis direction (specified in LCS of geomPtr solid). + ItGeomPtr geomPtr; ///< \ru Тело, которому принадлежит ось планарного угла. \en solid the axis of a planar angle belongs to. + GCM_geom_axis() + : axis( MbVector3D::zero ) + , geomPtr( NULL ) {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Структура параметров ограничения. \en Structure of constraint parameters. +//--- +struct GCM_c_params +{ + VERSION m_Version; ///< \ru Версия создания ограничения. \en Version of the constraint creation. + GCM_c_type m_Type; ///< \ru Тип сопряжения. \en Type of mating. + GCM_alignment m_Align; + GCM_tan_choice m_TanChoice; + GCM_angle_type m_AngType; + GCM_scale m_scale; + double m_RealPar; ///< \ru Вещественный параметр. \en Real parameter. + + GCM_c_params() + : m_Version( GetCurrentMathFileVersion() ) + , m_Type( GCM_UNKNOWN ) + , m_Align( GCM_None ) + , m_TanChoice( GCM_TAN_NONE ) + , m_AngType( GCM_NONE_ANGLE ) + , m_scale ( GCM_NO_SCALE ) + , m_RealPar( UNDEFINED_DBL ) + {} +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрического ограничение. + \en Geometric constraint. \~ + \details \ru Абстрактный класс для структуры данных геометрического ограничения. + Класс #ItConstraintItem может быть реализован клиентским приложением, он играет + роль интерфейса, через который решатель MtGeomSolver берет данные об ограничении из + геометрической модели CAD-системы. Кроме этого указатель ItConstraintItem* в решателе + рассматривается, как тип данных "ограничение" его значение уникально идентифицирует + конкретное ограничение на этапе выполнения (run-time) программы. Экземпляр класса + ItConstraintItem может быть реализован, как внутри решателя, так и в клиентском + приложении. + \en Abstract class or data structure of geometric constraint. Class + #ItConstraintItem can be implemented as a client application, it is used as + interface via which the solver receives data about a constraint from a geometric + model of CAD-system. Besides, pointer ItConstraintItem* in the solver MtGeomSolver + is considered as data type "constraint", its value uniquely identifies + a certain constraint during program run-time. Instance of class + ItConstraintItem can be implemented both inside the solver and in a client + application. \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +struct ItConstraintItem +{ +public: /* + Constraint data inquiries + */ + /// \ru Условие выравнивания \en Condition of alignment + virtual GCM_alignment AlignType() const = 0; + /// \ru Разновидность углового ограничения ("3D" или "Планарный"). \en Kind of angular constraint ("3D" or "Planar"). + virtual GCM_angle_type AngleType() const = 0; + /// \ru Ось углового сопряжения, заданная в ЛСК некоторого тела. Только для планарной разновидности. \en Axis of angular mating specified in LCS of some solid. Only for planar kind of constraint. + virtual GCM_geom_axis AxisOfPlanarAngle() const = 0; + /** \brief \ru Ось углового сопряжения с разновидностью GCM_3D_ANGLE. + \en Axis of angular mating with king GCM_3D_ANGLE. \~ + \details \ru Функция выдает вектор, задающий ось ротации для углового размера с + 3D-типом. Вектор задается в ЛСК первого объекта, GeomItem(1). + \en The function gives a vector of the rotation axis for angular dimension with 3D-kind. + The vector is assigned in local coordinates of the first object, GeomItem(1). \~ + */ + virtual MbVector3D AxisOf3DAngle() const { return AxisOf3DAngleType(); } + /// \ru Тип сопряжения (геометрического ограничения). \en Type of geometric constraint. + virtual GCM_c_type ConstraintType() const = 0; + /// \ru Диагностический код ошибки, прикрепленный к данному ограничению. \en Diagnostic error code attached to this constraint. + virtual GCM_result ErrorCode() const = 0; + /// \ru Версия математического ядра, в которой было создано сопряжение. \en The version of mathematical kernel in which the mating was created. + virtual VERSION Version() const = 0; + /** + \brief \ru Числовой параметр размерного ограничения. + \en Numerical parameter of the dimensional constraint. + \details \ru Если размерное ограничение является угловым, то возвращаемое значение + функции задается в радианах.\n + \en If the dimensional constraint is angular, then the returning parameter + is specified in radians. \~ + */ + virtual double DimParameter() const = 0; + /// \ru Вариант касания для ограничения c типом 'GCM_TANGENT'. \en Variant of tangency for constraint of type 'GCM_TANGENT'. \~ + virtual GCM_tan_choice TangencyChoice() const = 0; + +public: /* + Dependency constraint inquiries + */ + + /** \brief \ru Зависимый объект ограничения с типом GCM_DEPENDENT, он всегда первый. + \en Dependent geom of type GCM_DEPENDENT, it is always first geom item.\~ + */ + ItGeomPtr DependentGeom() const; + /** + \brief \ru Функция обратного вызова, которая определяет закон зависимости первого + геометрического объекта от остальных участников данного ограничения. + \en Callback function which defines a law of positioning of the first + geometric object which is dependent on positions of other objects. + */ + virtual GCM_dependent_func Function() const { return NULL; } + virtual GCM_extra_param ExtraParam() const { return GCM_extra_param(); } + +public: /* + Mating geometry inquiries + */ + + /** + \brief \ru Сопрягаемый объект ограничения по номеру аргумента. + \en Mating object of the constraint by a number of an argument . \~ + \param geomN - \ru Номер геометрического аргумента от 1 и более. + \en Number of geom argument from 1 and greater. \~ + \return \ru Сопрягаемый объект вычисляемый в системе ограничений. \en Mating object calculating in the constraint system. \~ + */ + virtual ItGeomPtr GeomItem( int geomN ) const = 0; + + /** + \brief \ru Геометрический аргумент ограничения. + \en Geometric argument of the constraint. + \details \ru Функция выдает геометрический аргумент данного ограничения по номеру от 1 до Arity(). + \en The function gives a geometric argument of the constraint by a number from 1 up to Arity(). + \~ + \param geomN - \ru Номер аргумента от 1 и более. + \en Number of argument from 1 and greater. + \~ + \return \ru Объект, значение которого рассматривается, как аргумент ограничения. + \en Object which value is considered as argument of the constraint. \~ + */ + + MtArgument GeomArg( int geomN ) const; + + /** + \brief \ru Геометрическое значение аргумента ограничения, заданное заданный в ЛСК сопрягаемого объекта GeomItem(geomN). + \en Geometric value of the argument, given in LCS of a "mating" object GeomItem(geomN). \~ + \details \ru Функция выдает геометрическое значение объекта, на которое ссылается ограничение. Данный объект задан + в ЛСК сопрягаемого тела, возвращаемого функцией GeomItem(), именно тело GeomItem(geomN) является предметом + вычислений решателя, а sub-geom задает подчиненный объект стыковки, принадлежащий данному телу. + (см. #ItConstraintItem::GeomItem). + \en The function gives a geometric value of an object which the constraint refer to. Given object specified + in local CS of the mating solid, which is returned by GeomItem() func. Namely, solid GeomItem(geomN) is + a subject of the evaluation, and a sub-geom specify suborinated object of mate, belonging the solid. + (see #ItConstraintItem::GeomItem). \~ + \param geomNb - \ru Номер аргумента от 1 и более. + \en Number of argument from 1 and greater. \~ + \return \ru Объект, значение которого рассматривается, как аргумент ограничения. + \en Object which value is considered as argument of the constraint. \~ + */ + MtGeomVariant SubGeom( int geomNb ) const { return _LinkageItem( geomNb ); } + +public: + /// \ru Количество геометрических объектов, участвующих в ограничении. \en Number of geoms involved in the constraint. \~ + int Arity() const; + void GetParams( GCM_c_params & ) const; + +public: /* + The functions for internal use in the solver. + */ + // \ru Регистрация аргумента ограничения в решателе. \en Register an argument of constraint. + MtArgument _RegisterArgument( int geomNb, MtGeomSolver & ); + // \ru Освободить от регистрации под узлом. \en Release from the constraint node registered in the solver. + void _Unregister( const MtConstraintNode * ); + +public: // \ru Методы для обратной связи (задающие). \en Methods for feedback (driving). + /// \ru Задать код ошибки для неудовлетворенного сопряжения. \en Specify error code for unsatisfied mating. + virtual void SetErrorCode( MtResultCode3D ) = 0; + /** \brief \ru Задать ось для углового сопряжения с трехмерным типом измерения (GCM_3D_ANGLE). + \en Specify the axis for angular mating with three-dimensional type of dimension (GCM_3D_ANGLE). \~ + \note \ru Ось задается и запоминается в СК первого тела GeomItem(1). + \en The axis is specified and stored in CS of the first object, solid given by GeomItem(1). + */ + virtual void SetAxisOf3DAngle( const MbVector3D & axis ) { SetAxisOf3DAngleType(axis); } + +public: // \ru Методы для управления временем жизни. См. также шаблон SPtr. \en Methods for lifetime management. See also template SPtr. + virtual refcount_t AddRef() const = 0; + virtual refcount_t Release() const = 0; + +private: + virtual MtGeomVariant _LinkageItem( int geomN ) const = 0; + virtual int _GeomsNb() const { return 0; } + ItGeomPtr _GArg( int geomN ) const; + +private: // (!) The members below will be removed in a future version (V17 or later). + typedef GCM_geom_axis PlanarAngleAxis; + typedef GCM_angle_type EnAngleType; + typedef GCM_alignment EnAlignCondition; + + +public: // (!) The members below will be removed in a future version (V17 or later). + virtual ItGeomPtr GeomOne() const { return GeomItem(1); } + virtual ItGeomPtr GeomTwo() const { return GeomItem(2); } + virtual MbVector3D AxisOf3DAngleType() const = 0; + virtual void SetAxisOf3DAngleType( const MbVector3D & ) = 0; + MtGeomVariant GeomArgument( int geomN ) const; + +public: // (!) The constants below will be removed in a future version (V17 or later). + static const GCM_angle_type at_Planar = GCM_2D_ANGLE; + static const GCM_angle_type at_3D = GCM_3D_ANGLE; + +protected: + ItConstraintItem() : m_args() {} + ~ItConstraintItem() {} + +private: + std::vector> m_args; + OBVIOUS_PRIVATE_COPY( ItConstraintItem ); +}; + +//---------------------------------------------------------------------------------------- +// \ru Геометрический аргумент ограничения \en Geometric argument of the constraint +//--- +inline MtGeomVariant ItConstraintItem::GeomArgument( int geomNb ) const +{ + return _LinkageItem( geomNb ); +} + +//---------------------------------------------------------------------------------------- +// Number of geoms involved in the constraint +/* + Each constraint type has a strictly defined number of involved + geom arguments with the exception of GCM_DEPENDENT. +*/ +//--- +inline int ItConstraintItem::Arity() const +{ + switch ( ConstraintType() ) + { + case GCM_UNKNOWN: + return 0; + + case GCM_RADIUS: + return 1; + + case GCM_COINCIDENT: + case GCM_PARALLEL: + case GCM_PERPENDICULAR: + case GCM_TANGENT: + case GCM_CONCENTRIC: + case GCM_DISTANCE: + case GCM_IN_PLACE: + case GCM_TRANSMITTION: + case GCM_CAM_MECHANISM: + return 2; + + case GCM_ANGLE: + case GCM_SYMMETRIC: + case GCM_LINEAR_PATTERN: + case GCM_ANGULAR_PATTERN: + case GCM_PATTERNED: // под вопросом, т.к. в API задается 2 аргумента + return 3; + + case GCM_DEPENDENT: + default: + return _GeomsNb(); + } +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline void ItConstraintItem::GetParams( GCM_c_params & pars ) const +{ + pars.m_Version = Version(); + pars.m_Type = ConstraintType(); + pars.m_Align = AlignType(); + pars.m_TanChoice = TangencyChoice(); + pars.m_AngType = AngleType(); + pars.m_RealPar = DimParameter(); +} + +//---------------------------------------------------------------------------------------- +// Зависимый объект (Dependent geom). +//--- +inline ItGeomPtr ItConstraintItem::DependentGeom() const +{ + return (ConstraintType() == GCM_DEPENDENT) ? GeomItem(1) : NULL; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Интерфейс "Механическая передача для двух тел". + \en Interface "Mechanical transmission for two solids". \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +struct ItMateTransmission +{ + enum Motion ///< \ru Тип движения \en Type of motion + { + NoDefined, ///< \ru Не задано \en Not specified + Translation, ///< \ru Линейное перемещение \en Linear increment + Rotation, ///< \ru Вращение \en Rotation + }; + + /// \ru Выдать первое или второе тело (nb -номер тела 1,2); \en Get the first or the second solid (ng is the number of solid 1,2); + virtual ItGeomPtr GetGeom( short nb ) const = 0; + /// \ru Выдать первое или второе тело, задающее направление вращения/перемещения (nb - номер тела 1,2); \en Get the first or the second solid specifying the direction of rotation/translation (nb is the number of solid 1,2); + virtual ItGeomPtr GetDirectionGeom( short nb ) const = 0; + /// \ru Выдать направление и тип движения для первого или второго тела, axis задается в ЛСК тела GetDirectionGeom(); \en Get direction and type of motion for the first or the second solid, axis is specified in LCS of solid GetDirectionGeom(); + virtual Motion GetAxis( short nb, MbAxis3D & axis ) const = 0; + /// \ru Выдать соотношение N1:N2; \en Get ratio N1:N2; + virtual double GetRatio() const = 0; +}; + +/** + \fn ItMateTransmission::GetAxis( short nb, MbAxis3D & axis ) + \ru Ось задается в ЛСК тела, возвращаемого в функции ItGeom * ItMateTransmission::GetDirectionGeom( short nb ) const + \en The axis is specified in LCS of the solid returned in function ItGeom * ItMateTransmission::GetDirectionGeom( short nb ) const \~ +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Интерфейс "Кулачковый механизм". + \en Interface "Cam mechanism". \~ + \details \ru Интерфейс для получения из модели "3D" исходных данных, описывающих + кулачковый механизм.\n + Кулачковый мехнизм описывается:\n + 1) Тело кулачка и тело толкателя;\n + 2) Оси движения кулачка и толкателя, а также типы движения (вращательное/потступательное);\n + 3) Подмножество граней, принадлежащих кулачку, контактирующих с толкателем; + 4) Подмножество граней, принадлежащих толкателю, контактирующих с кулачком; + \en Interface for extraction from "3D" model of the initial data describing + a cam mechanism.\n + Cam mechanism is described:\n + 1) Solid of cam and solid of follower;\n + 2) Axes of motion of the cam and the follower, and types of motion (rotational/translation);\n + 3) Subset of faces belonging to the cam and contacting with the follower; + 4) Subset of faces belonging to the follower and contacting with the cam; \~ + + \ingroup GCM_3D_ObjectAPI +*/ +//--- +struct ItCamMechanism +{ + enum Geom { // \ru Нумерация должна быть согласована с нумерацией участников кинематической пары ItMateTransmission \en Numeration should be compatible with the numeration of components of the kinematic pair ItMateTransmission + Cam = 1, ///< \ru Кулачок(1-е тело); \en Cam (1st solid); + Follower = 2 ///< \ru Толкатель(2-е тело); \en Follower(2nd solid); + }; + + /// \ru Выдать набор топологических объектов контактирования для 1-го или 2-го тела (nb=1-кулачок, nb=2-толкатель); \en Get a set of topological objects of contact for the 1st and the 2nd solid (nb=1- the cam, nb=2-the follower); + virtual void GetTouchFaceSet( Geom nb, RPArray & faceSet ) const = 0; + /// \ru Выдать матрицу преобразования топологических объектов касания в СК кулачка или толкателя (nb=1-кулачок, nb=2-толкатель); \en Get the transformation matrix of topological objects of tangency in coordinate system of the cam or the follower (nb=1- the cam, nb=2- the follower); + virtual void GetMatrixToGeomLCS( Geom nb, MbMatrix3D & toGeomLCS ) const = 0; + /// \ru Добавить ссылку на объект \en Add a reference to the object + virtual refcount_t AddRef() const = 0; + /// \ru Освободить ссылку на объект \en Free the reference to the object + virtual refcount_t Release() const = 0; +}; + +//---------------------------------------------------------------------------------------- +/// \ru Выдать трехзначную величину ориентации {-1,0,+1}. \en Get three-valued orientation {-1,0,+1}. +// --- +inline int AlignmentSign( GCM_alignment aVal ) +{ + switch ( aVal ) + { + case GCM_ALIGNED_0: + case GCM_ALIGNED_1: + case GCM_ALIGNED_2: + case GCM_ALIGNED_3: + return 1; + + case GCM_REVERSE_0: + case GCM_REVERSE_1: + case GCM_REVERSE_2: + case GCM_REVERSE_3: + return -1; + + default: + return 0; + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Выдать двузначную величину ориентации \en Get two-valued orientation +// --- +inline bool Orient( GCM_alignment aVal ) { return AlignmentSign(aVal) > 0; } + +//---------------------------------------------------------------------------------------- +/// \ru Выдать двузначную величину варианта касания \en Get two-valued variant of tangency +// --- +inline bool TangVariant( GCM_alignment aVal ) +{ + return aVal == GCM_REVERSE_1 || + aVal == GCM_ALIGNED_1 || + aVal == GCM_REVERSE_3 || + aVal == GCM_ALIGNED_3; +} + +//---------------------------------------------------------------------------------------- +/// \ru Выдать двузначную величину подварианта касания. \en Get two-valued subvariant of tangency. +// --- +inline bool TangSubVariant( GCM_alignment aVal ) +{ + return aVal == GCM_REVERSE_2 || + aVal == GCM_ALIGNED_2 || + aVal == GCM_REVERSE_3 || + aVal == GCM_ALIGNED_3; +} + +//---------------------------------------------------------------------------------------- +/// \ru Выдать код условия выравнивания по трем двухзначным флагам ориентации, варианта и подварианта касания \en Get code of alignment condition by three two-valued flags of orientation, variant and subvariant of tangency. +// --- +inline GCM_alignment AlignOption( bool axisOrient, bool tangOrient, bool tangSubvariant = false ) +{ + if ( axisOrient ) + { + if ( tangOrient ) { + return tangSubvariant ? GCM_ALIGNED_3 : GCM_ALIGNED_1; + } + else { + return tangSubvariant ? GCM_ALIGNED_2 : GCM_ALIGNED_0; + } + } + else + { + if ( tangOrient ) { + return tangSubvariant ? GCM_REVERSE_3 : GCM_REVERSE_1; + } + else { + return tangSubvariant ? GCM_REVERSE_2 : GCM_REVERSE_0; + } + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Выдать следующий вариант выравнивания. \en Get the next variant of alignment. +// --- +GCM_FUNC(void) NextSolution( GCM_alignment & ); + +//---------------------------------------------------------------------------------------- +/// \ru Выдать предыдущий вариант выравнивания. \en Get the previous variant of alignment. +// --- +GCM_FUNC(void) PrevSolution( GCM_alignment & ); + +/** \} */ + +//---------------------------------------------------------------------------------------- +// +//--- +inline ItGeomPtr ItConstraintItem::_GArg( int geomN ) const +{ + return size_t(geomN-1) < m_args.size() ? m_args[geomN-1] : ItGeomPtr( NULL ); +} + +//---------------------------------------------------------------------------------------- +// Аргумент ограничения +//--- +inline MtArgument ItConstraintItem::GeomArg( int geomN ) const +{ + if ( _GArg(geomN) ) + { + return MtArgument( _GArg(geomN) ); + } + return MtArgument( GeomItem(geomN), SubGeom(geomN) ); +} + +#endif // __GCM_CONSTRAINT_H + +// eof diff --git a/C3d/Include/gcm_geom.h b/C3d/Include/gcm_geom.h new file mode 100644 index 0000000..7cecfcb --- /dev/null +++ b/C3d/Include/gcm_geom.h @@ -0,0 +1,449 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Геометрические типы данных + \en Geometrical types of data \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_GEOM_H +#define __GCM_GEOM_H + +#include +#include +#include +#include +#include +#include +#include + +/** + \addtogroup GCM_3D_ObjectAPI + \{ +*/ + +//---------------------------------------------------------------------------------------- +// +//--- +typedef GCM_geom MtGeomId; +typedef GCM_constraint MtConstraintId; +typedef GCM_geom MtPatternId; +typedef GCM_g_type MtGeomType; +typedef GCM_c_type MtMateType; + +/** \} */ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрический объект. \en Geometrical object. \~ + \details \ru Геометрический объект этого типа данных, характеризуется матрицей + трансформации, которая переводит его в настоящее положение из некоторого стандартного + положения. Подразумевается, что для каждого типа объекта имеется + стандартное положение, которое, как правило, совпадает с мировой системой + координат.\n + Например, если экземпляром ItGeom является точка, то матрица TransMatrix() + задаст положение точки, как преобразование начала координат в некоторое + произвольное место пространства.\n + Если экземпляром ItGeom является жесткое тело в пространстве, то матрица TransMatrix() + будет служить в качестве ЛСК этого тела и задавать его положение в пространстве + моделирования. + \en Geometric object of this data type is described by a matrix + of transformation which transforms this object to real position from some + standard position. The implication is that each type of object has + a standard position which usually coincides with the global system + of coordinates. \n + For example, if ItGeom is a point, then the matrix TransMatrix() + sets the position of a point as the transformation of the origin to some + arbitrary place of the space.\n + If ItGeom is rigid solid in the space, then the matrix TransMatrix() + can be used as LCS of this solid and set its position in the space + of modeling. \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +struct ItGeom +{ + MtGeomId objectId; // (!) Будет закрыто + ItGeom() : objectId( GCM_NULL ) {} + /// \ru Тип геометрического объекта. \en Type of geometric object. \~ + virtual GCM_g_type GeomType() const { return GCM_LCS; } + /// \ru Строковое имя геометрического объекта. \en String name of geometric object. + virtual const TCHAR * GetName() const = 0; + /// \ru Выдать положение детали в виде ортонормированной ЛСК. \en Get position of part as orthonormalized LCS. + virtual void GetPlacement( MbPlacement3D & pl ) const { pl = MbPlacement3D::global; } + /// \ru Выдать трансформацию из стандартного положения. \en Get transformation from standard position. \~ + inline void GetTransMatrix( MbMatrix3D & ) const; + /// \ru Трансформация из стандартного положения. \en Transformation from the standard position. \~ + MbMatrix3D TransMatrix() const; + +public: /* + Reference counting support. + */ + virtual refcount_t AddRef() const = 0; + virtual refcount_t Release() const = 0; + +protected: + virtual ~ItGeom() {} + +private: // It will be removed ... use GetPlacement instead. + virtual void GetGeomPlacement( MbPlacement3D & ) const {} +}; + +/* + ItGeom as pointer type. +*/ +typedef ItGeom * ItGeomPtr; + +//---------------------------------------------------------------------------------------- +// \ru Трансформация из стандартного положения \en Transformation from the standard position +//--- +inline MbMatrix3D ItGeom::TransMatrix() const +{ + MbMatrix3D tValue; + GetTransMatrix( tValue ); + return tValue; +} + +//---------------------------------------------------------------------------------------- +// \ru Выдать трансформацию из стандартного положения. +// \en Get transformation from standard position. +//--- +inline void ItGeom::GetTransMatrix( MbMatrix3D & mat ) const +{ + MbPlacement3D place; + GetPlacement( place ); + place.GetMatrixFrom( mat ); +} + +//---------------------------------------------------------------------------------------- +// Internal data types +//--- +struct MtUnifiedGeom; +class MtParGeom; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрический объект, аргумент геометрического ограничения. + \en Geometric object, argument of geometric constraint. \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +class GCM_CLASS MtGeomVariant +{ +public: + MtGeomVariant() : m_value( NULL ) {} + MtGeomVariant( const MbCartPoint3D & ); + MtGeomVariant( const MtGeomVariant & ); + MtGeomVariant( const MtParGeom & g ) : m_value( NULL ) { Assign(g); } + MtGeomVariant( const GCM_g_type ); + MtGeomVariant( MtParGeom & g ) : m_value( NULL ) { Share(g); } + MtGeomVariant & operator = ( const MtGeomVariant & gVar ) { return Assign( gVar ); } + ~MtGeomVariant(); + +public: + /// \ru Тип геометрии, которому удовлетворяет объект. \en Type of geometry which is satisfied by the object. + MtGeomType GeomType() const; + /// \ru Выдать трансформацию объекта. \en Get transformation of the object. + MbMatrix3D & GetTransMatrix( MbMatrix3D & ) const; + /// \ru Определить, является ли объект пустым. \en Define whether the object is empty. + bool IsNull() const; + +public: /* Assigning methods + */ + MtGeomVariant & Assign( const MtGeomVariant & ); + MtGeomVariant & Assign( MtParGeom & ); + MtGeomVariant & Assign( const MtParGeom & ); + MtGeomVariant & Assign( MtGeomType, const MbCartPoint3D & org, const MbVector3D & zAxis + , const MbVector3D & xAxis, double r1 = 0.0, double r2 = 0.0 ); + template + MtGeomVariant & Assign( GeomDS * ); + MtGeomVariant & Reset(); ///< \ru Задать как тип GCM_NULL_GTYPE. \ru Set as GCM_NULL_GTYPE type. \~ + MtGeomVariant & SetAsPoint( const MbCartPoint3D & ); + MtGeomVariant & SetAsLine( const MbCartPoint3D & org, const MbVector3D & dir ); + MtGeomVariant & SetAsPlane( const MbCartPoint3D & org, const MbVector3D & normal ); + MtGeomVariant & SetAsPlane( const MbPlacement3D & ); + MtGeomVariant & Transform( const MbMatrix3D & ); + +public: /* Methods for internal use + */ + const MtParGeom & ParGeom() const; + MtUnifiedGeom & GetTuple( MtUnifiedGeom & ) const; + +private: + MtGeomVariant & Share( MtParGeom & ); + +private: + MtParGeom * m_value; +}; + +//---------------------------------------------------------------------------------------- +// +//--- +template +MtGeomVariant & MtGeomVariant::Assign( GeomDS * gDs ) +{ + if ( gDs ) + { + return Assign( *gDs ); + } + return Reset(); +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Структура данных сопрягаемой геометрии. + \en Data structure for matched geometry. \~ + \details \ru Эта структура используется для передачи информации о геометрическом + объекте, который участвует в ограничениях. Геометрический объект, передаваемый + через эту структуру данных, может быть задан в ЛСК жесткого тела или в мировой + системе координат модели. \n + Следует учитывать, что геометрический объект, возвращаемый функцию + #MtMatingGeometry::GetMatingGeom(), задан в ЛСК с матрицей + #MtMatingGeometry::LCSMatrix(), т.е. решатель внутри интерпретирует #MtMatingGeometry + как объект #MtMatingGeometry::GetMatingGeom(), заданный в #MtMatingGeometry::LCSMatrix(). + \en This structure is used for passing information about geometric + object involved in constraints. Geometric object passed + via this data structure can be specified in LCS of a rigid solid or in the world + coordinate system. \n + It should be taken into account that the geometric object returned from the function + #MtMatingGeometry::GetMatingGeom(), is given in LCS with matrix + #MtMatingGeometry::LCSMatrix(), i.e. the solver interprets #MtMatingGeometry + as object #MtMatingGeometry::GetMatingGeom() specified in #MtMatingGeometry::LCSMatrix(). \~ + \ingroup GCM_3D_ObjectAPI +*/ +//--- +class MtMatingGeometry +{ +public: + enum Orient ///< \ru Трехзначное свойство ориентации \en Three-valued property of orientation + { + Opposite = 0, ///< \ru "Обратное направление" \en "Reverse direction" + Cooriented = 1, ///< \ru "Прямое направление" \en "Forward direction" + Unoriented = 2 ///< \ru Ориентация не свойственна или "Прямое направление" \en Orientation is nonrelevant or "Forward direction" + }; + static const MtGeomType geom_Marker = GCM_MARKER; + +private: + MtGeomType myGeomType; // \ru Кодирует тип сопрягаемой геометрии \en Encodes type of mating geometry + SPtr myGeom; // \ru Геометрический объект сопряжения \en Geometric object of mating + Orient myOrientation; // \ru Ориентация геометрического объекта myMatingGeom \en Orientation of geometric object myMatingGeom + MbMatrix3D * myLCSMatrix; // \ru Матрица преобразования (ЛСК сопрягаемого тела) \en Transformation matrix (LCS of the mating solid) + +public: + MtMatingGeometry() + : myGeom( NULL ) + , myOrientation( Unoriented ) + , myLCSMatrix( NULL ) + {} + ~MtMatingGeometry() + { + _ClearMatrix(); + } + +public: + /// \ru Выдать тип сопрягаемой геометрии \en Get type of mating geometry + MtGeomType GetGeomType() const { return myGeomType; } + /// \ru Выдать ориентацию; \en Get orientation; + Orient GetOrientation() const { return myOrientation; } + /// \ru Выдать геометрический объект сопряжения. Если =NULL, то это точка, заданная MtMatingGeometry::myMatingPoint; \en Get geometric object of the mating. If =NULL, then this is a point specified by MtMatingGeometry::myMatingPoint; + const MbSpaceItem * GetMatingGeom() const { return myGeom; } + /// \ru Выдать матрицу ЛСК, в которой задан геометрический объект сопряжения \en Get matrix of LCS in which the geometric object of the mating is specified + const MbMatrix3D & LCSMatrix() const; + + + /** + \brief \ru Задать структуру данных как представление прямой. + \en Set the data structure to line representation. \~ + */ + void SetAsLine( const MbCartPoint3D &, const MbVector3D & ); + + /** \brief \ru Инициализировать структуру данных маркером. + \en Initialize the data structure with a marker.\~ */ + void SetAsMarker( const MbCartPoint3D &, const MbVector3D & z, const MbVector3D & x ); + /** + \brief \ru Инициализировать структуру данных маркером. + \en Initialize the data structure with a marker.\~ + \param \ru gArg маркер (! аргумент не передается во владение структуры) + \en gArg is marker (! the argument is not transferred to the structure ownership) \~ + */ + void SetAsMarker( const MbMarker & ); + + /// \ru Присвоить структуре значение ЛСК; \en Assign this data structure with a value of LCS \~ + void SetAsLCS( const MbPlacement3D & lcs ); + void Assign( const MbPlacement3D & lcs ) { SetAsLCS(lcs); } + + /// \ru Инициализировать структуру данных кривой или поверхностью; \en Initialize data structure with a curve or a surface; + /** + \param \ru gItem геометрический объект, подкласс MbSpaceItem (! передается во владение структуры) + \en gItem is geometric object, subclass of MbSpaceItem (! transferred to the structure ownership) \~ + \param \ru gDir флаг ориентации геометрического объекта + \en gDir is flag of geometric object orientation \~ + \param \ru gSpan матрица, задающая подпространство объекта + \en gSpan is matrix specifying subspace of the object \~ + */ + void SetAsMatingGeomItem( SPtr gItem, Orient gDir, const MbMatrix3D & gSpan ); + /// \ru Задать пустой объект \en Specify an empty object + void SetNull(); + +public: + /* + (!) Deprecated + \brief \ru Инициализировать структуру данных маркером или ЛСК. + \en Initialize the data structure with a marker or a LCS.\~ + \param \ru gType тип геометрии, для которой маркер является аргументом (описателем геометрии) + \en gType is a type of geometry for which the marker is an argument (geometry descriptor) \~ + \param \ru gArg маркер (! аргумент не передается во владение структуры) + \en gArg is marker (! the argument is not transferred to the structure ownership) \~ + */ + void SetAsMarker( MtGeomType gType, const MbMarker & gArg ); + + // Internal use only + MtGeomVariant GeomVariant( VERSION c3dVer ) const; + +private: + void _SetLCSMatrix( const MbMatrix3D & ); + void _ClearMatrix(); + +private: // \ru Реализовать при необходимости \en Implement if necessary + MtMatingGeometry( const MtMatingGeometry & ); + MtMatingGeometry & operator = ( const MtMatingGeometry & ); +}; + + +//---------------------------------------------------------------------------------------- +// \ru Выдать матрицу ЛСК, в которой задан геометрический объект сопряжения \en Get matrix of LCS in which the geometric object of the mating is specified +//--- +inline const MbMatrix3D & MtMatingGeometry::LCSMatrix() const +{ + if ( myLCSMatrix != NULL ) + return *myLCSMatrix; + return MbMatrix3D::identity; +} + +//---------------------------------------------------------------------------------------- +// Задать структуру данных как представление прямой. +//--- +inline void MtMatingGeometry::SetAsLine( const MbCartPoint3D & org, const MbVector3D & dir ) +{ + myGeomType = GCM_LINE; + myGeom = new MbLine3D( org, dir ); + myOrientation = Cooriented; + _ClearMatrix(); +} + +//---------------------------------------------------------------------------------------- +// \ru Инициализировать структуру данных кривой или поверхностью; \en Initialize data structure with a curve or a surface; +//--- +inline void MtMatingGeometry::SetAsMarker( MtGeomType gType, const MbMarker & gArg ) +{ + C3D_ASSERT( gType == GCM_MARKER ); + myGeomType = gType; + myGeom = new MbMarker( gArg ); + myOrientation = Unoriented; + _ClearMatrix(); +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline void MtMatingGeometry::SetAsMarker( const MbMarker & gArg ) +{ + myGeomType = GCM_MARKER; + myGeom = new MbMarker( gArg ); + myOrientation = Unoriented; + _ClearMatrix(); +} + +//---------------------------------------------------------------------------------------- +/* \ru Инициализировать структуру данных маркером. + \en Initialize the data structure with a marker.\~ */ +//--- +inline void MtMatingGeometry::SetAsMarker( const MbCartPoint3D & org, const MbVector3D & z, const MbVector3D & x ) +{ + myGeomType = GCM_MARKER; + myGeom = new MbMarker( org, z, x ); + myOrientation = Unoriented; + _ClearMatrix(); +} + +//---------------------------------------------------------------------------------------- +// \ru Присвоить структуре значение ЛСК; \en Assign this data structure with a value of LSC +//--- +inline void MtMatingGeometry::SetAsLCS( const MbPlacement3D & lcs ) +{ + myGeomType = GCM_LCS; + myGeom = NULL; // new MbMarker( MbCartPoint::origin, MbVector3D::zAxis, MbVector3D::xAxis ); + myOrientation = Unoriented; + _SetLCSMatrix( lcs.GetMatrixFrom() ); +} + +//---------------------------------------------------------------------------------------- +// Initialize the data structure by a curve or a surface +//--- +inline void MtMatingGeometry::SetAsMatingGeomItem( SPtr gItem + , Orient gDir + , const MbMatrix3D & gSpan ) +{ + if ( gItem ) + { + myGeomType = GCM_LAST_GTYPE; + myGeom = gItem; + myOrientation = gDir; + _SetLCSMatrix( gSpan ); + } +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline void MtMatingGeometry::_ClearMatrix() +{ + if ( myLCSMatrix != NULL ) + { + delete myLCSMatrix; + } + myLCSMatrix = NULL; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline void MtMatingGeometry::_SetLCSMatrix( const MbMatrix3D & gSpan ) +{ + if ( gSpan.IsSingle() ) + { + _ClearMatrix(); // \ru Единичная матрица эквивалентна её очистке \en Unit matrix is equal to its flush + } + else + { + if ( myLCSMatrix == NULL ) + myLCSMatrix = new MbMatrix3D( gSpan ); + else + *myLCSMatrix = gSpan; + } +} + +//---------------------------------------------------------------------------------------- +// \ru Задать пустой объект \en Specify an empty object +//--- +inline void MtMatingGeometry::SetNull() +{ + myGeomType = GCM_NULL_GTYPE; + myGeom = NULL; + myOrientation = Unoriented; + _ClearMatrix(); +} + +//---------------------------------------------------------------------------------------- +// \ru Конвертировать структуру MtMatingGeometry в аргумент ограничения \en Convert the structure MtMatingGeometry to the argument of constraint +//--- +GCM_FUNC(MtGeomVariant) GeomArgument( const MtMatingGeometry &, VERSION constraintVersion ); + +//---------------------------------------------------------------------------------------- +// +//--- +typedef ItGeom * IfGeomPtr; // deprecated +typedef const ItGeom * IfConstGeomPtr; // deprecated + +#endif // __IT_GEOM_H + +// eof diff --git a/C3d/Include/gcm_manager.h b/C3d/Include/gcm_manager.h new file mode 100644 index 0000000..96ba797 --- /dev/null +++ b/C3d/Include/gcm_manager.h @@ -0,0 +1,684 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Объектное API геометрического решателя в 3D. + \en Object API of geometric solver in 3D. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_MANAGER_H +#define __GCM_MANAGER_H + +#include +#include +#include +#include + +struct ItConstraintItem; +struct ItPositionManager; +struct ItGCBlackbox; +struct GCM_c_params; + +class MbVector3D; +class MbCartPoint3D; +class MbPlacement3D; +class MtGeomSolver; +class MtParGeom; + +/** + \addtogroup GCM_3D_ObjectAPI + \{ +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// \ru Состояние свободы тела \en State of the solid freedom +// +////////////////////////////////////////////////////////////////////////////////////////// + +typedef enum +{ + sof_Zero = 0, ///< \ru Полно-заданное или фиксированное тело (нулевая степень свободы). \en Fully-specified or fixed solid (zero degree of freedom). + sof_WellConstrained = sof_Zero, ///< \ru Полно-заданное или фиксированное тело (нулевая степень свободы). \en Fully-specified or fixed solid (zero degree of freedom). + sof_UnderConstrained = 1, ///< \ru Недоопределенное тело, т.е. имеющее степень свободы. \en Underconstrained solid, i.e. having a degree of freedom. + sof_Unknown = 2, ///< \ru Нет сведений о степени свободы. \en No information about the degree of freedom. +} MtStateOfFreedom; + + +typedef GCM_reposition MtRepositionMode; + +//---------------------------------------------------------------------------------------- +/// \ru Неопределенное значение для некоторого типа. \en Undefined value of some datatype +//--- +template +struct GCM_undefined +{ +private: + static const int value = -1; +}; +template<> struct GCM_undefined +{ + static const GCM_result value = GCM_RESULT_None; +}; +template<> struct GCM_undefined +{ + static const GCM_tan_choice value = GCM_TAN_NONE; +}; +template<> struct GCM_undefined +{ + static const GCM_alignment value = GCM_NO_ALIGNMENT; +}; +template<> struct GCM_undefined +{ + static const GCM_angle_type value = GCM_NONE_ANGLE; +}; +template<> struct GCM_undefined +{ + static const GCM_scale value = GCM_NO_SCALE; +}; +template<> struct GCM_undefined +{ + static const GCM_dependency value = GCM_NO_DEPENDENCY; +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Числовой или перечислительный параметр ограничения. + \en Numeric or enumerated parameter of constraint. \~ + \details \ru В зависимости от контекста тип #MtParVariant может трактоваться, + как число с плавающей точкой или целочисленная величина (int, enum, bool). + \en Depending on the context the type #MtParVariant can be treated + as a floating-point or integer (int, enum, bool). \~ +*/ +//--- +class GCM_CLASS MtParVariant +{ +public: + static const MtParVariant undef; ///< \ru Неопределенное значение. \en Undefined value. + +public: + MtParVariant() : tag( tagUndef ), enumVal( SYS_MAX_ST-2 ) {} // \ru Неопределенное значение \en Undefined value + MtParVariant( float val ) : tag( tagReal ), numVal( static_cast(val) ) {} + MtParVariant( double val ) : tag( tagReal ), numVal( val ) {} + template< class _EnumType > + MtParVariant( _EnumType val ) : tag( tagEnum ), enumVal( static_cast(val) ) {} + +public: + template< typename _EnumType > + bool GetEnum( _EnumType & ) const; + template< typename _EnumType > + _EnumType AsEnum() const; + double AsNumber() const { C3D_ASSERT(tag==tagReal); return numVal; } + int AsInteger() const { C3D_ASSERT(tag==tagInt); return static_cast( enumVal ); } + bool operator == ( const MtParVariant & ) const; + bool operator != ( const MtParVariant & v ) const { return !(v == *this); } + +public: + GCM_alignment AlignType() const; + GCM_c_arg CArg() const; ///< \ru Выдать как аргумент ограничения. \en Give as an argument of constraint. + +private: + union + { + double numVal; + ptrdiff_t enumVal; + }; + enum { tagUndef, tagReal, tagEnum, tagInt } tag : 8; +}; + +//---------------------------------------------------------------------------------------- +// +//--- +template< typename _EnumType > +inline _EnumType MtParVariant::AsEnum() const +{ + if ( tag == tagUndef ) + { + return GCM_undefined<_EnumType>::value; + } + C3D_ASSERT( tag == tagEnum ); + return static_cast<_EnumType>( enumVal ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template< typename _EnumType > +bool MtParVariant::GetEnum( _EnumType & val ) const +{ + if ( tag == tagEnum ) + { + val = AsEnum<_EnumType>(); + return true; + } + return false; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline bool MtParVariant::operator == ( const MtParVariant & var ) const +{ + if ( tag == var.tag ) + { + return ( (numVal == var.numVal) || (enumVal == var.enumVal) ); + } + return false; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline GCM_alignment MtParVariant::AlignType() const +{ + if ( *this == undef ) + return GCM_NO_ALIGNMENT; + + if ( (tag == tagEnum) && (GCM_MIN_ALIGNMENT <= enumVal && enumVal < GCM_MAX_ALIGNMENT) ) + { + return AsEnum(); + } + C3D_ASSERT_UNCONDITIONAL( false ); + return GCM_NO_ALIGNMENT; +} + +//---------------------------------------------------------------------------------------- +// +//--- +inline GCM_c_arg MtParVariant::CArg() const +{ + GCM_c_arg cArg; + switch( tag ) + { + case tagEnum: + case tagInt: + cArg = enumVal; + break; + case tagReal: + cArg = numVal; + break; + case tagUndef: + cArg = GCM_NULL; + break; + default: + C3D_ASSERT_UNCONDITIONAL( false ); + } + return cArg; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрический аргумент ограничения. + \en Geometric argument of constraint. \~ +*/ +//--- +class GCM_CLASS MtArgument +{ +public: + /// \ru Конструктор аргумента, как геометрический объект. \en Constructor of argument as geometric object. + MtArgument(); + MtArgument( const MtArgument & ); + /** \brief \ru Конструктор аргумента, как геометрический объект. + \en Constructor of argument as geometric object. \~ + */ + MtArgument( ItGeom * ); + + /** \brief \ru Конструктор аргумента, как "геометрический объект в кластере". + \en Constructor of argument as "geometric object in the cluster". \~ + \param[in] cluster - \ru Кластер, как геометрически-жесткое объединение. + \en Cluster as geometrically rigid union. \~ + \param[in] refGeom - \ru Геометрический объект, заданный в ЛСК кластера. + \en Geometric object given in the cluster LCS. \~ + \return \ru Аргумент геометрического ограничения. + \en Argument of geometric constraint. \~ + + \details \ru Аргумент, заданный этим способом, предполагает, что геометрический + объект refGeom, задан в ЛСК кластера. При этом в системе ограничений + решение ищется для кластера, в то время, как refGeom считается неподвижно + заданным в ЛСК кластера. + \en Argument given by this method assumes that the geometric + object refGeom is given in the cluster LCS. In this case in system of constraints + the solution is sought for the cluster and refGeom is considered fixed + in the cluster LCS. \~ + + \par \ru Аргумент, как матрица трансформации. + Аргумент, созданный данным методом, можно интерпретировать, как матрицу трансформации, + заданную в виде произведения: G*T, где T - матрица кластера, переменная задачи ограничений, + G - матрица объекта refGeom, константа. Заметим, что если G = I - единичная матрица, + то геометрический объект имеет "стандартное положение". + \en Argument as transformation matrix. + Argument created by this method can be interpreted as a matrix + of transformation given as multiplication: G*T, where T is cluster matrix, + variable of constraints, G - matrix of object refGeom, constant. + Note that if G = I - the identity matrix, then a geometric object + has "standard position". \~ + */ + MtArgument( ItGeom * cluster, MtGeomVariant refGeom ); + ~MtArgument(); + +public: + /// \ru Геометрический объект, вычисляемый в системе ограничений. \en Geometric object calculated in the constraint system. + ItGeomPtr Geom() { return m_geom; } + /// \ru Геометрический объект, вычисляемый в системе ограничений. \en Geometric object calculated in the constraint system. + const ItGeom * Geom() const { return m_geom; } + /** \brief \ru Геометрическое значение аргумента, заданное в ЛСК объекта ItGeom * Geom(). + \en Geometric value of the argument specified in the LCS of the object ItGeom * Geom(). + */ + MtGeomVariant RefGeom() const; + /// \ru Тип геометрии. \en Geometry type. + MtGeomType GeomType() const; + /// \ru Простой аргумент - не задан, как часть кластера. \en A simple argument, i.e. is not given as part of a cluster. \~ + bool Simple() const; + /// \ru Выдать положение геометрического объекта в виде ЛСК. \en Get a position of geometric object as its LSC. + void GetPlacement( MbPlacement3D & ) const; + /// \ru Оператор присваивания. \en Assignment operator. + MtArgument & operator = ( const MtArgument & ); + /// \ru Оператор равенства. \en Equality operator. + inline bool operator == ( const ItGeom * ) const; + +private: + SPtr m_geom; // Geometric object of the constraint system (often, it is a rigid body) + MtGeomVariant m_refGeom; // Geometric object given in the m_geom's LCS. +}; + +//---------------------------------------------------------------------------------------- +// \ru Оператор равенства. \en Equality operator. +//--- +inline bool MtArgument::operator == ( const ItGeom * geom ) const +{ + if ( m_geom == geom ) + { + return Simple(); + } + return false; +} + + +//---------------------------------------------------------------------------------------- +// +// --- +struct ItConstraintsEnum : public MtRefItem +{ + virtual const ItConstraintItem * GetDataAndGo() = 0; + virtual void Restart() = 0; +}; + +class MtConstraintManager; // Internal implementation of the solver + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрический решатель. + \en Geometric constraint solver. \~ + \details \ru Интерфейс геометрического решателя. Клиентское приложение может + работать любым количеством систем ограничений, для каждой из них заводится по + одному экземпляру решателя с помощью вызова #CreateSolver. + \en Interface of geometric solver. Client application can + run any count of constraint systems, for each of them is put + one copy of the solver by calling #CreateSolver. \~ + + \ingroup GCM_3D_ObjectAPI +*/ +//--- +class GCM_CLASS MtGeomSolver: public MtRefItem +{ + /** + \ru \name Функции задания системы сопряжений + \en \name Definition functions of the constraint system + \{ + */ +public: + /// \ru Добавить паттерн. \en Add a pattern. + MtPatternId AddPattern( MtMateType, MtArgument, MtArgument, MtParVariant par=MtParVariant::undef ); + /// \ru Добавить геометрический объект в паттерн. \en Add a geometric object to the pattern. + MtConstraintId AddGeomToPattern( MtPatternId ptrn, MtArgument ptrnObj, MtParVariant par1 = MtParVariant::undef, + MtParVariant par2 = MtParVariant::undef, GCM_scale scale=GCM_RIGID ); + /// \ru Добавить ограничение. \en Add constraint. + MtResultCode3D AddConstraintItem( ItConstraintItem & ); + + /** \brief \ru Добавить сопряжение для пары геометрических объектов(ограничение). + \en Add mate (constraint) of two geometric objects. \~ + \param[in] t - \ru Тип геометрического ограничения. + \en Type of geometric constraint. \~ + \param[in] g1, g2 - \ru Пара геометрических объектов - аргументы ограничения. + \en Pair of geometric objects - arguments of constraint. \~ + \param[in] p1 - \ru Условие выравнивания для таких типов ограничений, как GCM_COINCIDENT, + GCM_PARALLEL, GCM_PERPENDICULAR, GCM_CONCENTRIC, GCM_IN_PLACE, + GCM_TANGENT. Значения данного параметра берутся из #GCM_alignment. + \en Condition of alignment for or these types of constraints like GCM_COINCIDENT, + GCM_PARALLEL, GCM_PERPENDICULAR, GCM_CONCENTRIC, GCM_IN_PLACE, + mct_Tangency. Values of this parameter are taken from #GCM_alignment. \~ + \param[in] p1 - \ru Числовой параметр (double) размерных ограничений с типами GCM_ANGLE, GCM_DISTANCE. + \en Numeric parameter (double) of dimensional constraints to the types of GCM_ANGLE, GCM_DISTANCE. \~ + \param[in] p2 - \ru Вариант касания #GCM_tan_choice для ограничения типа GCM_TANGENCY + или значение #GCM_alignment для размерных ограничений. + \en Tangency variant #GCM_tan_choice for constraint with type GCM_TANGENCY + or value #GCM_alignment for dimensional constraint. \~ + \param[in] p3 - \ru Не имеет значения. + \en Irrelevant. \~ + \return \ru Геометрическое ограничение. \en Geometric constraint. \~ + */ + ItConstraintItem * AddConstraint ( MtMateType t, MtArgument g1, MtArgument g2 + , MtParVariant p1 = MtParVariant::undef + , MtParVariant p2 = MtParVariant::undef + , MtParVariant p3 = MtParVariant::undef ); + /** \brief \ru Добавить ограничение для тройки геометрических объектов. + \en Add constraint of three geometric objects. \~ + */ + ItConstraintItem * AddConstraint ( MtMateType, MtArgument, MtArgument, MtArgument, MtParVariant p1 = MtParVariant::undef ); + + /// \ru Добавить ограничение. \en Add constraint. + ItConstraintItem * AddConstraint( MtArgument, MtArgument, const GCM_c_params &, MtResultCode3D & ); + /** \brief \ru Добавить черный ящик в систему ограничений. + \en Add black box to the constraint system. \~ + \param[in] bBox - \ru Интерфейс чёрного ящика. + \en Interface of Interface black box. \~ + \return \ru Код результата. \en Result code. \~ + */ + /// \ru Добавить геометрический объект. \en Add the geometric object. + ItGeom * AddGeom( MtGeomVariant ); + // Not yet documented + MtResultCode3D AddBlackbox( ItGCBlackbox & ); + /// \ru Задать для данного ограничения зависимый объект. \ru Set a dependent object of constraint. + ItGeom * SetDependentGeom( ItConstraintItem *, ItGeom * ); + /// \ru Сообщить об изменении данных, определяющих сопряжение. \en Report about change in the data defining conjugation. + MtResultCode3D ChangeDefinition( ItConstraintItem & ); + /// \ru Сообщить об изменении вещественного параметра размерного сопряжения. \en Report about change of float-parameter of dimensional conjugation. + MtResultCode3D ChangeDimension( ItConstraintItem & ); + /** + \brief \ru Сообщить о изменении положения сопрягаемых тел. + \en Report about position change of conjugated solids. \~ + \return \ru Код результата. \en Result code. \~ + \details \ru Через эту функцию осуществляется синхронизация положения + объектов системы ограничений по состоянию объектов стороне клиентского + приложения. Надо сказать, что обновление положений происходит только для тех + наследников #ItGeom, которые реализованы на стороне приложения. Состояние + объектов, добавленных методом #MtGeomSolver::AddGeom остается неизменным. + \en Using this function implements synchronization of position + of objects of constraints as objects of a client + application. It should be said that the update of the positions happens only for those + inheritors of #ItGeom which are implemented by the application. State + of objects added by method #MtGeomSolver::AddGeom remains unchanged. \~ + */ + MtResultCode3D ChangeGeomPositions(); + /** + \brief \ru Создать пользовательский кластер. + \en Create an user-defined cluster. + \note \ru Объекты объединяемого множества не должны иметь ограничений на момент вызова. + Создавайте кластер перед добавлением ограничений. + \en The united objects should not have constraints at the moment of the call. + Create a cluster before adding constraints. + */ + ItGeom * CreateCluster( std::vector & ); + /// \ru Зафиксировать геометрический объект в ГСК. \en Fix geometric object in the WCS. + MtResultCode3D FixGeom( ItGeom & ); + /// \ru Узнать зафиксирован ли геометрический объект? \en Check if a geometric object is fixed? + bool IsFixed( const ItGeom * ); + /// \ru Очистить систему ограничений. \en Clear the system constraint. + void Flush(); + /// \ru Удалить из системы ограничений все черные ящики. \en Remove all the black boxes from the constraint system. + MtResultCode3D RemoveAllBlackboxes(); + /// \ru Удалить ограничение из системы. \en Remove constraint from system. + MtResultCode3D RemoveConstraint( ItConstraintItem * ); + /// \ru Удалить чёрный ящик из системы ограничений. \en Remove black box from constraint system. + MtResultCode3D RemoveBlackbox( ItGCBlackbox & ); + /// \ru Удалить геометрический объект из системы ограничений. \en Remove geometric object from constraint system. + bool RemoveGeom( ItGeom * ); + /// \ru Освободить геометрический объект от фиксации в ГСК. \en Free geometric object from fixation in the WCS. + MtResultCode3D UnfixGeom( ItGeom & ); + + /** + \} + \ru \name Функции решения и диагностики + \en \name Functions of solution and diagnostics + \{ + */ +public: + /// \ru Узнать удовлетворено ли ограничение? \en Check if constraint is satisfied? + bool IsSatisfied( const ItConstraintItem & ); + /// \ru Узнать является ли тело полно-заданным или фиксированным ? \en Check if solid is fully-specified or fixed? + MtStateOfFreedom IsWellConstrained( const ItGeom & ); + /** + \brief \ru Разослать диагностические коды ограничениям. + \en Send out diagnostic codes to constraints. \~ + \details \ru Осуществляется решение системы ограничений. Если она частично не решена, + то по результатам решения рассылаются диагностические коды ошибок всем ограничениям. + Функция не тратит существенного времени, если систему ограничений до этого уже пытались решать. + \en Solving the constraint system. If it is not solved partly, then by the + results of the solution diagnostic codes of errors are sent to all the constraints. + The function doesn't have a substantial amount of time if have already tried to + solve the constraint system before. \~ + */ + void DiagnoseConstraints(); + /** + \brief \ru Решить систему сопряжений. \en Solve the constraint system. \~ + \details \ru Меняет положение геометрических объектов в соответствии с геометрическими ограничениями. + \en Changes positions of geometric objects according to geometric constraints. \~ + */ + MtResultCode3D Evaluate(); + /// \ru Текущее или вычисленное положение геометрического объекта \en Current or calculated position of a geometric object + MbMatrix3D TransMatrix( ItGeom * ) const; + /** + \brief \ru Получить кластер, в котором содержится данный геометрический объект. + \en Get cluster which contains a given geometric object. \~ + */ + const ItGeom * Cluster( const ItGeom * subGeom ) const; + + /** + \} + \ru \name Функции для интерактивной манипуляции системой сопряжений + \en \name Functions for interactive manipulation of the constraint system + \{ + */ +public: + /// \ru Завершить режим "перетаскивания". \en Finish the dragging mode. + void FinishReposition(); + /** \brief \ru Выдать объект манипуляции, с которым работает решатель, находясь в режиме вращения/перемещения объектом (драггинг). + \en Get manipulation object. Solver works with it when being in the dragging mode (rotating or moving). + */ + ItGeom * GetMovingGeom() const; + /** + \brief \ru Инициализировать режим перетаскивания объектов в плоскости экрана. + \en Initialize mode of object moving in the screen plane. + \param movGeom - \ru Компонент, деталь, которой манипулируют. + \en Component, part which is manipulated. \~ + \param projPlane - \ru Плоскость экрана, заданная в ГСК сборки. + \en Plane of the screen given in the WCS of assembly. \~ + \param curPnt - \ru Точка, принадлежащая компоненту, которая проецируется на плоскость + экрана в положение курсора, и за которую осуществляется 'перетаскивание'. + curPnt задана в ЛСК геом.объекта movGeom. + \en Point of the component which is projected onto plane of the screen to + cursor position and is 'dragging'. curPnt given in the LCS of + the geometric object movGeom; \~ + \return \ru Код результата. \en Result code. \~ + + \details + \ru Функция запускается однократно перед входом в режим перетаскивания компонент, + который управляется (по движению мыши) через команду + MtResultCode3D SolveReposition( const MbCartPoint3D & ). Режим прекращается вызовом + любой иной команды, кроме этих двух; Также есть специальная функция для выхода из + режима "перетаскивания" - void FinishReposition(), для явного сбрасывания режима перемещения. + \en The function runs once before running the dragging mode of components, + which is controlled (by movement of the mouse) by the command + MtResultCode3D SolveReposition( const MbCartPoint3D & ). Mode is stopped calling any other + command other than these two. There is also the special feature. To exit from + the dragging mode - void FinishReposition(), for explicit stop of the dragging mode. \~ + */ + MtResultCode3D PrepareReposition( ItGeom & movGeom, const MbPlacement3D & projPlane, const MbCartPoint3D & curPnt ); + /** \brief \ru Инициализировать режим вращения компонента вокруг фиксированной оси. + \en Initialize mode of component rotation around a fixed point of axis. + + \param geom - \ru Геометрический объект, на которое направлено воздействие. + \en The geom object on which is directed at impact. \~ + \param org, axis - \ru Точка и вектор в ГСК, которые задают постоянную ось вращения. + \en Point and vector in the GCS which define constant axis of rotation. \~ + \return \ru Код ошибки, перечисленный enum #MtResultCode3D + \en Error code, enum #MtResultCode3D \~ + \par + \ru Функция запускается однократно перед входом в режим вращения, который управляется + через команду MtResultCode3D SolveReposition( double alpha ), где alpha - входной параметр, + определяющий угловое положение компонента, и заданный в радианах. Режим прекращается вызовом + void FinishReposition(). + \en The function runs once before running the rotation mode which is driven + by command MtResultCode3D SolveReposition( double alpha ), where "alpha" - input parameter, + defines the angular position of the component and given in radians. Mode is stopped by + calling void FinishReposition(). \~ + */ + MtResultCode3D PrepareReposition( ItGeom & rotGeom, const MbCartPoint3D & org, const MbVector3D & axis ); + /** + \brief \ru Решить систему для произвольного изменения положения одного тела. + \en Solve the system for an arbitrary change of position of one solid. \~ + \param \ru gItem тело, положение которого меняется; + \en gItem solid, the position of which is changed; \~ + \param \ru newPos новое пололожение тела g_item; + \en newPos new position of solid g_item; \~ + \param \ru movType код желаемого поведения + \en movType code of the desired behavior \~ + \return \ru Код результата. \en Result code. \~ + + \note \ru Эта функция не позволяет вывести систему сопряжений из состояния решаемости, + кроме случаев, когда до вызова функции система уже находилась в нерешенном состоянии. + Если новое положение 'newPos' не позволяет удовлетворять системе сопряжений, то новое + положение тела окажется наиболее близким к newPos (при сохранении решаемости). + \en This function doesn't allow to take out constraint system from decided state, + except when before call of function the system was already unsolved. If new position + 'newPos' doesn't allow to satisfy the system of constraints, then new position of solid + will be the most nearest to newPos (while preserving solvability). \~ + */ + MtResultCode3D SolveReposition( ItGeom & gItem, const MbPlacement3D & newPos, MtRepositionMode movType ); + /** + \brief \ru Решить систему сопряжений для новой позиции курсора в режиме драггинга. + \en Solve the system of conjugations for new position of cursor in the dragging mode. + \param - \ru curXYZ текущее положение курсора в ГСК. + \en curXYZ the current position of cursor in the WCS. \~ + \return \ru Код результата. \en Result code. \~ + + \details \ru Рабочая процедура, управляющая режимом перетаскивания, который прекращается + вызовом любой иной команды, например, добавить новое ограничение или перестроить. + \en Work procedure which controls dragging mode which are stopped after call + any other command. For example: add a new constraint or rebuild. \~ + */ + MtResultCode3D SolveReposition( const MbCartPoint3D & curXYZ ); + /** + \brief \ru Решить систему с изменением положения компонента через одну координату. + \en Solve the system with the position of the component through one coordinate. \~ + + \param alpha - \ru Управляющий параметр (зачастую задается в радианах). + \en Driving parameter (often, it's in radians ). \~ + \return \ru Код результата. \en Result code. \~ + + \details \ru Это рабочая функция, управляющая режимом перепозиционирования, + в котором положение тела управляется изменением одной координаты, например, угол + вращения вокруг оси. Режим прекращается вызовом #MtGeomSolver::FinishReposition или любой + иной командой, меняющей состояние решетеля, например, #MtGeomSolver::AddConstraint. + Функция для больших систем работает значительно быстрее, чем Solve(bool) или + SolveReposition( ItGeom &, const MbPlacement3D &). + \en This is the work function controls reposition mode, in which the position of + the solid is controlled by changing one coordinate. For example the angle of rotation + around an axis. Mode is stopped by calling #MtGeomSolver::FinishReposition or any + other command, which is changes state of the solver. + For example #MtGeomSolver::AddConstraint. Function for large systems is faster than + the Solve(bool) or SolveReposition( ItGeom &, const MbPlacement3D &). \~ + */ + MtResultCode3D SolveReposition( double alpha ); + +public: + /** + \} + \ru \name Вспомогательные функции и запросы. + \en \name Auxiliary functions and queries. + \{ + */ + + /** \brief \ru Узнать принадлежит ли системе ограничений геометрический объект. + \en Check if geometric object belongs to the system. \~ + */ + bool IsMyGeom( const ItGeom & ) const; + + /** \brief \ru Узнать принадлежит ли системе ограничений геометрическое ограничение. + \en Check if geometric constraint belongs to the system. + */ + bool IsMyConstraint( const ItConstraintItem & ) const; + + /** \brief \ru Выдать кластер неподвижных объектов, заданных в глобальной системой координат. + \en Get the cluster of rigid subset of objects which are given in global coordinate system. \~ + */ + ItGeom * Ground() const; + + /** \brief \ru Выдать систему геометрических ограничений, которую обслуживает решатель. + \en Get a geometric constraint system, which is served by the solver. \~ + */ + GCM_system System() const; + + // Not yet documented + void WriteSystem( TCHAR * fileName ); + /// \ru Выдать ограничения. \en Get the constraints iterator. + SPtr GetConstraintsEnum(); + + /** + \} + \ru \name Устаревшие функции, которые будут удалены в будущей версии. + \en \name Deprecated functions will be removed in the future version. + \{ + */ + + /// \ru Функция будет удалена из API. Использовать ChangeDefinition(). \en The call is deprecated. Use ChangeDefinition() instead this. + MtResultCode3D ChangeAlignCondition( ItConstraintItem & ); + /// \ru Функция будет удалена из API. Использовать Evalute(). \en The call is deprecated. Use ChangeDefinition() instead this. + MtResultCode3D Solve( bool diagQuery ); + + /** + \} + */ + +protected: + MtGeomSolver(); + ~MtGeomSolver(); + +private: + MtConstraintManager * _Impl(); + const MtConstraintManager * _Impl() const; + +private: + MtGeomSolver( const MtGeomSolver & ); + MtGeomSolver & operator = ( const MtGeomSolver & ); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Создать пустую систему ограничений. + \en Create a simple constraint system. \~ + \details \ru Вызов создает пустую систему ограничений. Кроме того, в памяти + создаются внутренние структуры данных геометрического решателя, обслуживающего + систему ограничений. Функция возвращает специальный дескриптор, по которому + система ограничений доступна для различных манипуляций: добавление или удаление + геометрических объектов, ограничений, варьирование размеров, драггинг + недоопределенных объектов и т.д. + \en The call creates an empty constraint system. Besides, there are created + internal data structures of geometric solver maintaining the system of constraints. + The function returns a special descriptor by which + the constraint system is available for various manipulations: addition and deletion + of geometric objects, constraints, variation of sizes, dragging + underdetermined objects etc. \~ + + \return \ru Дескриптор системы ограничений. + \en Descriptor of constraint system. \~ +*/ +//--- +GCM_FUNC(GCM_system) GCM_CreateSystem( ItPositionManager * ); + +/** \} */ + +//---------------------------------------------------------------------------------------- +// Запрос на аргумент (создать впервые или найти имеющийся), основано на базовом API +/* + Internal use only. +*/ +//--- +GCM_geom GCM_QueryArgument( GCM_system gSys, const MtArgument & gArg ); + +/* + Deprecated typenames +*/ +typedef MtGeomSolver IfGCManager; +typedef MtRepositionMode MtTypeOfReposition; + +#endif // __GCM_MANAGER_H + +// eof diff --git a/C3d/Include/gcm_mates_generator.h b/C3d/Include/gcm_mates_generator.h new file mode 100644 index 0000000..5a0edee --- /dev/null +++ b/C3d/Include/gcm_mates_generator.h @@ -0,0 +1,310 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Тестовый генератор 3D-сопряжений + \en Test generator of 3D-mates \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_MATES_GENERATOR_H +#define __GCM_MATES_GENERATOR_H + +#include +#include +#include +#include +#include +#include + +#include + +class MtGeomSolver; + +//---------------------------------------------------------------------------------------- +// Параметры сопряжений. +// --- +struct TMParameters +{ + typedef GCM_alignment AlignCondition; + + GCM_c_type matetype; // Constraint type. + GCM_alignment align; // Alignment condition. + double realpar; // Dimension value. + + TMParameters( AlignCondition al, MtMateType mtype, double par = 0. ) + : align ( al ) + , matetype( mtype ) + , realpar ( par ) + {} + TMParameters( GCM_c_type mtype, double par = 0.0, GCM_alignment al = GCM_NO_ALIGNMENT ) + : align ( al ) + , matetype( mtype ) + , realpar ( par ) + {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Размеры кирпича. \en Box sizes. +// --- +struct TMBoxSize +{ +public: + double length; ///< \ru Длина (вдоль OX). \en Length (along OX). + double width; ///< \ru Ширина (вдоль OY). \en Width (along OY). + double height; ///< \ru Высота (вдоль OZ). \en Height (along OZ). + double radius; ///< \ru Радиус отверстия посередине. Если < MIN_RADIUS, значит сплошной кирпич без отверстий. \en Radius of hole in the middle. If < MIN_RADIUS therefore a solid box without holes. + +public: + TMBoxSize() + : length( 30. ) + , width ( 60. ) + , height( 90. ) + , radius( 20. ) + {} + + TMBoxSize( double l, double w, double h, double r ) + : length( l ) + , width ( w ) + , height( h ) + , radius( r ) + {} +}; + +//---------------------------------------------------------------------------------------- +// \ru Элементарный кирпич для наложения сопряжений. \en Elementary box for the overlay of mates. +// --- +class MATH_CLASS TMBox : public ItGeom + , public MtRefItem +{ +public: + enum MateMarker ///< \ru маркер для наложения сопряжения. \en marker for overlay of mate. + { + front, + back, + left, + right, + up, + down, + axis, + distance + }; + +private: + MbPlacement3D place; // \ru ЛСК кирпича. \en LCS of box. + TMBoxSize size; // \ru Размер кирпича. \en Box size. + c3d::mt_string name; // \ru Имя. \en Name. + +public: + TMBox( const MbPlacement3D & p, const TMBoxSize & sz, const c3d::mt_char * n = _T("B") ); // \ru Конструктор. \en Constructor. + +public: + /// \ru Задать новую ЛСК. \en Set the new LCS. + void SetPlacement( const MbPlacement3D & p ) { place.Init( p ); } + void SetName( const c3d::mt_char * n ) { name = n; } // \ru Задать имя. \en Set the name. + double Length() const { return size.length; } // \ru Выдать длину. \en Get the length. + double Width() const { return size.width; } // \ru Выдать ширину. \en Get the width. + double Height() const { return size.height; } // \ru Выдать высоту. \en Get the height. + double Radius() const { return size.radius; } // \ru Выдать радиус. \en Get the radius. + bool IsHoled() const { return size.radius > c3d::MIN_RADIUS - GcPrecision::lengthRegion; } // \ru С цилиндром ли кирпич. \en Whether there is a hole. + MbVector3D CylinderAxis() const { return place.GetAxisX(); } // \ru выдать ось цилиндра. \en Get the cylinder axis. + +public: // Реализация ItGeom + + /// \ru Выдать положение объекта ItGeom; \en Get position of ItGeom object; + virtual void GetPlacement( MbPlacement3D & p ) const { p.Init(place); } + /// \ru Выдать null-terminated строку имени геометрического объекта \en Get null-terminated name string of geometric object + virtual const c3d::mt_char * GetName() const { return name.c_str(); } + virtual refcount_t AddRef() const { return MtRefItem::AddRef(); } + virtual refcount_t Release() const { return MtRefItem::Release(); } + +private: + TMBox(); + TMBox( const TMBox & ); + TMBox & operator = ( const TMBox & ); +}; + + +//---------------------------------------------------------------------------------------- +// \ru Наложение сопряжения на 2 кирпича. \en Overlaying mate onto two boxes. +// --- +class MATH_CLASS MtBoxConstraint : public MtRefItem + , public ItConstraintItem +{ + SPtr box1; // \ru Кирпич 1. \en Box 1. + SPtr box2; // \ru Кирпич 2. \en Box 2. + TMBox::MateMarker side1; // \ru Маркер сопряжения 1. \en Marker of mate 1. + TMBox::MateMarker side2; // \ru Маркер сопряжения 2. \en Marker of mate 2. + GCM_alignment aligncond; // \ru Условие выравнивания. \en Condition of alignment. + MtMateType matetype; // \ru Тип сопряжения. \en The mate type. + double realpar; // \ru Расстояние. \en Distance. + MtResultCode3D rescode; // \ru Коды ошибки сопряжения. \en Error code of mate. + +public: + MtBoxConstraint( TMBox & b1, TMBox::MateMarker s1, TMBox & b2, TMBox::MateMarker s2, TMParameters ); + +public: // \ru Запросы (const-методы) \en Requests (const-methods) + virtual GCM_alignment AlignType() const { return aligncond; } // \ru Выдать параметр условия выравнивания \en Get the parameter of alignment condition + virtual GCM_angle_type AngleType() const { return GCM_NONE_ANGLE; } // \ru Выдать тип угла (3D или планарный) \en Get the angle type (3D or planar) + virtual GCM_geom_axis AxisOfPlanarAngle() const { return GCM_geom_axis(); } // \ru Выдать ось для планарного углового сопряжения, заданную в ЛСК некоторого тела \en Get the axis for planar angular mate. Axis is given in the LCS of some solid + virtual MbVector3D AxisOf3DAngleType() const { return MbVector3D::zero; } // \ru Взять ось для планарного углового сопряжения \en Get the axis for planar angular mate + virtual MtMateType ConstraintType() const { return matetype; } // \ru Выдать тип сопряжения \en Get the mate type + virtual ItGeomPtr GeomItem( int nb ) const { return (nb==1)? box1.get(): box2.get(); } // \ru Выдать первый сопрягаемый объект \en Get the first mating object + virtual double DimParameter() const { return realpar; } // \ru Выдать вещественный параметр \en Get the real parameter + virtual GCM_tan_choice TangencyChoice() const { return GCM_TAN_NONE; } // \ru Выдать вариант касания \en Get the tangency choice + /// \ru Диагностический код ошибки, прикрепленный к данному ограничению. \en Diagnostic error code attached to this constraint. + virtual MtResultCode3D ErrorCode() const { return rescode; } + virtual VERSION Version() const { return GetCurrentMathFileVersion(); } // \ru Выдать версию сопряжения, которая совпадает с версией потока \en Get the mate version which same as the stream version + +public: + void SetDistance( double dist ) { realpar = dist; } + +public: // \ru Методы для обратной связи (задающие) \en Callback methods + /// \ru Задать код ошибки для неудовлетворенного сопряжения \en Set the error code for unsatisfied mate + virtual void SetErrorCode( MtResultCode3D res ) { rescode = res; } + /// \ru Задать ось для углового сопряжения с трехмерным типом измерения; \en Set axis for angular mate with three-dimensional type of dimension; + virtual void SetAxisOf3DAngleType( const MbVector3D & /*axis*/ ) { /*planarang.axis = axis;*/ } + +public: // \ru Методы для Smart-указателей \en The methods for Smart-pointers + virtual refcount_t AddRef() const { return MtRefItem::AddRef(); } + virtual refcount_t Release() const { return MtRefItem::Release(); } + +private: + virtual MtGeomVariant _LinkageItem( int geomNb ) const; + +private: + MtBoxConstraint(); + MtBoxConstraint( const MtBoxConstraint & ); + MtBoxConstraint & operator = ( const MtBoxConstraint & ); +}; + +//---------------------------------------------------------------------------------------- +// \ru Земля. \en Ground. +// --- +class MATH_CLASS TMGround : public ItGeom + , public MtRefItem +{ +private: + MbPlacement3D place; + +public: + explicit TMGround( const MbPlacement3D & p ); + +public: + /// \ru Выдать null-terminated строку имени геометрического объекта \en Get null-terminated name string of geometric object + virtual const TCHAR * GetName() const; + virtual refcount_t AddRef() const { return MtRefItem::AddRef(); } + virtual refcount_t Release() const { return MtRefItem::Release(); } + +private: + /// \ru Выдать положение объекта ItGeom; \en Get position of ItGeom object; + virtual void GetPlacement( MbPlacement3D & p ) const { p.Init(place); } + +private: + TMGround(); + TMGround( const TMGround & ); + TMGround & operator = ( const TMGround & ); +}; + +//---------------------------------------------------------------------------------------- +// \ru Управление положением в сборке. \en Position control in the assembly. +// --- +struct MATH_CLASS TMBoxPositioner : public MtRefItem + , public ItPositionManager +{ +private: + TMGround & ground; + +public: + explicit TMBoxPositioner( TMGround & ); + TMBoxPositioner( const TMBoxPositioner & ); + +public: + /// \ru Установить новое положение объекта \en Set new position of the object + virtual void Reposition( ItGeom & geom, const MbPlacement3D & pos ); + /// \ru Выдать геометрический объект-земля, со степенью свободы = 0 (жёстко привязанный к ГСК); \en Get geometric object- ground with the degree of freedom = 0 (hard bound to GCS); + virtual ItGeom & GetGround() const { return ground; } + /// \ru Выдать характер связи для пары сопрягаемых тел (направленность соединения) \en Get the link character for pair of mating solids (direct connection) + virtual GCM_dependency GetJointStatus( const ItGeom &, const ItGeom & ) const { return GCM_NO_DEPENDENCY; } + virtual refcount_t AddRef() const { return MtRefItem::AddRef(); } + virtual refcount_t Release() const { return MtRefItem::Release(); } + +private: + TMBoxPositioner(); + TMBoxPositioner & operator = ( const TMBoxPositioner & ); +}; + +typedef std::vector > MtBoxVector; +typedef std::vector MtBlocksVector; + +//---------------------------------------------------------------------------------------- +/// \ru Генератор сборок. \en Assembly generator. +// --- +class MATH_CLASS AssemblyGenerator +{ +public: + enum TMMateType ///< \ru Тип связи между блоками в сборке. \en Type of connection between the bricks in the assembly. + { + tmt_Rigid1Brick = 1, + tmt_Rigid3Bricks, + tmt_Rigid2Axis, + tmt_NonRigid2Axis, + tmt_NonRigidAxisDist, + tmt_NonRigidAxis + }; + + enum TMBrickMateType ///< \ru Тип связи между кирпичами. \en Type of connection between the boxes. + { + tbmt_1Mate = 1, ///< \ru Совпадение протипоположных плоскостей. \en Coincidence of opposite planes. + tbmt_2Mate = 2, ///< \ru Совпадение протипоположных плоскостей + 1-ой пары сонаправленных. \en Coincidence of opposite planes + 1-pair of codirected. + tbmt_3Mate = 3, ///< \ru Совпадение протипоположных плоскостей + 2-ух пар сонаправленных (жесткая связь). \en Coincidence of opposite planes + 2-pairs of codirected (hard link). + tbmt_Rigid = tbmt_3Mate ///< \ru Жесткая связь. \en Rigid link. + }; + +public: + std::list > dimConstrs; + +private: + MtGeomSolver & manager; ///< \ru Решатель сборки. \en Solver of the assembly. + +public: + AssemblyGenerator( MtGeomSolver & m ) : manager( m ), dimConstrs() {} + +private: + AssemblyGenerator(); + AssemblyGenerator( const AssemblyGenerator & ); + AssemblyGenerator & operator = ( const AssemblyGenerator & ); + +public: + /// \ru Сгенерировать линию из кирпичей. \en Generate a line from boxes. + size_t GenerateLine( MtBoxVector & line, size_t n, TMBrickMateType mttype = tbmt_Rigid ); + /// \ru Сгенерировать стенку из кирпичей. \en Generate a wall from boxes. + size_t GenerateWall( MtBoxVector & wall, size_t n, TMBrickMateType mttype = tbmt_Rigid ); + /// \ru Сгенерировать куб из кирпичей. \en Generate a cube from boxes. + size_t GenerateCube( MtBoxVector & cube, size_t n, TMBrickMateType mttype = tbmt_Rigid ); + /// \ru Сгенерировать фрактал. \en Generate fractal. + size_t GenerateFractal( MtBlocksVector & fractal, size_t n, TMMateType mttype = tmt_Rigid3Bricks, TMBrickMateType bmttype = tbmt_3Mate ); + /// \ru Сгенерировать нежестко сопряженную сборку с распределенными степенями свободы. \en Generate a non-rigid mating assembly with distributed degrees of freedom. + size_t NonRigidDistributedDoF( MtBlocksVector & assembly, size_t nBlocks + , TMMateType mttype = tmt_NonRigidAxis, TMBrickMateType bmttype = tbmt_3Mate ); + /// \ru Сгенерировать жестко сопряженную сборку с распределенными степенями свободы. \en Generate a rigid mating assembly with distributed degrees of freedom. + size_t RigidDistributedDoF( MtBlocksVector & assembly, size_t nRings, size_t nBlocksInRing + , TMMateType matetype = tmt_Rigid2Axis, TMBrickMateType bmttype = tbmt_3Mate, double dist = 0. ); + + /// \ru Передвинуть кирпичи. \en Shift boxes. + void ShiftBoxes( MtBoxVector & boxes, const MbVector3D & shift, bool comulative, bool shiftfirst = false ); + /// \ru Передвинуть блоки. \en Shift blocks. + void ShiftBoxes( MtBlocksVector & boxes, const MbVector3D & shift, bool comulative, bool shiftfirst = false ); + /// \ru Повернуть кирпичи. \en Rotate boxes. + void RotateBoxes( MtBoxVector & boxes, const MbVector3D & angles, bool comulative ); + /// \ru Повернуть блоки. \en Rotate blocks. + void RotateBoxes( MtBlocksVector & boxes, const MbVector3D & angles, bool comulative ); + +private: + /// \ru Сгенерировать N кирпичей. \en Generate N boxes. + void GenerateNBoxes( MtBoxVector & boxes, size_t n, const TMBoxSize & size ) const; + void SetBoxesNames( const MtBoxVector & boxes ); // \ru Задать имена кирпичей. \en Set names for boxes. + size_t CreateBlock( MtBoxVector & block, TMBrickMateType bmttype, bool solve = true ); // \ru Создать блок. \en Create a block. + void GetFractal( size_t & mtCnt, MtBlocksVector & boxes, size_t nBlocks, TMMateType mttype, TMBrickMateType bmttype, size_t ind = 0 ); // \ru Создать фрактал. \en Create a fractal. +}; + +#endif // __GCM_MATES_GENERATOR_H diff --git a/C3d/Include/gcm_reposition.h b/C3d/Include/gcm_reposition.h new file mode 100644 index 0000000..80a1b2f --- /dev/null +++ b/C3d/Include/gcm_reposition.h @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Абстракция для управления положением моделей в сборке. + \en Abstract for control of model position in the assembly. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_REPOSITION_H +#define __GCM_REPOSITION_H + +#include +#include + +//---------------------------------------------------------------------------------------- +// Deprecated typename +//--- +typedef GCM_dependency MtJointStatus; + +//---------------------------------------------------------------------------------------- +// +// --- +inline MtJointStatus InversionOf( MtJointStatus jointDir ) +{ + if ( jointDir == GCM_2ND_DEPENDENT ) + return GCM_1ST_DEPENDENT; + if ( jointDir == GCM_1ST_DEPENDENT ) + return GCM_2ND_DEPENDENT; + return jointDir; +} + + +struct ItGeom; + +/** + \addtogroup GCM_3D_ObjectAPI + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Абстракция для управления положением геометрических объектов в сборке. + \en Abstract for control of geom position in the assembly \~ + \details + \ru Объект ItPositionManager это класс, с помощью которого менеджер сопряжений + MtGeomSolver возвращает свое решение, т.е. положение тел ItGeom (см.функцию + ItPositionManager::Reposition( ItGeom & geom, const MbPlacement3D & pos )). + Экземпляр решателя MtGeomSolver располагает только одним объектом ItPositionManager. + Фактически в интерфейсе ItPositionManager будем собирать виртуальные функции для + организации обратной связи с клиентским приложением. + + \en ItPositionManager object is the class with which the mates manager + MtGeomSolver returns its decision, i.e. position of solids ItGeom (see function + ItPositionManager::Reposition( ItGeom & geom, const MbPlacement3D & pos )). + Instance of the solver MtGeomSolver has only one object ItPositionManager. + Actually in the interface of #ItPositionManager we will collect virtual functions + for organizing feedback of the solver client. \~ + + \par + \ru Объект, возвращаемый функцией ItGeom & ItPositionManager::GetGround() const + обычно соответствует сборке, система сопряжений которой обслуживается. + \en Object returned by function ItGeom & ItPositionManager::GetGround() const + usually corresponds to the assembly of which the mates system is solved. +*/ +//--- +struct ItPositionManager +{ + /// \ru Установить новое положение объекта. \en Set new position of the object. + virtual void Reposition( ItGeom & geom, const MbPlacement3D & pos ) = 0; + /** \brief \ru Выдать "геометрическую землю", имеющую систему координат всегда совпадающую с мировой. + \en Get "geometric ground" having a coordinate system which always coincident with World Coord System. + \details \ru Главное свойство "Земли" это нулевая степень свободы, т.е. неподвижность в контексте всей системы ограничений. + \en The main property of "Ground" is zero degree of freedom, i.e. absolute fixity in context of the constraint system. + */ + virtual ItGeom & GetGround() const = 0; + /// \ru Выдать характер связи для пары сопрягаемых тел (направленность соединения) \en Get the link character for pair of mating solids (direct connection) + virtual GCM_dependency GetJointStatus( const ItGeom & geomOne, const ItGeom & geomTwo ) const = 0; + /// \ru Добавить ссылку \en Add a reference + virtual refcount_t AddRef() const = 0; + /// \ru Удалить ссылку \en Release reference + virtual refcount_t Release() const = 0; +}; + +/** \} */ // GCM_3D_ObjectAPI + +#endif + +// eof \ No newline at end of file diff --git a/C3d/Include/gcm_res_code.h b/C3d/Include/gcm_res_code.h new file mode 100644 index 0000000..8f33b3a --- /dev/null +++ b/C3d/Include/gcm_res_code.h @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Коды ошибок геометрического решателя для 3D + \en Error codes of geometric solver for 3D \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_RES_CODE_H +#define __GCM_RES_CODE_H + +#include + +//---------------------------------------------------------------------------------------- +// \ru Приоритетность кода ошибки \en Priority of the error code. +/* + \ru Функция выдает критерий, т.е. целое число, которое позволяет выбрать какую из + двух ошибок, обнаруженных решателем в отношении одного и того же сопряжения, + лучше показать пользователю. Ошибка с более высоким приоритетом поглощает ошибку + с более низким приоритетом. + \en Function gives a criterion, i.e. an integer which allows to choose which of + the two errors detected by solver with respect to the same mate + better to show to the user. Error with the highest priority error absorbs error + with lower priority. \~ + \param \ru resCode Код ошибки + \en resCode Error code \~ + \return \ru Целочисленная величина приоритетности кода ошибки для пользователя + \en The integer value of the priority of the error code to the user \~ +*/ +//--- +inline int PriorityLevel( GCM_result resCode ) +{ + switch ( resCode ) + { + case GCM_RESULT_Ok: return 0; // \ru Хороший результат - самый низкий приоритет потому, что всегда поглащается любым плохим результатом \en Good result - the lowest priority because it always is absorbed by any bad result + case GCM_RESULT_None: return 1; // \ru Нет результат - тоже низкий приоритет, поскольку мало информативен; \en None result - too low a priority as not enough informative; + case GCM_RESULT_Error: return 2; // \ru Неустановленная ошибка, малоинформативная ошибка. Unknown error, uninformative error. + + case GCM_RESULT_Duplicated: return 3; // \ru Эта ошибка не делает систему не решаемой, поэтому покажем её только если нет других проблем, связанных с нерешаемостью; \en This error does not make the unsolved system therefore it will be shown only if there are no other problems with unsolvable; + case GCM_RESULT_Not_Satisfied: return 4; // \ru Приоритет меньше, чем GCM_RESULT_Unsolvable, поскольку меньше информативность; //-V112 \en Priority is less than GCM_RESULT_Unsolvable because less informativeness; //-V112 + case GCM_RESULT_Unsolvable: return 5; // \ru Приоритет должен быть выше, чем у mtResCode_Not_Satisfied - дает больше информации пользователю; \en Priority must be higher than mtResCode_Not_Satisfied - gives more information to the user; + case GCM_RESULT_InconsistentAlignment: return 6; // \ru Приоритет должен быть меньше, чем у GCM_RESULT_Overconstrained, потому, что правильность диагностики гарантируется только при осутствии сообщения mtResCode_OverConstraint; \en Priority must be less than mtResCode_OverConstraint because the correct diagnosis can be guaranteed if there is not message GCM_RESULT_Overconstrained; + case GCM_RESULT_Overconstrained: return 7; // \ru Приоритет выше, чем у GCM_RESULT_Unsolvable, поскольку точнее выявлена причина не решаемости; \en Priority higher than that of GCM_RESULT_Unsolvable because unsolvable reason have been found; + + /* + \ru Более высокий приоритет у группы ошибок, связанных с некорректными + зависимостями для черных ящиков - такие ошибки нужно устранять в + первую очередь. + \en Higher priority for the group errors associated with incorrect + dependencies for black boxes - first of all such errors must + be eliminated. + */ + + case GCM_RESULT_MultiDependedGeom: // \ru Задана входящая зависимость для выходного объекта черного ящика; \en Given an incoming dependence of the output object of a black box; + case GCM_RESULT_OverconstrainingDependedGeoms: // \ru Задана зависимость между экземплярами массива (выходными); \en Given dependence between copies of the pattern (output); + case GCM_RESULT_DependedGeomCantBeFixed: // The depended geom can't be fixed. + return 8; + + case GCM_RESULT_CyclicDependence: // \ru Задана циклическая зависимость \en Given a cyclic dependence + return 9; + + /* + Группа ошибок, связанная с некорректно заданным сопряжением. + Group of errors related to incorrectly specified constraint. + */ + case GCM_RESULT_InappropriateArgument: + case GCM_RESULT_InappropriateAlignment: // + case GCM_RESULT_InvalidArguments: // \ru В ограничении не заданы аргументы (пустые аргументы). \en Constraint has invalid or undefined (void) arguments. + case GCM_RESULT_IncompatibleArguments: + case mtResCode_UnsupportedTangencyChoice: // \ru Для сопряжения касание - опция выбора по окружности или по образующей не поддреживается \en For mate the option of tangency choice by circle or generating curve is unsupported + case mtResCode_IsNoPossibleForCircTanChoice: // \ru Для данной пары поверхностей касание по окружности геометрически не возможно \en For a given pair of surfaces the touching along the circle is geometrically impossible + case GCM_RESULT_InconsistentPlanarAngle: // \ru Не соблюдаются условия планарного угла (векторы от пары тел должны быть перпендикулярны оси) \en Planar angle conditions are not met (vectors from a pair of solids should be perpendicular to the axis) + case mtResCode_InconsistentFollowerAxis: + case mtResCode_CoaxialMtGearTransmissionIsNotAvalable: + return 10; + + /* + The group of system error codes. Priority overlapping all other errors. + */ + case GCM_RESULT_InternalError: + case GCM_RESULT_Aborted: + case GCM_RESULT_ItsNotDrivingDimension: + case GCM_RESULT_Unregistered: + return 99; + + /* + \ru Все остальные геометрические ошибки (Самый информативный для пользователя вариант); + \en All other geometric errors (the most informative variant for the user); + */ + + default: return 90; + } +} + +/** + \addtogroup GCM_3D_Routines + \{ +*/ + +//---------------------------------------------------------------------------------------- +// +// --- +inline bool OK( GCM_result res ) +{ + return res == mtResCode_Ok; +} + +//---------------------------------------------------------------------------------------- +// +// --- +inline GCM_result ResCode( bool ok ) +{ + return ok ? mtResCode_Ok : mtResCode_None; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выбрать "худший" результат. + \en Select "the worst" result code. \~ + \details \ru Функция выбирает из двух сообщений об ошибке, то которое нуждается во + внимании пользователя прежде другого. + \en The function selects from two error messages, something that needs + attention before another error. +*/ +//--- +inline GCM_result WorseResult( GCM_result res1, GCM_result res2 ) +{ + return PriorityLevel( res1 ) > PriorityLevel( res2 ) ? res1 : res2; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Суммировать результирующий код. \en Summarize the resulting code. + \details \ru Оператор выбирает из потока ошибок, то которое нуждается во + внимании пользователя прежде других. + \en The operator selects from stream of error messages, something that needs + attention before anything else. + +*/ +//--- +inline GCM_result & operator << ( GCM_result & sumRes, const GCM_result r ) +{ + if ( r == GCM_RESULT_None ) + { + return sumRes; + } + if ( PriorityLevel(r) > PriorityLevel(sumRes) || (sumRes==GCM_RESULT_None) ) + { + sumRes = r; + } + return sumRes; +} + +/** \} */ // GCM_3D_Routines + +#endif // __GCM_RES_CODE_H + +// eof diff --git a/C3d/Include/gcm_routines.h b/C3d/Include/gcm_routines.h new file mode 100644 index 0000000..13c3348 --- /dev/null +++ b/C3d/Include/gcm_routines.h @@ -0,0 +1,491 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru API процедур и функций геометрического решателя. + \en API of procedures and functions of geometric solver. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_ROUTINES_H +#define __GCM_ROUTINES_H + +#include +// +#include "gcm_constraint.h" +#include "gcm_manager.h" +#include "gcm_types.h" + +class MATH_CLASS MbProperties; +struct CNodeIterator; + +/** + \addtogroup GCM_3D_Routines + \{ +*/ + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запись о степени свободы перемещения. + \en Record about the degree of freedom of movement. \~ + \details \ru Структура для записи информации о степени свободы линейного перемещения + для трехмерной точки. + \en Structure for record the information about the degree of freedom of a linear displacement + for a three-dimensional point. \~ + \par \ru Как интерпретировать данные. + Если dof = 0, то точка неподвижна;\n + Если dof = 1, точка имеет свободу перемещения вдоль прямой с направление MtTransDof::vector;\n + Если dof = 2, точка имеет свободу перемещения вдоль плоскости с нормалью MtTransDof::vector;\n + Если dof = 3, точка имеет полную свободу перемещения, значение MtTransDof::vector не имеет значения.\n + \en How to interpret data. + If dof = 0, then the point is fixed;\n + If dof = 1, then the point has a freedom of movement along a curve with the direction MtTransDof::vector;\n + If dof = 2, then the point has a freedom of movement along the plane with the normal MtTransDof::vector;\n + If dof = 3, then the point has a complete freedom of movement, a value of MtTransDof::vector is not significant.\n \~ +*/ +//--- +struct MtTransDof +{ + int dof; ///< \ru Степень свободы. \en Degree of freedom. + MbVector3D vector; ///< \ru Направление прямой или нормаль плоскости, в зависимости от значения dof. \en Direction of line or normal of plane depending on the value of dof. + MtTransDof() : dof(0), vector() {} + +public: + bool operator == ( const MtTransDof & tDof ) const + { + if ( dof == tDof.dof ) + { + return ( dof == 0 || dof == 3 ) && (vector == tDof.vector); + } + return false; + } +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Параметры близости к решению для геометрического ограничения. + \en Parameters of proximity to solution for geometric constraint. \~ + \details \ru Эта структура данных применяется только, как результат работы + функции #GetClosestParameters. + \en This data structure is used only as result + of the function #GetClosestParameters. \~ +*/ +//--- +struct MtMateParameters +{ + double myDimVal; ///< \ru Числовой параметр размерного сопряжения. \en The numerical parameter of dimensional mate. + GCM_alignment myAlignVal; ///< \ru Условие выравнивания сопрягаемой геометрии. \en The alignment condition of mating geometry. + bool myDimEvaluated; ///< \ru Означает, что параметр myDimVal оценен. \en Means that the parameter myDimVal is evaluated. + bool myDimSigned; ///< \ru Означает, что сопряжение чувствительно к знаку myDimVal. \en Means that the mate is sensitive to the sign of myDimVal. + +public: + MtMateParameters() + : myAlignVal( GCM_NOT_ORIENTED ) + , myDimVal( 0.0 ) + , myDimEvaluated( false ) + , myDimSigned( false ) + {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Характеристические данные линейного размера. + \en Characteristic data of linear dimension. \~ + \details \ru Структура данных содержит характерную информацию, необходимую, + для визуализации линейного размера, а именно:\n + 1) Пару точек, заданных в общей СК модели, сооствественно лежащих на первом + и втором геометрических объектах сопряжения;\n + 2) Пара перечислителей #MtGeometryType, означающих типы сопрягаемой геометрии, + которым принадлежат точки;\n + 3) Степень свободы перемещения пары точек, в рамках которой сохраняется 1-е + условие (принадлежность геометрическим объектам, для которых задан размер);\n + 4) Значение размера - величина по сути равная расстоянию между точками.\n + \en The data structure contains characteristic information needed + for rendering a linear dimension, namely:\n + 1) A pair of points defined in a general CS model which lie on the first + and second geometric objects of mate; \n + 2) A pair of enumerators #MtGeometryType meaning the mating types of geometry + which owns the points; \n + 3) The degree of freedom of movement of a pair of points in which is stored the 1st + condition (belonging to geometric objects which have the dimension);\n + 4) The dimension value is equal to the distance between points. \n \~ +*/ +//--- +struct MtLDimensionTraits +{ + MbCartPoint3D firstPoint; ///< \ru Первая точка линейного размера. \en The first point of linear dimension. + MbCartPoint3D secondPoint; ///< \ru Вторая точка линейного размера. \en The second point of linear dimension. + MtGeomType firstType; ///< \ru Тип геометрии, которой принадлежит firstPoint. \en The geometry type which owns firstPoint. + MtGeomType secondType; ///< \ru Тип геометрии, которой принадлежит secondPoint. \en The geometry type which owns secondPoint. + MtTransDof translateDof; ///< \ru Степень свободы перемещения точек размера. \en The degree freedom of movement of dimension points. + double value; ///< \ru Текущее значение размера. \en Current value of the dimension. + + MtLDimensionTraits() + : firstPoint() + , secondPoint() + , firstType( GCM_NULL_GTYPE ) + , secondType( GCM_NULL_GTYPE ) + , translateDof() + , value( 0.0 ) + {} +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Характеристические данные углового размера. + \en Characteristic data of angular dimension. \~ + \details \ru Структура данных содержит характерную информацию, необходимую, для + визуализации углового размера, а именно:\n + 1) Вектор вращения, он же нормаль измерительной плоскости;\n + 2) Пара векторов, из которых второй вектор получается из первого вращением + его вокруг вектора вращения (axisZ) на угол, равный значению размера;\n + 3) Значение размера - величина, которая равна углу вращения первого вектора + вокруг оси axisZ для совпадения его со вторым вектором.\n + \en The data structure contains characteristic information needed for + rendering an angular dimension, namely:\n + 1) The rotation vector, it is normal of measuring plane; \n + 2) A pair of vectors where the second vector is obtained from the first by rotation + around the rotation vector (axisZ) by an angle which is equal to the value of dimension; \n + 3) Dimension value is equal to the rotation angle of the first vector + around axis axisZ to coincide it with the second vector.\n \~ +*/ +//--- +struct MtADimensionTraits +{ + MbVector3D firstVector; ///< \ru Первый вектор. \en The first vector. + MbVector3D secondVector; ///< \ru Второй вектор. \en The second vector. + MbVector3D axisZ; ///< \ru Ось вращения первого вектора до совпадения со вторым. \en Axis of rotation of the first vector to coincide with the second. + double value; ///< \ru Значение размера - угол вращения. \en Dimension value - the angle of rotation. + + MtADimensionTraits() + : axisZ() + , firstVector() + , secondVector() + , value( 0.0 ) + {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Создать Интерфейс геометрического решателя. + \en Create interface of geometric solver. \~ + \details \ru Функция возвращает smart-pointer интерфейса решателя. + \en The function returns smart-pointer of solver Interface. \~ + \param[in] pMan - \ru Интерфейс клиентского приложения, предоставляющий + функции репозиции геометрических объектов на стороне клиента. + \en Interface of the client application that provides + functions of reposition of geometric objects on the client side. \~ + \return \ru smart-pointer на экземпляр геометрического решателя. + \en smart-pointer to an instance of geometric solver. \~ +*/ +//--- +GCM_FUNC(SPtr) CreateSolver( ItPositionManager & pMan ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Автоматически назначить тип сопряжению для его аргументов. + \en Automatically assign the mate type for its arguments. \~ + \param cItem[in] - \ru Геометрическое ограничение с неизвестным типом: mct_Unknown (см. #MtMateType). + \en Geometric constraint with unknown type: mct_Unknown (see #MtMateType). \~ + \param forMove[in] - \ru Способ оценки для тел с поведением перемещения, иначе вращения. + \en The evaluation method for solids with the behavior of moving or expression. \~ + \return \ru Тип, который следует назначить этому сопряжению (см. #MtMateType). + \en Type which should be assigned to this mate (see #MtMateType). \~ + \details \ru Неизвестное сопряжение cItem этой функцией рассматривается, как пара + объектов сопряжения, для которой подбирается наиболее подходящий вариант + для стыковки. Например, для двух цилиндров это будет соосность. Флаг forMove + помогает подобрать вариант стыковки с наиболее естественным поведением при + динамическом изменении объектов (например, указателем мыши). + \en The unknown mate cItem of this feature is considered as a pair + of objects of mate for which to select the most suitable variant + for connection. For example: for the two cylinders it is coaxiality. The flag forMove + helps to determine variant of connections to the most natural behavior + in dynamic changing objects (for example: the mouse cursor). \~ +*/ +//--- +GCM_FUNC(MtMateType) GetAutoMateType( const ItConstraintItem & cItem, bool forMove ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Измерить параметры близости к решению для геометрического ограничения. + \en Measure parameters of proximity to solution for geometric constraint. \~ + \param[in] cItem - \ru Рассматриваемое ограничение. + \en Considered constraint. \~ + \param[out] cPars - \ru Результирующие параметры оценки. + \en The resulting evaluation parameters. \~ + \return \ru Если возвращается true, то cPars содержит правильный ответ на запрос. + \en If it returns true, then cPars contains the correct answer to the query. \~ + + \details \ru Сопряжение #ItConstraintItem характеризуется целочисленными и + вещественных параметрами (опция выравнивания и размер). Функция + #GetClosestParameters вычисляет такое состояние параметров, при котором + ограничение было бы удовлетворено или наиболее близко к решению. + \en The mate #ItConstraintItem is characterized by integer and + real parameters (alignment option and size). The function + #GetClosestParameters calculates the state of parameters in which + the mate would be satisfied or the closest to the solution. \~ +*/ +//--- +GCM_FUNC(bool) GetClosestParameters( const ItConstraintItem & cItem, MtMateParameters & cPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Определить характеристические данные размера. + \en Determine the characteristic data of dimension. \~ + \param[in] dCon - \ru Размерное геометрическое ограничение. + \en Dimensional geometric constraint. \~ + \param[out] dPars - \ru Структура характеристических параметров размера. + \en Structure of the characteristic parameters of dimension. \~ + \return \ru Если возвращается true, то dPars содержит правильный ответ на запрос. + \en If it returns true, then dPars contains the correct answer to the query. \~ +*/ +//--- +GCM_FUNC(bool) GetDimensionTraits( const ItConstraintItem & dCon, MtLDimensionTraits & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Определить характеристические данные углового размера. + \en Determine the characteristic data of angular dimension. \~ + \param[in] dCon - \ru Размерное геометрическое ограничение. + \en Dimensional geometric constraint. \~ + \param[out] dPars - \ru Структура характеристических параметров размера. + \en Structure of the characteristic parameters of dimension. \~ + \return \ru Если возвращается true, то dPars содержит правильный ответ на запрос. + \en If it returns true, then dPars contains the correct answer to the query. \~ +*/ +//--- +GCM_FUNC(bool) GetDimensionTraits( const ItConstraintItem & dCon, MtADimensionTraits & dPars ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Оценить возможно ли применить вариант касания к данному ограничению. + \en Whether it is possible to apply the variant of tangency to this constraint. \~ + \param[in] cItem - \ru Сопряжение, которое несет пару сопрягаемых объектов или хотя бы один (первый или второй). + \en Mate which carries a pair of mating objects or at least one (first or second). \~ + \param[in] tChoice - \ru Вариант касания, который хотелось бы применить к сопряжению cItem. + \en Tangency variant which was to be applied to mate cItem. \~ + \return \ru Вернет true, если опция касания применима для данного ограничения. + \en Will return true if the tangency option is applicable to this mate. \~ + \note \ru Сопряжение cItem может быть не полностью задано, т.е. выбран только один + геометрический объект, тогда функция ответит о применимости tChoice к + одному объекту без выбранного второго. + \en The mate cItem can not be fully specified, i.e. is selected only one + geometric object, then the function will respond about applicability tChoice to + the one object without selecting the second. \~ +*/ +// --- +GCM_FUNC(bool) EstimateTangencyChoice( const ItConstraintItem & cItem, GCM_tan_choice tChoice ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Определить для данного ограничения совместимость геометрических объектов. + \en Determine the compatibility of geometric objects to this constraint. \~ + \details \ru Если в ограничении заданы и первый и второй сопрягаемые объекты, то + функция отвечает о возможности сопряжения заданных геометрических объектов, + иначе если в ограничении задано только один из объектов (первый либо второй), + то функция отвечает о применимости данного геом.объекта для данного сопряжения. + \en If in the constraint given the first and second mating objects, then + a function provides about the possibility mating of given geometric objects, + otherwise if only one of the objects (either first or second) is given in the mate, + then function provides for the applicability of this geometric object for the given mate. \~ + \return \ru Вернет true, если данная пара геометрических объектов применима к данному типу сопряжения. + \en Returns true if given pair of geometric objects is applicable to this type of mate. \~ +*/ +//--- +GCM_FUNC(bool) IsCompatibleMatingGeometry( const ItConstraintItem & cItem ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вычислить "Относительное размещение". + \en Calculate "Relative placement". \~ + \details \ru Функция реализует тип GCM_dependent_func, предполагающий зависимость + g1 = f( g2, g3, g4 ), а именно вычисляет положение первого объекта (g1), размещаемого + относительно второго объекта g2 также, как g3 размещено относительно g4. Таким образом, + объект g1 является зависимым от остальных. + \en The function implements a type of GCM_dependent_func considering + dependency g1 = f( g2, g3, g4 ), namely calculates placement of first geom (g1) + that is related to second geom (g2) in same way as g3 was placed relative to g4. + In this way, g1 is dependent on others. + + \param[in] gPlaces - \ru Массив текущих положений геометрических объектов g1, g2 .. g4. + \en Array of current placements of geometric objects g1, g2 .. g4. \~ + \param[out] gPlaces - \ru Вычисленное значение зависимого объекта g1 (возвращается в элемент gPlaces[0]). + \en Calculated placement of first geom g1 (it is returned to the element gPlaces[0]). \~ + \param[in] gPlacesSize - \ru Известный размер принимаемого массива gPlaces. + \en Known size of received array gPlaces.\~ + \return \ru true, если функция выполнена успешно. + \en true if the function is performed successfully. \~ + + \par \ru Реализация + \en Implementation \~ + gPlaces[0] = gPlaces[2];\n + gPlaces[0].Transform( gPlaces[3].GetMatrixInto() );\n + gPlaces[0].Transform( gPlaces[1].GetMatrixFrom() );\n +*/ +//--- +GCM_FUNC(bool) GCM_RelativePlacement( MbPlacement3D gPlaces[] + , size_t gPlacesSize + , GCM_extra_param ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Выдать первый или второй геометрический объект сопряжения. + \en Get the first or second geometric object of mate. \~ + \param[in] cItem - \ru Геометрическое ограничение. + \en Geometric constraint. \~ + \param[in] geomNb - \ru 1-й или 2-й номер геометрического объекта. + \en 1st or 2nd index of geometric object. \~ + \param[in] inWCS - \ru Если = true, то функция вернет объект, + заданный в МСК, иначе в ЛСК соответственно 1-го или 2-го тела. + \en If = true, then the function returns object + given in GCS otherwise in LCS of 1st or 2nd solid respectively. \~ + + \param[out] gType - \ru Тип геометрического объекта. + \en A type of geometric object. \~ + \param pc, vec, r1, r2 - \ru Кортеж параметров объекта (описание ниже). + \en A tuple of object parameters (described below). \~ + \return \ru Если возвращается true, то кортеж {pc, vec, r1, r2} + содержит правильный ответ на запрос. + \en If returns true the tuple {pc, vec, r1, r2} + contains the correct answer to the query. \~ + + \par \ru Формат записи кортежа {pc, vec, r1, r2} + Кортеж значений {pc, vec, r1, r2} унифицированно описывает все типы + геометрических объектов, перечисленных в #MtGeometryType.\n + Точка задается единственным значением {pc};\n + Прямая задается парой {pc, vec};\n + Плоскость задается парой {\b pc, \b vec}, где \b vec - нормаль плоскости, + \b pc - точка на плоскости;\n + Цилиндр задается четверкой {\b pc, \b vec, \b r1, \b r2}, + где {\b pc,\b vec}-ось цилиндра, \b r1=\b r2 - радиус цилиндра;\n + Окружность задается тройкой {\b pc, \b vec, \b r1}, + где {\b pc,\b vec}-ось окружности с центром в начале оси, \b r1 - радиус окружности, \b r2 = 0;\n + Конус - {pc, vec, r1, r2}, где {pc,vec}-ось конуса, + \b r1 - радиус основания, \b r2 - радиус сечения. Конус имеет высоту, равную единице, + т.е. расстояние между основанием и сечением равно единице, точка \b pc лежит в + плоскости основания.\n + Сфера - задана точкой \b pc -центр сферы и r1=r2 -радиус сферы;\n + Тор задан точкой \b pc - центр тора, {pc,vec}-ось тора, + \b r1 -большой радиус тора, \b r2 -радиус малый (половина толщины бублика).\n + + \en Writing format of the tuple {pc, vec, r1, r2} + Tuple of values {pc, vec, r1, r2} unified describes all the types + of geometric objects listed in the #MtGeometryType. \n + Point is given by a single value {pc};\n + Line is given by a pair {pc, vec};\n + Plane is given by a pair {\b pc, \b vec} where \b vec - normal of plane + \b pc - point on the plane; \n + Cylinder is given by {\b pc, \b vec, \b r1, \b r2} + where {\b pc,\b vec} - the cylinder axis, \b r1=\b r2 - the cylinder radius; \n + Circle is given by triplet: {\b pc, \b vec, \b r1, \b r2} + where {\b pc,\b vec} - the circle axis with origin in circle center, \b r1 - the circle radius, \b r2=0; \n + Cone - {pc, vec, r1, r2}, where {pc,vec}-the cone axis, + \b r1 - the bottom radius, \b r2 - the section radius. Cone has a height equal to one + i.e. the distance between the base and section is equal to one, the point \b pc lies in + the plane of the base. \n + Sphere is given by a point \b pc - the sphere center and r1=r2 -the sphere radius; \n + Torus is given by a point \b pc - the torus center, {pc,vec}-the torus axis, + \b r1 -the major radius of torus, \b r2 -the minor radius (half the thickness of a torus).\n \~ +*/ +//--- +GCM_FUNC(bool) GetMatingGeometry( const ItConstraintItem & cItem, int geomNb, bool inWCS, + MtGeomType & gType, MbCartPoint3D & pc, MbVector3D & vec, + double & r1, double & r2 ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить геометрический объект типа MtGeomVariant из геометрии MbSpaceItem. + \en Get a geometric object of type MtGeomVariant from geometry of type MbSpaceItem. \~ + \details \en The function extracts geometry data of the solver type from geometric object presented class MbSpaceItem. +*/ +//-- +GCM_FUNC(MtGeomVariant) GCM_GeomArgument( const MbSpaceItem *, bool orient ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить геометрический объект типа GCM_geom из типа ItGeom *. + \en Get a geometric object of type GCM_geom from type of ItGeom *. \~ +*/ +//-- +GCM_FUNC(GCM_geom) GCM_GeomId( GCM_system gSys, const ItGeom * gPtr ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить геометрическое ограничение типа GCM_constraint из типа ItConstraintItem *. + \en Get a geometric constraint of type GCM_constraint from type of ItConstraintItem *. \~ +*/ +//-- +GCM_FUNC(GCM_constraint) GCM_ConstraintId( GCM_system gSys, const ItConstraintItem * cPtr ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить запись геометрического объекта по типу MtGeomVariant. + \en Get the geometric record of the variant data type. +*/ +// --- +GCM_FUNC(GCM_g_record) GCM_GeomRecord( const MtGeomVariant & ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Получить интерфейсный объект геометрического ограничения ItConstraintItem по дескриптору. + \en Get an interface object ItConstraintItem of geometric constraint by the descriptor. \~ + \note Internal use only +*/ +//-- +GCM_FUNC(const ItConstraintItem *) GCM_ConstraintItem( GCM_system gSys, GCM_constraint conId ); + +//---------------------------------------------------------------------------------------- +// Internal use only +/* + Returns a pointer equal gPtr, if the operation succeeded. +*/ +//-- +GCM_FUNC(const ItGeom *) GCM_SetDependencyGeom( GCM_system gSys, MtGeomId, const ItGeom * gPtr ); + +//---------------------------------------------------------------------------------------- +// for testing only +//--- +GCM_FUNC(void) GCM_GetProperties( GCM_system gSys , MbProperties & props ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Импортировать систему геометрических ограничений в модель C3D + \en Import the constraint system into C3D-model. \~ + \details \ru Алгоритм импорта распознает каркасные структуры в системе ограничений и + записывает их в файл формата C3D. Обнаруженные структуры конвертируются + в проволочное представление MbWireFrame. + \en The algorithm of import recognises a framework structures in the constraint + system and writes their into C3D model format. The recognized structures + are converted into wire-frame representation (see MbWireFrame). + \note For testing purposes. +*/ +//-- +GCM_FUNC(void) GCM_ImportToC3D( GCM_system gSys, const TCHAR * c3dFile ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Число способов выравнивания (GCM_alignment) для заданного сопряжения. + \en The number of alignment options (GCM_alignment) for a given mate. +*/ +// --- +GCM_FUNC(size_t) VolumeOfAlignOption( const ItConstraintItem & ); + +/** \} */ // GCM_3D_Routines + +//---------------------------------------------------------------------------------------- +/* + \ru Вызов устарел, будет удален в одной из последующих версий + \en This call is out of date, it will be removed in a future version (V17 or later) \~ +*/ +//--- +GCM_FUNC(MtGeomSolver &) Construct_GCMImp( ItPositionManager & ); + +//---------------------------------------------------------------------------------------- +// for internal use only +//--- +GCM_FUNC(MtResultCode3D) AdHocDiagnose( MtGeomSolver *, const ItGeom * ); + +//---------------------------------------------------------------------------------------- +// for testing only +//--- +GCM_FUNC(bool) CheckSatisfaction( MtGeomSolver * ); + +//---------------------------------------------------------------------------------------- +// for testing only +//--- +GCM_FUNC(size_t) GetGeomsCount( MtGeomSolver * ); + +//---------------------------------------------------------------------------------------- +// for testing only +//--- +GCM_FUNC(size_t) GetConstraintsCount( MtGeomSolver * ); + +//---------------------------------------------------------------------------------------- +// Get a range to traverse constraints of the system +//--- +GCM_FUNC(void) GCM_GetConstraints( GCM_system gSys, CNodeIterator & begIter, CNodeIterator & endIter ); + +#endif // __GCM_ROUTINES_H + +// eof diff --git a/C3d/Include/gcm_types.h b/C3d/Include/gcm_types.h new file mode 100644 index 0000000..23a3080 --- /dev/null +++ b/C3d/Include/gcm_types.h @@ -0,0 +1,535 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Типы данных геометрического решателя + \en Data types of geometric solver \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GCM_TYPES_H +#define __GCM_TYPES_H + +#include + +class MtGeomSolver; +class MbPlacement3D; + +#define GCM_ID_TYPE 1 // 1 - MtObjectId is a struct, 0 - MtObjectId is simple integer. + +#if ( GCM_ID_TYPE == 1 ) + +typedef struct { uint32 id; } MtObjectId; +const MtObjectId _GCM_NULL = { SYS_MAX_UINT32 }; +const MtObjectId _GCM_GROUND = { 0 }; + +#else // GCM_ID_TYPE + +typedef uint32 MtObjectId; +const MtObjectId _GCM_NULL = SYS_MAX_UINT32; +const MtObjectId _GCM_GROUND = 0; + +#endif // GCM_ID_TYPE + +/** \addtogroup GCM_3D_API + \{ +*/ + +/// \ru Система геометрических ограничений. \en System of geometric constraints. \~ +typedef MtGeomSolver* GCM_system; +/// \ru Дескриптор геометрического объекта, зарегистрированного в контексте решателя. \en Descriptor of geometrical object registered in the solver context. +typedef MtObjectId GCM_object; +/// \ru Дескриптор геометрического объекта, зарегистрированного в контексте решателя. \en Descriptor of geometrical object registered in the solver context. +typedef GCM_object GCM_geom; +/// \ru Дескриптор ограничения, зарегистрированного в решателе. \en Descriptor of a constraint registered in the solver. +typedef GCM_object GCM_constraint; +/// \ru Дескриптор паттерна, зарегистрированного в решателе. \en Descriptor of a pattern registered in the solver. +typedef GCM_object GCM_pattern; +/// \ru Дескриптор пустого объекта или ограничения. \en Descriptor of empty object or constraint. \~ +const GCM_object GCM_NULL = _GCM_NULL; +/** \brief \ru Дескриптор неподвижного подмножества объектов, заданных в глобальной системой координат. + \en Descriptor of rigid subset of objects which are given in global coordinate system. \~ +*/ +const GCM_geom GCM_GROUND = _GCM_GROUND; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Словарь типов геометрических примитивов. + \en Dictionary of geometric primitives types. \~ +*/ +// --- +typedef enum +{ + /* + (!) Do not change the integral constants (they are written to file permanently). + */ + + GCM_NULL_GTYPE = 0 ///< \ru Пустой геометрический объект. \en Empty geometric object. + , GCM_POINT ///< \ru Точка. \en Point. + , GCM_LINE ///< \ru Прямая. \en Line. + , GCM_PLANE ///< \ru Плоскость. \en Plane. + , GCM_CYLINDER ///< \ru Цилиндр. \en Cylinder. + , GCM_CONE ///< \ru Конус. \en Cone. + , GCM_SPHERE ///< \ru Сферическая поверхность. \en Spherical surface. + , GCM_TORUS ///< \ru Тороидальная поверхность. \en Toroidal surface. + , GCM_CIRCLE ///< \ru Окружность. \en Circle. + , GCM_LCS ///< \ru Система координат. \en Coordinate system. + , GCM_MARKER ///< \ru Точка и пара ортонормированных векторов. \en Point and pair of orthonormalized vectors. + , GCM_SPLINE ///< \ru Сплайновая кривая. \en Spline curve. + , GCM_VECTOR // Unit vector (internal use only) + , GCM_AXIS // Point with unit vector (internal use only) + , GCM_UNKNOWN_GTYPE // \ru Геометрический тип, не поддерживаемый решателем. \en Some geometric type, which is not supported by the solver. \~ + , GCM_LAST_GTYPE // \ru Количество типов. \en The count of types. +} GCM_g_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Словарь типов ограничения. + \en Dictionary of constraint types. \~ + + \note \ru Значения этого перечисления могут быть использованы для постоянного + хранения и останутся неизменными в следующих версиях. + \en Values of this enum can be used for permanent storage + and will be kept in the future versions. \~ +*/ +//--- +typedef enum +{ + /* + (!) Do not change the integral constants (they are written to file permanently). + */ + GCM_UNKNOWN = -1 ///< \ru Не определенный тип. \en Unknown type. + , GCM_COINCIDENT = 0 ///< \ru Геометрическое совпадение. \en Coincidence of loci. + , GCM_PARALLEL = 1 ///< \ru Параллельность двух объектов, имеющих направление. \en Parallelism of two objects which have a direction vector. + , GCM_PERPENDICULAR = 2 ///< \ru Перпендикулярность двух объектов, имеющих направление. \en Perpendicularity of two objects which have a direction vector. + , GCM_TANGENT = 3 ///< \ru Касание двух поверхностей или кривых. \en Tangency of two objects, surfaces and curves. + , GCM_CONCENTRIC = 4 ///< \ru Концентричность двух объектов, имеющих ось или центр. \en Concentricity of two objects having a center or an axis. + , GCM_DISTANCE = 5 ///< \ru Линейное размер между объектами. \en Linear dimension between objects. + , GCM_ANGLE = 6 ///< \ru Угловой размер между векторными объектами. \en Angular dimension between directed objects (vectors). + , GCM_TRANSMITTION = 9 ///< \ru Механическая передача. \en Mechanical transmission. + , GCM_CAM_MECHANISM = 10 ///< \ru Кулачковый механизм. \en Cam mechanism. + , GCM_SYMMETRIC = 11 ///< \ru Симметричность. \en Symmetry. + , GCM_DEPENDENT = 14 ///< \ru Зависимый объект. \en Dependent object. + , GCM_PATTERNED = 15 ///< \ru Элемент паттерна. \en Patterned object. + , GCM_LINEAR_PATTERN = 16 ///< \ru Линейный паттерн. \en Linear pattern. + , GCM_ANGULAR_PATTERN = 17 ///< \ru Угловой паттерн. \en Angular pattern. + , GCM_RADIUS = 18 ///< \ru Радиальный размер. \en Radial dimension. + , GCM_LAST_CTYPE + , GCM_IN_PLACE = 7 // Deprecated +} GCM_c_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Варианты выравнивания направлений. + \en Variants of alignment. \~ + \note \ru Значения этого перечисления могут быть использованы для постоянного + хранения и останутся неизменными в следующих версиях. + \en Values of this enum can be used for permanent storage + and will be kept in the future versions. \~ +*/ +//--- +typedef enum +{ + /* + (!) Do not change the constants (they are written to file permanently). + */ + GCM_MIN_ALIGNMENT= -1, // Minimum value of this enum + GCM_OPPOSITE = -1, ///< \ru Противонаправленные. \en Anti-align the directions. \~ + GCM_CLOSEST = 0, ///< \ru Ориентация согласно ближайшего решения. \en Orientation according to the nearest solution. \~ + GCM_COORIENTED = 1, ///< \ru Сонаправленные. \en Cooriented directions. \~ + GCM_NO_ALIGNMENT = 2, ///< \ru Нет определенной ориентации. \en No defined orientation. \~ + /* + Additional variants of alignment (they are used for tangency variants) + */ + GCM_ALIGNED_0 = GCM_COORIENTED, + GCM_ALIGNED_1 = 3, + GCM_ALIGNED_2 = 4, + GCM_ALIGNED_3 = 5, + GCM_REVERSE_0 = GCM_OPPOSITE, + GCM_REVERSE_1 = 6, + GCM_REVERSE_2 = 7, + GCM_REVERSE_3 = 8, + /* + Additional variants of alignment (they are used for patterns and symmetry) + */ + GCM_ALIGNED = 1, ///< \ru ЛСК с одинаковой ориентацией. \en Axis aligned local coordinate systems. \~ + GCM_ROTATED = 9, ///< Ротационное (вращательной) выравнивание элементов паттерна. + GCM_ALIGN_WITH_AXIAL_GEOM = 10, ///< Выровнять с объектом, задающим ось. + + GCM_MAX_ALIGNMENT, // Maximum value of this enum + +} GCM_alignment; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вариант углового размера. + \en Variant of angular dimension. \~ + \note \ru Значения этого перечисления могут быть использованы для постоянного + хранения данных приложения и останутся неизменными в следующих версиях. + \en Values of this enum can be used for permanent storing of app data + and will be kept in the future versions. \~ +*/ +//--- +typedef enum +{ + GCM_NONE_ANGLE = 0, ///< \ru Неопределен \en Undefined + GCM_2D_ANGLE = 1, ///< \ru Угол для планарных соединений (0 .. 360 градусов) \en Angle of planar joints (0 .. 360 degrees) + GCM_3D_ANGLE = 2, ///< \ru Угол в пространстве (0 .. 180 градусов) \en Angle in space (0 .. 180 degrees) + GCM_PLANAR_ANGLE = GCM_2D_ANGLE +} GCM_angle_type; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Варианты касания поверхностей или кривых. + \en Variants of tangency of surfaces or curves. \~ + \note \ru Значения этого перечисления могут быть использованы для постоянного + хранения данных приложения и останутся неизменными в следующих версиях. + \en Values of this enum can be used for permanent storage of app data and will + be kept in the future versions. \~ +*/ +//--- +typedef enum +{ + /* + (!) Do not change the constants + */ + GCM_TAN_NONE = 0x00 ///< \ru Не выбрано. \en Not chosen. + , GCM_TAN_POINT = 0x01 ///< \ru Касание в общем случае (контакт точкой). \en Tangency in general case (contact at a point). + , GCM_TAN_LINE = 0x02 ///< \ru Касание по образующей прямой (например два цилиндра с параллельными осями). \en Tangency by a generating line (for instance, two cylinders with parallel axes). + , GCM_TAN_CIRCLE = 0x04 ///< \ru Касание по окружности (например сфера в конусе). \en Tangency by a circle (for instance, a sphere inside a cone). +} GCM_tan_choice; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Диагностические коды 3d-решателя. \en Diagnostic codes of 3D-solver. \~ + \details \ru GCM_result перечисляет значения, возвращаемые вызовами API компонента GCM, + включая диагностические коды решения геометрических ограничений. Значения данного типа + возвращаются такими функциями, как GCM_Evaluate и GCM_EvaluationResult. + \en GCM_result enumerates the values returned by the GCM API calls including + the diagnostic codes of solving geometric constraints. Values of this type are returned + by functions such as GCM_Evaluate and GCM_EvaluationResult. + \note \ru Значения этого перечисления могут быть использованы для постоянного + хранения данных приложения и останутся неизменными в следующих версиях. + \en Values of this enum can be used for permanent storage of app data and will + be kept in the future versions. \~ +*/ +//--- +typedef enum +{ + GCM_RESULT_None = 0 ///< \ru Код неопределенного результата или состояния. \en Code of undefined result or status. \~ + , GCM_RESULT_Ok = 1 ///< \ru Успешный результат вызова API компонента GCM. \en The successful result of GCM API call. \~ + , GCM_RESULT_Satisfied = GCM_RESULT_Ok ///< \ru Ограничение или система ограничения решены. \en Constraint or system of constraints are fulfilled. \~ + , GCM_RESULT_Overconstrained = 2 ///< \ru Ограничение переопределяет систему и противоречит другим условиям. \en Constraint is redundant and contradicts the other conditions. \~ + , GCM_RESULT_MatedFixation = 3 ///< \ru Заданы ограничения для пары фиксированных объектов. \en Constraints are specified for pair of fixed objects. \~ + , GCM_RESULT_DraggingFailed = 4 ///< \ru Неудачная попытка перемещения фиксированного объекта (равно, как объекта жестко-связанного с фиксированным). \en Failed attempt to move a fixed object (as the object rigidly connected with fixed). \~ + , GCM_RESULT_Not_Satisfied = 5 ///< \ru Ограничение(я) не решено (по неизвестным причинам). \en Constraint(s) has not been solved (for unknown reasons). \~ + , GCM_RESULT_Unsolvable = 6 ///< \ru Ограничение(я) не разрешимо. \en Constraint(s) is not solvable. \~ + + /** + \brief \ru Ограничение GCM_DEPENDENT не вычислено или ее независимые аргументы находятся вне области решений. + \en The GCM_DEPENDENT constraint is not solved or its independent arguments are out of the solution domain. + \note \ru Ситуация возникает, когда функция GCM_dependent_func возвращает false. + \en The situation occurs when the GCM_dependent_func function returns false. + */ + , GCM_RESULT_DependentConstraintUnsolved = 7 + , GCM_RESULT_Error = 8 ///< \ru Неизвестная ошибка, как правило, не связанная с процессом решения. \en Unknown error is usually not related to the solving. \~ + , GCM_RESULT_InappropriateAlignment = 9 ///< \ru Опция выравнивания не подходит для данного типа ограничения. \en The alignment option is inappropriate to a given constraint type. \~ + , GCM_RESULT_InappropriateArgument = 10 ///< \ru Геометрический тип аргумента не подходит для данного ограничения. \en Geometric type of an argument is inappropriate to the constraint. \~ + + /* + Additional message codes. + */ + + , GCM_RESULT_IncompatibleArguments = 3001 ///< \ru Несовместные типы аргументов ограничения. \en Inconsistent types of constraint arguments. \~ + , GCM_RESULT_InconsistentAngleType ///< \ru Угловая опция несовместима со степенью свободы соединения (планарный тип угла применим только для соединения, оставляющего единственную степень свободы вращения). \en Angular option is inconsistent with the degree of freedom of the joint (planar type of angle is only applicable for the joint leaving only one degree of freedom of rotation); \~ + , GCM_RESULT_InconsistentAlignment ///< \ru Величина ориентации несовместна с другими сопряжениями. \en The orientation value is inconsistent with other mates. \~ + , GCM_RESULT_Duplicated ///< \ru Ограничение дублирует другое. \en Constraint duplicates another. + , GCM_RESULT_CyclicDependence ///< \ru Неразрешимая циклическая зависимость. \en Unsolvable cyclic dependence. + , GCM_RESULT_MultiDependedGeom ///< \ru Объект является зависимым от двух и более ограничений 'GCM_DEPENDED'. \en A geometric object is dependent on two or more constraints of 'GCM_DEPENDED' type. + , GCM_RESULT_OverconstrainingDependedGeoms ///< \ru Избыточное ограничение между зависимыми объектами. \en A redundancy constraint between depended geoms. \~ + , GCM_RESULT_DependedGeomCantBeFixed ///< \ru Зависимый аргумент ограничения 'GCM_DEPENDED' не может быть зафиксирован. \en The depended argument of 'GCM_DEPENDED' can't be fixed. + , GCM_RESULT_InvalidArguments ///< \ru В ограничении не заданы аргументы (пустые аргументы). \en Constraint has invalid or undefined (void) arguments. + , mtResCode_UnsupportedTangencyChoice ///< \ru Для сопряжения касание - опция выбора по окружности или по образующей не поддреживается \en For mate the option of tangency choice by circle or generating curve is unsupported. + , mtResCode_IsNoPossibleForCircTanChoice ///< \ru Для данной пары поверхностей касание по окружности геометрически не возможно \en For a given pair of surfaces the touching along the circle is geometrically impossible. + , mtResCode_CoaxialMtGearTransmissionIsNotAvalable ///< \ru Механическая передача вращения компонентов с совпадающими осями не поддерживается \en Mechanical transmission of components rotation with the same axis is not supported + , mtResCode_NoSeparatedSolutionForCamGear ///< \ru В сборке присутствуют сопряжения (геометрические условия), создающие зависимость движения толкателя от движения кулачка, помимо самого кулачкового механизма \en The assembly contains mates (geometric conditions) creating dependence of the motion of the pusher from the motion of cam in addition to the cam gear + , mtResCode_CyclicDependenceForTwoOrMoreCamGears ///< \ru Задана циклическая зависимость для двух или более кулачковых механизмов \en Given the cyclic dependence for two or more cam gears + , mtResCode_InconsistentFollowerAxis ///< \ru Заданные сопряжения для толкателя не соответствую его оси движения \en Given mates for pusher doesn't correspond to its motion axis + , GCM_RESULT_InconsistentPlanarAngle ///< \ru Не соблюдаются условия планарного угла (векторы сторон угла должны быть перпендикулярны оси). \en Planar angle conditions are not met (vectors from the sides of angle should be perpendicular to the axis). + /* + ATTENTION: New error messages should be added only before this line. + */ + + /* + \ru Сообщения о некорректных результатах вызовов API решателя (не вычислительные). + \en Messages about incorrect results of the solver API calls (not computational). \~ + */ + , GCM_RESULT_ItsNotDrivingDimension ///< \ru Данное ограничение должно быть управляющим размером. \en Given constraint should be a driving dimension. + , GCM_RESULT_Unregistered ///< \ru Обращение к недействительному объекту. \en Access to invalid object. + , GCM_RESULT_InternalError + , GCM_RESULT_Aborted ///< \ru Процесс вычислений был прерван по запросу приложения. \en The evaluation process aborted by the application. \~ + , GCM_RESULT_Last_ // The last error code of user for mates (adding before this line) +} GCM_result; + +//---------------------------------------------------------------------------------------- +/// \ru Характер зависимости пары тел (geoms) \en Dependency character of solid pair (geoms) +// --- +typedef enum +{ + GCM_NO_DEPENDENCY = 0 ///< \ru Нет односторонней зависимости. \en It means no one-directed dependency. + , GCM_1ST_DEPENDENT = 2 ///< \ru Первый объект зависит от другого(других). \en The first object is dependent on the other(s). + , GCM_2ND_DEPENDENT = 1 ///< \ru Второй объект зависит от другого(других). \en The second object is dependent on the other(s). +} GCM_dependency; + +//---------------------------------------------------------------------------------------- +/// \ru Тип связи между элементами в паттерне. \en The type of relationship between elements in the pattern. +// --- +typedef enum +{ + GCM_NO_SCALE = 0, + GCM_RIGID = 1, ///< \ru Шаг между элементами константен. Паттерн не масштабируется (не растягивается). \en Distance between elements is constant. The pattern is not scaled. + GCM_LINEAR_SCALE = 2 ///< \ru Шаг между элементами линейно масштабируется при растяжениях. \en Distance between elements is linearly scaled when stretching. +} GCM_scale; + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Режим поведения при манипулировании недоопределенной системой. + \en Mode of the behavior when manipulating the undeconstrained system. \~ +*/ +// --- +typedef enum +{ + /* + Произвольное поведение (arbitrary behavior). + */ + GCM_REPOSITION_FreeRotation ///< \ru Произвольная репозиция с преимуществом вращения. \en Arbitrary reposition with predominant rotation. + , GCM_REPOSITION_FreeMoving ///< \ru Произвольная репозиция с преимуществом перемещения. \en Arbitrary reposition with predominant moving. + + /* + Строгое поведение (strict behavior). + */ + , GCM_REPOSITION_Dragging ///< \ru Перетаскивание в плоскости "экрана". \en Dragging in the plane of the screen. + , GCM_REPOSITION_Rotation ///< \ru Вращение вокруг неподвижной оси. \en Rotation around fixed axis. + + /** \brief \ru Перенос только для одного твердого тела. \en Shift only one solid. + \note \ru Этот режим был задуман для процессов вставки нового тела в сборку САПР. + \en This mode have been intended for insertion processes of a new solid in the CAD assembly. + */ + , GCM_REPOSITION_Transfer + +} GCM_reposition; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты 3D-вектора. \en Coordinates of 3D-vector. +//--- +struct GCM_vec3d { double x, y, z; }; + +//---------------------------------------------------------------------------------------- +/// \ru Координаты точки 3D пространства. \en Coordinates of point in three-dimensional space. +//--- +struct GCM_point { double x, y, z; }; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Структура полей данных, представляющих геометрический объект. + \en Structure of data fields representing a geometric object. \~ + \details \ru Эта простая структура данных представляет варианты геометрических типов, + с которыми работает решатель.\n + \en This plain data structure represents variants of geometric data types that + the solver works with.\n + \~ + \par + \ru Кортежи, соответствующие типам геометрии:\n + \en Corresponding tuples of geometric types:\n + + \~ { GCM_POINT origin } - simple point;\n + { GCM_SPHERE origin radiusA } - center and radius of a sphere;\n + { GCM_LINE origin axisZ } - point and direction of a line;\n + { GCM_PLANE origin axisZ } - point and normal of a plane;\n + { GCM_CIRCLE origin axisZ radiusA } - center, rotation axis and radius;\n + { GCM_CYLINDER origin axisZ radiusA } - center, rotation axis and radius;\n + { GCM_CONE origin axisZ radiusA radiusB } - center, rotation axis and two radiuses;\n + { GCM_TORUS origin axisZ radiusA radiusB };\n + { GCM_LCS origin axisZ axisX axisY } - local coordinate system that specify a solid position.\n +*/ +//--- +struct GCM_g_record +{ + GCM_g_type type; ///< \ru Тип геометрии. \en Type of geometric object. + GCM_point origin; ///< \ru Точка позиционирования геометрического объекта. \en Location of a geometric object. + GCM_vec3d axisZ; ///< \ru Направляющий вектор прямой или вектор нормали плоскости. \en Direction of line, normal of plane, Z-axis of a local coordinate frame. + GCM_vec3d axisX; ///< \ru Ось X локальной системы координат. \en X-axis of local coordinate frame . + GCM_vec3d axisY; ///< \ru Ось Y локальной системы координат. \en Y-axis of local coordinate frame. + double radiusA; ///< \ru Радиус окружности, сферы или цилиндра либо радиус основания конуса, "большой" радиус тора. \en Radius of circle, sphere and cylinder or major radius of cone and torus. + double radiusB; ///< \ru "Малый" радиус тора или конуса. \en Minor radius of cone and torus. +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Дополнительный параметр для функций типа #GCM_dependent_func. + \en Additional parameter for functions of type #GCM_dependent_func. \~ + \sa #GCM_dependent_geom_func, #GCM_dependent_func +*/ +//--- +struct GCM_extra_param +{ + size_t funcId; // integral identifier of a user-defined callback + void * funcData; // pointer to an application data structure + GCM_extra_param() { funcId = 0, funcData = 0; } +}; + +//---------------------------------------------------------------------------------------- +// The function calculates position of a dependent geom regarding to other independent geoms. +/* + Note: The dependent geom is first element of argument list inGeoms, and others are independent. + argNb Number of arguments of dependency constraint, equals to size of inGeoms. + g1 = f( g2 g3 ... gn ); +*/ +//--- +typedef bool (*GCM_dependent_func) ( MbPlacement3D gPlaces[] + , size_t gPlacesSize + , GCM_extra_param exPar ); + +//---------------------------------------------------------------------------------------- +/// \~ Alternative typename of #GCM_dependent_func +//--- +typedef GCM_dependent_func GCM_dependent_geom_func; + +/** \} */ // GCM_3D_API + +//---------------------------------------------------------------------------------------- +// Argument of constraint to record in type 'GCM_c_record' +//-- +struct GCM_c_arg +{ + union + { + GCM_object geom; // Geometric object. + GCM_alignment alignVal; // Variant of alignment. + GCM_tan_choice tanChoice; // Option for tangency constraint only. + GCM_angle_type angType; // Option for angular constraint only. + GCM_scale scale; // Option for pattern constraint only. + double dimValue; // Numeric value of a dimension. + int enumVal; + }; + GCM_c_arg & operator = ( double val ) + { + dimValue = val; + return *this; + } + template + GCM_c_arg & operator = ( const _Enum & val ) + { + enumVal = static_cast( val ); + return *this; + } + GCM_c_arg & operator = ( const GCM_geom & gId ) + { + geom = gId; + return *this; + } + GCM_c_arg() { dimValue = 0.0; } +}; + +//---------------------------------------------------------------------------------------- +/** \brief \en Structure of geometric constraint record. + \ru Структура записи геометрического ограничения. \~ +*/ +/* + The argument tuples of each constraint type: + { GCM_c_type GCM_c_arg ... GCM_c_arg } + -------------------|------------------------------- + { GCM_COINCIDENT GCM_geom GCM_geom GCM_alignment } + { GCM_CONCENTRIC GCM_geom GCM_geom GCM_alignment } + { GCM_PARALLEL GCM_geom GCM_geom GCM_alignment } + { GCM_PERPENDICULAR GCM_geom GCM_geom GCM_alignment } + { GCM_IN_PLACE GCM_geom GCM_geom GCM_NO_ALIGNMENT } + { GCM_DISTANCE GCM_geom GCM_geom double GCM_alignment } + { GCM_TANGENT GCM_geom GCM_geom GCM_alignment GCM_tan_choice } + { GCM_ANGLE GCM_geom GCM_geom GCM_geom double GCM_alignment } - planar kind of angle + { GCM_ANGLE GCM_geom GCM_geom GCM_NULL double GCM_alignment } - 3d kind of angle + { GCM_SYMMETRIC GCM_geom GCM_geom GCM_geom GCM_alignment } + { GCM_PATTERNED GCM_geom GCM_geom GCM_geom double GCM_alignment GCM_scale } + { GCM_LINEAR_PATTERN GCM_geom GCM_geom GCM_geom GCM_alignment } + { GCM_ANGULAR_PATTERN GCM_geom GCM_geom GCM_geom GCM_alignment } + { GCM_TRANSMITTION not specified } + { GCM_CAM_MECHANISM not specified } + { GCM_RADIUS GCM_geom double } + { GCM_UNKNOWN } + Sample of the journal line: (GCM_AddConstraint (GCM_COINCIDENT #1 #2 GCM_CLOSEST) #3) +*/ +struct GCM_c_record +{ + static const size_t argsN = 5; + GCM_c_type type; // \ru Тип ограничения. \en Type of constraint. + GCM_c_arg args[argsN]; // \ru Аргументы ограничения. \en Arguments of constraint. +}; + +#if ( GCM_ID_TYPE == 1 ) + +inline bool operator == ( const MtObjectId & f, const MtObjectId & s ) { return f.id == s.id; } +inline bool operator != ( const MtObjectId & f, const MtObjectId & s ) { return f.id != s.id; } +inline bool operator < ( const MtObjectId & f, const MtObjectId & s ) { return f.id < s.id; } +inline uint32 & _id( MtObjectId & obj ) { return obj.id; } +inline const uint32 & _id( const MtObjectId & obj ) { return obj.id; } + +#else // GCM_ID_TYPE + +inline uint32 & _id( MtObjectId & obj ) { return obj; } +inline const uint32 & _id( const MtObjectId & obj ) { return obj; } + +#endif // GCM_ID_TYPE + +typedef GCM_alignment MtAlignType; +typedef GCM_g_type MtGeometryType; +typedef GCM_result MtResultCode3D; + +/* + The constants below are deprecated (2015) +*/ + +static const GCM_alignment GCM_NOT_ORIENTED = GCM_NO_ALIGNMENT; +static const GCM_alignment GCM_Opposite = GCM_OPPOSITE; +static const GCM_alignment GCM_Closest = GCM_CLOSEST; +static const GCM_alignment GCM_Cooriented = GCM_COORIENTED; +static const GCM_alignment GCM_None = GCM_NO_ALIGNMENT; +static const GCM_alignment GCM_Min = GCM_OPPOSITE; +static const GCM_alignment GCM_Max = GCM_MAX_ALIGNMENT; + +static const GCM_g_type GCM_FIRST_GTYPE = GCM_NULL_GTYPE; +static const GCM_g_type mgt_Cylinder = GCM_CYLINDER; +static const GCM_c_type mct_Coincidence = GCM_COINCIDENT; +static const GCM_c_type mct_Parallel = GCM_PARALLEL; +static const GCM_c_type mct_Perpendicular = GCM_PERPENDICULAR; +static const GCM_c_type mct_Tangency = GCM_TANGENT; +static const GCM_c_type mct_Concentric = GCM_CONCENTRIC; +static const GCM_c_type mct_Distance = GCM_DISTANCE; +static const GCM_c_type mct_Angle = GCM_ANGLE; +static const GCM_c_type mct_InPlace = GCM_IN_PLACE; +static const GCM_c_type mct_Unknown = GCM_UNKNOWN; +static const GCM_c_type mct_CamMechanism = GCM_CAM_MECHANISM; +static const GCM_c_type mct_Symmetry = GCM_SYMMETRIC; +static const GCM_c_type mct_Symmetric = GCM_SYMMETRIC; +static const GCM_c_type mct_Parallelism = GCM_PARALLEL; + +static const GCM_result mtResCode_None = GCM_RESULT_None; +static const GCM_result mtResCode_Ok = GCM_RESULT_Ok; +static const GCM_result mtResCode_Satisfied = GCM_RESULT_Ok; +static const GCM_result mtResCode_SystemError = GCM_RESULT_Error; +static const GCM_result mtResCode_Error = GCM_RESULT_Error; +static const GCM_result mtResCode_Overconstrained = GCM_RESULT_Overconstrained; +static const GCM_result mtResCode_Not_Satisfied = GCM_RESULT_Not_Satisfied; +static const GCM_result mtResCode_MovingOfFixedGeom = GCM_RESULT_DraggingFailed; +static const GCM_result mtResCode_InvalidAxisOfPlanarAngle = GCM_RESULT_InconsistentPlanarAngle; +static const GCM_result mtResCode_CyclicDependence = GCM_RESULT_CyclicDependence; +static const GCM_result mtResCode_InvalidDependenceForOutGeom = GCM_RESULT_MultiDependedGeom; +static const GCM_result mtResCode_InvalidDependenceForOutGeoms = GCM_RESULT_OverconstrainingDependedGeoms; // (2018) +static const GCM_result mtResCode_InvalidDependenceForFixGeom = GCM_RESULT_DependedGeomCantBeFixed; + +const GCM_dependency GCM_2ST_DEPENDENT = GCM_2ND_DEPENDENT; + +/* + Deprecated names of a dynamic reposition modes (2019) +*/ +const GCM_reposition rep_FreeRotation = GCM_REPOSITION_FreeRotation; +const GCM_reposition rep_FreeMoving = GCM_REPOSITION_FreeMoving; +const GCM_reposition rep_MovingToPoint = GCM_REPOSITION_Dragging; +const GCM_reposition rep_RotationAboutAxis = GCM_REPOSITION_Rotation; +const GCM_reposition rep_TransferOneGeomOnly = GCM_REPOSITION_Transfer; + + +#endif + +// eof diff --git a/C3d/Include/generic_utility.h b/C3d/Include/generic_utility.h new file mode 100644 index 0000000..569bab2 --- /dev/null +++ b/C3d/Include/generic_utility.h @@ -0,0 +1,1158 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Шаблонные утилиты. + \en Template utilities. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __GENERIC_UTILITY_H +#define __GENERIC_UTILITY_H + +#include +// +#include +// +#include +#include + +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------- +/// \ru Пустой тип данных. \en Empty data type. +//--- +struct null_type +{ + static const null_type value() { return null_type(); } +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Шаблон для получения индексного типа (для статического сопоставления типов на этапе компиляции) + \en Template to generate an indexed type (for static type-matching in compile-time) +*/ +//--- +template +struct index_tag +{ + index_tag() {} // Constructor under GCC compiler +}; + +//---------------------------------------------------------------------------------------- +/// \ru Цветовая маркировка (применяется для графов) \en Color marking (used for graphs) +//--- +enum color_code +{ + white_color=0 + , black_color=1 + , red_color=2 + , gray_color + , green_color + , orange_color + , visited_color +}; + +//---------------------------------------------------------------------------------------- +// Constant valued function +//--- +template +bool boolFunc() { return boolVal; } + +/* +//---------------------------------------------------------------------------------------- +/// \ru Цветовая маркировка, например, для графовых объектов \en Color marking, for example: for graph objects +//--- +template +struct color_traits +{ + static color_code white() { return white_color; } + static color_code gray() { return gray_color; } + static color_code green() { return green_color; } + static color_code red() { return red_color; } + static color_code black() { return black_color; } +}; + +template<> +struct color_traits +{ + static char white() { return 0; } + static char gray() { return 1; } + static char green() { return 2; } + static char red() { return 3; } + static char black() { return 4; } +}; +*/ + +//---------------------------------------------------------------------------------------- +/// \ru Графовые характеристики типов. \en Graph datatype traits. +//--- +template< class Graph > +struct graph_traits +{ + /* + Ассоциативные типы данных концепции графа. + Associative datatypes of the graph concept. + */ + typedef typename Graph::vertex vertex; // Тип, интерпретируемый, как вершина графа. + typedef typename Graph::edge edge; // Тип, интерпретируемый, как ребро графа + typedef typename Graph::vertex_iterator vertex_iterator; // Обход всех вершин графа + typedef typename Graph::adjacency_iterator adjacency_iterator; // Обход смежных вершин некоторой вершины + typedef typename Graph::vertices_size_t vertices_size_t; // Целочисленный тип размера графа + typedef typename Graph::degree_size_t degree_size_t; // Целочисленный тип вершинной степени + typedef typename Graph::edge_iterator edge_iterator; // Итератор обхода исходящих ребер [или неориентированных ребер] +}; + +//---------------------------------------------------------------------------------------- +/// \ru Пара ссылок. \en A pair of references. +//--- +template +struct ref_pair +{ + _Ty1 & first; + _Ty2 & second; + + ref_pair( _Ty1 & val1, _Ty2 & val2 ) + : first(val1), second(val2) + {} + ref_pair( const ref_pair & other ) + : first(other.first), second(other.second) + {} + + template + ref_pair( const std::pair<_Other1, _Other2> & right ) + : first(right.first), second(right.second) + {} + + template + ref_pair & operator = ( const std::pair<_Other1, _Other2> & right ) + { + first = right.first; + second = right.second; + return *this; + } + +private: + ref_pair & operator = ( const ref_pair & ); // \ru не реализуемо \en not implemented +}; + +//---------------------------------------------------------------------------------------- +/// \ru Выдать ссылки одной связкой. \en Get references as one bunch. +//--- +template +inline ref_pair +tie( Type & iter1, Type & iter2 ) +{ + return ref_pair ( iter1, iter2 ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Наибольшее из двух. \en Maximum of two. +// --- +template +inline const T & max_of( const T & elem1, const T & elem2 ) +{ + if ( elem2 < elem1 ) + return elem1; + return elem2; +} + +//---------------------------------------------------------------------------------------- +/// \ru Наибольшее из двух. \en Maximum of two. +// --- +template +inline const T & min_of( const T & elem1, const T & elem2 ) +{ + if ( elem1 < elem2 ) + return elem1; + return elem2; +} + +//---------------------------------------------------------------------------------------- +/// \ru Поменять местами значения. \en Swap the values. +// --- +template +inline void swap_vals( T & elem1, T & elem2 ) +{ + T tmp = elem1; + elem1 = elem2; + elem2 = tmp; +} + +//---------------------------------------------------------------------------------------- +/// \ru Поменять местами значения указателей. \en Swap the values of pointers. +// --- +template +inline void swap_ptrs( T* & elem1, T* & elem2 ) +{ + T * tmp = elem1; + elem1 = elem2; + elem2 = tmp; +} + +//---------------------------------------------------------------------------------------- +/// \ru Поменять местами значения указателей. \en Swap the values of pointers. +//--- +template +inline void swap_ptrs( SPtr & p1, SPtr & p2 ) +{ + SPtr t = p1; + p1 = p2; + p2 = t; +} + +//---------------------------------------------------------------------------------------- +// \ru Равенство пары указателей \en Equality of pointer pair +//--- +template< class Type1, class Type2 > +bool equal_ptrs( const Type1 * ptr1, const Type2 * ptr2 ) +{ + return static_cast(ptr1) == ptr2; +} + +//---------------------------------------------------------------------------------------- +// \ru Равенство пары указателей \en Equality of pointer pair +//--- +template< class Type1, class Type2 > +bool equal_ptrs( SPtr ptr1, const Type2 * ptr2 ) +{ + return static_cast(ptr1.get()) == ptr2; +} + +//---------------------------------------------------------------------------------------- +// \ru Равенство пары двухмерных векторов или точек \en Equality of 2D points or vectors +//--- +template< class XY1, class XY2 > +bool equal_xy( const XY1 & v1, const XY2 & v2, double eps ) +{ + if ( fabs(v1.x-v2.x) > eps ) + return false; + if ( fabs(v1.y-v2.y) > eps ) + return false; + return true; +} + +//---------------------------------------------------------------------------------------- +// \ru Наименьший общий делитель \en The lowest common denominator +// --- +template < typename Integer > +Integer euclid_algo ( Integer a, Integer b ) +{ + Integer const zero = static_cast( 0 ); + + bool goOn = true; + while ( goOn ) + { + if ( a == zero ) { + goOn = false; + return b; + } + + b %= a; + + if ( b == zero ) { + goOn = false; + return a; + } + + a %= b; + } + return zero; +} + +//---------------------------------------------------------------------------------------- +/// \ru Получить НОД для пары целых чисел \en Get GCD for a pair of integers +// --- +template < typename IntegerType > +inline IntegerType gcd( IntegerType a, IntegerType b ) +{ + IntegerType const zero = static_cast( 0 ); + IntegerType const result = ::euclid_algo( a, b ); + return ( result < zero ) ? -result : result; +} + + +//---------------------------------------------------------------------------------------- +// \ru Функциональный объект - коллектор \en The functional object - collector +/*\ru Играет роль посетителя foreach-алгоритмов, осуществляющий накачку STL-совместимых контейнеров + \en Serves as a visitor of foreach-algorithms exercising pumping of STL-compatible containers \~ +*/ +//--- +template +struct collector +{ + typedef typename _Cont::value_type value_type; + _Cont & container; // \ru STL-совместимый контейнер \en STL-compatible container + + collector( _Cont & arr ) + : container( arr ) {} + collector( const collector & c ) : container( c.container ) {} + void operator () ( const value_type & elem ) const + { + container.push_back( elem ); + } + +private: // \ru не реализовано \en not implemented + collector & operator = ( const collector & ); +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Статический вектор. + \en Static vector. + \note \ru Требуется, что бы элементы вектора имели конструктор по умолчанию, + конструктор копирования и оператор присвоения. + \en Required that the vector elements have a default constructor, + copy constructor and assignment operator. \~ +*/ +//--- +template +class static_array +{ +public: + typedef Elem value_type; // \ru ассоциативный тип элемента массива \en associative type of array element + +private: + value_type arr[arrSize]; // \ru статическое выделение памяти под массив \en static allocation for the array + +public: + /// \ru Инициализация одним элементом. \en Initialization of one element. + explicit static_array( const Elem & val ) + { + fill( val ); + } + /// \ru Инициализация парой элементов. \en Initialization of a pair of elements. + static_array( const Elem & e1, const Elem & e2 ) + { + PRECONDITION( arrSize == 2 ); + arr[0] = e1; + arr[1] = e2; + } + /// \ru Конструктор по тройке. \en Constructs as a triplet. + static_array( const Elem & e1, const Elem & e2, const Elem & e3 ) + { + PRECONDITION( arrSize == 3 ); + arr[0] = e1; + arr[1] = e2; + arr[2] = e3; + } + explicit static_array( const static_array & vec ) + { + _Assign( vec ); + } + + template + static_array( const _Vector & vec ) + { + _Assign( vec ); + } + + /// \ru Инициализация одним элементом. \en Initialization of one element. + static_array & fill( const Elem & val ) + { + for( size_t idx = 0; idx + static_array & assign( _Iter iter, _Iter last ) + { + for ( value_type * myIter = arr ; iter!=last; ++iter, ++myIter ) + { + PRECONDITION( myIter < arr+arrSize ); + *myIter = *iter; + } + return *this; + } + + inline value_type & operator[] ( size_t idx ) + { + PRECONDITION( idx < arrSize ); + return arr[idx]; + } + inline const value_type & operator[] ( size_t idx ) const + { + PRECONDITION( idx < arrSize ); + return arr[idx]; + } + template + static_array & operator = ( const _Vector & vec ) + { + _Assign( vec ); + return *this; + } + + inline const Elem * c_arr() const { return arr; } + inline Elem * c_arr() { return arr; } + inline size_t size() const { return arrSize; } + inline value_type & front() { return *arr; } + inline value_type & back() { PRECONDITION(arrSize>0); return arr[arrSize-1]; } + inline const value_type & front() const { return *arr; } + inline const value_type & back() const { PRECONDITION(arrSize>0); return arr[arrSize-1]; } + +private: + template< class _Vector > + void _Assign( const _Vector & vec ) + { + PRECONDITION( vec.size() == size() ); + for ( size_t idx = ::min_of( arrSize, vec.size() ); idx > 0; ) + { + idx--; + arr[idx] = vec[idx]; + } + } +}; + +// \ru (!) Запретить пустые статические массивы \en (!) Prevent empty static arrays +template class static_array {}; + +//---------------------------------------------------------------------------------------- +/// \ru Статический вектор двух элементов (пара). \en Static vector of two elements (pair). +//--- +template +struct static_pair: public static_array +{ + typedef static_array parent_type; + // static_pair(): parent_type() {} + explicit static_pair( const Elem & el ): parent_type( el ) {} + static_pair( const Elem & el1, const Elem & el2 ): parent_type( el1, el2 ) {} + explicit static_pair( const static_pair & pair ) : parent_type( pair ) {} + + static_pair & operator = ( const static_pair & vec ) + { + parent_type::operator=( vec ); + return *this; + } +}; + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Динамический контейнер для хранения элементов упорядоченного множества. + \en Dynamic container for storing elements of an ordered set. + + \details + \ru Тип элемента контейнера должен иметь операторы порядка. Не стоит путать этот + тип контейнера с set или map. Он вовсе не обязан всегда поддерживаться в отсортированном + состоянии, а только тогда, когда это закажут (с кэшированием алгоритма сортировки). + Гарантируется, что вектор отсортирован сразу после вызова функций get_sorted или sort. + Константные методы, а также метод erase не нарушают сортировки.\n + \en Type of container element must have order operators. Do not confuse this + type of container with a set or map. It is not obliged always be supported in a sorted + state, and only when it is needed (with caching of sorting algorithm). It is guaranteed + that the vector is sorted immediately after the function call get_sorted or sort. + Const methods and the erase method does not break sorting. \n \~ + + \par \ru Про эффективность + + Часто сортированный вектор оказывается более эффективным, чем std::map или std::set, + особенно если добавление/удаление элементов массива осуществляется серийно и достаточно + редко перемежаются, с запросами быстрого (бинарного) поиска элемента или его места по + порядку. В отличие от map или set минимально дефрагментируется память и не требуется + избыточной информации для хранения указателей (может занимать в 4 раза меньше памяти). + Для быстрых запросов можно применять стандартные алгоритмы, такие + как std::binary_search, std::lower_bound и т.п. + + \en About efficiency + + Often sorted vector is more effective than + std::map or std::set especially when adding/removing elements + of the array is standard and is rarely interspersed + with queries quickly (binary) search of element or its place by + the order. In contrast to the map or set minimal defragmented + memory and does not require excess information for storage of pointers + (can occupy memory in less than 4 times). + For fast queries, can use standard algorithms such + as std::binary_search, std::lower_bound etc. \~ +*/ +//--- +template > // \ru KeyType - тип элемента с операторами порядка "<" \en KeyType - the element type with the operators of order "<" +class sorting_array +{ +public: + typedef std::vector container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::const_iterator iterator; + typedef typename container_type::iterator _iterator; + typedef std::pair iter_range; + typedef _Pr key_compare; // \ru отношение порядка (предикат) \en order relation (predicate) + +public: + sorting_array() : m_vector(), m_sorted( true ) {} + +public: + iter_range get_sorted() { sort(); return iter_range(m_vector.begin(), m_vector.end()); } + iter_range range() const { return iter_range(m_vector.begin(), m_vector.end()); } + const KeyType & sorted_back() { sort(); return m_vector.back(); } + bool empty() const { return m_vector.empty(); } + iterator begin() const { return m_vector.begin(); } + iterator end() const { return m_vector.end(); } + _iterator _begin() { return m_vector.begin(); } + _iterator _end() { return m_vector.end(); } + const KeyType & front() const { return m_vector.front(); } + const KeyType & back() const { return m_vector.back(); } + void erase( iterator ); + void erase( iterator f, iterator l ); + bool is_sorted() const { return m_sorted; } + iterator insert( iterator _whereItr, const KeyType & val ); // \ru вставить элемент перед позицией whereItr \en insert element before position whereItr + template + void insert( iterator position, InputIterator first, InputIterator last ) + { + m_vector.insert( position, first, last ); + m_sorted = false; + } + template + void assign ( InputIterator first, InputIterator last ) + { + m_vector.assign( first, last ); + m_sorted = false; + } + void resize( size_t n, const KeyType & val ); + void reserve ( size_t n ) { m_vector.reserve( n ); } + void push_back( const KeyType & val ); + void sort() + { + if ( !m_sorted ) + { + std::sort( m_vector.begin(), m_vector.end(), _Pr() ); + m_sorted = true; + } + } + void clear() { m_vector.clear(); } + size_t size() const { return m_vector.size(); } + KeyType & operator[] ( size_t n ) { PRECONDITION( n < m_vector.size() ); return m_vector[n]; } + const KeyType & operator[] ( size_t n ) const { PRECONDITION( n < m_vector.size() ); return m_vector[n]; } + +private: + container_type m_vector; + bool m_sorted; + +private: + sorting_array( const sorting_array & ); // \ru реализовать по необходимости \en implement if necessary + sorting_array & operator = ( const sorting_array & ); // \ru реализовать по необходимости \en implement if necessary +}; + +//---------------------------------------------------------------------------------------- +// +// --- +template +void sorting_array::push_back( const KeyType & val ) +{ + m_sorted = m_vector.empty() ? true : m_sorted && _Pr()( m_vector.back(), val ); + m_vector.push_back( val ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template +void sorting_array::erase( iterator ersItr ) +{ + m_vector.erase( m_vector.begin() + (ersItr - begin()) ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template +void sorting_array::erase( iterator f, iterator l ) +{ + typename container_type::iterator first, last; + first = last = m_vector.begin(); + std::advance( first, std::distance(begin(),f) ); // convert from const-iterator to non-const + std::advance( last, std::distance(begin(),l) ); + m_vector.erase( first, last ); +} + +//---------------------------------------------------------------------------------------- +// \ru Вставить элемент перед позицией whereItr \en Insert element before position whereItr +//--- +template +typename sorting_array::iterator +sorting_array::insert( iterator _whereItr, const KeyType & val ) +{ + typename container_type::iterator whereItr = m_vector.begin(); + std::advance( whereItr, std::distance(begin(),_whereItr) ); // \ru перевод из конст-итератора в неконст \en convert from const-iterator to non-const + // \ru Далее проверяем не нарушает ли новая вставка упорядоченности массива \en Next, whether new insert does not break ordering of the array + if ( m_sorted && (_whereItr != m_vector.end()) ) + { + m_sorted = ! key_compare()( *_whereItr, val ); + if ( m_sorted ) // val <= _where + { + m_sorted = ( _whereItr == m_vector.begin() ) || !key_compare()( val, *(--_whereItr) ); + } + } + + // \ru Вставка \en Insert + return m_vector.insert( whereItr, val ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template +void sorting_array::resize( size_t n, const KeyType & val ) +{ + if ( m_sorted && (m_vector.size() < n) && !m_vector.empty() ) + { + m_sorted = !key_compare()( val, m_vector.back() ); // m_vector.back() <= val + } + + m_vector.resize( n, val ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Проверка упорядоченности массива \en Check for ordering array +//--- +template +bool check_ordering( const SortedArray & arr ) +{ + if ( arr.is_sorted() && !arr.empty() ) + { + typename SortedArray::value_type prev( *arr.begin() ); + typename SortedArray::iterator first = arr.begin()+1; + typename SortedArray::iterator last = arr.end(); + for( ; first!=last; ++first ) + { + if ( (*first) < prev ) + { + return false; // \ru нарушен порядок следования \en order has been broken + } + prev = *first; + } + } + + return true; +} + +//---------------------------------------------------------------------------------------- +/// \ru Обнулить структуру данных (использовать осторожно!). \en Reset the data structure (use with caution!). +//--- +template< class DataSt > +inline DataSt null_struct() +{ + DataSt data; + ::memset( &data, 0, sizeof(DataSt) ); + return data; +} + +//---------------------------------------------------------------------------------------- +/// \ru Отладочный инспектор union-контейнера (НЕдоделан!). \en Debug Inspector of union-container (NOT completed yet!). +//--- +template +struct dbg_inspector +{ + union data_t + { + typename _PairUnion::value_type * first; + }; + data_t data; + dbg_inspector() { data.first = 0; } + void init( const _PairUnion & ) {} +}; + +//---------------------------------------------------------------------------------------- +/// \ru Хвостовой элемент для рекурсивного определения типа recursive_union. \en Tail element for recursive determination of type recursive_union. +//--- +struct empty_variant +{ + static const size_t dataSize = 0; + static const size_t power = 0; + struct value_type {}; + bool empty() { return true; } +}; + +//---------------------------------------------------------------------------------------- +/// \ru Получить номер типа из списка union-контейнера. \en Get type index from the list of union-container. +//--- +template +struct which_type +{ + static const int value = 1 + which_type::value; +}; + +// \ru Специализация 1 \en Specialization 1 +template +struct which_type<_PairUnion,typename _PairUnion::value_type> +{ + static const int value = 0; +}; + +// \ru Специализация 2 \en Specialization 2 +template +struct which_type +{ + static const int value = -1; +}; + +//---------------------------------------------------------------------------------------- +/// \ru Получить тип варианта с заданным номером. \en Get variant type with a given index. +//--- +template +struct type_which +{ + typedef typename T::tail_type tail_t; + typedef typename type_which::value_t value_t; +}; + +template +struct type_which +{ + typedef typename T::value_type value_t; +}; + +template +struct type_which +{ +private: + typedef null_type value_t; +}; + +//---------------------------------------------------------------------------------------- +/// \ru Проводник посетителя для рекурсивно-заданного контейнера. \en Conductor of visitor for recursively given container. +//--- +template +struct union_conductor +{ + typedef typename type_which<_PairUnion,typeNb>::value_t _Type; + + /// \ru Статическое приведение типа. \en Static cast of type. + template + static T * unsafe_cast( U & u ) { return u.template unsafe_cast(); } + + /// \ru Статическое приведение типа. \en Static cast of type. + template + static const T * unsafe_cast( const U & u ) { return u.template unsafe_cast(); } + + /// \ru Применить функтор. \en Apply the functor. + template + static inline void apply( const _Visitor & vis, _PairUnion & oper ) + { + if ( oper.which() == typeNb ) + { + vis( *unsafe_cast<_PairUnion,_Type>(oper) ); + } + else + { + union_conductor<_PairUnion,typeNb+1,power>::apply( vis, oper ); + } + } +}; + +//---------------------------------------------------------------------------------------- +// \ru Вызвать деструктор для указателя, если его тип попадает в диапазон от t до power. \en Call the destructor for the pointer if its type is within the range from t to power. +//--- +template +struct union_conductor<_PairUnion,power,power> +{ + template + static inline void apply( const _Visitor & , _PairUnion & ) {} +}; + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Рекурсивное определение класса "union-контейнер". + \en Recursive definition of class "union-container". + \details \ru Контейнер, который может хранить элемент типа "value_type" или один из типов + хвостового контейнера. + \en Container which can store the element of type "value_type" or one of types + of tail container. \~ +*/ +//--- +template +class recursive_union +{ + typedef recursive_union _Myt; + +public: // \ru доступные ассоциативные типы и константы \en available associative types and constants + static const size_t dataSize = sizeof(Type) > Tail::dataSize ? sizeof(Type) : Tail::dataSize; + static const size_t power = 1 + Tail::power; // \ru Количество типов, которое может обеспечить вариант \en The count of types which can provide a variant + + typedef Type value_type; + typedef Tail tail_type; + +public: + recursive_union() : m_typeNb(-1) { ::memset(m_data, 0, dataSize); } + recursive_union( const Type & ); + +#ifndef __DEBUG_MEMORY_ALLOCATE_FREE_ + template + recursive_union( const _Type & elem ) + : m_typeNb( which_type<_Myt,_Type>::value ) + , dbg_data() + { + if ( m_typeNb >= 0 ) + { + new ( (void*)m_data ) _Type( elem ); + } + } +#else // __DEBUG_MEMORY_ALLOCATE_FREE_ + template + recursive_union( const _Type & ) + : m_typeNb( which_type<_Myt,_Type>::value ) + , dbg_data() + { + // (!) The placement form of operator new is required. + C3D_ASSERT_UNCONDITIONAL( false ); + } +#endif //__DEBUG_MEMORY_ALLOCATE_FREE_ + + ~recursive_union(); + +private: // \ru вспомогательные объекты \en assisting objects + // \ru Посетитель для вызова конструктора типа, которым занят union-контейнер \en The visitor to call the type constructor which is occupied by union-container + struct assigner + { + assigner( _Myt & d ) : lOper(&d) {} + + template + void operator() ( const _Type & elem ) const + { + C3D_ASSERT( lOper ); + *lOper = elem; + } + private: + mutable _Myt * lOper; // \ru Левый операнд присвоения \en The left operand of assignment + + private: + assigner & operator = ( const assigner & ); + }; + + // \ru Посетитель для вызова деcтруктора типа, которым занят union-контейнер \en The visitor to call the type destructor which is occupied by union-container + struct destroyer + { + template + static void ignore(const _Type & ) {} // \ru для подавления сообщений \en for suppression of messages + + template + void operator() (const _Type & elem ) const + { + ignore( elem ); + elem.~_Type(); + } + }; + + // \ru Проверка на равенство \en The check for equality + struct comparer + { + const _Myt & data; + mutable bool result; + comparer( const _Myt & d ) : data( d ), result(false) {} + template + void operator() ( const _Type & elem ) const + { + result = (data == elem); + } + private: + comparer & operator = ( const comparer & ); + }; + + struct conductor: public union_conductor<_Myt,0,power> {}; + struct const_conductor: public union_conductor {}; + +public: + int which() const { return m_typeNb; } + // \ru Проверить пустой ли контейнер \en Check whether the container is empty + bool empty() const { return m_typeNb < 0; } + + // \ru Безопасное динамическое приведение типа \en Secure dynamic cast of type + template + _Type * safe_cast() + { + if ( which_type<_Myt,_Type>::value == m_typeNb ) + { + return (_Type*)m_data; + } + return 0; + } + // \ru Безопасное динамическое приведение типа \en Secure dynamic cast of type + template + const _Type * safe_cast() const + { + if ( which_type<_Myt,_Type>::value == m_typeNb ) + { + return (const _Type*)m_data; + } + return 0; + } + + // \ru Статическое приведение типа \en Static cast of type + template + _Type * unsafe_cast() + { + assert( (which_type<_Myt,_Type>::value == m_typeNb) ); + return (_Type*)m_data; + } + + // \ru Статическое приведение типа \en Static cast of type + /* + template typename type_which<_Myt,_typeNb>::value_t & + unsafe_get(); + */ + /* + { + assert( (which_type<_Myt,_Type>::value == m_typeNb) ); + return (type_which<_Myt,_typeNb>::value_t*)m_data; + } + */ + + // \ru Статическое приведение типа \en Static cast of type + template + const _Type * unsafe_cast() const + { + assert( (which_type<_Myt,_Type>::value == m_typeNb) ); + return reinterpret_cast( m_data ); + } + + void release() + { + accept( destroyer() ); + m_typeNb = -1; + } + /* + template + void release() + { + if ( which_type<_Myt,_Type>::value == m_typeNb ) + { + ((_Type*)m_data)->~_Type(); + m_typeNb = -1; + } + } + */ + + // \ru Присвоение другого union-контейнера \en Assignment of another union-container + _Myt & operator = ( const _Myt & v ) + { + release(); + v.accept( assigner(*this) ); + C3D_ASSERT( m_typeNb == v.m_typeNb ); + return *this; + } + + // \ru Присвоение произвольного типа \en Assignment of arbitrary type + /* + template + _Myt & operator = ( const _Type & elem ) + { + m_typeNb = which_type<_Myt,_Type>::value; + if ( m_typeNb >= 0 ) + { + new ( (void*)m_data ) _Type( elem ); + } + return *this; + } + */ + + // \ru Равенство \en Equality + bool operator == ( const _Myt & v ) const + { + if ( m_typeNb == v.m_typeNb ) + { + comparer cmp( *this ); + v.accept( cmp ); + return cmp.result; + } + return false; + } + + // \ru Равенство \en Equality + template + bool operator == ( const _Type & elem ) const + { + if ( m_typeNb == which_type<_Myt,_Type>::value ) + { + return elem == *unsafe_cast<_Type>(); + } + return false; + } + + // \ru Доступ посетителя \en Visitor access + template + void accept( const _Visitor & vis ) const + { + const_conductor::apply( vis, *this ); + } + // \ru Доступ посетителя \en Visitor access + template + void accept( const _Visitor & vis ) + { + conductor::apply( vis, *this ); + } + +private: // \ru данные \en data + char m_data[dataSize]; + int m_typeNb; + dbg_inspector<_Myt> dbg_data; +}; + +//---------------------------------------------------------------------------------------- +// +//--- +template +recursive_union::recursive_union( const Type & elem ) + : m_typeNb( 0 ) + , dbg_data() +{ + dbg_data.init( *this ); + new ( (void*)m_data ) Type( elem ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template +recursive_union::~recursive_union() +{ + release(); +} + +template +struct def_pair_union // \ru определитель рекурсивного контейнера для пары типов \en determinant of a recursive container for a pair of types +{ + typedef recursive_union value_t; +}; +template +struct def_pair_union +{ + typedef recursive_union value_t; +}; +template<> +struct def_pair_union +{ + typedef empty_variant value_t; +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru union-контейнер для экземпляра типа из определенного набора типов. + \en union-container for instance of type from a specific set of types. + \details \ru Позволяет создать тип, принимающий значения из некоторого набора разнородных + типов. + \en Allows to create a type which takes values ??from a set of heterogeneous + types. \~ +*/ +//--- +template< + class T0 + , class T1 + , class T2 = null_type + , class T3 = null_type + , class T4 = null_type + , class T5 = null_type> +class aligned_union +{ + typedef empty_variant _Tail6; + typedef typename def_pair_union::value_t _Tail5; + typedef typename def_pair_union::value_t _Tail4; + typedef typename def_pair_union::value_t _Tail3; + typedef typename def_pair_union::value_t _Tail2; + typedef typename def_pair_union::value_t _Tail1; + typedef typename def_pair_union::value_t _Variant; + + typedef aligned_union _Myt; + +public: + aligned_union(): m_data() {} + template + aligned_union( const T & elem ) : m_data( elem ) {} + +public: + /// \ru Выдать номер текущего типа, которым занят контейнер \en Get a index of the current type which is occupied container + int which() const { return m_data.which(); } + /// \ru Проверить пустой ли контейнер \en Check whether the container is empty + bool empty() const { return m_data.empty(); } + /// \ru Применить функтор (посетитель) \en Apply the functor (visitor) + template + void accept( const _Vis & vis ) const { m_data.accept( vis ); } + /// \ru Применить функтор (посетитель) \en Apply the functor (visitor) + template + void accept( const _Vis & vis ) { m_data.accept( vis ); } + /// \ru Сделать контейнер пустым \en Make an empty container + void clear() { m_data.release(); } + /// \ru Операция присвоения \en Assignment operation + _Myt & operator = ( const _Myt & elem ) { m_data = elem.m_data; return *this; } + template + _Myt & operator = ( const T & elem ) { m_data = elem; return *this; } + // \ru Операция сравнения \en Compare operation + bool operator == ( const _Myt & elem ) const { return m_data == elem.m_data; } + template + bool operator == ( const T & elem ) const { return m_data == elem; } + /// \ru Безопасно преобразовать тип контейнера к указателю \en Safely convert type of container to a pointer + template + T * safe_cast() { return m_data.template safe_cast(); } + template + const T * safe_cast() const { return m_data.template safe_cast(); } + template + bool get( T & val ) const + { + if ( const T * ptr = m_data.template safe_cast() ) + { + val = *ptr; + return true; + } + return false; + } + +private: + _Variant m_data; +}; + +//---------------------------------------------------------------------------------------- +// +// --- +template +bool is_exist( _Iterator begIt, _Iterator endIt, const _Element & elem ) +{ + return std::find( begIt, endIt, elem ) != endIt; +} + +namespace c3d +{ + struct color_label + { + color_code val; + color_label() : val( white_color ) {} + bool operator == ( color_code col ) const { return col == val; } + color_label & operator = ( color_code col ) { val = col; return *this; } + }; +//---------------------------------------------------------------------------------------- +// Диапазон итераторов +//--- +template +struct range : public std::pair +{ + typedef std::pair _Pair; + typedef typename Iterator::value_type value_type; + + range( const Iterator & iter, const Iterator & last ) :_Pair( iter, last ) {} + range( const _Pair & other ) :_Pair( other ) {} + range() :_Pair() {} + Iterator begin() { return _Pair::first; } + Iterator end() { return _Pair::second; } + bool empty() const { return _Pair::first == _Pair::second; } + size_t size() const { return (size_t)std::distance( _Pair::first, _Pair::second ); } + void clear() { _Pair::first = _Pair::second; } + //value_type & front() { return *first; } + const value_type & front() const { return *_Pair::first; } +}; + +//---------------------------------------------------------------------------------------- +// Get a range of the STL-container +//--- +template +range range_of( const _Cont & list ) +{ + range rng( list.begin(), list.end() ); + return rng; +} + +}; + +#endif // __GENERIC_UTILITY_H + +// eof diff --git a/C3d/Include/graph_algorithms.h b/C3d/Include/graph_algorithms.h new file mode 100644 index 0000000..58dcccb --- /dev/null +++ b/C3d/Include/graph_algorithms.h @@ -0,0 +1,1030 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Обобщенные алгоритмы на графах. + \en Generic graph algorithms. \~ + +*/ +/////////////////////////////////////////////////////////////////////// MA 25.10.2010 //// + +#ifndef __GRAPH_ALGORITHMS_H +#define __GRAPH_ALGORITHMS_H +// +#include +#include + +//---------------------------------------------------------------------------------------- +// +/// Пустой посетитель алгоритма обхода графа в глубину +/** + \ingroup MathGC_Algo + \attention Класс не предназначен для того, что бы применять статический + или динамический полиморфизм, т.е. не обязывает своих наследников + перегружать методы. +*/ +//--- +template +struct DefaultDFSVisitor +{ + typedef typename Graph::vertex_index vertex_index; + + /// Встретили "обратное" ребро (дуга, если орграф) dfs-дерева. + /** + Вызывается когда при посещении вершины v найдено исх.ребро, направленное к + ранее посещенной вершине. Другими словами, вершина u является предком + вершине v в dfs-дереве. + */ + void BackEdge( vertex_index /*v*/, vertex_index /*u*/, const Graph & /*g*/ ) {} + /// Вызывается, когда впервые проходим через исходящую дугу v->u, вершину u еще не посещали + void ExamineEdge( vertex_index /*v*/, vertex_index /*u*/, const Graph & /*g*/ ) {} + /// Посещение вершины: Вызывается один раз для каждой вершины, когда она впервые начинает просматриваться + void DiscoverNode( vertex_index /*v*/, const Graph & /*g*/ ) {} + /// Вершина рассмотрена: Означает, что все исходящие ребра вершины рассмотрены + void FinishNode( vertex_index /*v*/, const Graph & /*g*/ ) {} + /// Встретили "поперечное" или "прямое" ребро + /** + Вызывается, когда находим дугу, идущую к другому dfs-дереву, либо прямую дугу, + идущую к потомку того же дерева, имеющему два и более отцов. + Для поперечного ребра вызывается только для ориентированных графов. + */ + void ForwardOrCrossEdge( vertex_index /*v*/, vertex_index /*u*/, const Graph & /*g*/ ) {} + /// Отвечает, что вершина исключена из рассмотрения + bool Ignored( vertex_index /*v*/, const Graph & /*g*/ ) const { return false; } + /// Означает, что начато рассмотрение корневой вершины будущего дерева обхода + void StartNode( vertex_index /*v*/, const Graph & /*g*/ ) {} + /// Ребро стало "древесным" (принадлежит dfs-дереву). Вызывается перед переходом от посещенной вершины v к еще не посещенной вершине u + void TreeEdge( vertex_index /*v*/, vertex_index /*u*/, const Graph & /*g*/ ) {} +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// Посетитель алгоритма поиска блоков и точек сочленения в неориентированном графе +/** + Позволяет настроить алгоритм поиска блоков и точек сочленения под конкретные реализации. +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +template< class Graph > +struct DefaultBicompVisitor +{ + /// Найден блок, как последовательность ребер + template + void BlockFounded( EdgeIterator, EdgeIterator, const Graph & ) {} + + /// Обнаружена точка сочленения (articulation vertex) + template + void CutNode( Vertex, const Graph & ) {} + + /// Функция обратного вызова: Фильтрация для точек сочленения + /** + С момощью этой функции пользователь настраивает поведение алгорита поиска блоков. + Если визитер отвечает true, то алгоритм не учитывает данную вершину, + как вершину разреза, отделяющую блоки. Таким образом в результате + отфильтрованная точка сочленения всегда будет принадлежать одному блоку. + */ + template + bool IsFilteredCut( Vertex, const Graph & ) const { return false; } +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// Посетитель обхода в глубину для поиска блоков и точек сочленения +/** + Класс является автономным и не нуждается в уточнении наследованием от него. + Graph - предполагается, что это неориентированный граф. + BicompVisitor - надстроенный визитер, посетитель этого визитера, который + реализует события обнаружения блока, точки сочленения и + фильтрацию вершин, которые принудительно запрещается быть + точками сочленения. +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +template< class Graph, class BicompVisitor = DefaultBicompVisitor > +class BicompDFSVisitor: public DefaultDFSVisitor +{ +public: + typedef typename Graph::adj_iterator adj_iterator; + typedef typename Graph::edge edge; + +public: + static const typename Graph::vertex_index NO_VERTEX = (size_t)-1; + + BicompDFSVisitor( BicompVisitor & vis ) + : m_graph( NULL ) + , m_bicompVis( vis ) + , m_dfsCounter( 1 ) + , num() + , father() + , lval() + , m_stackEdges() + {} + + /// Встретили поперечное или прямое ребро + void ForwardOrCrossEdge( typename Graph::vertex_index v, typename Graph::vertex_index u, const Graph & ) + { + DEBUG_UNUSED_PARAMETER( u ); + DEBUG_UNUSED_PARAMETER( v ); + PRECONDITION( num[v] < num[u] ); + } + + /// Найдено обратное ребро dfs-дерева, вызывается когда при посещении вершины v найдено исх.ребро к ранее посещенной вершине + /** + Вершина u является предком вершине v в dfs-дереве. + */ + void BackEdge( typename Graph::vertex_index v, typename Graph::vertex_index u, const Graph & g ) + { + DEBUG_UNUSED_PARAMETER( g ); + PRECONDITION( m_graph == &g ); + PRECONDITION( num[u] < num[v] ); + PRECONDITION( father[v] != NO_VERTEX ); + if ( u != father[v] ) + { + // Здесь vu - есть обратное ребро входящее в вершину u, которая выше, чем v в d-дереве; + m_stackEdges.push_back( edge(v,u) ); // вставить ребро vu; + lval[v] = min_of( lval[v], num[u] ); // см.лемму 6; + } + } + + /// Посещение вершины: Вызывается один раз для каждой вершины, когда она впервые начинает просматриваться + void DiscoverNode( typename Graph::vertex_index v, const Graph & g ) + { + DEBUG_UNUSED_PARAMETER( g ); + C3D_ASSERT( m_graph == &g ); + PRECONDITION( num[v] == 0 ); + PRECONDITION( lval[v] == 0 ); + num[v] = lval[v] = m_dfsCounter++; + } + + /// Вершина рассмотрена: Означает, что все исходящие ребра вершины рассмотрены + void FinishNode( typename Graph::vertex_index u, const Graph & g ) + { + PRECONDITION( m_graph == &g ); + typename Graph::vertex_index v = father[u]; + if ( v == NO_VERTEX ) // СЛУЧАЙ 1: Вершина u - корневая, завершен обход fds-дерева + { + // Оценить является ли u - точкой сочленения + // Сколько раз стартовая вершина стала папой (столько же в ней стыкуется блоков) + if ( _ChildrenNb(u, g) > 1) + { + // В корневой вершине стыкуются 2 или более блоков - значит она же является и точкой сочленения + m_bicompVis.CutNode( u, g ); + } + // Извещение о найденном блоке + if ( !m_stackEdges.empty() ) // Все что есть в m_stackEdges - следует считать последним найденным блоком. + { + m_bicompVis.BlockFounded( m_stackEdges.begin(), m_stackEdges.end(), g ); + // После извещения визитера - вычищаем стек + m_stackEdges.clear(); + } + } + else // СЛУЧАЙ 2: u - не корневая вершина + { + lval[v] = min_of( lval[v], lval[u] ); // см. лемму 6; + if ( lval[u] >= num[v] ) + { + // Здесь можно получить новый блок, для чего достаточно вытолкнуть из + // стека все ребра, включая ребро vu. + + // (!) Если вершина v не корень d-дерева, то можно утверждать, что она - есть точка сочленения; + // См. теорему 8.2. + if ( father[v] != NO_VERTEX ) // если v корневая вершина, то оценки для неё делаются в конце обхода дерева + { + m_bicompVis.CutNode( v, *m_graph ); + } + + // Извещение о найденном блоке + if ( !m_bicompVis.IsFilteredCut(v,*m_graph) ) // Запрет на отфильтрованные точки сочленения - они не могут "вырезать" блоки. + { + // Тут мы запретили собирать блок, т.к. вершина фильтрованная, однако это не принесет ущерба, + // если окажется что v - не точка сочленения. Вот почему: + /* + Если v - есть корень dfs-дерева, то возможны 2 варианта: v принадлежит одному блоку, + тогда v не точка сочленения; v принадлежит двум и более блокам, тогда v - есть точка сочленения. + В первом случае единственный блок, куда включена v, будет собран в конце текущего обхода dfs-дерева, + массив m_stackEdges полностью будет содержать этот блок. Во втором случае, если блок не + единственный, то v - есть точка сочленения, тогда очевидно запрет правомерен - в конце обхода дерева все, + что осталось в стеке ребер есть один блок. + */ + + PRECONDITION( !m_stackEdges.empty() ); + /* + std::vector::reverse_iterator vuIter = + std::find( m_stackEdges.rbegin(), m_stackEdges.rend(), edge(v,u) ); // Ищем с конца + PRECONDITION( vuIter != m_stackEdges.rend() ) // Это ребро обязано быть в стеке + m_bicompVis.BlockFounded( vuIter.base()-1, m_stackEdges.end(), *m_graph ); + // После извещения визитера - вычищаем блок из стека конца + m_stackEdges.erase( vuIter.base()-1, m_stackEdges.end() ); + */ + + const edge seek( v, u ); + typename std::vector::iterator first = m_stackEdges.begin(); + typename std::vector::iterator iter, last; + for ( iter = last = m_stackEdges.end(); iter != first; ) + { + --iter; + if ( *iter == seek ) + { + break; + } + } + + PRECONDITION( *iter == seek ); // Это ребро обязано быть в стеке + m_bicompVis.BlockFounded( iter, last, *m_graph ); + // После извещения визитера - вычищаем блок из стека конца + m_stackEdges.erase( iter, last ); + } + } + } + } + + /// Означает, что начато рассмотрение корневой вершины будущего дерева обхода + void StartNode( typename Graph::vertex_index v, const Graph & g ) + { + DEBUG_UNUSED_PARAMETER( v ); + _Init( g ); + PRECONDITION( father[v] == NO_VERTEX ); + PRECONDITION( num[v] == 0 && lval[v] == 0 ); + } + + /// Заход в ребро dfs-дерева, вызывается перед переходом от посещенной вершины v к еще не посещенной вершине u + void TreeEdge( typename Graph::vertex_index v, typename Graph::vertex_index u, const Graph & g ) + { + DEBUG_UNUSED_PARAMETER( g ); + PRECONDITION( m_graph == &g ); + PRECONDITION( father[u] == NO_VERTEX ); + m_stackEdges.push_back( edge(v,u) ); // Вставить ребро vu; + father[u] = v; // зафиксируем отца для вершины u; + } + +private: + /// Количество сыновей вершины + size_t _ChildrenNb( typename Graph::vertex_index u, const Graph & g ) const + { + PRECONDITION( m_graph == &g ); + // Оценить является ли u - точкой сочленения + size_t fatherNb = 0; // Сколько раз вершина u стала папой + std::pair adjIterPair = g.AdjacentVertices( u ); + for ( ; adjIterPair.first != adjIterPair.second; ++adjIterPair.first ) + { + if ( father[*adjIterPair.first] == u ) + { + ++fatherNb; + } + } + return fatherNb; + } + + void _Init( const Graph & graph ) + { + m_graph = &graph; + const typename Graph::vertices_size_t vertNb = graph.NumVertices(); + m_dfsCounter = 1; + num.assign( vertNb, 0 ); + father.assign( vertNb, NO_VERTEX ); + lval.assign( vertNb, 0 ); + m_stackEdges.clear(); + } + +private: + const Graph * m_graph; ///< Рассматриваемый граф, для которого ищутся точки сочленения + BicompVisitor & m_bicompVis; ///< Посетитель алгоритмов этого класса + ptrdiff_t m_dfsCounter; ///< Cчетчик вершин dfs-дерева + std::vector num; ///< Нумерация порядка обхода вершин d-дерева + std::vector lval; ///< Массив значений функции L[v] на каждую вершину - см.теорию стр.166, [Asan], Лемма 6; + std::vector father;///< Отец вершины в dfs-дереве + std::vector m_stackEdges; ///< Cтек ребер для обслуживания нахождения блоков + +private: + BicompDFSVisitor & operator = ( const BicompDFSVisitor & ); +}; + +//---------------------------------------------------------------------------------------- +// Стековый элемент для алгоритма обхода в глубину. +// --- +template +struct DFSVertexInfo +{ +private: + typedef typename Graph::vertex_index vertex_index; + typedef typename Graph::adj_iterator adj_iterator; + +public: + vertex_index m_node; + adj_iterator m_iter; + adj_iterator m_last; + + DFSVertexInfo( vertex_index v, adj_iterator iter, adj_iterator last ) + : m_node( v ) + , m_iter( iter ) + , m_last( last ) + {} + + DFSVertexInfo( vertex_index v, const Graph & graph ) + : m_node( v ) + , m_iter() + , m_last() + { + tie(m_iter,m_last) = graph.AdjacentVertices( v ); + } + + DFSVertexInfo( const DFSVertexInfo & vi ) + : m_node( vi.m_node ) + , m_iter( vi.m_iter ) + , m_last( vi.m_last ) + {} + + DFSVertexInfo & operator = ( const DFSVertexInfo & vi ) + { + m_node = vi.m_node; + m_iter = vi.m_iter; + m_last = vi.m_last; + return *this; + } +}; + +//---------------------------------------------------------------------------------------- +/// Алгоритм обхода в глубину графа смежности +/** + Вычислительная сложность алгоритма практически линейная, если считать что + методы визитера выполняются за константное время. + + \param graph Граф смежности + \param vis Посетитель алгоритма +*/ +//--- + +template +void DepthFirstSearch( const Graph & graph, Visitor & vis ) +{ + typedef typename Graph::vertices_size_t vertices_size_t; + typedef typename Graph::vertex_index vertex_index; + typedef typename Graph::adj_iterator adj_iterator; + /* + enum Color // Разметка + { + col_white // не посещалась + , col_gray // в стеке + , col_black // + }; + */ + + const vertices_size_t vCount = graph.NumVertices(); + + std::vector> stack; + std::vector colourMap( vCount, white_color ); // отображение: вершина -> цвет + + // Пометить, как рассмотренные, игнорируемые вершины + for ( vertex_index xIdx = 0; xIdx(startNode,graph) ); + + while ( !stack.empty() ) + { + { + DFSVertexInfo & curr = stack.back(); + vIter = curr.m_iter; + vLast = curr.m_last; + srcNode = curr.m_node; + stack.pop_back(); + } + + while ( vIter != vLast ) + { + const vertex_index trgNode = *vIter; + ++vIter; + + vis.ExamineEdge( srcNode, trgNode, graph ); + + switch ( colourMap[trgNode] ) // Переход по дереву к следующей вершине + { + case white_color: + { + vis.TreeEdge( srcNode, trgNode, graph ); // "древесное" ребро + colourMap[trgNode] = gray_color; + stack.push_back( DFSVertexInfo( srcNode, vIter, vLast ) ); + vis.DiscoverNode( srcNode = trgNode, graph ); + tie( vIter, vLast ) = graph.AdjacentVertices( srcNode ); + break; + } + case gray_color: // Встетили обратное ребро + { + vis.BackEdge( srcNode, trgNode, graph ); + break; + } + default: // Встретили "прямое" или "кросс-ребро" в ориентированном графе + { + vis.ForwardOrCrossEdge( srcNode, trgNode, graph ); + break; + } + } + } + + // Событие завершения обхода текущей вершины + colourMap[srcNode] = black_color; + vis.FinishNode( srcNode, graph ); + } + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// Отображение реберных свойств для графов, поддерживающих концепцию смежности вершин (без явных ребер) +/** + Для графов с инцидентными ребрами лучше использовать другие типы отображений +*/ +////////////////////////////////////////////////////////////////////////////////////////// +/* +template +class EdgePropertyMap +{ + typedef Graph::vertex_descriptor vertex_descriptor; + typedef Graph::edge_descriptor edge_descriptor; + typedef std::pair pair; + class node + { + public: + node( const node & ); + node & operator = ( const node & ); + + private: + vertex_descriptor vertex; + std::vector props; + }; + + std::vector nodes; + +public: + const Prop & operator[]( edge_descriptor ) const; + Prop & operator[]( edge_descriptor ); +}; +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// Инкапсуляция алгоритма поиска 2-связных компонент и/или точек сочленения +/** + ПЛАНИРУЕТСЯ ЗАМЕНИТЬ ЭТОТ АЛГОРИТМ НА БОЛЕЕ ОБЩИЙ НО НЕ МЕНЕЕ ЭФФЕКТИВНЫЙ: + DepthFirstSearch + BicompDFSVisitor + + \par Определение + d-деревом называем ациклический подграф рассматриваеморго графа, состоящего + из вершин и ребер, которые обходит поиск в глубину, на основе которого построен + данный адгоритм. + Graph - тип, отвечающий требованиям обычного графа смежности по вершинам + + \par РЕФАКТОРИНГ + 1) Нужно обобщить это алгоритм с библиотекой MtGraph + 2) Возможно снабдить это класс-алгоритм посетителем поиска компонент. + Это, например, позволит генерировать два варианта алгоритма поиска блоков: + Вариант, когда нужно найти только вершины сочленения (без блоков) вариант, + когда нужно искать шарниры и/или блоки; + 2.1.) Возможны другие рецепты, как генерить шаблоном два похожих алгоритма. + 3) Алгоритм можно упростить, если переложить его на еще более общный + алгоритм обхода в глубину. +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +template +class MtBicompSearch +{ + // Ассоциативные типы + typedef typename Graph::vertex_index vertex_index; + typedef typename Graph::vertex_size_t vertex_size_t; + typedef typename Graph::adj_iterator adj_iterator; + +private: + const Graph & m_graph; + ptrdiff_t m_dfsCounter; + std::vector num; ///< Нумерация порядка обхода вершин d-дерева + std::vector father; ///< Отец вершины в d-дереве + std::vector lval; ///< Массив значений функции L[v] на каждую вершину - см.теорию стр.166, [Asan], Лемма 6; + std::vector m_cutnodes; ///< Обнаруженные точки сочленения + std::vector m_cutnodeProp; ///< Признак точки сочленения для вершин + +public: + MtBicompSearch( const Graph & ); + /// Найти все точки сочленения + const std::vector & SearchCutnodes(); + +private: + /// Алгоритм реккурсивного вызова поиска блоков и точек сочленения в графе + void BiComp( vertex_index ); + /// Инициализировать все рабочие данные для нового поиска + void Init(); + /// Запустить алгоритм + void Perform(); +}; + +//---------------------------------------------------------------------------------------- +// +//--- +template +MtBicompSearch::MtBicompSearch( const Graph & g ) + : m_graph( g ) + , m_dfsCounter(1) + , num() + , father() + , lval() + , m_cutnodes() + , m_cutnodeProp() +{} + +//---------------------------------------------------------------------------------------- +/// Найти все точки сочленения +//--- +template +const std::vector & MtBicompSearch::SearchCutnodes() +{ + Init(); + Perform(); + return m_cutnodes; +} + +//---------------------------------------------------------------------------------------- +/// Инициализировать все рабочие данные для нового поиска +//--- +template +void MtBicompSearch::Init() +{ + const vertex_size_t vertNb = m_graph.NumVertecies(); + m_dfsCounter = 1; + num.assign( vertNb, 0 ); + father.assign( vertNb, -1 ); + lval.assign( vertNb, -1 ); + m_cutnodeProp.assign( vertNb, false ); + m_cutnodes.clear(); +} + +//---------------------------------------------------------------------------------------- +/// Запустить алгоритм +//--- +template +void MtBicompSearch::Perform() +{ + PRECONDITION( m_cutnodes.empty() ); + + const vertex_size_t vertNb = m_graph.NumVertecies(); + for ( vertex_index startIdx = 0; startIdx adjIterPair = m_graph.AdjacentVertices( startIdx ); + for ( ; adjIterPair.first!=adjIterPair.second; ++adjIterPair.first ) + { + if ( father[*adjIterPair.first] == startIdx ) + { + ++fatherNb; + } + } + if ( fatherNb > 1 ) + { + // Корневая вершина - есть точка сочленения + PRECONDITION( !m_cutnodeProp[startIdx] ); + m_cutnodes.push_back( startIdx ); + m_cutnodeProp[startIdx] = true; + } + } + } +} + +//---------------------------------------------------------------------------------------- +/// Алгоритм реккурентного вызова поиска блоков и точек сочленения в графе +/** + Теорию см.главе 8, стр.166, Графы, матроиды, алгоритмы [Asan]; + \param vIdx - вершина (индекс), с которой начинаем поиск, которая ещё не рассмотрена, т.е. + num[vIdx] = 0; + + \par Определения + d-дерево - ациклический подграф основного подграфа, образуемого при обходе + вершин во время поиска в глубину; + + \par Вычислительная сложность + Вычислительная сложность: O(n+m), где n-кол-во вершин, m-кол-во ребер. Это следует из + того факта, что каждая вершина посещается не более одного раза. +*/ +//--- +template +void MtBicompSearch::BiComp( const vertex_index vIdx ) +{ + PRECONDITION( num[vIdx] == 0 ); + num[vIdx] = lval[vIdx] = m_dfsCounter; + ++m_dfsCounter; + + // Цикл по всем смежным вершинам vert; + std::pair adjIterPair = m_graph.AdjacentVertices( vIdx ); + for ( ; adjIterPair.first!=adjIterPair.second; ++adjIterPair.first ) + { + const vertex_index uIdx = *adjIterPair.first; // Вершина - сын в d-дереве; + // const edge_descriptor vuEdg = m_graph.GetEdge( vIdx, uIdx ); + if ( num[uIdx] == 0 ) // uIdx - сын вершины vIdx + { + // stackE.push_back( vuEdg ); // Вставить ребро vu; + PRECONDITION( father[uIdx] == -1 ); + father[uIdx] = vIdx; // зафиксируем отца для данной вершины uIdx; + BiComp( uIdx ); + + // При выходе из рекурсии значение функции L[u] уже вычислено; + lval[vIdx] = min_of( lval[vIdx], lval[uIdx] ); // см.лемму 6; + if ( lval[uIdx] >= num[vIdx] ) + { + // Здесь можно получить новый блок, для чего достаточно вытолкнуть из + // стека все ребра, включая ребро vu. + + // (!) Если вершина vIdx не корень d-дерева, то можно утверждать, что она - есть точка сочленения; + // См. теорему 8.2. + if ( father[vIdx] != -1 ) // Первородитель + { + if ( !m_cutnodeProp[vIdx] ) + { + m_cutnodes.push_back( vIdx ); + m_cutnodeProp[vIdx] = true; + } + } + /* + PRECONDITION( !stackE.empty() ) + blocks.NewComp(); + + #pragma message ( __TODO__ "(**) Собирать ребра возможно не понадобится! Достаточно cutnodes;" ) + while( !stackE.empty() ) + { + edge_descriptor edge = stackE.back(); + blocks.AddEdge( edge ); + stackE.pop_back(); // вытолкнуть ребро из стека; + if ( edge == vuEdg ) + { + break; + } + } + */ + } + } + else if ( num[uIdx] < num[vIdx] && uIdx != father[vIdx] ) + { + // Здесь vu - есть обратное ребро входящее в вершину u, которая выше, чем v в d-дереве; + // stackE.push_back( vuEdg ); // вставить ребро vu; + lval[vIdx] = min_of( lval[vIdx], num[uIdx] ); // см.лемму 6; + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Посетитель алгоритма поиска компонент сильной связности +// +////////////////////////////////////////////////////////////////////////////////////////// +struct DefaultSCVisitor +{ + // Вызывается алгоритмом перед началом обхода всего графа + template + inline void Start( const Graph & ) {} + // Вызывается, когда найден очередной компонент сильной связности в орграфе + /* + Аргументы: граф и пара вершинных итераторов, пробегающих подмножество компонента + */ + template + inline void Component( const Graph &, VertexIter, VertexIter ) {} + // Если IsFiltered = true, вершина считается исключенной из графа + template + inline bool IsFiltered( const Graph &, Vertex ) { return false; } +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +/// Алгоритм поиска компонент сильной связности в орграфе +/** + Напомним, что две вершины орграфа считаются сильно связанными, если + существует маршрут из первой вершины ко второй и обратный маршрут из второй + к первой. Подграф называется сильно связным, если любая пары его + вершин сильно связаны. Компонент сильной связности графа - это один из + его сильно сзязный подграфов G', для которого не существует сильно связной пары + вершин u и v, таких, что u-принадлежит G', а v не принадлежит G'. Другими словами, + вершины компонента сильной связости принадлежат классу взаимной достижимости вершин; + \note Алгоритм #MtStrongComponents имеет линейную сложность вычислений + \ingroup GCBase +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +template +class MtStrongComponents +{ +public: // Ассоциативные типы + typedef typename graph_traits::vertex vertex; + typedef typename graph_traits::edge edge; + typedef typename graph_traits::edge_iterator edge_iterator; + typedef typename graph_traits::vertex_iterator vertex_iterator; + +public: + MtStrongComponents( const Graph &, SCVisitor & ); + void operator() (); ///< Исполнить алгоритм поиска сильных компонентов + +private: + // DFS-алгоритм для поиска компонент сильной связности в графе ограничений + void StrongSearch( vertex, std::vector & ); + +private: + const Graph & m_diGraph; ///< Ориентированный граф + SCVisitor & m_vis; ///< Посетитель алгоритма поиска компонент сильной связности + size_t m_counter; ///< Порядок DFS-обхода + VertexPropertyMap num; ///< Вспомогательный массив порядковых номеров обхода в глубину + VertexPropertyMap lval; ///< Массив для промежуточных целочисленных вычислений + +private: + MtStrongComponents( const MtStrongComponents & ); + MtStrongComponents & operator = ( const MtStrongComponents & ); +}; + +//---------------------------------------------------------------------------------------- +// +//--- +template +MtStrongComponents::MtStrongComponents( const Graph & b_graph, Vis & vis ) + : m_diGraph( b_graph ) + , m_vis( vis ) + , num( b_graph.NumVertices() ) + , lval( b_graph.NumVertices() ) + , m_counter( 1 ) +{} + +//---------------------------------------------------------------------------------------- +// Главный алгоритм поиска компонент сильной связности в графе ограничений +//--- +template +void MtStrongComponents::operator() () +{ + m_vis.Start( m_diGraph ); + + std::vector stack; + stack.reserve( m_diGraph.NumVertices() ); + m_counter = 1; + + vertex_iterator vIter, vLast; + + for ( tie(vIter,vLast) = m_diGraph.Vertices(); vIter!=vLast; ++vIter ) + { + num[*vIter] = 0; + } + + for ( tie(vIter,vLast) = m_diGraph.Vertices(); vIter!=vLast; ++vIter ) + { + if ( num[*vIter] == 0 && !m_vis.IsFiltered(m_diGraph,*vIter) ) + StrongSearch( *vIter, stack ); + } +} + +//#define _RECURSIVE_STRONG_SEARCH 1 + +#ifdef _RECURSIVE_STRONG_SEARCH + +//---------------------------------------------------------------------------------------- +/// Алгоритм поиска компонент сильной связности в орграфе +/** + Алгоритм применяется для разбиения графа ограничений на независимо + решаемые подсистемы (сегменты). Рекурсивный вариант. Описание алгоритма приведено + в книжке Асанова по теории графов, стр.171.\n + \param vx - корневая вершина поддерева DFS + \param stack - стек рассмотренных вершин, для которых не установлена компонентная принадлежность +*/ +//--- +template +void MtStrongComponents::StrongSearch( vertex vx, std::vector & stack ) +{ + PRECONDITION( !m_vis.IsFiltered(m_diGraph,vx) ); + + num[vx] = m_counter; + lval[vx] = m_counter; + ++m_counter; + stack.push_back( vx ); + + edge_iterator eIter, eLast; // итераторы обхода инцидентных ребер + for ( tie(eIter,eLast) = m_diGraph.OutArcs(vx); eIter!=eLast; ++eIter ) + { + vertex w = m_diGraph.Target( *eIter ); // Выходящая вершина прямого ребра + PRECONDITION( w != vx ); // Граф не ориентированный !!! + if ( w != vx && !m_vis.IsFiltered(m_diGraph,w) ) // игнорируем обратное ребро из w в vx, а также отфильтрованные узлы; + { + if ( num[w] == 0 ) // - "древесная" дуга + { + StrongSearch( w, stack ); + if ( lval[w] < lval[vx] ) // При выходе из рекурсии значение l(w) должно быть уже насчитано; + lval[vx] = lval[w]; + } + else + { + const size_t wNum = num[w]; + if ( wNum < num[vx] && wNum < lval[vx] ) // - "поперечная" или "обратная" дуга + { + // Предположение: В стеке лежат вершины, из которых вершина vx достижима; + if ( std::find(stack.rbegin(), stack.rend(), w) != stack.rend() ) + { + lval[vx] = wNum; + } + } + } + } + } + + const size_t vNum = num[vx]; + if ( lval[vx] == vNum ) // vx - корневая вершина очередной компоненты сильной связности + { + // Обнаружен очередной сильный компонент + if ( !stack.empty() && num[stack.back()] >= vNum ) + { + // Посчитать размер компонента + typename std::vector::reverse_iterator vIter, vLast; + vIter = stack.rbegin(); + vLast = stack.rend(); + ptrdiff_t compSize = 0; + for ( ; vIter != vLast && num[*vIter] >= vNum; ++vIter, ++compSize ); + + // Передать диапазон компонента визитеру + typename std::vector::iterator cIter, cLast; + cIter = cLast = stack.end(); + std::advance( cIter, -compSize ); + m_vis.Component( m_diGraph, cIter, cLast ); + stack.erase( cIter, cLast ); // очистить верхушку стека + } + } +} + +#else // _RECURSIVE_STRONG_SEARCH + + +//---------------------------------------------------------------------------------------- +/// Стековый элемент для алгоритма обхода в глубину +//--- +template +struct DFS_element +{ + typedef typename Graph::vertices_size_t vertices_size_t; + typedef typename Graph::vertex vertex; + typedef typename Graph::edge_iterator edge_iterator; + + vertex node; + edge_iterator iter; + edge_iterator last; + + DFS_element( vertex v, const std::pair & pair ) + : node( v ) + , iter( pair.first ) + , last( pair.second ) + {} + + DFS_element( vertex v, const Graph & graph ) + : node( v ) + , iter() + , last() + { + tie( iter, last ) = graph.OutArcs( v ); + } + + DFS_element( const DFS_element & vi ) + : node( vi.node ) + , iter( vi.iter ) + , last( vi.last ) + {} + + DFS_element & operator = ( const DFS_element & vi ) + { + node = vi.node; + iter = vi.iter; + last = vi.last; + return *this; + } +}; + +//---------------------------------------------------------------------------------------- +/// Алгоритм поиска компонент сильной связности в орграфе +/** + Алгоритм применяется для разбиения графа ограничений на независимо-решаемые + подсистемы (сегменты). Описание алгоритма приведено в книжке Асанова по + теории графов, стр.171.\n + MA2013-02-22: Алгоритм переделан под нерекурсивный вариант; + \param rootVert - корневая вершина поддерева DFS + \param comStack - стек рассмотренных вершин, для которых не установлена компонентная принадлежность +*/ +//--- +template +void MtStrongComponents::StrongSearch( vertex rootVert + , std::vector & comStack ) +{ + typedef DFS_element DfsStackElem; + + PRECONDITION( !m_vis.IsFiltered(m_diGraph,rootVert) ); + std::vector dfsStack; + + num[rootVert] = lval[rootVert] = m_counter; + ++m_counter; + comStack.push_back( rootVert ); + dfsStack.push_back( DfsStackElem( rootVert, m_diGraph ) ); + DfsStackElem * topElem = &dfsStack.back(); + + while( !dfsStack.empty() ) // Цикл возвратов из стека (одна итерация - одно возвращение против древесного ребра ) + { + while ( topElem->iter != topElem->last ) + { + vertex w = m_diGraph.Target( *topElem->iter ); // Выходящая вершина прямого ребра + PRECONDITION( w != topElem->node ); // Граф не ориентированный !!! + if ( (w != topElem->node) && !m_vis.IsFiltered(m_diGraph,w) ) // игнорируем обратное ребро из w в vx, а также отфильтрованные узлы; + { + if ( num[w] == 0 ) // - "древесная" дуга + { + // Вместо рекурсии: StrongSearch( w, stack ); + num[w] = lval[w] = m_counter; + ++m_counter; + comStack.push_back( w ); + dfsStack.push_back( DfsStackElem(w, m_diGraph) ); + topElem = &dfsStack.back(); + continue; + } + else + { + const size_t wNum = num[w]; + if ( wNum < num[topElem->node] && wNum < lval[topElem->node] ) // - "поперечная" или "обратная" дуга + { + // Предположение: В стеке лежат вершины, из которых вершина vx достижима; + if ( std::find(comStack.rbegin(), comStack.rend(), w) != comStack.rend() ) + { + lval[topElem->node] = wNum; + } + } + } + } + ++topElem->iter; + } + + PRECONDITION( dfsStack.back().iter == dfsStack.back().last ); + PRECONDITION( topElem == &dfsStack.back() ); + + // Завершено посещение узла sElem->m_node + const size_t vNum = num[topElem->node/*vx*/]; + if ( lval[topElem->node/*vx*/] == vNum ) // vx - корневая вершина очередной компоненты сильной связности + { + // Обнаружен очередной сильный компонент + if ( !comStack.empty() && num[comStack.back()] >= vNum ) + { + // Посчитать размер компонента + typename std::vector::reverse_iterator vIter, vLast; + vIter = comStack.rbegin(); + vLast = comStack.rend(); + ptrdiff_t compSize = 0; + for ( ; vIter != vLast && num[*vIter] >= vNum; ++vIter, ++compSize ); + + // Передать диапазон компонента визитеру + typename std::vector::iterator cIter, cLast; + cIter = cLast = comStack.end(); + std::advance( cIter, -compSize ); + m_vis.Component( m_diGraph, cIter, cLast ); + comStack.erase( cIter, cLast ); // очистить верхушку стека + } + } + // Возвращение против древесного ребра , где w-просмотренная вершина, v-вершина из которой пришли в w; + { + const vertex w = topElem->node; + dfsStack.pop_back(); + + if ( !dfsStack.empty() ) + { + topElem = &dfsStack.back(); + const vertex vxPrev = dfsStack.back().node; + // При выходе из рекурсии значение lVal(w) должно быть уже насчитано; + if ( lval[w] < lval[vxPrev] ) + { + lval[vxPrev] = lval[w]; + } + } + } + } +} + +#endif // _RECURSIVE_STRONG_SEARCH + +#endif // __GRAPH_ALGORITHMS_H + +// eof diff --git a/C3d/Include/hash32.h b/C3d/Include/hash32.h new file mode 100644 index 0000000..be2eeda --- /dev/null +++ b/C3d/Include/hash32.h @@ -0,0 +1,456 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Хэш. + \en Hash. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __HASH32_H +#define __HASH32_H + +#include +#include + + +class writer; +class reader; + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Oпределение простого имени \en Definition of simple name +// +//////////////////////////////////////////////////////////////////////////////// + +// Activate to check compilation // #define SIMPLENAME_AS_CLASS + +#ifndef SIMPLENAME_AS_CLASS + +//------------------------------------------------------------------------------ +/** \brief \ru Определение простого имени. + \en Definition of simple name. \~ + \details \ru Определение простого имени. \n + \en Definition of simple name. \n \~ + \ingroup Base_Tools +*/ +// --- +typedef uint32 SimpleName; + +//------------------------------------------------------------------------------ +/** \brief \ru Сравнить простые имена. + \en Compare simple names. \~ + \ingroup Base_Tools +*/ +// --- +inline int SimpleNameCompare( const SimpleName & h1, const SimpleName & h2 ) { return ( (h1 > h2) ? 1 : ( (h1 < h2) ? -1 : 0 ) ); } + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить валидность простого имени. + \en Check the simple name correctness. \~ + \ingroup Base_Tools +*/ +// --- +inline +bool IsGoodSimpleName( const SimpleName & s ) { + return (bool)(s > 0); +} + +#else // SIMPLENAME_AS_CLASS + +// \ru При активации этой ветки обязательно собрать проект с активацией максимального уровеня предупреждений \en When this branch is activated, the project must be rebuilt with the highest level of warnings activated + +class SimpleName { +protected: + size_t body; + +public: + // \ru конструкторы \en constructors + SimpleName() : body( SYS_MAX_UINT32 ) {} + SimpleName( const SimpleName & other ) : body( SYS_MAX_UINT32 ) { body = other.body; } + SimpleName( size_t other ) : body( SYS_MAX_UINT32 ) { body = other; } + + // \ru операторы копирования \en copy operators + SimpleName & operator = ( const SimpleName & other ) { body = other.body; return *this; } + SimpleName & operator = ( size_t other ) { body = other; return *this; } + +// \ru операторы сравнения \en compare operators + bool operator == ( const SimpleName & other ) const { return Сompare( other.body ) == 0; } + bool operator != ( const SimpleName & other ) const { return Сompare( other.body ) != 0; } + bool operator > ( const SimpleName & other ) const { return Сompare( other.body ) > 0; } + bool operator >= ( const SimpleName & other ) const { return Сompare( other.body ) >= 0; } + bool operator < ( const SimpleName & other ) const { return Сompare( other.body ) < 0; } + bool operator <= ( const SimpleName & other ) const { return Сompare( other.body ) <= 0; } + + SimpleName operator + ( size_t other ) const { return SimpleName( body + (size_t)other ); } + SimpleName operator * ( size_t other ) const { return SimpleName( body * (size_t)other ); } + SimpleName & operator += ( size_t other ) { body += (size_t)other; return *this; } + SimpleName & operator *= ( size_t other ) { body *= (size_t)other; return *this; } + SimpleName & operator |= ( size_t other ) { body |= (size_t)other; return *this; } + SimpleName & operator ++ () { ++body; return *this; } // pre increment + SimpleName operator ++ ( int ) { size_t _tmp = body; ++body; return _tmp; } // post increment + + // \ru доступ к данным \en access to data + operator bool () const { return body != 0 && body != SYS_MAX_UINT32; } + operator size_t() const { return (size_t)body; } + // service + int Сompare( const SimpleName & other ) const { return Сompare( other.body ); } // return value [-1; 0; +1] +protected: + int Сompare( size_t other ) const { return ((body > other) ? 1 : ( (body < other) ? -1 : 0 )); } +protected: + friend void WriteSimpleName( writer &, const SimpleName & s ); + friend SimpleName ReadSimpleName ( reader & ); +}; + +inline int SimpleNameCompare( const SimpleName & h1, const SimpleName & h2 ) { return h1.Сompare( h2 ); } +inline bool IsGoodSimpleName( const SimpleName & s ) { return (bool)s; } +inline void SwapIT( SimpleName & a, SimpleName & b ) { SimpleName tmp = a; a = b; b = a; } + +#endif // SIMPLENAME_AS_CLASS + + +/** \addtogroup Base_Tools + \{ +*/ + +//------------------------------------------------------------------------------ +/** \brief \ru Максимально допустимое простое имя. + \en Maximum allowable simple name. \~ +*/ +//--- +const SimpleName SIMPLENAME_MAX = SYS_MAX_UINT32; + +//------------------------------------------------------------------------------ +/** \brief \ru Значение используемое, в качестве "неопределенного", еще не назначенного имени. + \en A value is used as "undefined", not yet assigned name. \~ +*/ +//--- +const SimpleName UNDEFINED_SNAME = SYS_MAX_UINT32; + +//------------------------------------------------------------------------------ +/** \brief \ru Начальное число для хэш-функции. + \en The initial value for the hash-function. \~ +*/ +// --- +const SimpleName INIT_HASH32_VAL = 31415926; + + +//------------------------------------------------------------------------------ +/** \brief \ru Золотое сечение - произвольное число для хэш-функции. + \en Golden section - an arbitrary number for hash-function. \~ +*/ +// --- +#define GOLDENRATIO 0x9e3779b9 + +/** + \} +*/ + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru hash-функция с вероятностью совпадения значений 1/(2^^32) \en hash-function with probability of values coincidence 1/(2^32) +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// \ru Обратимая 32-битная смесь для любых трёх 32-битных чисел a, b, c. \en Invertible 32-bit mixture for any three 32-bit numbers a, b, c. +// \ru Вероятность изменения значений в любом случае равна как минимум одной четвёртой. \en In any case the probability of values modification is equal to 1/4 at least. +// --- +static void mix( uint & a, uint & b, uint & c ) +{ + a -= b; a -= c; a ^= (c >> 13); + b -= c; b -= a; b ^= (a << 8 ); + c -= a; c -= b; c ^= (b >> 13); + a -= b; a -= c; a ^= (c >> 12); + b -= c; b -= a; b ^= (a << 16); + c -= a; c -= b; c ^= (b >> 5 ); + a -= b; a -= c; a ^= (c >> 3 ); + b -= c; b -= a; b ^= (a << 10); + c -= a; c -= b; c ^= (b >> 15); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш-функция. + \en Hash-function. \~ + \details \ru Хэш по последовательности байти и предыдущему хэшу. \n + Каждый бит k влияет на возвращаемое значение. \n + Функция плохо подходит для использования в криптографии. \n + k - Указатель на начало последовательности байт. \n + length - Количество байт в последовательности. \n + _c - Предыдущий hash или произвольное значение. \n + \en Hash by sequence of bytes and the previous hash. \n + Each byte k influences on the return value. \n + The function is bad for use in the cryptography. \n + k - A pointer to the beginning of the bytes sequence. \n + length - Number of bytes in the sequence. \n + _c - The previous hash or an arbitrary value. \n \~ + \return \ru Возвращает 32-битное число. + \en Returns 32-bit number. \~ + \ingroup Base_Tools +*/ +// --- +inline SimpleName Hash32( uint8 * k, size_t length, SimpleName _c = INIT_HASH32_VAL ) +{ + PRECONDITION( HiUint32( length ) == 0 ); + + // \ru Установка внутреннего значения. \en Setting of the internal value. + size_t len = length; + +#ifndef SIMPLENAME_AS_CLASS + uint c = _c; +#else // SIMPLENAME_AS_CLASS + uint c = LoUint32( (size_t)_c ); +#endif // SIMPLENAME_AS_CLASS + uint b = GOLDENRATIO; // \ru Золотое сечение (произвольное значение) \en Golden ratio (an arbitrary value) + uint a = GOLDENRATIO; // \ru Золотое сечение (произвольное значение) \en Golden ratio (an arbitrary value) + + // handle most of the key + while ( len >= 12 ) + { + a += ((uint)k[0] + ((uint)k[1]<<8) + ((uint)k[2] <<16) + ((uint)k[3] <<24)); + b += ((uint)k[4] + ((uint)k[5]<<8) + ((uint)k[6] <<16) + ((uint)k[7] <<24)); //-V112 + c += ((uint)k[8] + ((uint)k[9]<<8) + ((uint)k[10]<<16) + ((uint)k[11]<<24)); + mix ( a, b, c ); + k += 12; + len -= 12; + } + + // \ru Значение последних одиннадцати байт. \en The values of the last eleven bytes. + c += LoUint32( length ); // \ru Первый байт с резервируется для length \en The first byte c is reserved for 'length' + switch ( len ) // \ru Случаи \en Cases + { + case 11: c += ((uint)k[10]<<24); + case 10: c += ((uint)k[9] <<16); + case 9 : c += ((uint)k[8] <<8 ); + // \ru Первый байт с резервируется для length \en The first byte c is reserved for 'length' + case 8 : b += ((uint)k[7] <<24); + case 7 : b += ((uint)k[6] <<16); + case 6 : b += ((uint)k[5] <<8 ); + case 5 : b += ((uint)k[4]); //-V112 + case 4 : a += ((uint)k[3] <<24); + case 3 : a += ((uint)k[2] <<16); + case 2 : a += ((uint)k[1] <<8 ); + case 1 : a += ((uint)k[0]); + // \ru case 0: Ничего не добавляем. \en case 0: Add nothing. + } + + mix( a, b, c ); + + _c = (uint)c; + return _c; +} + + +#undef GOLDENRATIO + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш указателя. + \en Hash of the pointer. \~ + \details \ru Хэш указателя. \n + \en Hash of the pointer. \n \~ + \ingroup Base_Tools +*/ +// --- +template +SimpleName Hash32Ptr( T * k ) { return ::Hash32( reinterpret_cast(&k), sizeof(T*) ); } + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш строки. + \en Hash of the string. \~ + \details \ru Хэш строки. \n + \en Hash of the string. \n \~ + \ingroup Base_Tools +*/ +// --- +inline SimpleName HashStr( const c3d::string_t & str ) { + return ::Hash32( (uint8*)str.c_str(), str.length() * sizeof(TCHAR) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш строки. + \en Hash of the string. \~ + \details \ru Хэш строки. \n + \en Hash of the string. \n \~ + \ingroup Base_Tools +*/ +// --- +inline +SimpleName HashStr( const char * c_str ) +{ + PRECONDITION( c_str ); + return ::Hash32( (uint8*)c_str, strlen(c_str) * sizeof(char) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш строки. + \en Hash of the string. \~ + \details \ru Хэш строки. \n + \en Hash of the string. \n \~ + \ingroup Base_Tools +*/ +// --- +inline +SimpleName HashStr( const wchar_t * w_str ) +{ + PRECONDITION( w_str ); +#ifndef __MOBILE_VERSION__ + return ::Hash32( (uint8*)w_str, wcslen(w_str) * sizeof(wchar_t) ); +#else // __MOBILE_VERSION__ + uint16 * hashBuf = Ucs4ToUtf16((uint32*)w_str); + uint16 * hashBufPointer = hashBuf; + SimpleName hash = ::Hash32( (uint8*)hashBufPointer, wcslen(w_str) * 2 ); + delete[] hashBuf; + return hash; +#endif // __MOBILE_VERSION__ +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш с типом строки. + \en Hash with a string type. \~ + \details \ru Хэш с типом строки-источника. \n + Класс введен для идентификации хэша, взятого с char строки и хеша, взятого с той же wchar_t строки. + \en Hash with type of source string. \n + The class is introduced for identification of the hash taken from char of the string and from hash taken with the same wchar_t of the string. \~ + \ingroup Base_Tools +*/ +// --- +class StrHash { +public: + /// \ru Тип строки-источника имени. \en Type of the source string of name. + enum StrHashType { + htp_undef = 0, ///< \ru Тип источника неизвестен. \en The source type is unknown. + htp_char = 1, ///< \ru Тип источника char. \en The source type is char. + htp_wchar = 2 ///< \ru Тип источника wchar. \en The source type is wchar. + }; +private: + SimpleName m_val; ///< \ru Простое имя. \en Simple name. + uint8 m_type; ///< \ru Тип строки-источника имени. \en Type of the source string of name. + +public: + /// \ru Конструктор по имени и типу его происхождения. \en Constructor by name and type of its origin. + StrHash( SimpleName val, uint8 type ) + : m_val ( val ) + , m_type( type ) + {} + /// \ru Конструктор по строке. \en Constructor by string. + StrHash ( const char * str ) + : m_val ( ::HashStr(str) ) + , m_type( htp_char ) + {} + /// \ru Конструктор по строке. \en Constructor by string. + StrHash ( const wchar_t * str ) + : m_val ( ::HashStr(str) ) + , m_type( htp_wchar ) + {} + + SimpleName GetVal() const { return m_val; } ///< \ru Получить значение. \en Get the value. + uint8 GetType() const { return m_type; } ///< \ru Получить тип. \en Get type. + + int operator == ( const StrHash & with ) const; ///< \ru Оператор равенства. \en Equality operator. + int operator == ( const char * with ) const; ///< \ru Оператор равенства. \en Equality operator. + int operator == ( const wchar_t * with ) const; ///< \ru Оператор равенства. \en Equality operator. + + // \ru Чтение-запись \en Reading-writing + friend writer & operator << ( writer &, const StrHash & strHash ); ///< \ru Оператор записи. \en Write operator. + friend reader & operator >> ( reader &, StrHash & strHash ); ///< \ru Оператор чтения. \en Read operator. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш пустой строки. + \en Hash of the empty string. \~ + \details \ru Хэш пустой строки. \n + \en Hash of the empty string. \n \~ + \ingroup Base_Tools +*/ +// --- +#define NullStrHash StrHash( 0, StrHash::htp_undef ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш при отсутствии строки. + \en Hash for the string absence. \~ + \details \ru Хэш при отсутствии строки. \n + \en Hash for the string absence. \n \~ + \ingroup Base_Tools +*/ +// --- +#define UndefStrHash StrHash( -1, StrHash::htp_undef ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Хэш двух простых имен. + \en Hash of two simple names. \~ + \details \ru Хэш двух простых имен. \n + Часто встречающаяся комбинация - hash от двух SimpleName (uint32). + \en Hash of two simple names. \n + Frequently occurring combination - hash of two SimpleName (uint32). \~ + \ingroup Base_Tools +*/ +// --- +inline SimpleName Hash32SN( SimpleName k1, SimpleName k2 ) +{ + //SimpleName array[] = { k1, k2 }; + uint arr[2]; +#ifndef SIMPLENAME_AS_CLASS + arr[0] = k1; + arr[1] = k2; +#else // SIMPLENAME_AS_CLASS + arr[0] = LoUint32( (size_t)k1 ); + arr[1] = LoUint32( (size_t)k2 ); +#endif // SIMPLENAME_AS_CLASS + return ::Hash32( (uint8*)arr, 2 * sizeof(uint) ); // \ru длина - 4 * 2 = 8 \en length - 4 * 2 = 8 +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en The check for equality +//--- +inline int StrHash::operator == ( const StrHash & with ) const +{ + PRECONDITION(m_type == with.m_type); // \ru должны быть одного типа, иначе сравнение не имеет смысла \en must be of the same type, otherwise the comparison is senseless + return ::SimpleNameCompare( m_val, with.m_val ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство char строкой \en Check for equality of char by string +//--- +inline int StrHash::operator == ( const char * with ) const +{ + PRECONDITION( false ); // \ru по идее использоваться не должна \en should not be used + PRECONDITION( m_type != htp_undef ); + + // \ru Если у нас хеш с wchar_t \en If we have hash with wchar_t, + if ( m_type == htp_wchar ) // \ru то что прислали нужно перевести в wchar_t \en then the input data should be converted to wchar_t + return *this == StrHash( wcsbuf(with) ); + else + return *this == StrHash( with ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство с wchar_t строкой \en Check for equality with wchar_t by string +//--- +inline int StrHash::operator == ( const wchar_t * with ) const +{ + PRECONDITION( m_type != htp_undef ); + + // \ru Если у нас хеш с char \en If we have hash with char, + if ( m_type == htp_char ) // \ru то что прислали нужно перевести в char \en then the input data should be converted to char + return *this == StrHash( strbuf(with) ); + else + return *this == StrHash( with ); +} + + +#endif // __HASH32_H + diff --git a/C3d/Include/iges_basic.h b/C3d/Include/iges_basic.h new file mode 100644 index 0000000..d09ffea --- /dev/null +++ b/C3d/Include/iges_basic.h @@ -0,0 +1,353 @@ +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IGES_BASIC_H +#define __IGES_BASIC_H + +#include + +#include + +#define IGS_DOUBLE_TO_STRING_NDEC 15 + + +//------------------------------------------------------------------------------ +// типы IGS псевдо объектов +// --- +typedef enum { + igs_CopiousData11 = 11, + igs_MetalHatch = 31, + igs_CeramicHatch = 32, + igs_Hatch33 = 33, + igs_Hatch34 = 34, + igs_Hatch35 = 35, + igs_Hatch36 = 36, + igs_NonMetalHatch = 37, + igs_BrickHatch = 38, + igs_WitnesLine = 40, + + igs_ItArcOrCircleIGES = 100, + igs_ItContourIGES = 102, + igs_ItConicIGES = 104, + igs_ItCopiousDataIGES = 106, + igs_ItPlaneIGES = 108, + igs_ItLineSegIGES = 110, + igs_ItSplineIGES = 112, + igs_ItParametricSplineSurfaceIGES = 114, + igs_ItPointIGES = 116, + igs_ItRuledSurfaceIGES = 118, + igs_ItSurfaceOfRevolutionIGES = 120, + igs_ItTabulatedCylinderIGES = 122, + igs_ItDirectionIGES = 123, + igs_ItTransformMatrixIGES = 124, + igs_ItRationalBSplineCurveIGES = 126, + igs_ItRationalBSplineSurfaceIGES = 128, + igs_ItOffsetSurfaceIGES = 140, + igs_ItBoundaryIGES = 141, + igs_ItCurveOnParametricSurfaceIGES = 142, + igs_ItBoundedSurfaceIGES = 143, + igs_ItTrimmedParametricSurfaceIGES = 144, + igs_ItManifoldSolidBRepIGES = 186, + igs_ItPlaneSurfaceIGES = 190, + igs_ItRCCylindricalSurfaceIGES = 192, + igs_ItRCConicalSurfaceIGES = 194, + igs_ItSphericalSurfaceIGES = 196, + igs_ItToroidalSurfaceIGES = 198, + + igs_AngularDim = 202, + igs_DiamDim = 206, + igs_Text = 212, + igs_Leader = 214, + igs_LinDim = 216, + igs_RadDim = 222, + + igs_ItSubfigureIGES = 308, + igs_ItColorIGES = 314, + igs_ItBlockIGES = 402, + igs_ItPropertyIGES = 406, + igs_ItSingularSubfigureInstanceIGES = 408, + igs_ItExternalReferenceIGES = 416, + igs_ItVertexListIGES = 502, + igs_ItEdgeListIGES = 504, + igs_ItLoopIGES = 508, + igs_ItFaceIGES = 510, + igs_ItShellIGES = 514, + igs_Surface, + igs_SpaceCurve, +} IGSGConverterType; + + +//----------------------------------------------------------------------------- +// +// --- +typedef enum { // секция + UndefSection, + FlagSection, // not always present + StartSection, + GlobalSection, + DirectoryEntrySection, + ParametrDataSection, + TerminateSection +} NameSectionIGES; + +#define LENGTH_STRING_FILE 80 +#define LENGTH_STRING_IGES 72 + +#define IGS_WIDTH 1000 // число градаций толщины + +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS 58 +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS_GOST 6 +//#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS1001 30 +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS1001 29 +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS1002 34 +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS1003 32 +#define LENGTH_ARRAY_IGES_SPEC_SYMBOLS800 7 + + +#define IGS_BLOCK_GROUP 1 // + форма блока 1 +#define IGS_BLOCK_GROUP_WO_BACK_POINTERS 7 // + форма блока 7 - без обратных указателей + +#define IGS_DOUBLE_UNDEF -1e32 // + +#define ENTITY_LABEL_COUNT 8 ///< Длина поля entityLabel + +#define VDE_VISIBLE_YES 0 ///< Объект видим +#define VDE_VISIBLE_NO 1 ///< Объект невидим + +#define VDE_DEPEND_NO 0 ///< Объект независим +#define VDE_DEPEND_PHYS 1 ///< Объект зависим физически +#define VDE_DEPEND_LOG 2 ///< Объект зависим логически +#define VDE_DEPEND_BOTH 3 ///< Зависим физически и логически + +#define VDE_USE_GEOMETRY 0 ///< Объект геометрический +#define VDE_USE_ANNOT 1 ///< Объект аннотационный +#define VDE_USE_DEF 2 ///< Объект определение +#define VDE_USE_OTHER 3 ///< Объект вне классификации +#define VDE_USE_LOG_POS 4 ///< Объект логический / позиционирование +#define VDE_USE_2D_PARAM 5 ///< Объект параметрический 2D +#define VDE_USE_CONSTR_GM 6 ///< Объект конструктивной геометрии + +#define VDE_HIER_TOP_DOWN 0 ///< Сверху вниз +#define VDE_HIER_GLOB_DEFER 1 ///< Глобально +#define VDE_HIER_PROPERTY 2 ///< Свойство + + +//------------------------------------------------------------------------------- +// +// --- +struct VectorDE{ + unsigned short visible : 1;// 9 вектор состояния + unsigned short depend : 2;// 9 + unsigned short geometry : 3;// 9 + unsigned short hierarchy : 2;// 9 +}; + + +//----------------------------------------------------------------------------- +// +// --- +struct DirEntryParameter { +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// горячо рекомендую все изменения в структуре согласовывать с процедурой чтения +// ProcessingOneEntityDirEntrySection(), иначе есть очень реальный шанс все порушить, +// еще рекомендую крепко подумать, прежде чем делать виртуальные функции и наследников +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + int32 typeNumber; // 1 номер типа +// поле typeNumber должно идти первым - см. функцию Init этой структуры +// !!!!!!!!!!!!!!!!!!!! + ptrdiff_t numbParDataString; // 2 номер строки данных в секции Parametr Data + ptrdiff_t structure; // 3 инвертированный указатель на на строку в секции DirEntry обычно 0 + ptrdiff_t lineFontPattern; // 4 номер стандартного типа линии или указатель на строку с описанием нестандартного + ptrdiff_t level; // 5 номер слоя или указатель на строку с описанием слоя в секции DirEntry + ptrdiff_t view; // 6 указатель на строку с описанием вида в секции DirEntry + ptrdiff_t transformMatrix; // 7 указатель на строку с описанием матрицы преобразования в секции DirEntry + ptrdiff_t labelDisplayAssociativ;// 8 указатель на строку с ???? в секции DirEntry + // 9 вектор состояния + union { + VectorDE def; + unsigned short vector; + }; + ptrdiff_t numbString; // 10 номер строки + ptrdiff_t lineWeight; // 12 - 11 пропущен - градация толщины + ptrdiff_t color; // 13 номер цвета или указатель на строку с описанием цвета + ptrdiff_t lineCount; // 14 число строк под описание параметров в секции Parametr Data + int32 formNumber; // 15 + std::string entityLabel; // 18 метка + // SpAG K14 BUG_65022 - избавляемся от низкоуровневых абстракций + ptrdiff_t numerLabel; // 19 числовая метка + + DirEntryParameter( int32 type = 0 ): typeNumber( type ), numbParDataString( 0 ), structure( 0 ), lineFontPattern( 0 ), level( 0 ), + view( 0 ), transformMatrix( 0 ), labelDisplayAssociativ( 0 ), numbString( 0 ), lineWeight( 0 ), + color( 0 ), lineCount( 0 ), formNumber( 0 ), entityLabel( ENTITY_LABEL_COUNT, ' ' ), numerLabel( 0 ) { Init(); } // SpAG K13 SP1 анализаторы кода + + void Init() { + // SpAG - С точки зрения cppCheck должно быть гораздо более пристойно + def.visible = VDE_VISIBLE_YES; + def.depend = VDE_DEPEND_NO; + def.geometry = VDE_USE_DEF; + def.hierarchy = VDE_HIER_TOP_DOWN; + } + + void operator = ( const DirEntryParameter & o ) { + typeNumber = o.typeNumber; + numbParDataString = o.numbParDataString; + structure = o.structure; + lineFontPattern = o.lineFontPattern; + level = o.level; + view = o.view; + transformMatrix = o.transformMatrix; + labelDisplayAssociativ = o.labelDisplayAssociativ; + numbString = o.numbString; // BUG_71099 + lineWeight = o.lineWeight; + color = o.color; + lineCount = o.lineCount; + formNumber = o.formNumber; + entityLabel = o.entityLabel; // SpAG K14 BUG_65022 + numerLabel = o.numerLabel; + vector = o.vector; + } + + void Zero() { + typeNumber = 0; + numbParDataString = structure = lineFontPattern = level = view = transformMatrix = labelDisplayAssociativ = numbString = lineWeight = color = lineCount = numerLabel = 0; + formNumber = 0; + vector = 0; + entityLabel.assign( ENTITY_LABEL_COUNT, ' ' ); + } + + bool operator == ( DirEntryParameter & o ) const { return numbString == o.numbString; } + bool operator < ( DirEntryParameter & o ) const { return numbString < o.numbString; } +}; + + +//----------------------------------------------------------------------------- +// Данные общей секции. +// --- +struct GlobalSectionParameter { + int32 delimiter; // ограничитель параметров 1 + int32 recordDelimiter; // ограничитель записей 2 + std::string identifSendingSystem; // версия системы откуда 3 + std::string fileName; // 4 + std::string systemID; // идентификатор системы откуда 5 + std::string verPreProc; // версия препроцессора( на хрен она упала?) 6 + int32 numbBitsOnInt; // разрядность целого откуда 7 + int32 maxPowerFloat; // максимальная степень float откуда 8 + int32 numbSignFloat; // число значащих цифр float откуда 9 + int32 maxPowerDouble; // максимальная степень double откуда 10 + int32 numbSignDouble; // число значащих цифр double откуда 11 + std::string identifReceivngSystem;// версия системы куда 12 + double scale; // масштаб 13 + int32 unitFlag; // 14 1- дюймы 2 -мм 3- 4 -футы 5 -мили 6 -м 7 -км 8 -милидюймы 9- мкм 10- см 11 - микродюйм + std::string nameUnit; // 15 + int32 maxNumberOfLineWeightGrad; // 16 + double widthOfMaxLineWeight; // 17 + std::string dateAndTime; // 18 YYMMMDD.HHNNSS + double minResolution; // 19 - мин. разрешение системы + double maxAbsCoord; // 20 максимальное координата по модулю + std::string nameOfAuthor; // 21 автор + std::string authorsOrg; // 22 организация + int32 intVer; // 23 + int32 intDraftStandart; // 24 + std::string dateAndTimeMod; // 25 YYMMMDD.HHNNSS + + GlobalSectionParameter () { Init(); } + void Init() { + delimiter = ','; // ограничитель параметров 1 + recordDelimiter = ';'; // ограничитель записей 2 + identifSendingSystem = " "; // версия системы откуда 3 + fileName = " "; // 4 + systemID = " "; // идентификатор системы откуда 5 + verPreProc = " "; // версия препроцессора( на хрен она упала?) 6 + numbBitsOnInt = 32; // разрядность целого откуда 7 //-V112 + maxPowerFloat = 38; // максимальная степень float откуда 8 + numbSignFloat = 6; // число значащих цифр float откуда 9 + maxPowerDouble = 307; // максимальная степень double откуда 10 + numbSignDouble = 15; // число значащих цифр double откуда 11 + identifReceivngSystem = " "; // версия системы куда 12 + scale = 1.0; // масштаб 13 + unitFlag = 2; // 14 1- дюймы 2 -мм 3- 4 -футы 5 -мили 6 -м 7 -км 8 -милидюймы 9- мкм 10- см 11 - микродюйм + nameUnit = "MM"; // 15 + maxNumberOfLineWeightGrad = IGS_WIDTH;// 16 + widthOfMaxLineWeight = 1; // 17 + dateAndTime = ""; // 18 YYMMMDD.HHNNSS + minResolution = 0.001; // 19 - мин. разрешение системы + maxAbsCoord = 10000; // 20 максимальное координата по модулю + nameOfAuthor = " "; // 21 автор + authorsOrg = " "; // 22 организация + intVer = 0/*3*/; // 23 + intDraftStandart = 0; // 24 + dateAndTimeMod = " "; // 25 + } +}; + + +//------------------------------------------------------------------------------- +// структура для формирования отчета о записи в IGES +// --- +struct ReportEntity { + int32 kompasResNumHigh; // номер в ресурсе строки наименования того, что пришло из Компаса + int32 kompasResNumBase; // номер в ресурсе строки наименования подложки, которая пришла из Компаса + ptrdiff_t igesResNum; // номер в ресурсе строки наименования того, чем записали в IGES + ReportEntity( ptrdiff_t _igesResNum = 0 ) + : kompasResNumHigh( 0 ) + , kompasResNumBase( 0 ) + , igesResNum( _igesResNum ) + {} +}; + + +//------------------------------------------------------------------------------- +/// Базовый класс для IGES объектов +// --- +class CONV_CLASS BasicIGES { +public : + ptrdiff_t numStr; ///< место хранения - номер строки в секции DE + union { + VectorDE def; + unsigned short vector; + }; + ptrdiff_t color; + ptrdiff_t level; + ptrdiff_t matrix; + ptrdiff_t form; + ReportEntity report; + +private: + ptrdiff_t numType; // номер типа + +public : + BasicIGES( ptrdiff_t _numType, ptrdiff_t _form = 0 ) + : numStr (0) + , vector (0) + , color (0) + , level (0) + , matrix (0) + , form ( _form ) + , report ( _numType ) + , numType( _numType ) + {} + + BasicIGES( const BasicIGES & o ) + : numStr ( o.numStr ) + , vector ( o.vector ) + , color ( o.color ) + , level ( o.level ) + , matrix ( o.matrix ) + , form ( o.form ) + , report ( o.numType ) + , numType( o.numType ) + {} + + virtual ~BasicIGES() {} + + bool Less( const BasicIGES & o ) const { return numType < o.numType ? true : numType > o.numType ? false : form < o.form ? true : form > o.form ? false : matrix < o.matrix;} + bool Eq ( const BasicIGES & o ) const { return numType == o.numType && form == o.form && matrix == o.matrix;} + const ptrdiff_t GetTypeIGES() const { return numType; } + const ptrdiff_t GetFormIGES() const { return form; } + virtual bool operator == ( const BasicIGES & o ) const { return Eq( o ); } + virtual bool operator < ( const BasicIGES & o ) const { return Less( o ); } +}; + + +#endif // __IGES_BASIC_H diff --git a/C3d/Include/iges_structure.h b/C3d/Include/iges_structure.h new file mode 100644 index 0000000..91a6708 --- /dev/null +++ b/C3d/Include/iges_structure.h @@ -0,0 +1,535 @@ +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IGES_STRUCTURES_H +#define __IGES_STRUCTURES_H + + +#include +#include +#include +#include "iges_basic.h" + + +//------------------------------------------------------------------------------- +// функции сравнения двух наследников от BasicIGES, которые не содержат +// динамических данных +// --- +template +inline bool Eq( const Type * t, const BasicIGES & o ) { + if ( !t->Eq( o ) ) + return false; + + const Type * r = dynamic_cast(&o); + if ( !r ) + return false; + + return ::IsEqualSArrayItems( t, r ); +} + + +//------------------------------------------------------------------------------- +// функции сравнения двух наследников от BasicIGES, которые не содержат +// динамических данных +// --- +template +inline bool Less( const Type * t, const BasicIGES & o ) { + if ( !t->Eq( o ) ) + return t->Less( o ); + + const Type * r = dynamic_cast(&o); + if ( !r ) + return false; + + return ::IsLessThanSArrayItems( t, r ); +} + + +//------------------------------------------------------------------------------- +// структура для сохранения типов линий +// --- +struct CONV_CLASS LTypeNameIGES { + uint16 number; // номер стиля в чертеже C3D + ptrdiff_t colorOrStr; // цвет или номер строки цвета в файле IGES + ptrdiff_t width; // толщина линии на бумаге * 1000 + ptrdiff_t numOrStr; // номер IGES-типа линии или номер строки типа в файле IGES + + LTypeNameIGES() : number(0), colorOrStr( 0 ), width(1), numOrStr(0){} + + bool operator == (const LTypeNameIGES & o) const { return number == o.number; } + bool operator < (const LTypeNameIGES & o) const { return number < o.number; } + + void Assign( const LTypeNameIGES & o ); +}; + + +//------------------------------------------------------------------------------- +// структура цвета и места его хранения +// --- +struct CONV_CLASS ColorIGES : public BasicIGES { + int32 trueColor; + + ColorIGES( int32 _color = 0 ); + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef ColorIGES * PCOLORIGES; +typedef const ColorIGES * PCCOLORIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCCOLORIGES &obj1, const PCCOLORIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< ColorIGES const* > ( ColorIGES const* const& obj1, ColorIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------ +// +// --- +struct CONV_CLASS ColourIGES : public BasicIGES { + double red, green, blue; + + ColourIGES( double, double, double ); +}; + + +//------------------------------------------------------------------------------- +// точка +// --- +struct CONV_CLASS PointIGES : public BasicIGES { + double x, y, z; + + PointIGES( double _x, double _y, double _z ); + PointIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef PointIGES * PPOINTIGES; +typedef const PointIGES * PCPOINTIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCPOINTIGES &obj1, const PCPOINTIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< PointIGES const* > ( PointIGES const* const& obj1, PointIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// базовый curve примитив +// --- +struct CONV_CLASS BasicCurveIGES : public BasicIGES { + LTypeNameIGES lt; // стиль + BasicCurveIGES( int32 _numType, int32 _form = 0 ) : BasicIGES( _numType, _form ), lt(){} +}; + + +//------------------------------------------------------------------------------- +// структура отрезка +// --- +struct CONV_CLASS LineSegIGES : public BasicCurveIGES { + double x1, y1, z1; // координаты 1 точки + double x2, y2, z2; // координаты 2 точки + + LineSegIGES(); + + LineSegIGES( double x1, double y1, double z1, // 3D + double x2, double y2, double z2 ); + LineSegIGES( double x1, double y1, // 2D + double x2, double y2 ); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// структура дуги и окружности +// --- +struct CONV_CLASS ArcOrCircleIGES : public BasicCurveIGES { + double dir; // напрвление + double xc, yc; // координаты центра + double x1, y1; // координаты 1 точки + double x2, y2; // координаты 2 точки + + ArcOrCircleIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// 104 IGS_CONIC_ARC коническая кривая ( эллипс, гипербола, парабола ) +// --- +struct CONV_CLASS EllipsIGES : public BasicCurveIGES { + double A, B, C, D, E, F, X1, Y1, X2, Y2, ZT; + + EllipsIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef EllipsIGES * PELLIPSIGES; +typedef const EllipsIGES * PCELLIPSIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCELLIPSIGES &obj1, const PCELLIPSIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< EllipsIGES const* > ( EllipsIGES const* const& obj1, EllipsIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// структура элемента текста +// --- +struct CONV_CLASS TextItemIGES { + double width; // ширина + double height; // высота + int32 fontCode; // код шрифта + double angleChar; // угол наклона букв + double angleStr; // угол наклона строки + int32 flagMirror;// флаг зеркальности + int32 horizont; // 0 - отсчет от горизонали 1 - от вертикали + double x, y, z; // координаты + std::string text; // текст + + TextItemIGES(); + + bool operator == ( const TextItemIGES & o ) const; + bool operator < ( const TextItemIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// структура текста +// --- +struct CONV_CLASS TextIGES : public BasicIGES { + PArray arr; + + TextIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef TextIGES * PTEXTIGES; +typedef const TextIGES * PCTEXTIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCTEXTIGES &obj1, const PCTEXTIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< TextIGES const* > ( TextIGES const* const& obj1, TextIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// 123 IGS_DIRECTION - вектор +// --- +struct CONV_CLASS DirectionIGES: public BasicIGES { + double x, y, z; + + DirectionIGES( double _x, double _y, double _z ); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef DirectionIGES * PDIRECTIONIGES; +typedef const DirectionIGES * PCDIRECTIONIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCDIRECTIONIGES &obj1, const PCDIRECTIONIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< DirectionIGES const* > ( DirectionIGES const* const& obj1, DirectionIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// 124 матрица трансформации +// --- +struct CONV_CLASS MatrixIGES : public BasicIGES { + SArray matr; + MatrixIGES(); + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// 126 IGS_RATIONAL_B_SPLINE_CURVE +// --- +struct CONV_CLASS RationalBSplineCurveIGES : public BasicCurveIGES { + ptrdiff_t upperIndexSum; // верхний индекс суммы + ptrdiff_t degree; // степень базовой функции + int32 planar; // 0 - пространственная 1 - плоская + int32 closed; // 1 - замкнутая 0 - незамкнутая + int32 polynominal; // 1 - Polynominal + // 0 - Rational + int32 periodic; // 1 - Периодическая + // 0 - Непериодическая +// Значения последовательностей узлов + SArray sequence; // значения от -degree до 1 + upperIndexSum + + // массив весовых коэффициентов размером 1 + upperIndexSum + SArray weight; + // массив координат контрольных точек размером 1 + upperIndexSum + SArray x; + SArray y; + SArray z; + double u0, u1; // начальное и конечное значение параметрических координат + double xNorm, yNorm, zNorm; + + RationalBSplineCurveIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// стрелка( или линия выноски ) IGS_LEADER +// --- +struct CONV_CLASS LeaderIGES : public BasicCurveIGES { + double arrowLen; // длина стрелки IGS_LENGTH_ARROW + double arrowWidth;// ширина стрелки IGS_WIDTH_ARROW + double zDepth; // глубина по z + // координаты стрелки + double xHead, yHead; + // координаты конца линии + SArray x; + SArray y; + int formArrow; // 0,4 никакой 1,2,3,11 обычная стрелка 9,10 засечка 5,6,7,8 точка + + LeaderIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef LeaderIGES * PLEADERIGES; +typedef const LeaderIGES * PCLEADERIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCLEADERIGES &obj1, const PCLEADERIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< LeaderIGES const* > ( LeaderIGES const* const& obj1, LeaderIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// вспомогательная линия +// --- +struct CONV_CLASS WitnessLineIGES : public BasicCurveIGES { + int32 interpretFlag; + double z; // displacement + // координаты конца линии N >= 3 и нечетное + SArray x; + SArray y; + + WitnessLineIGES(); + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef WitnessLineIGES * PWITNESSLINEIGES; +typedef const WitnessLineIGES * PCWITNESSLINEIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCWITNESSLINEIGES &obj1, const PCWITNESSLINEIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< WitnessLineIGES const* > ( WitnessLineIGES const* const& obj1, WitnessLineIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// структура линейного размера +// --- +struct CONV_CLASS LinDimensionIGES : public BasicIGES { + int32 text; // указатель на текст + int32 firstArrow; // первая стрелка( половина размерной линии ) + int32 secondArrow; // вторая стрелка( половина размерной линии ) + int32 firstLine; // первая выносная линия + int32 secondLine; // вторая выносная линия + LinDimensionIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef LinDimensionIGES * PLINDIMENSIONIGES; +typedef const LinDimensionIGES * PCLINDIMENSIONIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCLINDIMENSIONIGES &obj1, const PCLINDIMENSIONIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< LinDimensionIGES const* > ( LinDimensionIGES const* const& obj1, LinDimensionIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// структура диаметрального размера +// --- +struct CONV_CLASS DimDimensionIGES : public BasicIGES { + int32 text; // указатель на текст + int32 firstArrow; // первая стрелка( половина размерной линии ) + int32 secondArrow; // вторая стрелка( половина размерной линии ) + double x, y; + DimDimensionIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef DimDimensionIGES * PDIMDIMENSIONIGES; +typedef const DimDimensionIGES * PCDIMDIMENSIONIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCDIMDIMENSIONIGES &obj1, const PCDIMDIMENSIONIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< DimDimensionIGES const* > ( DimDimensionIGES const* const& obj1, DimDimensionIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// структура диаметрального размера +// --- +struct CONV_CLASS RadDimensionIGES : public BasicIGES { + int32 text; // указатель на текст + int32 arrow; // первая стрелка( половина размерной линии ) + double x, y; + RadDimensionIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef RadDimensionIGES * PRADDIMENSIONIGES; +typedef const RadDimensionIGES * PCRADDIMENSIONIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCRADDIMENSIONIGES &obj1, const PCRADDIMENSIONIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< RadDimensionIGES const* > ( RadDimensionIGES const* const& obj1, RadDimensionIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +//------------------------------------------------------------------------------- +// структура углового размера +// --- +struct CONV_CLASS AngDimensionIGES : public BasicIGES { + int32 text; // указатель на текст + int32 firstLine; // первая выносная линия + int32 secondLine; // вторая выносная линия + double x, y, r; + int32 firstArrow; // первая стрелка( половина размерной линии ) + int32 secondArrow; // вторая стрелка( половина размерной линии ) + AngDimensionIGES(); + + virtual bool operator == ( const BasicIGES & o ) const; + virtual bool operator < ( const BasicIGES & o ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +typedef AngDimensionIGES * PANGDIMENSIONIGES; +typedef const AngDimensionIGES * PCANGDIMENSIONIGES; + + +//------------------------------------------------------------------------------- +// +// --- +#ifdef _MSC_VER // C3D_WINDOWS +inline bool IsLessThanSArrayItems ( const PCANGDIMENSIONIGES &obj1, const PCANGDIMENSIONIGES &obj2 ) { return obj1 < obj2; } +#else // C3D_WINDOWS +template<> bool IsLessThanSArrayItems< AngDimensionIGES const* > ( AngDimensionIGES const* const& obj1, AngDimensionIGES const* const& obj2 ); +#endif // C3D_WINDOWS + + +#endif // __IGES_STRUCTURES_H diff --git a/C3d/Include/iges_write.h b/C3d/Include/iges_write.h new file mode 100644 index 0000000..5c4b9ad --- /dev/null +++ b/C3d/Include/iges_write.h @@ -0,0 +1,215 @@ +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IGES_WRITE_H +#define __IGES_WRITE_H + + +#include "iges_basic.h" +#include +#include + + +class ostream; +struct CONV_CLASS ColourIGES; +struct IGESData; +struct DirEntryParameter; // запись в DE +class CONV_CLASS BasicIGES; +struct CONV_CLASS BasicCurveIGES; +struct CONV_CLASS LTypeNameIGES; // структура для сохранения типов линий +struct CONV_CLASS TextItemIGES; // структура элемента текста + + +//------------------------------------------------------------------------------- +// +// --- +class CONV_CLASS IWIGES { +// тип функции - записи какого-то элемента - создан для передачи в параметрах +public: + typedef ptrdiff_t (IWIGES::*WriteEntityFunc)( BasicIGES & ); +private: + IGESData * data; + +public : + IWIGES( std::ostream & _os ); + ~IWIGES(); + + // добавить к строке преобразованый к строке и дополненый до 8 символов пробелами int32 + size_t AddLongToString( int32 l, char ch1 = 0 ); +#if defined(PLATFORM_64) + size_t AddLongToString( ptrdiff_t l, char ch1 = 0 ); +#endif // PLATFORM_64 + + // Преобразовать строковую константу к строковой константе IGES + std::string & AddString( std::string & s, std::string & d, std::string & delimiter ); + // Преобразовать double к строковой константе IGES + std::string & AddDouble( double d, std::string & s, std::string & delimiter ); + // Преобразовать int32 к строковой константе IGES + std::string & AddLong( int32 l, std::string & s, std::string & delimiter ); +#if defined(PLATFORM_64) + std::string & AddLong( ptrdiff_t l, std::string & s, std::string & delimiter ); +#endif // PLATFORM_64 + + // добавить к строке выовода другую строку, если длина превышает критическую + // вывести строку, обнулить ее и добавить к ней остаток. Если стоит флаг вывода - + // вывести остаток и обнулить строку + // применяется для глобальной секции и секции комментария + bool AddValToStrAndOut( std::string & outS, // добавляемая строка + ptrdiff_t & numStr, // номер строки в секции + char section, // символ секции + bool out = false );// флаг вывода + + + // добавить к строке выовода секции PD другую строку, если длина превышает критическую + // вывести строку, обнулить ее и добавить к ней остаток. Если стоит флаг вывода - + // вывести остаток и обнулить строку + ptrdiff_t AddValToStrAndOutPD( std::string & outS, + bool divide, // строку можно разделять, числа - нежелательно + bool out ); + // вывести в секцию PD int32 после него запятая + ptrdiff_t WriteLong( int32 v ); +#if defined(PLATFORM_64) + ptrdiff_t WriteLong( ptrdiff_t v ); +#endif // PLATFORM_64 + // вывести в секцию PD double после него запятая + ptrdiff_t WriteDouble( double v ); + // вывести в секцию PD х, Y, и z. после каждого запятая + ptrdiff_t WriteXY0ZPD( double x, double y, double z = 0 ); + // вывести в секцию PD х, y. после каждого запятая + ptrdiff_t WriteXYPD( double x, double y ); + // вывести в секцию PD дополнительные нулевые указатели, в конце - ";" + ptrdiff_t WriteAddNULLPointerPD(); + // Ищет такую структуру в массиве записанных в IGES стркутур. Если находит + // - уничтожает присланное и возвращает номер найденного, если нет - возвращает + // 0, в случае ошибки - возвращает -1 + ptrdiff_t FindOrAddBasicIGES( BasicIGES * b ); + // запись примитива. в параметре - процедура записи этого примитива и его структура. + // перед записью производится проверка - нет ли уже такой и если есть - присланная + // структура уничтожается, если нет - запускается процедура записи, + // возвращается номер строки DE + ptrdiff_t WriteEntity( WriteEntityFunc func, BasicIGES * ); + // подготовка к записи - применять в паре с функцией FinishRecord - только + // для записей, где не нужен стиль линии, уровень и номер формы + // возвращает запомненый указатель- начало записи в PD + ptrdiff_t PrepareRecord( BasicIGES & bi ); + // завершение записи - применять в паре с функцией PrepareRecord - только + // для записей, где не нужен стиль линии + // возвращает номер строки- начало записи в DE + ptrdiff_t FinishRecord( BasicIGES & bi ); + // завершение записи - применять в паре с функцией PrepareRecord - только + // для записей, где НУЖЕН стиль линии + // возвращает номер строки- начало записи в DE + ptrdiff_t FinishCurveRecord( BasicCurveIGES & bi ); + void ClearBuffer(); + + // заполнить структуру глобальной секции и секции комментария + ptrdiff_t Global( const c3d::path_string & fileName, + const double & gabarit, + const std::string & documentName, // Название документа + const std::string & author, + const std::string & organization, + const std::string & productComments, + double lenUnits ); + // Запись завершения в файл IGES + void Terminate(); + + // инициализировать DE + DirEntryParameter & InitDirEntry( ptrdiff_t type, + ptrdiff_t numPD, + ptrdiff_t level, + ptrdiff_t numForm, + ptrdiff_t color, + ptrdiff_t matrix, + unsigned short vectorDE ); + // инициализировать геом. DE + DirEntryParameter & InitCurveDirEntry( ptrdiff_t type, + ptrdiff_t numPD, + ptrdiff_t level, + LTypeNameIGES & lt, + ptrdiff_t numForm, + ptrdiff_t matrix, + unsigned short vectorDE ); + // сформировать запись 2х строк DirEntry + bool DirEntry( DirEntryParameter & de ); + + // записать цвет + ptrdiff_t Color( BasicIGES * color ); + ptrdiff_t Colour( ColourIGES & ); + + // вернуть структуру типа линии из массива + ptrdiff_t GetTypeLine ( ptrdiff_t num, LTypeNameIGES & lt ); + // найти номер структуры типа линии в массиве + ptrdiff_t FindTypeLine( LTypeNameIGES & lt ); + // добавить структуру типа линии в массив + LTypeNameIGES * AddTypeLine ( LTypeNameIGES & lt ); + + // вернуть буферную строку + std::string & BuffStr (); + // разделитель + std::string & Delimiter(); + // разделитель в записях + std::string & RecordDelimiter(); + + // число строк в записи + ptrdiff_t GetCountRowInRec(); + // запомнить и обнулить число строк в записи + void KeepInMindAndResetCountRowInRec(); + // восстановить число строк в записи + void RestoreCountRowInRec(); + // обнулить число строк в записи + void ResetCountRowInRec(); + + // счетчик строк секции DE + ptrdiff_t GetCountStringDE(); + + // счетчик строк секции PD + ptrdiff_t GetCountStringPD(); + + // вернуть массив пар номеров ресурса строк ( названия в Компасе и в IGES ) для формирования отчета +// void GetReport( int32 *& report, int & size ); + + // вернуть имя файла из которого пишется + std::string & GetSourceFileName(); + + // сброс геометрии + + // вектор + ptrdiff_t Direction( BasicIGES & ); + // матрица трансформации + ptrdiff_t Matrix( BasicIGES & ); + // Точка + ptrdiff_t Point( BasicIGES & p ); + // Отрезок + ptrdiff_t LineSeg( BasicIGES & ls ); + // Окружность + ptrdiff_t ArcOrCircle( BasicIGES & acs ); + // 104 IGS_CONIC_ARC коническая кривая ( эллипс, гипербола, парабола ) + ptrdiff_t Ellipse( BasicIGES & ); + // 126 IGS_RATIONAL_B_SPLINE_CURVE + ptrdiff_t RationalBSplineCurve( BasicIGES & b ); + // Элемент текста + void TextItem( TextItemIGES & ti ); + // Текст + ptrdiff_t Text( BasicIGES & t ); + // стрелка( или линия выноски ) IGS_LEADER + ptrdiff_t Leader( BasicIGES & l ); + // вспомогательная линия + ptrdiff_t WitnessLine( BasicIGES & w ); + // линейный размер + ptrdiff_t LinDimension( BasicIGES & b ); + // диаметральный размер + ptrdiff_t DimDimension( BasicIGES & b ); + // радиальный размер + ptrdiff_t RadDimension( BasicIGES & b ); + // угловой размер + ptrdiff_t AngDimension( BasicIGES & b ); + // номер строки DE записанного примитива + ptrdiff_t GetLastDE(); +private: + // записать глобальную секцию + ptrdiff_t WriteGlobal(); +}; + + +#endif // __IGES_WRITE_H diff --git a/C3d/Include/instance.h b/C3d/Include/instance.h new file mode 100644 index 0000000..e608a0e --- /dev/null +++ b/C3d/Include/instance.h @@ -0,0 +1,185 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вставка объекта. + \en Instance of object. \~ + \details \ru Вставка объекта геометрической модели MbItem в локальной системе координат MbPlacement3D + позволяет накладывать геометрические ограничения на объект в сборке и позиционоровать объект. + Вставка не может содержать другую вставку. \n + \en The instance of geometric model MbItem object in local coordinate system MbPlacement3D + allows to define constraints for an object in the assembly and to locate the object. + The instance cannot contain another instance. \n \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __INSTANCE_H +#define __INSTANCE_H + +#include +#include + + +class MATH_CLASS MbSolid; +class MATH_CLASS MbInstance; +class MATH_CLASS MbAssembly; + +namespace c3d // namespace C3D +{ +typedef SPtr InstanceSPtr; +typedef SPtr ConstInstanceSPtr; + +typedef std::vector InstancesVector; +typedef std::vector ConstInstancesVector; + +typedef std::vector InstancesSPtrVector; +typedef std::vector ConstInstancesSPtrVector; +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вставка объекта. + \en Instance of object. \~ + \details \ru Вставка объекта геометрической модели MbItem в локальной системе координат MbPlacement3D + позволяет накладывать геометрические ограничения на объект в сборке и позиционоровать объект. + Вставка не может содержать другую вставку. \n + \en The instance of geometric model MbItem object in local coordinate system MbPlacement3D + allows to define constraints for an object in the assembly and to locate the object. + The instance cannot contain another instance. \n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbInstance : public MbItem +{ + MbPlacement3D place; ///< \ru Локальная система координат объекта. \en Local coordinate system of the object. + SPtr item; ///< \ru Геометрический объект. \en A geometric object. + +protected : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbInstance( const MbInstance &, MbRegDuplicate * ); + +public : + /// \ru Конструктор по объекту и его системе координат. \en The constructor by an object and its coordinate system. + MbInstance( MbItem &, const MbPlacement3D & ); + /// \ru Деструктор. \en Destructor. + virtual ~MbInstance(); + +public : + VISITING_CLASS( MbInstance ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en An object type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * iReg = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * iReg = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * iReg = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Whether the objects are equal? + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными? \en Whether the objects are similar? + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add own bounding box to the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate the bounding box in a local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create own property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Получить систему координат объекта. \en Get the coordinate system of an item. + virtual bool GetPlacement( MbPlacement3D & ) const; + // \ru Установить систему координат объекта. \en Set the coordinate system of an item. + virtual bool SetPlacement( const MbPlacement3D & ); + + // \ru Перестроить объект по журналу построения. \en Reconstruct object according to the history tree. + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Добавить полигонную сетку объекта. \en Add a polygon mesh of the object. + virtual bool AddYourMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + // \ru Разрезать полигональный объект одной или двумя параллельными плоскостями. \en Cut the polygonal object by one or two parallel planes. + virtual MbItem * CutMesh( const MbPlacement3D & cutPlace, double distance ) const; + // \ru Найти ближайший объект или имя ближайшего объекта. \en Find the closest object or its name. + virtual bool NearestMesh( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType, + const MbAxis3D & axis, double maxDistance, bool gridPriority, double & t, double & dMin, + MbItem *& find, SimpleName & findName, + MbRefItem *& element, SimpleName & elementName, + MbPath & path, MbMatrix3D & from ) const; + // \ru Дать все объекты указанного типа. \en Get all objects by type. \~ + virtual bool GetItems( MbeSpaceType type, const MbMatrix3D & from, + RPArray & items, SArray & matrs ); + // \ru Дать все уникальные объекты указанного типа. \en Get all unique objects by type . \~ + virtual bool GetUniqItems( MbeSpaceType type, CSSArray & items ) const; + // \ru Дать объект по его пути положения в модели и матрицу преобразования объекта в глобальную систему координат. \en Get the object by its path in the model and get the matrix of transformation of the object to the global coordinate system. + virtual const MbItem * GetItemByPath( const MbPath & path, size_t ind, MbMatrix3D & from, size_t currInd = 0 ) const; + + // \ru Найти объект по геометрическому объекту (MbSpaceItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbSpaceItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Найти объект по геометрическому объекту (MbPlaneItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbPlaneItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Найти объект и матрицу его преобразования в глобальную систему координат. \en Find the object and the matrix of its transformation to the global coordinate system. + virtual const MbItem * FindItem( const MbItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Дать объект с заданным именем и матрицу его преобразования в глобальную систему координат. \en Get the object with the specified name and the matrix of its transformation to the global coordinate system. + virtual const MbItem * GetItemByName( SimpleName n, MbPath & path, MbMatrix3D & from ) const; + + // \ru Преобразовать согласно матрице c использованием регистратора содержимый объект, если он селектирован. \en Transform the contained object according to the matrix using the registrator if the object selected. + virtual void TransformSelected( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + // \ru Сдвинуть вдоль вектора с использованием регистратора содержимый объект, если он селектирован. \en Translate the contained object along the vector according to the matrix using the registrator if the object selected. + virtual void MoveSelected( const MbVector3D & to, MbRegTransform * iReg = NULL ); + // \ru Повернуть вокруг оси на заданный угол с использованием регистратора содержимый объект, если он селектирован. \en Translate the contained object about the axis according to the matrix using the registrator if the object selected. + virtual void RotateSelected( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + + /// \ru Дать матрицу преобразования из локальной системы объекта. \en Get transform matrix from local coordinate system of object. + virtual bool GetMatrixFrom( MbMatrix3D & from ) const; + /// \ru Дать матрицу преобразования в локальную систему объекта. \en Get transform matrix into local coordinate system of object. + virtual bool GetMatrixInto( MbMatrix3D & into ) const; + + /** \ru \name Функции вставки объекта. + \en \name Functions of the object instance. + \{ */ + /// \ru Выдать геометрический объект. \en Get the geometric object. + const MbItem * GetItem() const { return item; } + /// \ru Выдать геометрический объект для модификации. \en Get the geometric object for modification. + MbItem * SetItem() { return item; } + /// \ru Установить другой геометрический объект. \en Set another geometric object. + void SetItem( MbItem * init ); + + /** \brief \ru Заменить объект. + \en Replace an item. \~ + \details \ru Заменить объект новым. + \en Replace an item by a new one. \~ + \param[in] item - \ru Заменяемый объект. + \en An item to be replaced. \~ + \param[in] newItem - \ru Новый объект. + \en A new item. \~ + \return \ru Возвращает true, если замена была выполнена. + \en Returns true if the replacement has been performed. \~ + */ + bool ReplaceItem( const MbItem & item, MbItem & newItem, bool saveName = false ); + + /// \ru Выдать количество граней. \en Get the number of faces. + size_t GetFacesCount() const; + /// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. + template + void GetFacesSet( FacesVector & faces ) const; + /// \ru Выдать систему координат объекта. \en Get the coordinate system of an item. + const MbPlacement3D & GetPlacement() const { return place; } + /// \ru Выдать систему координат объекта для редактирования. \en Get the coordinate system of an assembly item for editing. + MbPlacement3D & SetPlacement() { return place; } + + /** \} */ + +private: + // Найти объект по геометрическому объекту + template + const MbItem * _FindItem( const _ItemType * s, MbPath & path, MbMatrix3D & from ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbInstance ) ; + OBVIOUS_PRIVATE_COPY( MbInstance ); +}; + +IMPL_PERSISTENT_OPS( MbInstance ) + + +#endif diff --git a/C3d/Include/io_buffer.h b/C3d/Include/io_buffer.h new file mode 100644 index 0000000..9157aa8 --- /dev/null +++ b/C3d/Include/io_buffer.h @@ -0,0 +1,850 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация: буфер потока, работа с диском, хранитель версий. + \en Serialization: stream buffer, access to disk, version storage. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_BUFFER_H +#define __IO_BUFFER_H + + +#include +#include +#include +#include +#include +#include + + +class reader; +class writer; +class membuf; +class iobuf; + +//------------------------------------------------------------------------------ +// \ru Имена и перечисления для классов iobuf_Seq, tape, Catalog и их наследников. +// \en Names and enums for classes iobuf_Seq, tape, Catalog and their descendants. +// --- +namespace io +{ + typedef ptrdiff_t pos; ///< \ru Рабочая переменная (позиция, длина, количество). \en Working variable (position, length, count). + typedef ptrdiff_t off; ///< \ru Начало кластера (смещение (при работе с диском) или адрес (при работе с памятью)). \en The beginning of the cluster (shift (while working with the disk) or address (while working with the memory)). + + /// \ru Режимы потоковых операций. \en Modes of stream operations. + enum mode_flags + { + /// \ru Открыть для чтения. \en Open for reading. + in = 0x0001, + /// \ru Открыть для записи. \en Open for writing. + out = 0x0002, + /// \ru Открыть существующий файл и удалить его содержимое. \en Open the existent file and clear its contents. + trunc = 0x0004, //-V112 + /// \ru Упорядочить при закрытии. \en Sort while closing. + speedOnClose = 0x0008, + /// \ru Удалить файл, если он оказался пустым. \en Delete file if it is empty. + delIfEmpty = 0x0010, + /// \ru Удалить файл при закрытии. \en Delete file while closing. + delOnClose = 0x0020, //-V112 + /// \ru Режим восстановления. \en Recovery mode. + recovery = 0x0040, + /// \ru Вспомогательный флаг приложения. \en Auxiliary flag of application. + appSpecial = 0x0080, + /// \ru Создать новый файл. Выдается ошибка, если такой файл уже существует. \en Create a new file. An error is generated if the file already exists. + createNew = 0x0100, + /// \ru Создать новый файл. Если такой файл уже существует, то он перезаписывается. \en Create a new file. If the file already exists, then it is to be rewritten. + createAlways = 0x0200, + /// \ru Открыть существующий файл. Выдается ошибка, если файл не существует. \en Open the existent file. An error is generated if the file does not exist. + openExisting = 0x0300, + /// \ru Открыть существующий файл. Если файл не существует, то создается новый. \en Open the existent file. If the file does not exist, a new file is created. + openAlways = 0x0400, + /// \ru Открыть файл с удалением его содержимого. \en Open the file with clearing of its contents. + truncExisting = 0x0500 + }; + + /// \ru Направление поиска. \en Direction of search. + enum dir + { + beg = 0, ///< \ru С начала файла. \en From the beginning of the file. + cur = 1, ///< \ru С текущей позиций от начала к концу файла. \en From the current position from the beginning to the end of the file. + end = 2 ///< \ru С конца файла. \en From the end of the file. + }; + + /// \ru Флаги состояния потока. \en Flags of stream state. + enum state + { + /// \ru Все в порядке (никакие биты не выставлены). \en Everything is all right (no bits are set). + good = 0x00000000L, + /// \ru Конец файл. \en The end of the file. + eof = 0x00000001L, + /// \ru Выход за пределы файла. \en Out of limits of the file. + outOfRead = 0x00000002L, + /// \ru Не получилось выделить необходимую память. \en Failed to allocate the required memory. + outOfMemory = 0x00000004L, //-V112 + /// \ru Ошибка операции ввода-вывода. \en Input-output operation error. + fail = 0x00000008L, + /// \ru Неверная структура файла. \en Incorrect structure of the file. + badData = 0x00000010L, + /// \ru Файл не найден. \en File not found. + notFound = 0x00000020L, //-V112 + /// \ru Доступ запрещен. \en Access is denied. + accessViolation = 0x00000040L, + /// \ru Не получилось открыть хранилище. \en Can't open the storage. + cantOpenStore = 0x00000080L, + /// \ru Не получилось создать хранилище. \en Can't create a storage. + cantCreateStore = 0x00000100L, + /// \ru Нет подписи или подпись чужая. \en There is no signature or the signature is wrong. + badSig = 0x00000200L, + /// \ru Не получилось прочитать каталог хранилища. \en Can't read the storage catalog. + cantReadCatalog = 0x00000400L, + /// \ru Не получилось записать каталог хранилища. \en Can't write the catalog of the storage. + cantWriteCatalog = 0x00000800L, + /// \ru Не получилось найти файл в каталоге. \en Can't find a file in the catalog. + cantFind = 0x00001000L, + /// \ru Не получилось прочитать файл. \en Can't read the file. + cantRead = 0x00002000L, + /// \ru Не получилось записать файл. \en Can't write the file. + cantWrite = 0x00004000L, + /// \ru Прочитанный идентификатор класса не найден в базе данных. \en The identifier of a class was not find in the data base. + badClassId = 0x00008000L, + /// \ru Попытка повторной регистрации идентификатора класса. \en Attempt for repeated registration of the class identifier. + doubledClassId = 0x00010000L, +// AR /// \ru Версия хранилища старше версии задачи. \en The storage version is older than the task version. +//AR storeVerViolation= 0x00020000L, + /// \ru Версия файла старше версии задачи. \en The file version is older than the task version. + verViolation = 0x00040000L, + /// \ru Ошибка файловой операции. \en The file operation error. + hardFail = 0x00080000L, + /// \ru Буфер закрыт. \en The buffer is closed. + closed = 0x00100000L, + /// \ru У файла установлен атрибут "Только чтение". \en "Read only" attribute is set to the file. + writeProtect = 0x00200000L, + /// \ru Не могу записать объект \en Can't write the object. + /// \ru (версия потока младше версии появления нового класса объектов). \en (the stream version is newer than the new objects class occurrence version). + cantWriteObject = 0x00400000L, + /// \ru Не могу прочитать файл с 64-битными данными в 32-битной задаче \en Can't read file with 64-bit data in 32-bit task + /// \ru (потеря старшего слова uint32 при чтении uin64 в 32-битной задаче). \en (loss of upper word uint32 while reading uint64 in 32-bit task). + underflow64to32 = 0x00800000L, + /// \ru Файл защищен или закодирован. \en File is protected or encrypted. + encrypted = 0x01000000L, + /// \ru Файл в расширенном формате прочитан частично (неизвестные объекты пропущены). \en Partial read of file in extended format (unknown objects skipped). + skippedUnknown = 0x02000000L, + /// \ru Чтение файла прервано пользователем. \en File reading aborted by user. + readAborted = 0x04000000L, + /// \ru Файл в расширенном формате прочитан частично (неизвестные объекты пропущены). \en Partial read of file in extended format (unknown objects skipped). + skippedUnknAttr = 0x08000000L, + /// \ru Все ошибки. \en All errors. +//AR all = 0xffffffe0L + allMask = 0xffffffffL + }; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кластер. + \en Cluster. \~ + \details \ru Кластер. \n + \en Cluster. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS Cluster +{ +private: + size_t m_f; ///< \ru Начало кластера (для дисковых - смещение, для памяти - адрес). \en The cluster beginning (shift - for disk, address - for memory). + uint16 m_l; ///< \ru Длина в байтах (для памяти - количество заполненных байт, распределено возможно больше). \en The length in bytes (for memory - count of used bytes; more bytes can be allocated). + +public: //OV_x64 protected: + // \ru Конструктор. \en Constructor. + Cluster(); + + // \ru деструктора нет, т.к. кластеры хранятся в SArray и деструктор не вызывается \en there is no destructor since the clusters are stored in SArray and the destructor is not called + +public: + // \ru Доступ к полю длины. \en Access to the length field. + uint16 _len() const; + // \ru Доступ к полю начала. \en Access to the beginning field. + size_t _off() const; + // \ru Выдать адрес. \en Get the address. + const uint8 * _ptr() const; + // \ru Выдать адрес. \en Get the address. + uint8 * _getMemPointer(); + // \ru Очистить. \en Clear. + void clear(); + // \ru Запомнить смещение в файле и кол-во байт. \en Memorize the shift in file and the bytes count. + void AllocFile( size_t beg, uint16 len ); + // \ru Установить начало кластера. \en Set the cluster's beginning. + void SetClusterOffset( size_t off ); + // \ru Установить длину кластера. \en Set the cluster's length. + void SetClusterLength( uint16 len ); + // \ru Размер данных о кластере в потоке указанной версии. \en Size of cluster data in the stream of the specified version. + static size_t SizeOf( VERSION version ); + +protected: + void AllocMem( uint16 len ); ///< \ru Захватить столько памяти. \en Allocate memory of the given size. + void FreeMem () ; ///< \ru Освободить память. \en Free memory. + +//OV_LNX /// \ru Вычислить размер в памяти. \en Calculate size in memory. +//OV_LNX friend size_t getMemLen ( const Cluster& c, VERSION version ); + + /// \ru Записать информацию о кластере. \en Write the information about the cluster. + friend MATH_FUNC (size_t) WriteClusterInfo ( void *, VERSION version, const Cluster & ); + /// \ru Прочитать информацию о кластере. \en Read the information about the cluster. + friend MATH_FUNC (size_t) ReadClusterInfo ( void *, VERSION version, Cluster & ); + /// \ru Записать содержимое кластера. \en Write the cluster's contents. + friend MATH_FUNC (size_t) WriteClusterBody ( void *, VERSION version, const Cluster & obj, uint16 clusterSize ); + /// \ru Прочитать содержимое кластера. \en Read the cluster's contents. + friend MATH_FUNC (size_t) ReadClusterBody ( void *, VERSION version, Cluster & obj, uint16 clusterSize ); + /// \ru Записать кластер. \en Write the cluster. + friend MATH_FUNC (void) ReadCluster ( reader &, uint16 clusterSize, Cluster & ); + /// \ru Прочитать кластер. \en Read the cluster. + friend MATH_FUNC (void) WriteCluster ( writer &, const Cluster &, uint16 clusterSize ); + + friend class membuf; + +public: + bool operator < (const Cluster& e ) const { if ( m_f != e.m_f) return m_f < e.m_f; return m_l < e.m_l; } + bool operator > (const Cluster& e ) const { return !operator < (e); } + + OBVIOUS_PRIVATE_COPY( Cluster ) +}; + + + +//------------------------------------------------------------------------------ +/** \brief \ru Файловое пространство. + \en File space. \~ + \details \ru Файловое пространство. + Место отведенное под файл (это массив индексов в массиве кластеров). \n + \en File space. + Space allocated for file (array of indices in array of clusters). \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS FileSpace +{ +protected: + uint16 m_last; ///< \ru Количество занятых байт в последнем кластере. \en Count of used bytes in the last cluster. + SArray self; ///< \ru Массив данных. \en Data array. +public: + /// \ru Конструктор. \en Constructor. + FileSpace(); + /// \ru Деструктор. \en Destructor. + virtual ~FileSpace(); +public: + // \ru Дать количество элементов массива. \en Get the number of elements in array. + size_t Count () const; + // \ru Обнулить количество элементов. \en Set the number of elements to zero. + void Flush (); + // \ru Удалить элемент из массива. \en Delete an element from array. + void RemoveInd( size_t idx ); + // \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + size_t * Add (); + // \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + size_t * Add ( const size_t & el ); + // \ru Установить новый размер массива. \en Set the new size of an array. + void SetSize ( size_t newSize, bool clear ); + // \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + void Reserve ( size_t count ); + // \ru true если элемент найден. \en true if the element found. + bool IsExist ( size_t & el ) const; + // \ru индекс элемента, если он найден или -1. \en index of the element if it is found or -1. + size_t FindIt ( const size_t & el ) const; + // \ru Вставить пустой элемент перед указанным. \en Insert the empty element before the specified one. + size_t * InsertInd( size_t index, const size_t & el ); + // \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const size_t * GetAddr() const; + // \ru Добавить n элементов в конец массива. \en Add n elements to the end of the array. + size_t * AddItems ( size_t n ); + // \ru Оператор доступа по индексу. \en Operator of access by index. + size_t & operator []( size_t loc ) const; + // \ru Получить количество занятых байт в последнем кластере. \en Get the number of used bytes in the last cluster. + uint16 & rest(); + +//OV_LNX /// \ru Получить общий размер данных FileSpace в потоке указанной версии \en Get the total size of FileSpace data in the stream of the specified version +//OV_LNX friend size_t getMemLen ( const FileSpace& s, VERSION version ); +//OV_LNX /// \ru Получить размер данных FileSpace в потоке указанной версии \en Get the size of FileSpace data in the stream of the specified version +//OV_LNX friend size_t SizeOfFileSpace( VERSION version, size_t cnt, bool calcFull ); + /// \ru Записать файловое пространство. \en Write the file space. + friend MATH_FUNC (void) WriteFileSpace ( void *, VERSION version, const FileSpace &, bool writeFull ); + /// \ru Прочитать файловое пространство. \en Read the file space. + friend MATH_FUNC (bool) ReadFileSpace ( void *, VERSION version, size_t & cnt, FileSpace &, const iobuf * owner, bool readFull ); + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader&) operator >> ( reader &, FileSpace & ); + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader&) operator >> ( reader &, FileSpace *& ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer&) operator << ( writer &, const FileSpace & ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer&) operator << ( writer &, const FileSpace * ); + + OBVIOUS_PRIVATE_COPY( FileSpace ) +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Позиция в кластере для чтения/записи. + \en Position for reading/writing in a cluster. \~ + \details \ru Позиция в кластере для чтения/записи. + \en Position for reading/writing in a cluster. \~ + \ingroup Base_Tools_IO +*/ +// --- +struct ClusterReference +{ + size_t clusterIndex; ///< \ru Индекс кластера в массиве кластеров iobuf_Seq. \en Index of the cluster in the cluster array of iobuf_Seq. + uint16 offset; ///< \ru Смещение в данном кластере. \en Offset in the cluster. + + ClusterReference() : clusterIndex ( SYS_MAX_T ), offset ( (uint16)-1 ) {} + explicit ClusterReference( size_t idx, uint16 off ) : clusterIndex( idx ), offset( off ) {} + ClusterReference( const ClusterReference & ref ) : clusterIndex( ref.clusterIndex ), offset( ref.offset ) {} + + bool operator == ( const ClusterReference & ref ) const { + return clusterIndex == ref.clusterIndex && offset == ref.offset; + } + bool operator < ( const ClusterReference & ref ) const { + if ( clusterIndex == ref.clusterIndex ) + return offset < ref.offset; + return clusterIndex < ref.clusterIndex; + } + ClusterReference & operator = ( const ClusterReference & ref ) { + clusterIndex = ref.clusterIndex; offset = ref.offset; return *this; + } + bool IsValid() const { return clusterIndex != SYS_MAX_T && offset != (uint16)-1; } +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Потоковый буфер, обеспечивает только последовательную запись, без возможности удалить или перезаписать файл. + \en Stream buffer. \~ + \details \ru Потоковый буфер - базовый класс. \n + + Буфер iobuf_Seq и его наследники служат для выполнения операций чтения и записи в интересах потока (класс tape). \n + Классы iobuf_Seq, tape и их наследников следует рассматривать в совокупности. \n + + Терминология: \n + - Xранилище - файл на диске или область памяти. \n + - Файл - файл внутри хранилища. \n + + Класс iobuf_Seq содержит массив кластеров. \n + + Класс Кластер (Cluster) - это структурированная информация о кластере (его начало и длина). + Он используется для операций с диском, где тогда начало - это смещение, + и операций с памятью, где начало - это адрес в памяти. + Все операции чтения и записи производятся по-кластерно, + используя индекс в массиве кластеров iobuf_Seq. \n + + Класс Файловое пространство (FileSpace) - это место, отведенное под файл, это массив индексов в массиве кластеров. + Это как раз то, что здесь мы называем файлом. \n + + Внимание: с этого места и далее вместо слова кластер следует читать - + индекс кластера в массиве кластеров iobuf_Seq. \n + + \n + Важнейшие поля данных iobuf_Seq: \n + + FileSpace sys - "системный" файл. Он открывается в конструктор класса tape. \n + 1. Если класс iobuf_Seq используется классом tape непосредственно + (например: writer potok( "file.ext" ); + или reader * potok = new reader( "file.ext" ), + то в файле sys содержится непосредственно информация, + которая записывалась в file.ext. \n + 2. Если класс iobuf_Seq используется классом Catalog, + то в sys хранится структура каталогов и файлов внутри Catalog + (он зачитывается в конструкторе класса Catalog). \n + + PArray files - список файлов содержащихся в iobuf_Seq. + Первым эл-том в нем всегда лежит адрес sys. + При записи Catalog содержимое files записывается в sys, + исключая, естественно, первый элемент. \n + + uint32 stateFlag - состояние буфера. + Предполагается, что все операции чтения-записи устанавливают этот флаг когда надо + и проверяют его состояние перед реальным выполнением. + С этим флагом работают следующие функции: + iobuf_Seq::good, iobuf_Seq::eof, iobuf_Seq::state, iobuf_Seq::setState, iobuf_Seq::clearState; + tape::good, tape::eof, tape::state; + Catalog::good, Catalog::goodeof, Catalog::goodstate. \n + + VERSION storageVers - версия хранилища. \n + VERSION curFileVers - версия текущего открытого файла (потока). \n + В общем случае версия хранилища и версия любого файла в нем могут не совпадать. \n + + uint8 bufferMode - Режим, в котором может работать буфер. \n + uint8 curFileMode - Режим открытия текущего файла. \n + В общем случае режим хранилища и режим открытого файла в нем могут не совпадать. + Ограничение - если режим буфера io::in, то попытка открыть файл на запись (io::out) + не приводит к открытию. \n + + uint8 * base - Указатель на начало буфера в памяти. \n + uint8 * ptr - Указатель на след символ в памяти. \n + uint8 * end - Указатель на конец буфера в памяти. \n + При работе с диском указатели устанавливаются на фиксированный + участок памяти, куда подгружаются участки файла при чтении. + При работе с памятью membuf устанавливает их на выделенную под кластер память. \n + + \n + Важнейшие функции iobuf_Seq: \n + Функция setup() - установить в buffer(переменные base,ptr,end) следующий кластер. + Вызывается из функций overflow (при записи) и underflow (при чтении), + когда заканчивается очередной буфер. + Они в свою очередь вызываются из функций чтения-записи символов из потока + (gc(), getn(), getln(), pc(), putn(), putln()). + + Функция flush() - сбросить буфер. + Вызывается перед подъемом следующего кластера. + При чтении ничего не делает. При записи, при работе с диском, + сохраняет предыдущий кластер на диск, а при работе с памятью + запоминает размер последнего заполненного кластера. \n + + Операции чтения выполняются внутри открытого в данный момент файла, не выходя за его конец. \n + \en Stream buffer - the base class. \n + + Buffer iobuf_Seq and its descendants are used for read and write operations in the interest of the stream (class tape). \n + Classes iobuf_Seq, tape, Catalog and their descendants should be considered together. \n + + Terminology: \n + - Storage - file on the disk or memory space. \n + - Catalog - catalog inside the storage. \n + - File - file inside the storage. \n + + Class iobuf_Seq contains a cluster array. \n + + Class Cluster is structured information about the cluster (its beginning and length). + It is used for operations with disk, in this case the beginning is a shift, + and for operations with memory, in this case the beginning is an address in memory. + All the operations of reading and writing are performed clusterwise + using the index in the array of clusters iobuf_Seq. \n + + Class FileSpace is a place allocated for the file, is an array of indices in the array of clusters. + It is just what we call 'file' here. \n + + Attention: from this place the word 'cluster' should be read as + index of cluster in the array iobuf_Seq of clusters. \n + + \n + The most important data fields of iobuf_Seq: \n + + FileSpace sys - "system" file. It is opened in the constructor of the class tape. \n + 1. If the class iobuf_Seq is directly used by class tape + (for instance: writer potok( "file.ext" ); + or reader * potok = new reader( "file.ext" ), + then the file sys contains the information + which were written to file.ext. \n + 2. If the class iobuf_Seq is used by class Catalog, + then file sys contains the structure of catalogs and files inside Catalog + (it is read in the constructor of class Catalog). \n + + PArray files - the list of files contained in iobuf_Seq. + The first element is always the address of sys. + While writing Catalog, the contents of files is written to sys, + except the first element, naturally. \n + + uint32 stateFlag - the buffer state. + It is considered that all the read-write operations set this flag when it is necessary + and check its state before the real execution. + The following functions work with this flag: + iobuf_Seq::good, iobuf_Seq::eof, iobuf_Seq::state, iobuf_Seq::setState, iobuf_Seq::clearState; + tape::good, tape::eof, tape::state; + Catalog::good, Catalog::goodeof, Catalog::goodstate. \n + + VERSION storageVers - the storage version. \n + VERSION curFileVers - version of the current open file (stream). \n + In the common case the storage version and the version of any file in the storage can be different. \n + + uint8 bufferMode - A possible buffer mode. \n + uint8 curFileMode - Mode of the current file opening. \n + In the common case the storage mode and the mode of open file in this storage can be different. + Constraint - if the buffer mode is io::in, then an attempt to open the file for writing (io::out) + doesn't result in opening. \n + + uint8 * base - Pointer to the beginning of the buffer in memory. \n + uint8 * ptr - Pointer to the next symbol in memory. \n + uint8 * end - Pointer to the end of buffer in the memory. \n + When working with the disk, pointers are set to a fixed + memory block the sections of file are loaded to while reading. + When working with the memory, 'membuf' set them to the memory allocated for the cluster. \n + + \n + The most important functions of iobuf_Seq: \n + Function setup() - set the next cluster to 'buffer' (variables 'base', 'ptr', 'end'). + Called from functions 'overflow' (while writing) and 'underflow' (while reading) + when the current buffer is over. + These functions are in turn called from functions of reading-writing of symbols from the stream + (gc(), getn(), getln(), pc(), putn(), putln()). + + Function flush() - flush the buffer. + Called before getting the next cluster. + Do nothing while reading. When writing, when working with the disk, + saves the previos cluster on the disk, and, when working with the memory, + stores the size of the last filled cluster. \n + + Read operations are performed inside the file which is open at the moment, no read after end of the file. \n \~ + + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS iobuf_Seq +{ +protected: + uint8 * base; ///< \ru Указатель на начало буфера. \en Pointer to the beginning of the buffer. + uint8 * ptr; ///< \ru Указатель на следующий байт. \en Pointer to the next byte. + uint8 * end; ///< \ru Указатель на конец буфера. \en Pointer to the end of the file. + + VERSION storageVers; ///< \ru Версия хранилища (должна быть ранее curFileVers). \en The storage version (must be before 'curFileVers'). + VersionContainer curFileVers; ///< \ru Версии текущего открытого файла (потока). \en Version of the current open file (stream). + VERSION formatVersion; ///< \ru Версия формата. \en The format version. + + FileSpace sys; ///< \ru Системный файл. \en System file. + PArray files; ///< \ru Список файлов содержащихся в iobuf_Seq (первый элемент - адрес sys). \en List of files contained in iobuf_Seq (the first element is the address of 'sys'). + + FileSpace * curr; ///< \ru Текущий открытый файл (поток). \en Current open file (stream). + size_t part; ///< \ru Текущий кластер в текущем открытом файле. \en Current cluster in the current open file. + + uint16 clusterSize; ///< \ru Размер кластера. \en Cluster size. + + uint8 bufferMode; ///< \ru Режим работы буфера. \en Buffer mode. + //AR todo io::mode + + uint8 curFileMode; ///< \ru Режим открытия текущего файла. \en Mode of opening the current file. + +private: + uint32 stateFlag; ///< \ru Состояние буфера. \en The buffer state. + // todo io::state + SArray content; // \ru Массив кластеров. \en Clusters array. + +protected: + bool modifiedFlag; ///< \ru Буфер модифицирован. \en The buffer has been modified. + bool freshFlag; ///< \ru Свежий ли буфер. \en Is the buffer fresh. + +public: + /// \ru Конструктор \en Constructor + iobuf_Seq( uint16 clusterSize ); + /// \ru Деструктор. \en Destructor. + virtual ~iobuf_Seq() {} + +public: + + // \ru Методы доступа к массиву кластеров. \en Methods for an access to the clusters array. + + ///< \ru Зарезервировать место под заданное количество элементов. \en Reserve space for a given number of elements. + void Reserve ( size_t n, bool addAdditionalSpace = true ); + ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + void Flush (); + ///< \ru Освободить всю память. \en Free the whole memory. + void HardFlush (); + ///< \ru Удалить лишнюю память. \en Free the unnecessary memory. + void Adjust (); + ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + Cluster * Add (); + ///< \ru Добавить данный элемент в конец массива. \en Add a given element to the end of the array. + Cluster * Add ( const Cluster &e ); + ///< \ru Дать количество элементов массива. \en Get the number of elements in array. + size_t Count () const; + /// \ru Оператор доступа по индексу. \en Access by index operator. + Cluster & operator []( size_t loc ) const; + + ///< \ru Зарезервировать место под заданное количество файлов. \en Reserve space for a given number of FileSpace. + void ReserveFiles( size_t n, bool addAdditionalSpace ) { files.Reserve( n, addAdditionalSpace ); } + +public: + + /// \ru Получить следующий байт из буфера. \en Get the next byte from the buffer. + int gc (); // get next char and advance + /// \ru Получить следующие n байт из буфера поэлементно. \en Get the next n bytes from the buffer elementwise. + size_t getn ( void *, size_t ); // get next n chars and advance + /// \ru Получить следующие n байт из буфера копированием участка памяти. \en Get the next n bytes from the buffer by copying the storage area. + size_t getln( void *, size_t ); // get next n chars and advance + /// \ru Получить очередной байт из буфера, но указатель на следующий не сдвигать. \en Get the next byte from the buffer but don't shift the pointer to the next one. +//AR int ch (); // return next char and do not advance + /// \ru Поместить байт в буфер. \en Put byte to the buffer. + int pc ( uint8 c ); + /// \ru Поместить следующие n байт в буфер поэлементно \en Put the next n bytes to the buffer elementwise. + size_t putn ( const void *, size_t ); // put n chars with 'pc' func and advance + /// \ru Поместить следующие n байт в буфер копированием участка памяти. \en Put the next n bytes to the buffer by copying the storage area. + size_t putln( const void *, size_t ); // put long string and advance + /// \ru Если кончился текущий буфер, переместить указатель на следующий. \en If current buffer exhausted, advance pointer to the next one. + void advance(); + /// \ru Корректно ли состояние буфера. \en Whether the buffer state is correct. + bool good () const; + /// \ru Достигнут ли конец файла? \en Is the end of file reached? + bool eof () const; + /// \ru Получить состояние буфера. \en Get the buffer state. + uint32 state() const; //AR getState + /// \ru Добавить состояние буфера. \en Add the buffer state. + void setState ( io::state add ); /*AR const*/ + /// \ru Убрать состояние буфера. \en Remove the buffer state. + void clearState( io::state sub ); /*AR const*/ + /// \ru Посчитать размер текущего файла. \en Calculate the current file size. + io::pos size() const; + /// \ru Возвращает текущую позицию в файле \en Returns the current position in the file. + io::pos tell() const; + /// \ru Установить текущую позицию в буфере \en Set current position in the buffer. + void lseek ( size_t pos = SYS_MAX_T ); + /// \ru Присоединить файл к буферу с проверкой или без. \en Attach the file to the buffer with or without checking. + bool attach ( FileSpace & file, bool check = true ); + /// \ru Открыть файл, если он свой. Флаг fullCheck == false отключает избыточные проверки (ради производительности). + /// \en Open the file if it is one's own file. The flag fullCheck == false switches off excessive checks (for the sake of performance). + virtual bool open ( FileSpace & file, uint8 om, const VersionContainer &, bool fullCheck = true ); + /// \ru Открыть системный файл. \en Open the system file. + bool openSys( uint8 om ); + /// \ru Закрыть файл. \en Close the file. + virtual void close (); + /// \ru Закрыть буфер. \en Close the buffer. + virtual void closeBuff(); + + /// \ru Установить для записи FileSpace с заданным индексом (при необходимости создать новый). + ///\en Set FileSpace with given index for writing (create if necessary). + virtual FileSpace * enterFileSpace ( uint8 ) { return NULL; } // не реализовано; not implemeneted + /// \ru Установить позицию для записи/чтения по заданному ClusterReference. + /// Сохранить предыдущую позицию, если saveCurr = true. + /// \en Set position for for writing/reading by given ClusterReference. + /// If saveCurr = true, save previous position. + virtual FileSpace * enterFileSpace ( const ClusterReference & , bool ) { return NULL; } // не реализовано; not implemeneted + /// \ru Установить позицию для записи/чтения по заданным FileSpace и ClusterReference. + /// Внимание, здесь ClusterReference.clusterIndex должен содержать индекс в массиве индексов кластеров в FileSpace! + /// Сохранить предыдущую позицию, если saveCurr = true. + /// \en Set position for writing/reading by given FileSpace and ClusterReference. + /// Warning: in this function, ClusterReference.clusterIndex should contain an index in array of cluster indices in FileSpace! + /// If saveCurr = true, save previous position. + virtual FileSpace * enterFileSpace ( const ClusterReference &, FileSpace *, bool ) { return NULL; } // не реализовано; not implemeneted + /// \ru Установить предыдущий FileSpace для записи/чтения. + ///\en Set previous FileSpace for writing/reading. + virtual FileSpace * returnToPreviousFileSpace() { return NULL; } // не реализовано; not implemeneted + + /// \ru Получить текущую позицию в буфере. \en Get current position in the buffer. + ClusterReference getCurrentClusterPos(); + + /// \ru Получить доступ к системному файлу. \en Get access to the system file. + FileSpace & sysFile (); + /// \ru Получить доступ к открытому файлу. \en Get access to the open file. + FileSpace * openedFile() const; + + /// \ru Размер данных хранилища (файла на диске). \en The storage data size (of the file on the disk). + virtual size_t DOSFileLen () const; + /// \ru Имя хранилища (файла на диске). \en Storage name (of file on the disk). + virtual const TCHAR * DOSFileName() const; + + /// \ru Свежий ли буфер? \en Is the buffer fresh? + bool fresh() const; + /// \ru Установить состояние свежести буфера. \en Set the state of buffer freshness. + void fresh( bool f ); + /// \ru Модифицирован ли буфер? \en Is the buffer modified? + bool modified() const; + /// \ru Установить состояние модифицированности буфера. \en Set the state of modified buffer. + void modified( bool m ); + /// \ru Узнать режим работы буфера. \en Get the buffer mode. + uint8 mode() const; // getMode + /// \ru Установить режим работы буфера. \en Set the buffer mode. + void mode( uint8 m ); // curMode + void setMode( uint8 m ); + /// \ru Находимся в режиме чтения? \en Is in the reading mode? + bool IsInMode() const; + /// \ru Находимся в режиме записи? \en Is in the writing mode? + bool IsOutMode() const; + /// \ru Находимся в режиме чтения или записи? \en Is in the reading or writing mode? + bool IsInOrOutMode() const; + /// \ru Нужно ли удалять пустой файл? \en Is the empty file to be deleted? + bool deleteIfEmpty() const; + /// \ru Установить флаг необходимости удаления пустого файла. \en Set the flag of deleting the empty file. + void deleteIfEmpty( bool s ); + /// \ru Нужно ли удалять файл при закрытии буфера? \en Is the file to be deleted while closing the buffer? + bool deleteOnClose() const; + /// \ru Установить флаг необходимости удаления файла при закрытии буфера. \en Set the flag of deleting the file while closing the buffer. + void deleteOnClose( bool s ); + /// \ru Установить текущую версию равной версии хранилища. \en Set the current version to be equal to the storage version. + void SetVersionsByStorage(); + /// \ru Вернуть главную версию (математического ядра). \en Return the main version (of the mathematical kernel). + VERSION MathVersion() const; + /// \ru Вернуть дополнительную версию (конечного приложения). \en Return the additional version (of the target application). + VERSION AppVersion( size_t ind = -1 ) const; + /// \ru Получить версии буфера. \en Get the buffer versions. + const VersionContainer & GetVersionsContainer() const; +protected: + int underflow(); ///< \ru Вызывается когда прочитан весь буфер, а еще хочется. \en Called when the whole buffer are read, but it is necessary to continue reading. + int overflow( uint8 ch ); ///< \ru Вызывается когда заполнен весь буфер, а еще хочется. \en Called when the buffer is full but it is necessary to continue writing. + virtual int setup() = 0; ///< \ru Установить следующий буфер. \en Set the next buffer. + virtual int flush() = 0; ///< \ru Сбросить буфер. \en Flush the buffer. + void checkEof(); ///< \ru Установить конец файла, если необходимо. \en Set the end of file if necessary. + + /// \ru Узнать количество необработанных байт в буфере. \en Get the number of unprocessed bytes in the buffer. + size_t avail () const; + /// \ru Узнать количество обработанных байт в буфере. \en Get the number of processed bytes in the buffer. + size_t waiting() const; + + bool mine ( FileSpace & ); ///< \ru Проверить, мой ли это файл. \en Check if the file is mine. + + /// \ru Установить версию открытого файла. \en Set the version of open file. + void SetVersionsContainer( const VersionContainer & vers ); + /// \ru Установить версию хранилища. \en Set the storage version. + VERSION SetStorageVersion( VERSION ); +public: + /// \ru Узнать версию хранилища. \en Get the storage version. + VERSION GetStorageVersion(); + + /// \ru Узнать версию формата. \en Get the format version. + VERSION GetFormatVersion() const; + /// \ru Установить версию формата. \en Set the format version. + void SetFormatVersion ( VERSION version ); + + friend class tape; + + OBVIOUS_PRIVATE_COPY( iobuf_Seq ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Потоковый буфер с произвольным доступом + , расширяет функциональность iobuf_Seq возможностью удаления и перезаписи файлов. + \en Stream buffer. \~ + \details \ru Потоковый буфер - базовый класс. \n + + FileSpace freed - список освобожденных кластеров. + При удалении файла все его кластеры переносятся сюда. + При записи, когда необходимо распределить новый кластер, + сначала проверяется этот массив на наличие свободных кластеров. + Кластеры в freed всегда лежат упорядоченными по смещению от начала файла. \n + + \en Stream buffer - the base class. \n + + FileSpace freed - the list of freed clusters. + When the file is deleted, all its clusters are moved here. + When the modified Catalog is being closed, all the clusters are deleted from 'freed' + which physically lie after the last used cluster. + After that the contents of 'freed' is written to 'sys'. + While writing, when it is necessary to allocate the new cluster, + this array is firstly checked for availability of free clusters. + Clusters in 'freed' are always ordered by shift from the beginning of the file. \n + + */ +// --- +class MATH_CLASS iobuf : public iobuf_Seq +{ +protected: + FileSpace freed; ///< \ru Список освобожденных кластеров. \en List of released clusters. + +public: + /// \ru Конструктор \en Constructor + iobuf( uint16 clusterSize ); + /// \ru Деструктор. \en Destructor. + virtual ~iobuf(); + +public: + /// \ru Открыть файл, если он свой. Флаг fullCheck == false отключает избыточные проверки (ради производительности). + /// \en Open the file if it is one's own file. The flag fullCheck == false switches off excessive checks (for the sake of performance). + virtual bool open ( FileSpace & file, uint8 om, const VersionContainer &, bool fullCheck = true ); + + /// \ru Освободить место, занимаемое файлом. \en Free space allocated for the file. + bool del ( FileSpace & file ); + /// \ru Урезать файл. \en Truncate the file. + bool truncate( FileSpace & file, size_t from ); + + ///< \ru Отсоединить файл от буфера. \en Detach file from the buffer. + bool detach( FileSpace & ); + + /// \ru Нужно ли упорядочивать при закрытии. \en Is to be ordered while closing. + bool speedOnClose() const; + /// \ru Установить флаг необходимости упорядочивания при закрытии. \en Set the flag of ordering while closing. + void speedOnClose( bool s ); + + virtual void free( size_t c ); ///< \ru Освободить кластер. \en Free the cluster. + + friend class tape; + + OBVIOUS_PRIVATE_COPY( iobuf ); +}; + + +//------------------------------------------------------------------------------ +/// \ru Конец файла. \en End of file. \~ \ingroup Base_Tools_IO +//--- +#define EOF (-1) + +//------------------------------------------------------------------------------ +/**\ru Сравнить два кластера. +\en Compare two clusters. \~ +\ingroup Base_Tools_IO +*/ +//--- +inline bool IsEqualSArrayItems( const Cluster & /*obj1*/, const Cluster & /*obj2*/ ) { + return 0; +} + +//------------------------------------------------------------------------------ +/// \ru Длина данных size_t в потоке. \en Length of size_t data in the stream. \~ \ingroup Base_Tools_IO +// --- +inline size_t LenCOUNT( VERSION version ) +{ + if ( IsVersion64bit(version) ) + return sizeof(uint64); + else + return sizeof(uint32); +} + + +//------------------------------------------------------------------------------ +/// \ru Размер данных FileSpace в потоке указанной версии. \en Length of FileSpace data in stream of the specified version. \~ \ingroup Base_Tools_IO +// --- +inline size_t SizeOfFileSpace( VERSION version, size_t cnt, bool calcFull ) +{ + const size_t lenCount = IsVersion16bit(version) ? sizeof( uint16 ) + : LenCOUNT( version ); + + size_t len = (calcFull ? lenCount : 0); // count + len += cnt * lenCount; + len += (calcFull ? sizeof(uint16) : 0); // m_last + + return len; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Размер данных кластера. +\en Size of cluster's data. \~ +\details \ru Размер данных кластера в потоке указанной версии. \n +\en Size of cluster data in the stream of the specified version. \n \~ +\ingroup Base_Tools_IO +*/ +//--- +inline size_t getMemLen( const Cluster & c, VERSION /*version*/ ) +{ + // \ru для кластера будет записываться uint16(кол-во заполненных байт) \en the following number will be stored for a cluster: uint16 (the number of filled bytes) + // \ru плюс заполненные байты \en plus filled bytes + return (c._len() + sizeof(uint16)); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Размер данных файла. +\en The file data size. \~ +\details \ru Размер данных файлового пространства в потоке указанной версии. \n +\en The file space data size in the stream of the specified version. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +inline size_t getMemLen( const FileSpace & s, VERSION version ) { + return SizeOfFileSpace( version, s.Count(), true/*calcLast*/ ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить массив кластеров файла. +\en Check the cluster array of the file. \~ +\details \ru Проверить массив кластеров, из которых состоит этот файл. \n +\en Check array of clusters this file consists of. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +inline bool IsGoodFile( const FileSpace & file, const iobuf_Seq & owner ) +{ + bool good = true; + + size_t clustersCount = owner.Count(); + for ( size_t i = 0, fileCount = file.Count(); i < fileCount && good ; i++ ) + { + size_t fileIndex = file[i]; + good = ( (ptrdiff_t)fileIndex >= 0 && (ptrdiff_t)fileIndex < (ptrdiff_t)clustersCount ); + } + + return good; +} + +#endif // __IO_BUFFER_H diff --git a/C3d/Include/io_define.h b/C3d/Include/io_define.h new file mode 100644 index 0000000..b3fa4cc --- /dev/null +++ b/C3d/Include/io_define.h @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Макросы сериализации, подавление предупреждений, контроль памяти. + \en Macros of serialization, warnings suppression, memory control. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_DEFINES_H +#define __IO_DEFINES_H + + +#include + + +class reader; +class writer; + +//------------------------------------------------------------------------------ +// \ru Объекты, для которых при записи и чтении точно известен тип \en Objects which type is exactly known while reading and writing +// \ru могут записываться в поток и читаться из потока с помощью \en can be written to the stream and read from the stream using +// \ru операторов << и >> \en operators << and >> +//--- +#define KNOWN_OBJECTS_RW_REF_OPERATORS(Class) \ + friend reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ); \ + friend writer & CALL_DECLARATION operator << ( writer & out, const Class & ref ); \ + friend writer & CALL_DECLARATION operator << ( writer & out, Class & ref ) { return operator << ( out, (const Class &)ref ); } + +#define KNOWN_OBJECTS_RW_PTR_OPERATORS(Class) \ + friend reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ); \ + friend writer & CALL_DECLARATION operator << ( writer & out, const Class * ptr ); \ + friend writer & CALL_DECLARATION operator << ( writer & out, Class * ptr ) { return operator << ( out, (const Class *)ptr ); } + +// \ru тоже для экспорта/импорта \en for export/import too +// \ru DLLFUNC -> __declspec( dllexport ) или __declspec( dllimport ) объявляется специально \en DLLFUNC -> __declspec( dllexport ) or __declspec( dllimport ) are specially declared +// \ru для этих дефайнов в файлах типа ????_def.h (см. MATH_FUNC_EX выше) \en for this definitions in files like ?????_def.h (see MATH_FUNC_EX above) +#define KNOWN_OBJECTS_RW_REF_OPERATORS_EX(Class, DLLFUNC) \ + friend DLLFUNC reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ); \ + friend DLLFUNC writer & CALL_DECLARATION operator << ( writer & out, const Class & ref ); \ + friend DLLFUNC writer & CALL_DECLARATION operator << ( writer & out, Class & ref ) { return operator << ( out, (const Class &)ref ); } + +#define KNOWN_OBJECTS_RW_PTR_OPERATORS_EX(Class, DLLFUNC) \ + friend DLLFUNC reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ); \ + friend DLLFUNC writer & CALL_DECLARATION operator << ( writer & out, const Class * ptr ); \ + friend DLLFUNC writer & CALL_DECLARATION operator << ( writer & out, Class * ptr ) { return operator << ( out, (const Class *)ptr ); } + + +#endif // __IO_DEFINES_H diff --git a/C3d/Include/io_memory_buffer.h b/C3d/Include/io_memory_buffer.h new file mode 100644 index 0000000..ececdfb --- /dev/null +++ b/C3d/Include/io_memory_buffer.h @@ -0,0 +1,178 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация: буфер в памяти. + \en Serialization: memory buffer. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_MEMORY_BUFFER_H +#define __IO_MEMORY_BUFFER_H + + +#include +#include +#include +#include +#include +#include +#include + +class mem; +class iobuf; +class reader; +class writer; + + +//------------------------------------------------------------------------------ +/// \ru Размер кластера по умолчанию. \en Cluster size by default. \~ \ingroup Base_Tools_IO +//--- +const uint16 DEFCLSIZE = 0x1000; +// \ru САА K13 12.5.2011 Увеличил размер кластера по умолчанию - параллельное перестроение видов. \en САА K13 12.5.2011 Increased cluster size by default - parallel rebuilding of views. +// \ru САА K13 12.5.2011 const uint16 DEFCLSIZE = 256; \en САА K13 12.5.2011 const uint16 DEFCLSIZE = 256; + + +//------------------------------------------------------------------------------ +/** \brief \ru Потоковый буфер памяти. + \en Memory stream buffer. \~ + \details \ru Потоковый буфер памяти. \n + Потоковый буфер памяти предназначен для использования в потоках чтения и записи. + Кроме необходимых для буфера принадлежностей имеет функции для упаковки в непрерывный блок памяти, + что позволяет передавать файлы через память в другое приложение. + \en Memory stream buffer. \n + Stream memory buffer is intended for using in read and write streams. Besides the + instruments needed for the buffer, it has functions for packing to a contiguous memory block, + what allows to transfer files to another application via the memory. \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS membuf : public iobuf +{ +protected: + /// \ru Максимальное количество регистрируемых объектов. \en The maximum number of registered facilities. + size_t maxRegCount; + + /// \ru Вектор filesPool хранит все используемые FileSpaces ,кроме sys, который определен в iobuf_Seq. + /// При использовании расширенного формата объекты каждого уровня записываются в отдельный FileSpace. + /// При этом индекс FileSpace в векторе соответствует уровню объекта в модели. + /// \en Keep all used FileSpaces (except sys, which is defined in iobuf_Seq). + /// When using the extended format, objects of each level are saved to a separate FileSpace. + /// Index of FileSpace in the vector corresponds to the level of the object in the model. + std::vector filesPool; + + /// \ru Стек FileSpaces. + /// \en Stack of FileSpaces. + struct FileStackEntry + { + ClusterReference _ref; + FileSpace * _file; + + FileStackEntry() : _file(NULL) {} + FileStackEntry ( ClusterReference r, FileSpace * f ) : _ref(r), _file(f) {} + }; + std::stack filesStack; + + /// \ru Кэш для данных о кластерах в FileSpace. + /// map: индекс кластера в массиве кластеров iobuf_Seq -> данные FileSpace (указатель на FileSpace и индекс в массиве индексов кластеров). + /// \en Cache for clusters data in FileSpace. + /// map: cluster index in cluster array iobuf_Seq -> FileSpace data (pointer to FileSpace and index in array of cluster indices in FileSpace). + std::map > fileClusterIndexCache; + +public: + /// \ru Конструктор. \en Constructor. + membuf(); + + /// \ru Деструктор. \en Destructor. + virtual ~membuf(); + +public: + /// \ru Буфер пуст? \en Is the buffer empty? + bool isEmpty() const; + /// \ru Записать в непрерывную память. + /// Функция подразумевает вполне определенное толкование значений входных данных, поэтому она не должна вызываться с неинициализированными аргументами. + /// \param[in,out] memory - память, куда писать. Если memory == NULL, то память выделяется. + /// \param[in] addSize - размер памяти, которую надо дополнительно выделить при выделении памяти. + /// Смысл addSize зависит от начального значения параметра memory: + /// если memory != 0 (т.е.память уже распределена), то addSize должен быть равен размеру памяти (addSize >= getMemLen() !!!). + /// если memory == 0, то addSize определяет, столько байт дополнительно добавить (обнулив) в начале при выделении памяти. + /// \en Write to contiguous memory. + /// The function implies a well-defined interpretation of the input values, so it should not be called with uninitialized arguments. + /// \param[in,out] memory - memory to write to. If memory == NULL, then memory is allocated. + /// \param[in] addSize - size of memory, which should be allocated additionally when allocating memory. + /// The meaning of addSize depends on the initial value of the parameter 'memory': + /// if memory != 0 (i.e. the memory is already allocated), then addSize should be equal to memory size (addSize >= getMemLen() !!!). + /// if memory == 0, then addSize defines a number of bytes to be added (and zeroed) at the beginning when allocating memory. + size_t toMemory( const char *& memory, size_t addSize = 0 ) const; + /// \ru Прочитать из непрерывной памяти. \en Read from the contiguous memory. + bool fromMemory( const char * memory ); + /// \ru Вычислить необходимую длину непрерывного куска памяти для буфера. \en Compute the necessary length of the contiguous memory block for a buffer. + size_t getMemLen() const; + + // \ru Установить максимальное количество регистрируемых объектов. \en Set the maximum number of registered facilities. + void setMaxRegCount( size_t n ); + // \ru Получить максимальное количество регистрируемых объектов. \en Get the maximum number of registered facilities. + size_t getMaxRegCount() const; + + /// \ru Подготовить поток чтения. \en Prepare read stream. + reader & read( reader & in ); + /// \ru Подготовить поток записи. \en Prepare write stream. + writer & write( writer & out ) const; + /// \ru Очистить буфер. \en Clear the buffer. + void clean(); + + ///< \ru Закрыть буфер. \en Close the buffer. + virtual void closeBuff(); + + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader &) operator >> ( reader & in, membuf *& ptr ); + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader &) operator >> ( reader & in, membuf & ref ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, const membuf * ptr ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, const membuf & ref ); + +protected: + virtual int setup(); ///< \ru Установить буфер для следующего кластера. \en Set the buffer for the next cluster. + virtual int flush(); ///< \ru Cбросить буфер. \en Flush the buffer. + void PrepareToRead( const VersionContainer & vers ); ///< \ru Инициировать все поля перед чтением. \en Initialize all the fields before reading. + + /// \ru Установить новый FileSpace для записи объекта уровня level. \en Set new FileSpace for writing an object of given level. + virtual FileSpace * enterFileSpace ( uint8 level ); + /// \ru Установить позицию для записи/чтения по заданному ClusterReference. + /// Сохранить предыдущую позицию в стеке File Spaces, если updateStack = true. + /// \en Set position for writing/reading by given ClusterReference. + /// If updateStack = true, push previous position to the File Spaces stack. + virtual FileSpace * enterFileSpace ( const ClusterReference & ref, bool updateStack ); + /// \ru Установить позицию для записи/чтения по заданным FileSpace и ClusterReference. + /// Внимание, в данном случае ClusterReference.clusterIndex указывает на индекс в массиве индексов кластеров в FileSpace! + /// Сохранить предыдущую позицию в стеке File Spaces, если updateStack = true. + /// \en Set position for writing/reading by given FileSpace and ClusterReference. + /// Warning: in this case, ClusterReference.clusterIndex is an index in the array of cluster indices in FileSpace! + /// If updateStack = true, push previous position to the File Spaces stack. + virtual FileSpace * enterFileSpace ( const ClusterReference & ref, FileSpace * file, bool updateStacke ); + /// \ru Извлечь предыдущий FileSpace из стека и установить его для записи/чтения. \en Pop the previous FileSpace from the stack and set it up for writing/reading. + virtual FileSpace * returnToPreviousFileSpace(); + +private: + bool alloc(); // \ru Добавить новый кластер; \en Add a new cluster. + bool fromFilebuf( mem & p ); // \ru Прочитать данные из файла записанного через дисковый буфер. \en Read data from the file recorded via the disk buffer. + void toFilebuf( mem & p, VERSION& version ) const; // \ru Записать данные. \en Write data. + +OBVIOUS_PRIVATE_COPY( membuf ) +}; + +//------------------------------------------------------------------------------ +/// \ru Прочитать буфер с диска. \en Read the buffer from the disk. \~ \ingroup Base_Tools_IO +// --- +#ifndef __MOBILE_VERSION__ +MATH_FUNC (iobuf &) createiobuf( const TCHAR * fileName ); + +//------------------------------------------------------------------------------ +/// \ru Записать буфер на диск. \en Write the buffer to the disk. \~ \ingroup Base_Tools_IO +// --- +MATH_FUNC (bool) writeiobuftodisk( const TCHAR * fileName, membuf & buf ); +#endif // __MOBILE_VERSION__ + +#endif // __IO_MEMORY_BUFFER_H diff --git a/C3d/Include/io_tape.h b/C3d/Include/io_tape.h new file mode 100644 index 0000000..b0cc193 --- /dev/null +++ b/C3d/Include/io_tape.h @@ -0,0 +1,3374 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация: чтение и запись потоковых классов. + \en Serialization: reading and writing of stream classes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_TAPE_H +#define __IO_TAPE_H + + +/// \ru Для контроля чтения/записи char* и TCHAR* только через ReadTCHAR/WriteTCHAR() скомпилировать с данным дефайном и увидим все места, где незаконно пишутся/читаются данные через operator << и >>. +/// \en Compile with the given preprocessor define for control of reading/writing char* and TCHAR* only via ReadTCHAR/WriteTCHAR(), not via illegally operator << and >>. +//#define DISABLE_RWTCHAR + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Классы, для которых при записи и чтении точно известен тип, \en Classes for which the type is exactly known while reading and writing +// \ru могут записываться в поток и читаться из потока с помощью \en can be written to the stream and read from the stream using +// \ru операторов << и >>, \en << and >> operators. +// \ru Это, например, классы лежащие в массиве SArray \en They are, for instance, classes contained in array SArray +// +// \ru Для таких объектов необходимо в описании класса установить : \en For such objects one should set in the class definition: +// \ru KNOWN_OBJECTS_RW_REF_OPERATORS( Class ) - для работы со ссылками и объектами класса \en KNOWN_OBJECTS_RW_REF_OPERATORS( Class ) - for work with references and class objects +// \ru KNOWN_OBJECTS_RW_PTR_OPERATORS( Class ) - для работы с указателями на объекты класса \en KNOWN_OBJECTS_RW_PTR_OPERATORS( Class ) - for work with pointers to class objects +// +// \ru и определить тела самих операторов : \en and define the solids of operators: +// +// \ru -- для ссылок \en -- for references +// inline reader& operator >> ( reader& in, Class& ref ) { +// return in >> ref. >> ref.... ; +// } +// +// writer& operator << ( writer& out, const Class& ref ) { +// return out << ref. << ref. ... ; +// } +// +// \ru -- для указателей \en -- for pointers +// inline reader& operator >> ( reader& in, Class*& ptr ) { +// ptr = new Class(...); +// return in >> ptr-> >> ptr->.... ; +// } +// +// writer& operator << ( writer& out, const Class* ptr ) { +// return out << ptr-> << ptr-> ... ; +// } +// +// \ru Классы, для которых при записи и чтении тип не известен. \en Classes for which the type is unknown while writing and reading. +// \ru Для описания такого класса Class как поточного в общем случае требуется : \en There are the following requirements for description of such class Class as a stream class: +// \ru -- Наследовать класс от TapeBase напрямую или через своих предков \en -- Inherit the class from TapeBase directly or via ancestors +// \ru Примечание : \en Note: +// \ru Если класс наследует более чем от одного поточного класса, \en If the class is inherited from more than one stream class, +// \ru то его предки !!!обязательно!!! должны наследовать от TapeBase \en then its parents MUST be inherited from TapeBase +// \ru виртуально, т.е. \en virtually, i.e. +// class A : public virtual TapeBase { +// ... +// }; +// +// class B : public virtual TapeBase { +// ... +// }; +// +// class C : public A, public B { +// ... +// }; +// +// \ru При этом классы A,B равно как и C нельзя укладывать в SArray, \en At the same time classes A,B cannot be put to array SArray, as well as class C, +// \ru поскольку они неявно содержат указатель на виртуальную базу \en since they implicitly contain a pointer to the virtual base +// +// \ru -- В декларации класса установить : \en -- Set in declaration of the class: +// \ru DECLARE_PERSISTENT_CLASS( Class ) - если Class не имеет поточных предков \en DECLARE_PERSISTENT_CLASS( Class ) - if Class does not have stream ancestors +// +// \ru -- В любом *.cpp файле установить : \en -- Set in any *.cpp file: +// \ru IMP_PERSISTENT_CLASS( AppID, Class ); - требуется написание конструктора \en IMP_PERSISTENT_CLASS( AppID, Class ); - the constructor implementation is required +// +// \ru -- Описать тела функций : \en -- Describe the solids of functions: +// void Class::Read( reader& in, Class* obj ); +// void Class::Write( writer& out, const Class* obj ); +// +// \ru Если Class не содержит своих полей данных, которые необходимо \en If Class does not contain its own data fields which should +// \ru писать в поток и читать оттуда, то вместо \en be written to stream and be read from stream, then instead of +// \ru IMP_PERSISTENT_CLASS следует применять \en IMP_PERSISTENT_CLASS one should use +// IMP_PERSISTENT_CLASS_FROM_BASE( Class, Base ), +// \ru при этом не надо определять функции Class::Read и Class::Write \en at that the functions Class::Read and Class::Write don't have to be defined +// +// \ru Если Class абстрактный -- применять \en If Class is abstract - apply +// IMP_A_PERSISTENT_CLASS( Class ); +// +// \ru Если Class не наследует ни от кого кроме TapeBase и плюс к этому \en If Class does not inherit from any class except TapeBase and, in addition, +// \ru не имеет полей данных для записи, применять : \en does not have data fields for writing, apply: +// \ru в cpp-файле \en in cpp-file +// \ru для абстрактного -- IMP_AWD_PERSISTENT_CLASS( Class ); \en for the abstract one -- IMP_AWD_PERSISTENT_CLASS( Class ); +// \ru для обычного -- IMP_WD_PERSISTENT_CLASS( Class ); \en for the ordinary one -- MP_WD_PERSISTENT_CLASS( Class ); +// \ru примечание : WD - Without Data \en note: WD - Without Data +// +// \ru Если Class наследует более чем от одного TapeBase'а \en If Class inherit from more than one TaperBase class, +// \ru наследование от него должно быть virtual'ным, например : \en the inheritance from it should be virtual, for instance: +// class first : virtual public TapeBase { +// ... +// DECLARE_PERSISTENT_CLASS( AppID, first ); +// }; +// +// class second : virtual public TapeBase { +// ... +// DECLARE_PERSISTENT_CLASS( AppID, second ); +// }; +// +// class third : public first, public second { +// ... +// DECLARE_PERSISTENT_CLASS( AppID, third ); +// }; +// IMP_PERSISTENT_CLASS( AppID, first ) +// IMP_PERSISTENT_CLASS( AppID, second ) +// IMP_PERSISTENT_CLASS( AppID, third ) +// \ru + функции чтения - записи \en + functions of reading-writing +// \ru + соответствующие конструкторы чтения \en + the corresponding reading constructors +// +// \ru Если Class template'ный, то для описания класса поточным требуется : \en If Class is a template class, then the following is required for definition the class as a stream class: +// \ru -- Наследовать template от TapeBase \en -- Inherit template from TapeBase +// +// \ru -- В декларации template'а установить : \en -- Set in the declaration of template : +// DECLARE_T_PERSISTENT_CLASS( Templ, Arg ); +// \ru где Templ - имя самого template'а \en where Templ is the name of template +// \ru Arg - имя формального template'ного аргумента \en Arg - the name of formal argument of template +// +// \ru -- В этом же h-файле вне декларации template'а установить \en -- Set in the same h-file outside the template declaration +// IMP_T_PERSISTENT_OPS( Templ ); +// +// \ru -- В этом же h-файле вне декларации template'а описать тела функций : \en -- In the same h-file outside the template declaration describe solids of functions: +// template +// void Templ::Read( reader& in, Templ* obj ); +// template +// void Templ::Write( writer& out, const Templ* obj ); +// \ru где \en where +// \ru Arg - формальный аргумент \en Arg - formal argument +// +// \ru -- В любом(ых) cpp-файле(ах) установить для каждого применения template'а : \en -- In any cpp-files set for each use of template: +// IMP_T_PERSISTENT_CLASS( Templ, Class ); +// \ru где \en where +// \ru Class - имя класса с которым применяется template ( фактический аргумент ) \en Class - name of the class the template is used with (the actual argument) +// +// \ru Примечание : для классов List, DList, SArray, PArray, Array2 все действия \en Note: for classes List, DList, SArray, PArray, Array2 all the instructions +// \ru уже выполнены, кроме последнего пункта. \en already applied except the last one. +// +// +// \ru По поводу функции Class::Read( reader& in, Class* obj ) рекомендуется \en Regarding function Class::Read( reader& in, Class* obj ) it is recommended +// \ru обратить внимание на : \en to pay attention to: +// +// \ru 1.Поля данных базового класса самостоятельно читать не нужно, вместо этого \en 1.Data fields of the base class don't require any special code to be read, instead of it +// \ru нужно вызвать функцию ReadBase( out, (Base*)obj ). \en one should call function ReadBase( out, (Base*)obj ). +// \ru Вызывать ее желательно в голове функции Class::Read \en It is desirable to call it in the head of function Class::Read +// \ru Обратите внимание на преобразование типа (Base*)obj ! \en Pay attention to the conversion like (Base*)obj ! +// +// \ru 2.Функция Class::Read декларирована статической (static), поэтому она не имеет \en 2. Function Class::Read is declared as static so it has no +// \ru указателя this ==> не пытайтесь делать что-нибудь типа : \en 'this' pointer ==> don't try to do something like: +// in >> field +// \ru правильно : \en the correct variant is: +// in >> obj->field; +// +// \ru По поводу функции Class::Write( writer& out, const Class* obj ) рекомендуется \en As for function Class::Write( writer& out, const Class* obj ), it is recommended +// \ru обратить внимание на : \en to pay attention to: +// +// \ru 1.Поля данных базового класса самостоятельно писать не нужно, вместо этого \en 1.Data fields of the base class don't require any special code to be written, instead of it +// \ru нужно вызвать функцию WriteBase( out, (const Base*)obj ). \en one should call function WriteBase( out, (const Base*)obj ). +// \ru Вызывать ее желательно в голове функции Class::Write \en It is desirable to call it in the head of function Class::Write +// \ru Обратите внимание на преобразование типа (const Base*)obj ! \en Pay attention to the conversion like (const Base*)obj ! +// +// \ru 2.Функция Write декларирована статической (static), поэтому она не имеет \en 2.Function Class::Write is declared as static so it has no +// \ru указателя this ==> не пытайтесь делать что-нибудь типа : \en 'this' pointer ==> don't try to do something like: +// out << field +// \ru правильно : \en the correct variant is: +// out << obj->field; +// +// +// \ru По поводу поддержки версий : \en As for versions support: +// \ru 1. При записи - \en 1. While reading - +// \ru iobuf имеет статическое поле данных iobuf_defaultVersionCont - контейнер версии \en iobuf has static data field iobuf_defaultVersionCont - the version container +// \ru и статическую функцию void iobuf::SetDefaultVersion( VERSION ); \en and the static function void iobuf::SetDefaultVersion( VERSION); +// \ru которую можно вызывать в любом месте программы, например : \en which can be called in any place of the program, for instance: +// iobuf::SetDefaultVersion( 192 ); +// \ru все потоки, которые будут записываться после этого, будут записывать этот \en all the streams which will be written after this will write this +// \ru номер в качестве версии \en number as a version +// \ru 2. При чтении - \en 2. While reading - +// \ru номер версии, записанный в поток возвращается функцией \en the version number written to the stream is returned by function +// VERSION in.MathVersion(), +// \ru где in - экземпляр потока \en where in - is the stream instance +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#ifdef _MSC_VER // LF-Linux: incomplete type reader/writer errors +#include // R/W +#endif // _MSC_VER +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif + +#include +#include + +//---------------------------------------------------------------------------------------- +// \ru Предварительное объявление классов чтения/записи. +// \en The forward declaration of the read/write classes. \~ +// --- +class TapeManager; +class reader; +class writer; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Типы регистрации объектов. + \en Types of objects registration. \~ + \details \ru Типы регистрации потоковых объектов. \n + \en Types of stream objects registration. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +enum RegistrableRec { + noRegistrable, ///< \ru Нерегистрируемый объект. \en Unregistrable object. + registrable ///< \ru Регистрируемый объект. \en Registrable object. +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Типы инициализации объектов. + \en The objects initialization types. \~ + \details \ru Типы регистрации потоковых объектов. \n + \en Types of stream objects registration. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +enum TapeInit { + tapeInit ///< \ru По умолчанию. \en By default. +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Упакованное имя класса. + \en Packed class name. \~ + \details \ru Упакованное имя одного класса - для набора массива потоковых классов в TapeClass. \n + \en Packed name of one class - for array of stream classes in TapeClass. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS ClassDescriptor +{ +protected: + uint16 val; ///< \ru Хэш имени класса. \en The class name hash. + MbUuid appID_; ///< \ru Дополнительный идентификатор приложения. \en Additional application identifier. + +private: + /// Признак записи appID + static const uint16 rwIdFlag; + +public: + /// \ru Конструктор. \en Constructor. + ClassDescriptor(); + /// \ru Конструктор по хэшу. \en Constructor by hash. + ClassDescriptor( uint16 v ); + /// \ru Конструктор по имени. \en Constructor by name. + ClassDescriptor( const char * name ); + /// \ru Конструктор по хэшу. \en Constructor by hash. + ClassDescriptor( uint16 v, const MbUuid & appID ); + /// \ru Конструктор по имени. \en Constructor by name. + ClassDescriptor( const char * name, const MbUuid & appID ); + /// \ru Конструктор по хэшу. \en Constructor by hash. + ClassDescriptor( const ClassDescriptor & other ); + + /// \ru Оператор присваивания. \en An assignment operator. + ClassDescriptor & operator = ( const ClassDescriptor & other ); + + /// \ru Оператор равенства. \en The equality operator. + bool operator == ( const ClassDescriptor & other ) const; + + /// \ru Оператор неравенства. \en The inequality operator. + bool operator!=( const ClassDescriptor & other ) const; + + /// \ru Оператор сравнения. \en Comparison operator. + bool operator < (const ClassDescriptor & other ) const; + + /// \ru Оператор сравнения. \en Comparison operator. + bool operator > ( const ClassDescriptor & other ) const; + +#ifdef C3D_DEBUG + /// \ru Оператор доступа. \en An access operator. + operator uint16() const { return val; } +#endif + + /// \ru Оператор записи. \en Write operator. + void Write( writer & out ); + + /// \ru Оператор чтения. \en Read operator. + bool Read( reader & in ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый класс для потоковых классов. + \en Base class for stream classes. \~ + \details \ru Базовый класс для потоковых классов. \n + \en Base class for stream classes. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS TapeBase { +private: + mutable use_count_type m_countRegistrable; ///< \ru Счетчик ссылок регистрируемого объекта. \en Number of usages of the registrable object. + +public: + /// \ru Конструктор. \en Constructor. + TapeBase( RegistrableRec regs = noRegistrable ); + /// \ru Конструктор копирования \en Copy-constructor. + TapeBase( const TapeBase & ); + /// \ru Деструктор. \en Destructor. + virtual ~TapeBase(); + + /// \ru Является ли потоковый класс регистрируемым. \en Whether the stream class is registrable. + RegistrableRec GetRegistrable() const; + /// \ru Установить состояние регистрации потокового класса. \en Set the state of registration of the stream class. + void SetRegistrable( RegistrableRec regs = registrable ) const; + /// \ru Получить дескриптор класса + //virtual ClassDescriptor GetClassDescriptor( const VersionContainer & ) const { return ClassDescriptor( ::pureName(typeid(*this).name()) ); } + virtual ClassDescriptor GetClassDescriptor( const VersionContainer & ) const = 0; + + /// \ru Получить имя класса. \en Get the class name. + virtual const char * GetPureName( const VersionContainer & ) const; + + /// \ru Принадлежит ли объект к регистрируемому семейству. \en Whether the object belongs to a registrable family. + virtual bool IsFamilyRegistrable() const; + +private: + /// \ru Функция-пустышка для обеспечения полиморфизма данного класса и его наследников. \en Dummy function for providing polymorphism of the given class and its descendants. + virtual void dummy(); // I need this to make class polymorphic + /// \ru Оператор присваивания \en Assignment operator + void operator = ( const TapeBase & other ); +}; + + +//---------------------------------------------------------------------------------------- +/// \ru Шаблон функции создания нового экземпляра. \en Template of function of a new instance creation. \~ \ingroup Base_Tools_IO +//--- +typedef TapeBase * (CALL_DECLARATION * BUILD_FUNC) ( void ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Шаблон функции преобразования. + \en Template of conversion function. \~ + \details \ru Шаблон функции преобразования из указателя на TapeBase к указателю на класс. \n + \en Template of function of conversion from a pointer to TapeBase to a pointer to the class. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +typedef void * (CALL_DECLARATION * CAST_FUNC) ( const TapeBase * ); + +//---------------------------------------------------------------------------------------- +/**\ru Шаблон функции чтения экземпляра. + \en Template of instance reading function. \~ + \ingroup Base_Tools_IO +*/ +//--- +typedef void (CALL_DECLARATION * READ_FUNC) ( reader & in, void * /*obj*/ ); + +//---------------------------------------------------------------------------------------- +/// \ru Шаблон функции записи экземпляра. \en Template of instance writing function. \~ \ingroup Base_Tools_IO +//--- +typedef void (CALL_DECLARATION * WRITE_FUNC) ( writer & out, void * /*obj*/ ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru "Обертка" для одного потокового класса. + \en "Wrapper" for one stream class. \~ + \details \ru "Обертка" для одного потокового класса ( не экземпляра! ). + Xранит упакованное имя класса и адреса функций, необходимых при чтении/записи. \n + \en "Wrapper" for one stream class ( not instance! ). + Stores packed class name and addresses of functions necessary while reading/writing. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS TapeClass { +protected: + ClassDescriptor hashValue; ///< \ru Упакованное имя класса. \en Packed class name. + BUILD_FUNC _builder; ///< \ru Функция создания нового экземпляра. \en Functions of a new instance creation. + CAST_FUNC _caster; ///< \ru Функция преобразования от TapeBase к указателю на класс. \en Function of conversion from TapeBase to a pointer to a class. + READ_FUNC _reader; ///< \ru Функция чтения. \en Read function. + WRITE_FUNC _writer; ///< \ru Функция записи. \en Write function. + +public: + /// \ru Конструктор. \en Constructor. + /// \ru Конструктор. \en Constructor. + TapeClass( const char * name, BUILD_FUNC b, CAST_FUNC c, READ_FUNC r, WRITE_FUNC w ); + TapeClass( const char * name, MbUuid appID, BUILD_FUNC b, CAST_FUNC c, READ_FUNC r, WRITE_FUNC w ); + /// \ru Деструктор. \en Destructor. + virtual ~TapeClass(); + /// \ru Получить упакованное имя класса. \en Get the packed class name. + ClassDescriptor GetPackedClassName() const; + /// \ru Получить упакованное имя класса для записи с учетом версии. \en Get the packed class name for writing subject to the version. + virtual ClassDescriptor GetPackedClassNameForWrite( VERSION ) const; + + friend class TapeManager; + friend struct TapeClassContainer; + +OBVIOUS_PRIVATE_COPY( TapeClass ) +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Массив для регистрации объектов при чтении/записи. + \en Array for object registration while reading/writing. \~ + \details \ru Массив для регистрации объектов при чтении/записи. \n + \en Array for object registration while reading/writing. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +class MATH_CLASS TapeRegistrator +{ +public: + typedef std::map TapeIndexMap; + typedef std::map IndexTapeMap; +protected: + TapeIndexMap tapeIndexPairs; /// \ru Ассоциативный массив связок [указатель на объект]-[номер в массиве]. \en Map of [object]-[index] pairs. + size_t maxCount; /// \ru Максимальное количество зарегистрированных объектов. \en Maximal number of registered objects. + IndexTapeMap indexesAndObjs; /// \ru Ассоциативный массив связок [номер в массиве]-[указатель на объект]. \en Map of [index]-[object] pairs. + +public: + /// \ru Конструктор. \en Constructor. + TapeRegistrator(); + /// \ru Деструктор. \en Destructor. + virtual ~TapeRegistrator(); + + /// \ru Получить количество зарегистрированных объектов. \en Get a number of registered objects. + size_t Count() const; + /// \ru Зарезервировать место под данное количество элементов. \en Reserve space for a given number of elements. + bool Reserve ( size_t n ); + + /// \ru Найти объект в массиве. \en Find the object in array. + size_t FindIt( const TapeBase * e ) const; + /// \ru Существует ли объект в массиве. \en Whether the object is in the array. + bool IsExist( const TapeBase * e ) const; + /// \ru Узнать максимально возможное количество регистрируемых объектов. \en Get the maximal possible number of registered objects. + size_t GetMaxCount() const; + /// \ru Выдать из массива зарегистрированных объектов указатель по заданному индексу. \en Get the pointer from the registered object array by the given index. + TapeBase * operator[]( size_t ind ) const ; + + ///< \ru Вставить элемент с определенным индексом. \en Insert an element with defined index. + void AddAt( const TapeBase * e, size_t ind ); + + /// \ru Добавить объект в массив. \en Add the object to the array. + size_t Add( const TapeBase * e ); + + /// \ru Выдать указатель на зарегистрированный объект по заданной позиции в кластере. \en Get the pointer of the registered object by the position in the cluster. + virtual TapeBase * Get( const ClusterReference & ) const { return NULL; } // unsupported + /// \ru Выдать позицию в кластере по заданному индексу. \en Get position in the cluster by given index. + virtual ClusterReference GetClusterRef( size_t ) const { return ClusterReference(); } // unsupported + /// \ru Добавить позицию объекта в кластере. \en Add the object position in the cluster. + virtual void AddClusterRef( size_t, const ClusterReference & ) {} // unsupported + /// \ru Очистить массив зарегистрированных объектов. \en Flush the array of registered objects. + virtual void FlushRegistered(); + /// \ru Очистить зарегистрированный объект \en Flush the registered object + virtual void FlushObj( const TapeBase * ); + + /// \ru Поменять местами массивы для регистрации + void Swap ( TapeRegistrator & swapReg ); + +protected: + /// \ru Очистить зарегистрированный объект \en Flush the registered object + void FlushObjInd( size_t ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t size ) { + return ::Allocate( size, typeid(TapeRegistrator).name() ); + } + void operator delete ( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(TapeRegistrator).name() ); + } +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +OBVIOUS_PRIVATE_COPY( TapeRegistrator ) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Массив для регистрации объектов с сохраненим информации о позиции чтения/записи. + \en Array for registration of objects with information about reading/writing position. \~ + \details \ru Массив для регистрации объектов с сохраненим информации о позиции чтения/записи. \n + \en Array for registration of objects with information about reading/writing position. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +class MATH_CLASS TapeRegistratorEx : public TapeRegistrator { +public: + typedef std::map ClusterIndexMap; + typedef std::map IndexClusterMap; +private: + /// \ru Ассоциативный массив [cluster position] -> [object index]. Основное хранилище для значений ClusterReference. + /// \en Map: [cluster position] -> [object index]. The primary container for ClusterReference values. + ClusterIndexMap refIndex; + /// \ru Ассоциативный массив [object index] -> [pointer to cluster position]. Содержит указатели на объекты ClusterReference из массива refIndex. + /// \en Map: [object index] -> [pointer to cluster position]. Contains pointers to object ClusterReference from refIndex map. + IndexClusterMap objReferences; + +public: + /// \ru Конструктор. \en Constructor. + TapeRegistratorEx(); + + /// \ru Выдать указатель на зарегистрированный объект по заданной позиции в кластере. + /// \en Get the pointer ещ the registered object by the position in the cluster. + virtual TapeBase * Get ( const ClusterReference & ref ) const; + + /// \ru Выдать позицию в кластере по заданному индексу. \en Get position in the cluster by given index. + virtual ClusterReference GetClusterRef ( size_t ind ) const; + + /// \ru Добавить позицию объекта в кластере. \en Add the object position in the cluster. + virtual void AddClusterRef( size_t ind, const ClusterReference & ref ); + + /// \ru Очистить массив зарегистрированных объектов. \en Flush the array of registered objects. + virtual void FlushRegistered(); + /// \ru Очистить зарегистрированный объект \en Flush the registered object + virtual void FlushObj ( const TapeBase * ); + +OBVIOUS_PRIVATE_COPY( TapeRegistratorEx ) +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Cпособы записи указателей. + \en Methods of writing pointers. \~ + \details \ru Cпособы записи указателей. \n + \en Methods of writing pointers. \n \~ + \ingroup Base_Tools_IO +*/ +//--- +enum TapePointerType { + tpt_Null = 0x00, ///< \ru Нулевой указатель. \en Null pointer. + tpt_Indexed16 = 0x01, ///< \ru Индекс указателя в массиве регистрации (2 байта). \en Pointer index in the registration array (2 bytes). + tpt_Object = 0x02, ///< \ru Тело объекта. \en The object solid. + tpt_Indexed8 = 0x03, ///< \ru Индекс указателя в массиве регистрации (1 байт). \en Index of pointer in the registration array (1 byte). + tpt_Indexed32 = 0x04, ///< \ru Индекс указателя в массиве регистрации (4 байта). \en Pointer index in the registration array (4 bytes). + tpt_Indexed64 = 0x05, ///< \ru Индекс указателя в массиве регистрации (8 байт). \en Index of pointer in the registration array (8 byte). + tpt_DetachedObject = 0x06, ///< \ru Тело объекта в отдельном FileSpace. \en The object solid in separated FileSpace. + tpt_ObjectCatalog = 0x07, ///< \ru Каталог объектов в отдельном FileSpace. \en The object catalog in separated FileSpace. +}; + + +#pragma pack( push, 1 ) +//---------------------------------------------------------------------------------------- +/** \brief \ru Базовый класс потока для реализации чтения и записи. + \en The base class of the stream for implementation of reading and writing. \~ + \details \ru Базовый класс потока для реализации чтения и записи. \n + \en The base class of the stream for implementation of reading and writing. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS tape { +protected: + iobuf_Seq & buf; ///< \ru Буфер для данных. \en Buffer for data. + TapeManager & manager; ///< \ru Менеджер потоков. \en Stream manager. + uint8 level; ///< \ru Уровень вложенности при чтении/записи. \en Nesting level while reading/writing. + TapeRegistrator & registrator; ///< \ru Структура для регистрации записанных/прочитанных адресов. \en Structure for registration of written/read addresses. + mutable ProgressBarWrapper * progress; ///< \ru Индикатор прогресса. \en Progress indicator. + +private: + uint8 ownBuf; ///< \ru Владеет ли буфером. \en Whether it owns the buffer. + bool ownReg; ///< \ru Признак владения регистратором. + +public: + /// \ru Тип объекта. \en An object type. + enum objectType { + otNull, + otIndexed, + otObject + }; + /// \ru Деструктор. \en Destructor. + virtual ~tape(); + + /// \ru Получить доступ к буферу. \en Get access to the buffer. + DEPRECATE_DECLARE iobuf & buffer() const; + /// \ru Получить доступ к буферу. \en Get access to the buffer. + DEPRECATE_DECLARE iobuf & operator()() const; + + /// \ru Получить доступ к буферу. \en Get access to the buffer. + const iobuf_Seq & GetIOBuffer() const; + + /// \ru Получить доступ к буферу. \en Get access to the buffer. + iobuf_Seq & GetIOBuffer(); + + /// \ru Узнать режим работы буфера. \en Get the buffer mode. + uint8 mode() const; //AR getMode + /// \ru Установить режим работы буфера. \en Set the buffer mode. + void setMode( uint8 m ); + /// \ru Убрать состояние буфера. \en Remove the buffer state. + void clearState( io::state sub ); + /// \ru Добавить состояние буфера. \en Add the buffer state. + void setState ( io::state add ); + + /// \ru Установить текущую версию равной версии хранилища. \en Set the current version to be equal to the storage version. + void SetVersionsByStorage(); + /// \ru Вернуть главную версию (математического ядра). \en Return the main version (of the mathematical kernel). + VERSION MathVersion() const; + /// \ru Вернуть дополнительную версию (конечного приложения). \en Return the additional version (of the target application). + VERSION AppVersion( size_t ind = -1 ) const; + + /// \ru Получить доступ к контейнеру версий. \en Get access to the version container. + const VersionContainer & GetVersionsContainer() const; + /// \ru Установить версию открытого файла. \en Set the version of open file. + void SetVersionsContainer( const VersionContainer & vers ) const; + /// \ru Установить версию хранилища. \en Set the storage version. + VERSION SetStorageVersion( VERSION v ); + + /// \ru Свежий ли буфер? \en Is the buffer fresh? + int fresh() const; + /// \ru Корректно ли состояние буфера.. \en Whether the buffer state is correct. + bool good() const; + /// \ru Достигнут ли конец файла? \en Is the end of file reached? + virtual uint8 eof() const; + /// \ru Получить флаг состояния буфера. \en Get the flag of the buffer state. + virtual uint32 state() const; + /// \ru Получить текущую позицию в потоке. \en Get current position in stream + virtual io::pos tell(); + ///< \ru Зарегистрировать указатель. \en Register the pointer. + void registrate( const TapeBase * e ); + ///< \ru Отменить регистрацию указателя. \en Unregister the pointer. + void unregistrate( const TapeBase * e ); + ///< \ru Есть ли зарегистрированный объект? \en Does a registered object exist? + bool exist ( const TapeBase * e ) const; + ///< \ru Очистить массив регистрации. \en Flush the registration array. + void flushRegister (); + ///< \ru Получить количество зарегистрированных объектов. \en Get the number of registered objects. + size_t RegisteredCount() const; + ///< \ru Получить максимально возможное количество объектов для регистрации. \en Get the maximal possible number of objects for registration. + size_t GetMaxRegisteredCount() const; + ///< \ru Зарезервировать память под n объектов. \en Reserve memory for n objects. + void ReserveRegistered( size_t n ); + /// \ru Владеем ли буфером? \en Do we own the buffer? + bool IsOwnBuffer() const; + /// \ru Установить флаг владения буфером. \en Set the flag of buffer ownership. + void SetOwnBuffer( bool own ); + + /// \ru Получить тип индекса. \en Get index type. + uint8 GetIndexType( size_t index ) const; + + /// \ru Работа с индикатором прогресса. \en Work with progress indicator. + + /// Инициализировать индикатор прогресса. \en Initialize progress indicator. + void InitProgress( IProgressIndicator * pr ); + void InitProgress( ProgressBarWrapper & pr ); + /// \ru Освободить текущий индикатор прогресса. Установить родительский индикатор прогресса, если он есть. + /// \en Release current progress indicator. Set parent progress indicator if it exists. + void ResetProgress(); + /// \ru Получить индикатор прогресса. \en Get progress indicator. + ProgressBarWrapper * GetProgress(); + /// \ru Завершить индикатор прогресса. \en End the progress indicator. + void FinishProgress(); + +protected: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE tape( membuf &, bool openSys, uint8 om, TapeRegistrator * , bool ownReg = false); + + /// \ru Конструктор. \en Constructor. + tape( iobuf_Seq & buf, bool ownBuf, bool openSys, uint16 om, TapeRegistrator * , bool ownReg = false); //AR(DP) + +private: + /// \ru Открыть системный файл в соответствующем режиме (чтение или запись). \en Open the system file in the appropriate mode (reading or writing). + void init( uint8 om ); + +private: + tape ( const tape & ); // \ru запрещено \en forbidden + void operator = ( const tape & ); // \ru запрещено \en forbidden +}; +#pragma pack( pop ) + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поток для чтения. + \en Stream for reading. \~ + \details \ru Поток для чтения. \n + \en Stream for reading. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS reader : public virtual tape { +public: + typedef std_unique_ptr reader_ptr; +protected: + /// \ru Конструктор. \en Constructor. + reader( iobuf_Seq & buf, bool ownbuf, bool openSys, uint16 om, TapeRegistrator * reg ); + + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader( iobuf_Seq & buf, bool ownbuf, bool openSys, uint16 om, TapeRegistrator & reg ); + + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader( membuf & sb, bool openSys, uint8 om, TapeRegistrator & reg ); + +public: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader( membuf & sb, uint8 om ); + + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader( iobuf_Seq & buf, uint16 om ); + + virtual ~reader() {} + +public: + /// \ru Создать читатель для последовательного буфера. \en Create reader for iobuf_Seq. + static reader_ptr CreateReader ( std_unique_ptr buf, uint16 om ); + + /// \ru Создать читатель для буфера в памяти. \en Create reader for membuf. + static reader_ptr CreateMemReader ( membuf & sb, uint8 om ); + +public: + /// \ru Прочитать объект. \en Read the object. + TapeBase * readObject ( TapeBase * mem = 0 ); + /// \ru Прочитать указатель на объект. \en Read a pointer to the object. + TapeBase * readObjectPointer(); + + /// \ru Читать каталог объектов. \en Read the object catalog. + virtual void ReadObjectCatalog(); + /// \ru Читать объект по позиции в кластере. \en Read an object by position in cluster. + virtual TapeBase * ReadObjectByPosition ( const ClusterReference & ) { return NULL; } + /// \ru Установить позицию чтения. \en Set reading position. + virtual bool SetReadPosition ( ClusterReference & ) { return false; } // not supported + + /// \ru Прочитать последовательность байт из буфера. \en Read a sequence of bytes from the buffer. + DEPRECATE_DECLARE size_t readSBytes ( void * bf, size_t len ); + + /// \ru Прочитать беззнаковое 64-разрядное целое \en Read unsigned 64-bit integer. + bool readUInt64( uint64 & ); + /// \ru Прочитать 64-разрядное целое \en Read 64-bit integer. + bool readInt64( int64 & ); + + /// \ru Прочитать байт из буфера. \en Read a byte from the buffer. + virtual int readByte(); + /// \ru Прочитать последовательность байт из буфера. \en Read a sequence of bytes from the buffer. + virtual bool readBytes( void * bf, size_t len ); + + /// \ru Получить указатель на дерево модели. \en Get pointer to the model tree. + virtual const c3d::IModelTree * GetModelTree() const { return NULL; } // not supported + + /// \ru Получить признак полного чтения текущего объекта. \en Get indicator of full reading of the current object. + /// \ru Установить признак полного чтения текущего объекта. \en Set indicator of full reading of the current object. + virtual bool IsFullRead() { return true; } // not supported + virtual void SetFullRead( bool ) {} // not supported + + /// \ru Получить ошибки чтения. \en Get reading errors. + virtual uint32 GetLastError(); + + // \ru Работа с индикатором прогресса. + // \en Work with progress indicator. + void InitProgress( IProgressIndicator * pr ); + void InitProgress( ProgressBarWrapper & pr ); + +protected: + /// \ru Читаем объект по заданной позиции. \en Read object on defined position. + virtual TapeBase * ReadDetachedObject (); + /// \ru Регистрируем объект. \en Register the object. + virtual void RegisterObject( TapeBase * obj, uint8 regId, ClusterReference ref = ClusterReference() ); + /// \ru Читаем индекс объекта. \en Read object index. + size_t ReadObjectIndex(); + +private: + reader ( const reader & ); // \ru запрещено \en forbidden + reader & operator = ( const reader & ); // \ru запрещено \en forbidden +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Индикатор прогресса в области видимости для reader. + \en Scoped progress indicator for reader. \~ + \details \ru Индикатор прогресса в области видимости для чтения модели с помощью reader. + Создается дочерний индикатор прогресса для reader. При выходе из области видимости + освобождается текущий индикатор прогресса и устанавливается родительский индикатор прогресса. \n + \en Scoped progress indicator for reader. + A scoped child progress indicator for reader is created. + When exiting the scope, the current progress indicator is released and + the parent progress indicator is set. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS ScopedReadProgress +{ + SPtr _progress; + reader & _reader; +public: + ScopedReadProgress( reader & in ); + ~ScopedReadProgress(); + // \ru Доступ к индикатору прогресса. \en Access to progress indicator. + ProgressBarWrapper * operator()(); + +private: + ScopedReadProgress(); + void operator = ( const ScopedReadProgress& ); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поток для чтения с возможностью чтения из нескольких FileSpaces по заданным позициям. + \en Stream for reading from several FileSpaces by given positions in clusters. \~ + \details \ru Поток для чтения с возможностью чтения из разных FileSpaces по заданным позициям. \n + \en Stream for reading from several FileSpace by given positions in clusters. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS reader_ex : public reader +{ + std_unique_ptr m_tree; + uint32 m_lastError; + bool m_fullRead; +protected: + /// \ru Конструктор. \en Constructor. + reader_ex( iobuf_Seq & buf, bool ownbuf, bool openSys, uint16 om ); + +public: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader_ex( membuf & sb, uint8 om ); + + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE reader_ex( iobuf_Seq & buf, uint16 om ); + + virtual ~reader_ex() {} + +public: + /// \ru Создать экземпляр reader_ex для последовательного буфера. \en Create reader_ex instance for sequential buffer. + static std_unique_ptr CreateReaderEx( std_unique_ptr buf, uint16 om ); + + /// \ru Создать читатель для буфера в памяти. \en Create reader for membuf. + static std_unique_ptr CreateMemReaderEx ( membuf & sb, uint8 om ); + + +public: + /// \ru Читаем каталог объектов. \en Read the object catalog. + virtual void ReadObjectCatalog(); + /// \ru Читать объект по позиции в кластере. \en Read an object by position in cluster. + virtual TapeBase * ReadObjectByPosition ( const ClusterReference& position ); + /// \ru Установить позицию чтения. \en Set reading position. + virtual bool SetReadPosition ( ClusterReference & ); + + /// \ru Получить указатель на дерево модели. \en Get pointer to the model tree. + virtual const c3d::IModelTree * GetModelTree() const; + + /// \ru Признак полного чтения текущего объекта. + /// При чтении произвольного объекта может возникнуть необходимость чтения некоторых данных его родителя. + /// В этом случае объект родителя читается не полностью и имеет флаг FullRead = false. + /// \en Indicator of full reading of the current object. + /// While reading an arbitrary object there can be a need to read some data from its parent. + /// In this case the parent object is read partially and has the flag FullRead = false. + + /// \ru Получить признак полного чтения текущего объекта. \en Get indicator of full reading of the current object. + virtual bool IsFullRead(); + /// \ru Установить признак полного чтения текущего объекта. \en Set indicator of full reading of the current object. + virtual void SetFullRead( bool full ); + + /// \ru Получить ошибки чтения. \en Get reading errors. + virtual uint32 GetLastError(); + +protected: + /// \ru Читать объект по заданной позиции. \en Read object on defined position. + virtual TapeBase * ReadDetachedObject(); + /// \ru Зарегистрировать объект. \en Register the object. + virtual void RegisterObject( TapeBase * obj, uint8 regId, ClusterReference ref = ClusterReference() ); + +private: + reader_ex ( const reader_ex & ); // \ru запрещено \en forbidden + reader_ex & operator = ( const reader_ex & ); // \ru запрещено \en forbidden +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поток для записи. + \en Stream for writing. \~ + \details \ru Поток для записи. \n + \en Stream for writing. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS writer : public virtual tape { +public: + typedef std_unique_ptr writer_ptr; +protected: + /// \ru Конструктор. \en Constructor. + writer ( iobuf_Seq & buf, bool ownBuf, bool openSys, uint16 om, TapeRegistrator * reg ); + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer( iobuf_Seq & buf, bool ownBuf, bool openSys, uint16 om, TapeRegistrator & reg ); + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer ( membuf & sb, bool openSys, uint8 om, TapeRegistrator & reg ); + +public: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer ( membuf & sb, uint8 om ); + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer ( iobuf_Seq & buf, uint16 om ); + + virtual ~writer() {} + +public: + /// \ru Создать писатель для последовательного буфера. \en Create writer for iobuf_Seq. + static writer_ptr CreateWriter( std_unique_ptr buf, uint16 om ); + /// \ru Создать писатель для буфера в памяти. \en Create writer for membuf. + static writer_ptr CreateMemWriter( membuf & sb, uint8 om ); + +public: + /// \ru Записать объект. \en Write the object. + void writeObject( const TapeBase * ); + /// \ru Записать указатель на объект. \en Write the pointer to the object. + void writeObjectPointer( const TapeBase * ); + + /// \ru Записать дерево модели. \en Write the model tree. + virtual void WriteModelCatalog(); + /// \ru Выдать следующую позицию записи. \en Get next writing position. + virtual ClusterReference GetNextWritePosition () { return ClusterReference(); } // not supported + + /// \ru Записать байт в буфер. \en Write the byte to the buffer. + virtual void writeByte ( uint8 ch ); + /// \ru Записать последовательность байт в буфер. \en Write the sequence of bytes to the buffer. + virtual void writeBytes ( const void * bf, size_t len ); + /// \ru Записать последовательность байт в буфер. \en Write the sequence of bytes to the buffer. + DEPRECATE_DECLARE size_t writeSBytes( const void * bf, size_t len ); + /// \ru Записать беззнаковое 64-разрядное целое. \en Write unsigned 64-bit integer. \~ \return \ru Возвращает количество записанных байт. \en Returns the number of written bytes. \~ + void writeUInt64( const uint64 & val ); + /// \ru Записать 64-разрядное целое. \en Write 64-bit integer. \~ \return \ru Возвращает количество записанных байт. \en Returns the number of written bytes. \~ + void writeInt64 ( const int64 & val ); + + // \ru Запись CHAR строки в поток (кодировка ANSI, русская локаль). \en Writing CHAR string to the stream. (ANSI coding, Russian locale). + writer & __writeChar ( const char * s ); + // \ru Запись WCHAR строки в поток (в потоке хранится как UTF-16). \en Writing WCHAR string to the stream (stored in the stream as UTF-16). + writer & __writeWchar( const TCHAR * s ); + // \ru Запись WCHAR строки в поток (в потоке хранится как UTF-16). \en Writing WCHAR string to the stream (stored in the stream as UTF-16). + writer & __writeWcharT( const wchar_t * s ); + // \ru Длина записи WCHAR строки в поток (в потоке хранится как UTF-16). \en Length of WCHAR string in the stream (stored in the stream as UTF-16). + size_t __lenWchar( const TCHAR * s ); + + /// \ru Получить указатель на дерево модели. \en Get pointer to the model tree. + virtual const c3d::IModelTree * GetModelTree() const { return NULL; } // not supported + +protected: + /// \ru Записать объект и тип. \en Write the object and type. + virtual void WriteObjectAndType ( const TapeBase * ); + /// \ru Зарегистрировать объект. \en Register the object. + virtual void RegisterObject ( const TapeBase * ); + /// \ru Завершить запись объекта. \en Finish writing the object. + virtual void EndWriteObject ( const TapeBase * ); + /// \ru Добавить ссылку на объект в каталог. \en Add reference to the object to the object catalog. + virtual void UpdateObjectCatalog ( const TapeBase * , const ClusterReference & ); + /// \ru Является ли объект регистрируемым. \en Whether the object is registrable. + virtual bool IsRegistrable( const TapeBase * mem ); + /// Записать индекс объекта + void WriteObjectIndex ( size_t index ); + +private: + writer ( const writer & ); // \ru запрещено \en forbidden + writer & operator = ( const writer & ); // \ru запрещено \en forbidden +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поток для записи в разные FileSpaces. +\en Stream for writing to several FileSpaces. \~ +\details \ru Поток для записи в разные FileSpaces. \n +\en Stream for writing to several FileSpaces. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS writer_ex : public writer +{ + std_unique_ptr m_tree; + ClusterReference m_catalogRef; +protected: + /// \ru Конструктор. \en Constructor. + writer_ex ( iobuf_Seq & buf, bool ownBuf, bool openSys, uint16 om ); + +public: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer_ex ( membuf & sb, uint8 om ); + + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE writer_ex ( iobuf_Seq & buf, uint16 om ); + + virtual ~writer_ex() {} + +public: + /// \ru Создать писатель для последовательного буфера. \en Create writer for iobuf_Seq. + static std_unique_ptr CreateWriterEx( std_unique_ptr buf, uint16 om ); + + /// \ru Создать писатель для буфера в памяти. \en Create writer for membuf. + static std_unique_ptr CreateMemWriterEx( membuf & sb, uint8 om ); + +public: + /// \ru Записать дерево модели. \en Write the model tree. + virtual void WriteModelCatalog(); + /// \ru Выдать следующую позицию записи. \en Get next writing position. + virtual ClusterReference GetNextWritePosition (); + + /// \ru Получить указатель на дерево модели. \en Get pointer to the model tree. + virtual const c3d::IModelTree * GetModelTree () const; + +protected: + /// \ru Записать объект и тип. \en Write the object and type. + virtual void WriteObjectAndType ( const TapeBase * ); + /// \ru Зарегистрировать объект. \en Register the object. + virtual void RegisterObject ( const TapeBase * ); + /// \ru Завершить запись объекта. \en Finish writing the object. + virtual void EndWriteObject ( const TapeBase * ); + /// \ru Добавить ссылку на объект в каталог. \en Add reference to the object to the object catalog. + virtual void UpdateObjectCatalog ( const TapeBase *mem, const ClusterReference& ref ); + /// \ru Является ли объект регистрируемым. \en Whether the object is registrable. + virtual bool IsRegistrable( const TapeBase * mem ); + +private: + writer_ex ( const writer_ex & ); // \ru запрещено \en forbidden + writer_ex & operator = ( const writer_ex & ); // \ru запрещено \en forbidden +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поток для чтения и записи. + \en Stream for reading and writing. \~ + \details \ru Поток для чтения и записи. \n + \en Stream for reading and writing. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS rw : public writer, public reader { +public: + typedef std_unique_ptr rw_ptr; +public: + /// \ru Конструктор. \en Constructor. + DEPRECATE_DECLARE rw( membuf & sb, uint8 om ); + + /// \ru Создать читатель/писатель для буфера в памяти. \en Create reader/writer for membuf. + static rw_ptr CreateMemWriter( membuf & sb, uint8 om ); + + /// \ru Конструктор. \en Constructor. + rw( iobuf & buf, uint16 om ); + + virtual ~rw() {} + +private: + /// \ru Конструктор. \en Constructor. + rw( iobuf_Seq & sb, bool ownBuf, bool openSys, uint16 om, TapeRegistrator * reg ); + + rw ( const rw & ); // \ru запрещено \en forbidden + rw & operator = ( const rw & ); // \ru запрещено \en forbidden +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Менеджер потоков. +\en Stream manager. \~ +\details \ru Менеджер потоков чтения и записи. \n +\en Reading and writing streams manager. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS TapeManager { +private: + //static TPointer & StaticTapeManager(); +protected : + TapeClass * currentClass; ///< \ru Указатель на объект потокового класса. \en A pointer to the object of stream class. +protected : + /// \ru Конструктор. \en Constructor. + TapeManager(); + /// \ru Конструктор копирования. \en Copy constructor. + TapeManager( const TapeManager & ); +public : + /// \ru Деструктор. \en Destructor. + virtual ~TapeManager() {} +public: + /// \ru Чтение экземпляра. \en Reading of the instance. + bool SpecimenReading ( reader & r, TapeBase & o ) const; + /// \ru Запись экземпляра. \en Writing of the instance. + bool SpecimenWriting ( writer & w, const TapeBase & o ) const; + /// \ru Установить текущим класс по упакованному имени класса. \en Set class as default one by packed class name. + bool SetCurrentClassByDescriptor ( const ClassDescriptor & descr ); + /// \ru Установить текущим класс по упакованному имени класса. \en Set class as default one by packed class name. + bool SetCurrentClassByDescriptor ( const ClassDescriptor & descr, const VersionContainer & ver ); + /// \ru Установить текущим класс по имени класса. \en Set class to be current by class name. + //bool SetCurrentClassByName ( const char * name ); + /// \ru Создать объект потокового класса. \en Create an object of a stream class. + TapeBase * BuildObject () const; + /// \ru Есть ли функция записи у класса? \en Is there the writing function in the class? + bool HasWriter () const; + /// \ru Получить упакованное имя класс для записи в версию. \en Get packed class name for writing to the version. + ClassDescriptor GetPackedClassNameForWrite ( VERSION version ) const; + + /// \ru Отпустить менеджер потоков после использования. \en Release the stream manager after using. + virtual void FreeTapeManager(); + + /// \ru Получить ссылку на менеджер потоков. \en Get a reference to the stream manager. + static TapeManager & GetTapeManager(); + +private: + TapeManager & operator = ( const TapeManager & ); +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Массив регистрации потоковых классов. +\en Array of stream classes registration. \~ +\details \ru Массив регистрации потоковых классов TapeClass. \n +\en Array of stream TapeClass classes registration. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +struct TapeClassContainer +{ + /// \ru Создать массив регистрации потоковых классов. \en Create an array of stream classes registration. + static EXPORT_DECLARATION TPointer< SFDPArray > & CALL_DECLARATION StaticTapeClassContainer(); + + /// \ru Добавить потоковый класс. \en Add a stream class. + static bool Add( TapeClass & tapeClass ) + { + if ( !StaticTapeClassContainer() ) + StaticTapeClassContainer() = new SFDPArray( 430, 1, TapeClass_Compare, NULL ); // \ru не владеет \en doesn't own + + return StaticTapeClassContainer()->AddExact( tapeClass ); + } + /// \ru Функция сравнения двух TapeClass для поиска. \en Function of two TapeClass comparison for a search. + static int TapeClass_Search( const TapeClass & t1, size_t d ) + { + return ( ( t1.hashValue == *(ClassDescriptor*)d ) ? 0 : (( t1.hashValue > *(ClassDescriptor*)d ) ? 1 : -1 ) ); + } + /// \ru Функция сравнения двух TapeClass для сортировки при вставке. \en Function of two TapeClass comparison for sorting while inserting. + static int TapeClass_Compare( const TapeClass & t1, const TapeClass & t2 ) + { + return ( ( t1.hashValue == t2.hashValue ) ? 0 : (( t1.hashValue > t2.hashValue ) ? 1 : -1 ) ); + } +}; + + +//---------------------------------------------------------------------------------------- +/// \ru Функция чтения базового класса. \en Function of reading the base class. \~ \ingroup Base_Tools_IO +// --- +template +inline void ReadBase( reader & in, Base * base ) { + Base::Read( in, base ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Функция записи базового класса. \en Function of writing the base class. \~ \ingroup Base_Tools_IO +// --- +template +inline void WriteBase( writer & out, const Base * base ) { + Base::Write( out, base ); +} + + +//---------------------------------------------------------------------------------------- +/// \ru Функция чтения виртуального базового класса. \en Function of reading of a virtual base class. \~ \ingroup Base_Tools_IO +// --- +template +void ReadVBase( reader & in, Base * base ) +{ + switch( in.readByte() ) { + case tape::otIndexed: + break; + case tape::otObject : + in.registrate( dynamic_cast(base) ); + Base::Read( in, base ); + break; + } +} + + +//---------------------------------------------------------------------------------------- +/// \ru Функция записи виртуального базового класса. \en Function of writing of a virtual base class. \~ \ingroup Base_Tools_IO +// --- +template +void WriteVBase( writer & out, const Base * base ) +{ + if ( !out.good() ) + return; + if ( out.exist( dynamic_cast(base) ) ) + out.writeByte( tape::otIndexed ); + else { + out.registrate( dynamic_cast(base) ); + out.writeByte( tape::otObject ); + Base::Write( out, base ); + } +} + + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Дружественные операторы чтения и записи указателей и ссылок. + \en Friend operators of reading and writing of pointers and references. \~ + \ingroup Base_Tools_IO +*/ +// --- +#define DECLARE_PERSISTENT_OPS( Class ) \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ) { \ + in.readObject( dynamic_cast(&ref) ); \ + return in; \ + } \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ) { \ + ptr = dynamic_cast( in.readObjectPointer() ); \ + return in; \ + } \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, const Class *& ptr ) \ + { \ + ptr = dynamic_cast( in.readObjectPointer() ); \ + return in; \ + } \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, const Class & ref ) { \ + out.writeObject( dynamic_cast(&ref) ); \ + return out; \ + } \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, const Class * ptr ) { \ + out.writeObjectPointer( dynamic_cast(ptr) ); \ + return out; \ + } \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, Class & ref ) { \ + out.writeObject( dynamic_cast(&ref) ); \ + return out; \ + } \ + friend inline writer & CALL_DECLARATION operator << ( writer& out, Class * ptr ) { \ + out.writeObjectPointer( dynamic_cast(ptr) ); \ + return out; \ + } + +/** + \brief \ru Объявление операторов чтения и записи указателей и ссылок. + \en Declaration of operators of reading and writing of pointers and references. \~ + \ingroup Base_Tools_IO +*/ +// --- +#define DECLARE_PERSISTENT_OPS_B( Class ) \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ); \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ); \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, const Class *& ptr ); \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, const Class & ref ); \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, const Class * ptr ); \ + friend inline writer & CALL_DECLARATION operator << ( writer & out, Class & ref ); \ + friend inline writer & CALL_DECLARATION operator << ( writer& out, Class * ptr ); + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Операторы чтения и записи указателей и ссылок. + \en Operators of reading and writing of pointers and references. \~ + \ingroup Base_Tools_IO +*/ +// --- +#ifdef __BORLANDC__ +#define IMPL_PERSISTENT_OPS( Class ) \ + inline reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ) { \ + in.readObject( dynamic_cast(&ref) ); \ + return in; \ + } \ + inline reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ) { \ + ptr = dynamic_cast( in.readObjectPointer() ); \ + return in; \ + } \ + inline reader & CALL_DECLARATION operator >> ( reader & in, const Class *& ptr ) \ + { \ + ptr = dynamic_cast( in.readObjectPointer() ); \ + return in; \ + } \ + inline writer & CALL_DECLARATION operator << ( writer & out, const Class & ref ) { \ + out.writeObject( dynamic_cast(&ref) ); \ + return out; \ + } \ + inline writer & CALL_DECLARATION operator << ( writer & out, const Class * ptr ) { \ + out.writeObjectPointer( dynamic_cast(ptr) ); \ + return out; \ + } \ + inline writer & CALL_DECLARATION operator << ( writer & out, Class & ref ) { \ + out.writeObject( dynamic_cast(&ref) ); \ + return out; \ + } \ + inline writer & CALL_DECLARATION operator << ( writer& out, Class * ptr ) { \ + out.writeObjectPointer( dynamic_cast(ptr) ); \ + return out; \ + } +#else +#define IMPL_PERSISTENT_OPS( Class ) +#endif + +//---------------------------------------------------------------------------------------- +/** + \brief \ru Операторы чтения указателей и ссылок для класса без записи. + \en Operators of reading pointers and references for a class without writing. \~ + \ingroup Base_Tools_IO +*/ +// --- +#define DECLARE_PERSISTENT_RO_OPS( Class ) \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class & ref ) { \ + in.readObject( dynamic_cast(&ref) ); \ + return in; \ + } \ + friend inline reader & CALL_DECLARATION operator >> ( reader & in, Class *& ptr ) { \ + ptr = dynamic_cast( in.readObjectPointer() ); \ + return in; \ + } + +//---------------------------------------------------------------------------------------- +/// \ru Функции чтения и записи. \en Functions of reading and writing. \~ \ingroup Base_Tools_IO +// --- +#define DECLARE_PERSISTENT_FUNCS( Class ) \ + public: \ + static void Read ( reader & in, Class * obj ); \ + static void Write( writer & out, const Class * obj ) + +//---------------------------------------------------------------------------------------- +/// \ru Функции чтения для класса без записи. \en Function of reading for class without writing. \~ \ingroup Base_Tools_IO +// --- +#define DECLARE_PERSISTENT_RO_FUNCS( Class ) \ + public: \ + static void Read( reader & in, Class * obj ) + +//------------------------------------------------------------------------------ +/// \ru Функции получения дескриптора класса. \~ \ingroup Base_Tools_IO +// --- +#define DECLARE_CLASS_DESC_FUNC( Class ) \ + public: \ + virtual ClassDescriptor GetClassDescriptor( const VersionContainer & ) const; + +//------------------------------------------------------------------------------ +/// \ru Функции получения дескриптора (хэш + APP UID) класса. \~ \ingroup Base_Tools_IO +// --- +#define IMP_CLASS_DESC_FUNC( AppID, Class ) \ + ClassDescriptor Class::GetClassDescriptor( const VersionContainer & v) const \ + { return ClassDescriptor( GetPureName(v), AppID ); } + +//---------------------------------------------------------------------------------------- +/// \ru Конструктор для потокового класса. \en Constructor for a stream class. \~ \ingroup Base_Tools_IO +// --- +#define DECLARE_PERSISTENT_CTOR( Class ) \ + public: \ + Class( TapeInit ) + +//---------------------------------------------------------------------------------------- +/// \ru Конструктор для потокового класса. \en Constructor for a stream class. \~ \ingroup Base_Tools_IO +// --- +#define IMP_PERSISTENT_CTOR( Class ) \ + Class::Class( TapeInit ) {} + +//---------------------------------------------------------------------------------------- +/// \ru Конструктор для класса с одной потоковой базой. \en Constructor for a class with one stream base. \~ \ingroup Base_Tools_IO +// --- +#define IMP_PERSISTENT_CTOR1( Class, Base ) \ + Class::Class( TapeInit ) : Base( tapeInit ) {} + +//---------------------------------------------------------------------------------------- +/// \ru Конструктор для класса с двумя потоковыми базами. \en Constructor for a class with two stream bases. \~ \ingroup Base_Tools_IO +// --- +#define IMP_PERSISTENT_CTOR2( Class, Base1, Base2 ) \ + Class::Class( TapeInit ) : Base1( tapeInit ), Base2( tapeInit ) {} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Конструирование нового экземпляра класса. + \en Construction of a new instance of the class. \~ + \details \ru Конструирование нового экземпляра класса. \n + Определяются функция конструирования нового экземпляра класса, + функция преобразования от указателя на TapeBase к указателю на класс + и класс (не экземпляр!) добавляется в массив потоковых + путем создания переменной r ## Class типа TapeClass + (а в конструкторе TapeClass производится + добавление в массив потоковых классов). + Символ ## - это указание препроцессору о необходимости "склейки" + текущего идентификатора с последующим. + \en Construction of a new instance of the class. \n + Definition of functions of construction a new instance of the class, + function of conversion from a pointer to TapeBase to a pointer to the class + and addition of the class (not an instance) to the array of stream classes + by creating variable r ## Class of type TapeClass + (and in constructor of TapeClass + addition to array of stream classes is performed). + Symbol ## is a directive for preprocessor about the necessity of "glueing" + of the current identifier with the next one. \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_REGISTRATION( AppID, Class ) \ + TapeBase * CALL_DECLARATION make ## _ ## Class () { \ + return new Class(tapeInit); \ + } \ + void * CALL_DECLARATION cast ## _ ## Class ( const TapeBase * obj ) { \ + return dynamic_cast(const_cast(obj) ); \ + } \ + \ + TapeClass r ## Class( \ + typeid(Class).name(), \ + AppID, \ + (BUILD_FUNC) make ## _ ## Class, \ + (CAST_FUNC ) cast ## _ ## Class, \ + (READ_FUNC ) Class::Read, \ + (WRITE_FUNC) Class::Write \ + ) + +//------------------------------------------------------------------------------ +// \ru Как записать переименованный класс в старую версию (с) Столяров А.Г. \en How to write the renamed class to the old version (c) Stolyarov A.G. +/* #define IMP_PERSISTENT_REGISTRATION_OLDCLASS( Class, OldClass ) \ + TapeBase * CALL_DECLARATION make ## _ ## Class () { \ + return dynamic_cast( new Class(tapeInit) ); \ + } \ + void * CALL_DECLARATION cast ## _ ## Class ( const TapeBase * obj ) { \ + return dynamic_cast(const_cast(obj) ); \ + } \ + TapeClass r ## Class( \ + typeid(Class).name(), \ + typeid(OldClass).name(), \ + (BUILD_FUNC) make ## _ ## Class, \ + (CAST_FUNC ) cast ## _ ## Class, \ + (READ_FUNC ) Class::Read, \ + (WRITE_FUNC) Class::Write \ + ) + +#define IMP_PERSISTENT_OLDCLASS( Class, OldClass ) \ + IMP_PERSISTENT_REGISTRATION_OLDCLASS( Class, OldClass ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) + +IMP_PERSISTENT_OLDCLASS( Class, OldClass ); + +class TapeClassForNewObjects : public TapeClass { +protected : + ClassDescriptor hashValueOld; // \ru упакованное имя класса для старой версии файла \en packed class name for the old version of file +public : + TapeClassForNewObjects( const char * name, const char * oldName, BUILD_FUNC b, CAST_FUNC c, READ_FUNC r, WRITE_FUNC w ); + virtual ~TapeClassForNewObjects(); + virtual ClassDescriptor GetPackedClassNameForWrite( long version ) const; + OBVIOUS_PRIVATE_COPY(TapeClassForNewObjects); +}; + +TapeClassForNewObjects::TapeClassForNewObjects( const char * name, const char * oldName, + BUILD_FUNC b, CAST_FUNC c, READ_FUNC r, WRITE_FUNC w ) + : TapeClass( name, b, c, r, w ) + , hashValueOld( ::hash(::pureName( oldName ) ) ) +{ +} + +ClassDescriptor TapeClassForNewObjects::GetPackedClassNameForWrite( long version ) const { + uint16 res = version > CHANGE_VERSION ? TapeClass::GetPackedClassName() : uint16(hashValueOld); + return res; +} +*/ + +//---------------------------------------------------------------------------------------- +/// \ru Конструирование нового экземпляра класса для класса без записи. \en Construction of a new instance of the class for a class without writing. \~ \ingroup Base_Tools_IO +// --- +#define IMP_PERSISTENT_RO_REGISTRATION( AppID, Class ) \ + TapeBase * CALL_DECLARATION make ## _ ## Class () { \ + return new Class(tapeInit); \ + } \ + void * CALL_DECLARATION cast ## _ ## Class ( const TapeBase * obj ) { \ + return dynamic_cast(const_cast(obj) ); \ + } \ + TapeClass r ## Class( \ + typeid(Class).name(), \ + AppID, \ + (BUILD_FUNC) make ## _ ## Class, \ + (CAST_FUNC ) cast ## _ ## Class, \ + (READ_FUNC ) Class::Read, \ + (WRITE_FUNC) 0 \ + ) + +/** \brief \ru Переменная включает перегрузку операторов new/delete, + обеспечивающую последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en The variable enables overloading of new/delete operators + which provides sequential access to the allocation/deallocation functions + from different threads. \~ + \details \ru Переменная включает перегрузку операторов new/delete, + обеспечивающую последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en The variable enables overloading of new/delete operators + which provides sequential access to the allocation/deallocation functions + from different threads. \~ +\ingroup Base_Tools_IO +*/ +// --- +#define __OVERLOAD_MEMORY_ALLOCATE_FREE_ + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ + //---------------------------------------------------------------------------------------- + /// \ru Объявление функций new, delete и операторов доступа. \en Declaration of functions new, delete and access operators. \~ \ingroup Base_Tools_IO + // \ru операторы * и -> автоматически не перегружаются, \en operators * and -> are not overloaded automatically, + // \ru для их использования нужно писать примерно так: \n \en one should write like this to use them: \n + // \ru вместо ptr->F(); ptr->operator ->()->F(); \n \en instead of ptr->F(); ptr->operator ->()->F(); \n + // \ru или ptr->operator *().F(); \n \en or ptr->operator *().F(); \n + // \ru или ptr->operator Class*()->F(); \n \en or ptr->operator Class*()->F(); \n + // \ru Для ссылок так же. \en Similarly for references. + // --- + #define DECLARE_NEW_DELETE_CLASS( Class ) \ + public: \ + void * operator new ( size_t ); \ + void operator delete ( void *, size_t ); \ + void * operator new [] ( size_t ); \ + void operator delete [] ( void * ); + + //-------------------------------------------------------------------------------------- + /// \ru Реализация функций new, delete и операторов доступа. \en Implementation of functions new, delete and access operators. \~ \ingroup Base_Tools_IO + // --- + #define IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) \ + void * Class::operator new( size_t size ) { \ + return ::Allocate( size, typeid(Class).name() ); } \ + void Class::operator delete ( void *ptr, size_t size ) { \ + ::Free( ptr, size, typeid(Class).name() ); } \ + \ + void * Class::operator new[] ( size_t size ) { \ + return ::AllocateArray( size, typeid(Class[]).name()); } \ + void Class::operator delete[] ( void *ptr ) { \ + ::FreeArray( ptr, typeid(Class[]).name() ); } + + //-------------------------------------------------------------------------------------- + /// \ru Объявление операторов new и delete, обеспечивающих последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// \en Declaration of new and delete operators which provide sequential access + /// to the allocation/deallocation functions from different threads. \~ + /// \ingroup Base_Tools_IO + // --- + #define DECLARE_NEW_DELETE_CLASS_EX( Class ) + + //-------------------------------------------------------------------------------------- + /// \ru Реализация операторов new и delete, обеспечивающих последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// \en Implementation of new and delete operators which provide sequential access + /// to the allocation/deallocation functions from different threads. \~ + /// \ingroup Base_Tools_IO + // --- + #define IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) + +#else // __DEBUG_MEMORY_ALLOCATE_FREE_ + //-------------------------------------------------------------------------------------- + /// \ru Объявление функций new, delete и операторов доступа. \en Declaration of functions new, delete and access operators. \~ \ingroup Base_Tools_IO + // --- + #define DECLARE_NEW_DELETE_CLASS( Class ) + //-------------------------------------------------------------------------------------- + /// \ru Реализация функций new, delete и операторов доступа. \en Implementation of functions new, delete and access operators. \~ \ingroup Base_Tools_IO + // --- + #define IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) + +#if defined(__OVERLOAD_MEMORY_ALLOCATE_FREE_) && !defined(C3D_DEBUG) + + //-------------------------------------------------------------------------------------- + /// \ru Объявление операторов new и delete, обеспечивающих последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// Перегружаются все стандартные операторы new и delete. + /// \en Declaration of new and delete operators which provide sequential access + /// to the allocation/deallocation functions from different threads. + /// All standard new and delete operators are overloaded. \~ + /// \ingroup Base_Tools_IO + // --- + #define DECLARE_NEW_DELETE_CLASS_EX( Class ) \ + public: \ + void * operator new ( size_t ); \ + void * operator new ( size_t, const std::nothrow_t & ) throw(); \ + void * operator new ( size_t, void * ); \ + void * operator new [] ( size_t ); \ + void * operator new [] ( size_t, const std::nothrow_t & ) throw(); \ + void * operator new [] ( size_t, void * ); \ + void operator delete ( void * ); \ + void operator delete ( void *, const std::nothrow_t & ) throw(); \ + void operator delete ( void *, void* ); \ + void operator delete [] ( void * ); \ + void operator delete [] ( void *, const std::nothrow_t & ) throw(); \ + void operator delete [] ( void *, void * ); + + //-------------------------------------------------------------------------------------- + /// \ru Реализация операторов new и delete, обеспечивающая последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// Перегружаются все стандартные операторы new и delete. + /// \en Implementation of new and delete operators which provides sequential access + /// to the allocation/deallocation functions from different threads. + /// All standard new and delete operators are overloaded. \~ + /// \ingroup Base_Tools_IO + // --- + #define IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) \ + void* Class::operator new( size_t size ) { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new( size ); } \ + void Class::operator delete( void *ptr ) { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete( ptr ); } \ + \ + void* Class::operator new( size_t size, void *ptr ) { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new( size, ptr ); } \ + void Class::operator delete( void *ptr, void *ptr2 ) { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete( ptr, ptr2 ); } \ + \ + void* Class::operator new[]( size_t size ) { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new[]( size ); } \ + void Class::operator delete[]( void *ptr ) { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete[]( ptr ); } \ + \ + void* Class::operator new []( size_t size, void *ptr ) { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new[]( size, ptr ); } \ + void Class::operator delete []( void *ptr, void *ptr2 ) { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete[]( ptr, ptr2 ); } \ + \ + void* Class::operator new( size_t size, const std::nothrow_t &nt ) throw() { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new( size, nt ); } \ + void Class::operator delete( void *ptr, const std::nothrow_t &nt ) throw() { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete( ptr, nt ); } \ + \ + void* Class::operator new []( size_t size, const std::nothrow_t &nt ) throw() { \ + SET_MEMORY_SCOPED_LOCK; \ + return ::operator new[]( size, nt ); } \ + void Class::operator delete []( void *ptr, const std::nothrow_t &nt ) throw() { \ + SET_MEMORY_SCOPED_LOCK; \ + ::operator delete[]( ptr, nt ); } + +#else // __OVERLOAD_MEMORY_ALLOCATE_FREE_ + + //-------------------------------------------------------------------------------------- + /// \ru Объявление операторов new и delete, обеспечивающих последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// \en Declaration of new and delete operators which provide sequential access + /// to the allocation/deallocation functions from different threads. \~ + /// \ingroup Base_Tools_IO + // --- + #define DECLARE_NEW_DELETE_CLASS_EX( Class ) + + //-------------------------------------------------------------------------------------- + /// \ru Реализация операторов new и delete, обеспечивающая последовательное обращение + /// к функциям выделения/освобождения памяти из разных потоков. + /// \en Implementation of new and delete operators which provides sequential access + /// to the allocation/deallocation functions from different threads. \~ + /// \ingroup Base_Tools_IO + // --- + #define IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) + +#endif // __OVERLOAD_MEMORY_ALLOCATE_FREE_ + +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +//------------------------------------------------------------------------------ +/** \brief \ru Объявление класса Class поточным. + \en Declaration of class Class as a stream one. \~ + \details \ru Объявление класс Class поточным. + Устанавливается в декларации класса в файле *.h. + Декларирует операторы <<, >>, а также функции Read и Write, + которые должны быть определены в любом файле *.cpp + Class должен наследовать от TapeBase. + Для этого класса должен быть определен конструктор чтения, + а его тело должно быть в .cpp файле. \n + \en Declaration of class Class as a stream one. + It is set in the declaration of class in file *.h. + Declares operators <<, >> and also functions Read and Write + which must be defined in any file *.cpp + Class must be inherited from TapeBase. + The read constructor must be defined for the class + and its solid should be in .cpp file. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +#ifndef __BORLANDC__ + +#define DECLARE_PERSISTENT_CLASS( Class ) \ + DECLARE_PERSISTENT_FUNCS( Class ); \ + DECLARE_PERSISTENT_OPS( Class ); \ + DECLARE_PERSISTENT_CTOR( Class ); \ + DECLARE_NEW_DELETE_CLASS( Class ); \ + DECLARE_CLASS_DESC_FUNC(Class) + +#else // __BORLAND__ + +#define DECLARE_PERSISTENT_CLASS( Class ) \ + DECLARE_PERSISTENT_FUNCS( Class ); \ + DECLARE_PERSISTENT_OPS_B( Class ); \ + DECLARE_PERSISTENT_CTOR( Class ); \ + DECLARE_NEW_DELETE_CLASS( Class ); \ + DECLARE_CLASS_DESC_FUNC(Class) + +#endif // __BORLAND__ + +/** \brief \ru Аналог макроса DECLARE_PERSISTENT_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en Analog of DECLARE_PERSISTENT_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads. \~ +\details \ru Аналог макроса DECLARE_PERSISTENT_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков + (включается переменной __OVERLOAD_MEMORY_ALLOCATE_FREE_). + \en Analog of DECLARE_PERSISTENT_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads + (enabled by defining __OVERLOAD_MEMORY_ALLOCATE_FREE_). \~ +\ingroup Base_Tools_IO +*/ +// --- +#define DECLARE_PERSISTENT_CLASS_NEW_DEL( Class ) \ + DECLARE_PERSISTENT_CLASS( Class ) \ + DECLARE_NEW_DELETE_CLASS_EX( Class ) + +//------------------------------------------------------------------------------ +/** \brief \ru Реализация объявления DECLARE_PERSISTENT_CLASS. + \en Implementation of DECLARE_PERSISTENT_CLASS declaration. \~ + \details \ru Реализация объявления DECLARE_PERSISTENT_CLASS. + Описывает необходимые действия для поточного класса. + Устанавливается в любой .cpp файл. + Class должен наследовать от TapeBase. + Должны быть реализованы функции чтения Read и записи Write. \n + \en Implementation of DECLARE_PERSISTENT_CLASS declaration. + Describes the necessary operations for a stream class. + It is set into any .cpp file. + Class must be inherited from TapeBase. + Function Read of reading and function Write of writing should be implemented. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_CLASS( AppID, Class ) \ + IMP_PERSISTENT_REGISTRATION( AppID, Class ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ); \ + IMP_CLASS_DESC_FUNC( AppID, Class ) + +/** \brief \ru Аналог макроса IMP_PERSISTENT_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en Analog of IMP_PERSISTENT_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads. \~ + \details \ru Аналог макроса IMP_PERSISTENT_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков + (включается переменной __OVERLOAD_MEMORY_ALLOCATE_FREE_). + \en Analog of IMP_PERSISTENT_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads + (enabled by defining __OVERLOAD_MEMORY_ALLOCATE_FREE_). \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_CLASS_NEW_DEL( AppID, Class ) \ + IMP_PERSISTENT_CLASS( AppID, Class ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ); + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые действия для поточного класса без записи \en Describes the necessary operations for a stream class without writing. +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется наличие функций \en 2. There must be the following functions +// - void Class:Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// --- +#define IMP_PERSISTENT_RO_CLASS( AppID, Class ) \ + IMP_PERSISTENT_RO_REGISTRATION( AppID, Class ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) + +//------------------------------------------------------------------------------ +/** \brief \ru Аналог макроса IMP_PERSISTENT_RO_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en Analog of IMP_PERSISTENT_RO_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads. \~ + \details \ru Аналог макроса IMP_PERSISTENT_RO_CLASS + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков + (включается переменной __OVERLOAD_MEMORY_ALLOCATE_FREE_). + \en Analog of IMP_PERSISTENT_RO_CLASS macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads + (enabled by defining __OVERLOAD_MEMORY_ALLOCATE_FREE_). \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_RO_CLASS_NEW_DEL( AppID, Class ) \ + IMP_PERSISTENT_RO_CLASS( AppID, Class ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые операции для абстрактного \en Describes the necessary operations for abstract +// \ru поточного класса \en stream class +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется наличие функций \en 2. There must be the following functions +// - void Class::Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// --- +#define IMP_A_PERSISTENT_CLASS( AppID, Class ) \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) \ + IMP_CLASS_DESC_FUNC( AppID, Class ) + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые операции абстрактного поточного класса, \en Describes the necessary operations for the abstract stream class +// \ru наследующего от другого такого же, и у которого \en inherited from another class which is the same and which +// \ru нет своих полей данных для записи в поток \en has no its own data fields for writing to stream +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется (!!!) отсутствие (!!!) функций \en 2. The following functions must be (!!!) absent (!!!) +// - void Class::Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// \ru эти функции генерируются автоматически \en these functions are generated automatically +// --- +#define IMP_A_PERSISTENT_CLASS_FROM_BASE( AppID, Class, Base ) \ + void Class::Read( reader & in, Class * obj ) { \ + Base::Read( in, obj ); \ + } \ + void Class::Write( writer & out, const Class * obj ) { \ + Base::Write( out, obj ); \ + } \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) \ + IMP_CLASS_DESC_FUNC( AppID, Class ) + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые операции поточного класса, \en Describes the necessary operations of the stream class +// \ru наследующего от другого такого же, и у которого \en inherited from another class which is the same and which +// \ru нет своих полей данных для записи в поток \en has no its own data fields for writing to stream +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется (!!!) отсутствие (!!!) функций \en 2. The following functions must be (!!!) absent (!!!) +// - void Class::Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// \ru эти функции генерируются автоматически \en these functions are generated automatically +// --- +#define IMP_PERSISTENT_CLASS_FROM_BASE( AppID, Class, Base ) \ + IMP_PERSISTENT_REGISTRATION( AppID, Class ); \ + IMP_A_PERSISTENT_CLASS_FROM_BASE( AppID, Class, Base ) + +//------------------------------------------------------------------------------ +/** \brief \ru Аналог макроса IMP_PERSISTENT_CLASS_FROM_BASE + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en Analog of IMP_PERSISTENT_CLASS_FROM_BASE macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads. \~ + \details \ru Аналог макроса IMP_PERSISTENT_CLASS_FROM_BASE + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков + (включается переменной __OVERLOAD_MEMORY_ALLOCATE_FREE_). + \en Analog of IMP_PERSISTENT_CLASS_FROM_BASE macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads + (enabled by defining __OVERLOAD_MEMORY_ALLOCATE_FREE_). \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_CLASS_FROM_BASE_NEW_DEL( AppID, Class, Base ) \ + IMP_PERSISTENT_CLASS_FROM_BASE( AppID, Class, Base ) \ + IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые операции для поточного класса, \en Describes the necessary operations for the stream class +// \ru не наследующего ни от кого кроме TapeBase, и у которого \en which is not inherited from any class except TapeBase and which +// \ru нет своих полей данных для записи в поток \en has no its own data fields for writing to stream +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется (!!!) отсутствие (!!!) функций \en 2. The following functions must be (!!!) absent (!!!) +// - void Class::Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// --- +#define IMP_PERSISTENT_CLASS_WD( AppID, Class ) \ + IMP_PERSISTENT_REGISTRATION( AppID, Class ); \ + void Class::Read( reader &, Class * ) {} \ + void Class::Write( writer &, const Class * ) {} \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) \ + IMP_CLASS_DESC_FUNC( AppID, Class ) + +//---------------------------------------------------------------------------------------- +/** \brief \ru Аналог макроса IMP_PERSISTENT_CLASS_WD + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков. + \en Analog of IMP_PERSISTENT_CLASS_WD macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads. \~ + \details \ru Аналог макроса IMP_PERSISTENT_CLASS_WD + с возможностью перегрузки операторов new/delete, + обеспечивающий последовательное обращение к функциям + выделения/освобождения памяти из разных потоков + (включается переменной __OVERLOAD_MEMORY_ALLOCATE_FREE_). + \en Analog of IMP_PERSISTENT_CLASS_WD macro + with support of new/delete operators overloading which provides + sequential access to the allocation/deallocation functions + from different threads + (enabled by defining __OVERLOAD_MEMORY_ALLOCATE_FREE_). \~ + \ingroup Base_Tools_IO +*/ +// --- +#define IMP_PERSISTENT_CLASS_WD_NEW_DEL( AppID, Class ) \ + IMP_PERSISTENT_CLASS_WD( AppID, Class ); \ + IMP_PERSISTENT_NEW_DELETE_CLASS_EX( Class ) + +//---------------------------------------------------------------------------------------- +// \ru Описывает необходимые операции для абстрактного поточного класса, \en Describes the necessary operations for the abstract stream class +// \ru не наследующего ни от кого кроме TapeBase, и у которого \en which is not inherited from any class except TapeBase and which +// \ru нет своих полей данных для записи в поток \en has no its own data fields for writing to stream +// \ru Устанавливается в любой .cpp файл \en It is set to any .cpp file +// \ru Примечание : \en Note: +// \ru 1. Class должен наследовать от TapeBase \en 1. Class must be inherited from TapeBase +// \ru 2. Требуется (!!!) отсутствие (!!!) функций \en 2. The following functions must be (!!!) absent (!!!) +// - void Class::Read( reader& in, Class* obj ); +// - void Class::Write( writer& out, const Class* obj ); +// \ru где Class - имя класса \en where Class is a class name +// --- +#define IMP_A_PERSISTENT_CLASS_WD( AppID, Class ) \ + void Class::Read( reader &, Class * ) {} \ + void Class::Write( writer &, const Class * ) {} \ + IMP_PERSISTENT_NEW_DELETE_CLASS( Class ) \ + IMP_CLASS_DESC_FUNC( AppID, Class ) + + +//---------------------------------------------------------------------------------------- +/// \ru Удаление пробелов и записей перед пробелами. \en Deleting of spaces and records before spaces. \~ \ingroup Base_Tools_IO +// \ru Для совместимости с предыдущими компиляторами по именам возвращаемым typeid(a).name() \en For compatibility with the previous compilers by names returned by typeid(a).name() +// \ru Для определения того, что надо делать, скомпилируйте и запустите из консоли код \en Compile and run the following code from console to define what is to do +// #include +// #include +// class CLASS_A { +// public: virtual ~CLASS_A() {} +// }; +// +// int main(int argc, char **argv) { +// CLASS_A a; +// std::cout << typeid(a).name() << '\n'; +// return 0; +// } +// +// \ru Выдаваемые значения \en Returned values +// MS Visual C++ 6.0 ... 2010: "class CLASS_A" +// gcc (Linux): "7CLASS_A" +// BORLAND C++ 5.0: "CLASS_A" +// Embarcadero C++ 7.20 for Win32 "$CLASS_A" +// \ru Интересующая нас функция должна выдавать "CLASS_A" \en The desired function must write "CLASS_A" +// --- +inline const char * pureName( const char * name ) +{ + if ( name && *name ) + { +#ifdef _MSC_VER + // \ru убираем ключевые слова "class", "struct" и т.д. в начале строки \en remove the keywords "class", "struct" and so on at the beginning of the string + ptrdiff_t i = strlen(name) - 1; + for ( ; i >= 0 && name[i] != ' '; i-- ); + return ((i >= 0) && (name[i] == ' ')) ? &(name[i+1]) : name; +#elif __BORLANDC__ + // \ru убираем "$" в начале строки \en remove "$" at the beginning of the string + for ( size_t i = 0, c = strlen(name); i < c; i++ ) + if ( name[i] != '$' ) + return &(name[i]); +#else // _MSC_VER + // \ru убираем длину имени в начале строки \en remove the name length at the beginning of the string + for ( size_t i = 0, c = strlen(name); i < c; i++ ) + if ( !(name[i] >= '0' && name[i] <= '9') ) + return &(name[i]); +#endif // _MSC_VER + } + return name; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Упаковать строку(имя класса) в uint16. \en Pack the string (class name) into uint16. \~ \ingroup Base_Tools_IO +// --- +inline uint16 hash( const char * name ) +{ + const uint16 * c = (const uint16 *)name; + + uint16 h = uint16(strlen(name)); // Mix in the string length. + uint16 l = h; + uint16 i = uint16(h / sizeof(uint16)); // Could do "<<" here, but less portable. + + while ( i-- ) + h ^= *c++; // XOR in the characters. + + // If there are any remaining characters, + // then XOR in the rest, using a mask: + if ( (i = uint16(l % sizeof(uint16))) != 0 ) + h ^= uint16(*c & 0xff); + + return h; +} + +//---------------------------------------------------------------------------------------- +// \ru Чтение CHAR строки из потока. (в кодировке ANSI, с русской локалью) \en Reading of CHAR string from the stream. (in ANSI coding, with Russian locale) +// \ru И нулевой указатель и пустая строка возвращаются как нулевой указатель! \en Both null pointer and an empty string are returned as null pointer! +// \ru Длина строки не может превышать SYS_MAX_UINT16 - 1 \en The string length cannot exceed SYS_MAX_UINT16 - 1 +// \ru Созданную строку кто-то потом должен уничтожить (через delete[]) \en Created string must be deleted by someone then (using delete[]) +// --- +inline reader & __readChar( reader & ps, char *& s ) +{ + s = NULL; + + if ( ps.good() ) + { + uint16 len = 0; + ps.readBytes( &len, sizeof(len) ); // \ru длина строки - uint16 \en string length - uint16 + + if ( len == 0 || + len == SYS_MAX_UINT16 || + (len > 0 && ps.eof()) || + !ps.good() ) + { + s = NULL; + } + else // good + { + s = new char[len + 1]; + if ( s ) + { + if ( ps.readBytes(s, len) ) + { + // \ru прочли сколько нужно - добавить ограничивающий 0 \en have read as much as necessary - the terminating 0 is to be added + s[len] = 0; + } + else + { + // \ru прочли не все, скорее всего ошибка - очистить строку \en not everything has been read, must be an error - clear the string + delete [] s; + s = NULL; + } + } + else + ps.setState( io::outOfMemory ); + } + } + + return ps; +} + + +//---------------------------------------------------------------------------------------- +// \ru Чтение WCHAR строки из потока. (в потоке хранится как UTF-16) \en Reading of WCHAR string from the stream. (stored in the stream as UTF-16) +// \ru И нулевой указатель и пустая строка возвращаются как нулевой указатель! \en Both null pointer and an empty string are returned as null pointer! +// \ru Длина строки не может превышать SYS_MAX_UINT32 - 1 \en The string length cannot exceed SYS_MAX_UINT32 - 1 +// \ru Созданную строку кто-то потом должен уничтожить \en Created string should be deleted by someone then +// --- +inline reader & __readWchar( reader & ps, TCHAR * & s ) +{ + s = NULL; // \ru на случай, если ничего не прочитаем \en for case if nothing will be read + if ( ps.good() ) + { + uint32 len = 0; + if ( ps.readBytes(&len, sizeof(len)) && // \ru длина строки в символах без терминального нуля - uint32 \en the string length in symbols without the termination zero - uint32 + len != 0 && + len != SYS_MAX_UINT32 && + !ps.eof() ) + { + uint16 * readBuf = new uint16[(size_t)len + 1]; // \ru длина (количество символов) вычитываемой строки с терминальным нулем \en length (number of symbols) of string being read with terminating 0 + size_t size = sizeof(uint16) * (size_t)len; // \ru длина (в байтах) вычитываемой строки без терминального нуля \en length (in bytes) of string being read without terminating null + + if ( ps.readBytes(readBuf, size) ) + // \ru прочли сколько нужно - добавить ограничивающий 0 \en have read as much as necessary - the terminating 0 is to be added + readBuf[(size_t)len] = 0; + else { + // \ru прочли не все, скорее всего ошибка - очистить строку \en not everything has been read, must be an error - clear the string + delete [] readBuf; + readBuf = NULL; + } + + if ( readBuf ) { // is OK +#ifdef _UNICODE // TCHAR == wchar_t + #if __SIZEOF_WCHAR_T__ == 2 // sizeof(wchar_t) == sizeof(uint16) + s = (TCHAR *)readBuf; // \ru собственно ничего конвертировать не нужно \en nothing to convert + #else // sizeof(wchar_t) == sizeof(uint32) + s = (TCHAR *)Utf16ToUcs4(readBuf); // \ru Конвертировать UTF-16 в WCHAR \en Convert from UTF-16 to WCHAR + delete [] readBuf; + #endif +#else // _UNICODE + #if __SIZEOF_WCHAR_T__ == 2 // sizeof(wchar_t) == sizeof(uint16) + s = wcsnewmbs( (const wchar_t*)readBuf ); // \ru Конвертировать WCHAR в CHAR строку. \en Convert WCHAR-string to CHAR-string. + #else // sizeof(wchar_t) == sizeof(uint32) + uint32* readBuf32 = Utf16ToUcs4(readBuf); // \ru Конвертировать UTF-16 в WCHAR \en Convert from UTF-16 to WCHAR + s = wcsnewmbs( (const wchar_t*)readBuf32 ); // \ru Конвертировать WCHAR в CHAR строку. \en Convert WCHAR-string to CHAR-string. + delete [] readBuf32; + #endif + delete [] readBuf; +#endif // _UNICODE + } + } + } + + return ps; +} + + +//---------------------------------------------------------------------------------------- +// \ru Чтение WCHAR строки из потока. (в потоке хранится как UTF-16) \en Reading of WCHAR string from the stream. (stored in the stream as UTF-16) +// \ru И нулевой указатель и пустая строка возвращаются как нулевой указатель! \en Both null pointer and an empty string are returned as null pointer! +// \ru Длина строки не может превышать SYS_MAX_UINT32 - 1 \en The string length cannot exceed SYS_MAX_UINT32 - 1 +// \ru Созданную строку кто-то потом должен уничтожить \en Created string should be deleted by someone then +// --- +inline reader & __readWcharT( reader & ps, wchar_t * & s ) +{ + s = NULL; // \ru на случай, если ничего не прочитаем \en for case if nothing will be read + if ( ps.good() ) + { + uint32 len = 0; + if ( ps.readBytes(&len, sizeof(len)) && // \ru длина строки в символах без терминального нуля - uint32 \en the string length in symbols without the termination zero - uint32 + len != 0 && + len != SYS_MAX_UINT32 && + !ps.eof() ) + { + uint16 * readBuf = new uint16[(size_t)len + 1]; // \ru длина (количество символов) вычитываемой строки с терминальным нулем \en length (number of symbols) of string being read with terminating 0 + size_t size = sizeof(uint16) * (size_t)len; // \ru длина (в байтах) вычитываемой строки без терминального нуля \en length (in bytes) of string being read without terminating null + + if ( ps.readBytes(readBuf, size) ) + // \ru прочли сколько нужно - добавить ограничивающий 0 \en have read as much as necessary - the terminating 0 is to be added + readBuf[(size_t)len] = 0; + else { + // \ru прочли не все, скорее всего ошибка - очистить строку \en not everything has been read, must be an error - clear the string + delete [] readBuf; + readBuf = NULL; + } + + if ( readBuf ) { // is OK +#if __SIZEOF_WCHAR_T__ == 2 // sizeof(wchar_t) == sizeof(uint16) + s = (wchar_t *)readBuf; // \ru собственно ничего конвертировать не нужно \en nothing to convert +#else // sizeof(wchar_t) == sizeof(uint32) + s = (wchar_t *)Utf16ToUcs4(readBuf); // \ru Конвертировать UTF-16 в WCHAR \en Convert from UTF-16 to WCHAR + delete [] readBuf; +#endif + } + } + } + + return ps; +} + + +#ifdef C3D_WINDOWS //_MSC_VER // \ru Код для поддержки КОМПАС \en Code for KOMPAS support +//---------------------------------------------------------------------------------------- +/// \ru Чтение CHAR строки из потока. \en Reading of CHAR string from the stream. \~ \ingroup Base_Tools_IO +// \ru И нулевой указатель и пустая строка возвращаются как нулевой указатель! \en Both null pointer and an empty string are returned as null pointer! +// --- +#ifndef DISABLE_RWTCHAR +#ifdef _UNICODE +inline reader & operator >> ( reader & ps, char *& s ) +{ + return __readChar( ps, s ); +} +#endif // _UNICODE +#endif // DISABLE_RWTCHAR + + +//---------------------------------------------------------------------------------------- +/// \ru Запись CHAR строки в поток. \en Writing CHAR string to the stream. \~ \ingroup Base_Tools_IO +// --- +#ifndef DISABLE_RWTCHAR +#ifdef _UNICODE +inline writer & operator << ( writer & ps, const char * s ) +{ + return ps.__writeChar( s ); +} +#endif // _UNICODE +#endif // DISABLE_RWTCHAR + +//---------------------------------------------------------------------------------------- +/// \ru Чтение WCHAR строки из потока. \en Reading of WCHAR string from the stream. \~ \ingroup Base_Tools_IO +// \ru И нулевой указатель и пустая строка возвращаются как нулевой указатель! \en Both null pointer and an empty string are returned as null pointer! +// \ru OV длина строки не может превышать SYS_MAX_UINT32 - 1 \en OV length of string can't exceed SYS_MAX_UINT32 - 1 +// --- +#ifndef DISABLE_RWTCHAR +inline reader & operator >> ( reader & ps, TCHAR *& s ) +{ + return __readWchar( ps, s ); +} +#endif // DISABLE_RWTCHAR + + +//---------------------------------------------------------------------------------------- +/// \ru Запись WCHAR строки в поток. \en Writing WCHAR string to the stream. \~ \ingroup Base_Tools_IO +// \ru длина строки не может превышать SYS_MAX_UINT32 - 1 \en string length can't exceed SYS_MAX_UINT32 - 1 +// --- +#ifndef DISABLE_RWTCHAR +inline writer & operator << ( writer & ps, const TCHAR * s ) +{ + return ps.__writeWchar( s ); +} +#endif // DISABLE_RWTCHAR + +#endif // C3D_WINDOWS + +#ifdef __MOBILE_VERSION__ +#ifdef _UNICODE +inline reader & operator >> ( reader & ps, char *& s ){ return __readChar( ps, s );} +inline writer & operator << ( writer & ps, const char * s ){ return ps.__writeChar( s );} +inline reader & operator >> ( reader & ps, TCHAR *& s ){ return __readWchar( ps, s );} +inline writer & operator << ( writer & ps, const TCHAR * s ){ return ps.__writeWchar( s );} +#endif // _UNICODE +#endif // __MOBILE_VERSION__ + +//---------------------------------------------------------------------------------------- +/// \ru Запись bool в поток. \en Writing bool to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, bool i ) +{ + //unsigned char val = i; + uint8 val = i ? 1 : 0; + ps.writeByte( val ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение bool в поток. \en Reading of bool to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, bool & i ) +{ + if ( IsVersion16bit( ps.MathVersion() ) ) + { + unsigned short tmp = 0; + ps.readBytes( &tmp, sizeof(unsigned short) ); + i = !!tmp; + } + else + i = !!ps.readByte(); + + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись signed int в поток. \en Writing signed int to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор записи для типов: int (не поддерживает int32, long, LONG - для них есть своя реализация) \en write operator for types: int (doesn't support int32, long, LONG - there is a separate implementation for them) +// \ru поддерживает запись в 32 и 16-битный формат файла \en supports writing to 32- and 16-bit format of file +// --- +inline writer & operator << ( writer & ps, signed int i ) +{ +#ifdef C3D_WINDOWS //_MSC_VER + if ( IsVersion16bit( ps.MathVersion() ) ) + { + // \ru чтение из 16-битной версии файла \en reading from 16-bit version of file + // \ru ради этого куска чтение/запись int отделено от чтения/записи long \en reading/writing of int is separated from reading/writing of long for the sake of this fragment + int16 val = (int16)i; + ps.writeBytes( &val, sizeof(val) ); + } + else { + int32 val = (int32)i; + ps.writeBytes( &val, sizeof(val) ); + } + return ps; +#else // C3D_WINDOWS + if ( IsVersion16bit( ps.MathVersion() ) ) + ps.setState( io::fail ); // \ru в Linux-версии 16-битные файлы не поддерживаются \en 16-bit files are not supported in Linux + else { + int32 val = (int32)i; + ps.writeBytes( &val, sizeof(val) ); + } + return ps; +#endif // C3D_WINDOWS +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись unsigned int в поток. \en Writing unsigned int to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор записи для типов: uint (не поддерживает uint32, ulong - для них есть своя реализация) \en write operator for types: uint (doesn't support uint32, ulong - there is a separate implementation for them) +// \ru поддерживает запись в 32 и 16-битный формат файла \en supports writing to 32- and 16-bit format of file +// --- +inline writer & operator << ( writer & ps, unsigned int i ) { +#ifdef C3D_WINDOWS //_MSC_VER + if ( IsVersion16bit( ps.MathVersion() ) ) { + // \ru чтение из 16-битной версии файла \en reading from 16-bit version of file + // \ru ради этого куска чтение/запись int отделено от чтения/записи long \en reading/writing of int is separated from reading/writing of long for the sake of this fragment + uint16 val = (uint16)i; + ps.writeBytes( &val, sizeof(val) ); + } + else { + uint32 val = i; + ps.writeBytes( &val, sizeof(val) ); + } + return ps; +#else // C3D_WINDOWS + if ( IsVersion16bit( ps.MathVersion() ) ) + ps.setState( io::fail ); // \ru в Linux-версии 16-битные файлы не поддерживаются \en 16-bit files are not supported in Linux + else { + uint32 val = i; + ps.writeBytes( &val, sizeof(val) ); + } + return ps; +#endif // C3D_WINDOWS +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение signed int в поток. \en Reading signed int to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор чтения для типов: int (не поддерживает int32, long, LONG - для них есть своя реализация) \en read operator for types: int (doesn't support int32, long, LONG - there is a separate implementation for them) +// \ru поддерживает чтение из 32 и 16-битного формата файла \en supports reading from 32- and 16-bit format of file +// --- +inline reader & operator >> ( reader & ps, signed int & i ) +{ +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 + if ( IsVersion16bit( ps.MathVersion() ) ) { + // \ru чтение из 16-битной версии файла \en reading from 16-bit version of file + // \ru ради этого куска чтение/запись int отделено от чтения/записи long \en reading/writing of int is separated from reading/writing of long for the sake of this fragment + int16 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = val; + } + else { + int32 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = (signed int)val; + } + return ps; +#else // C3D_WINDOWS + if ( IsVersion16bit( ps.MathVersion() ) ) + ps.setState( io::fail ); // \ru в Linux-версии 16-битные файлы не поддерживаются \en 16-bit files are not supported in Linux + else { + int32 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = (signed int)val; + } + return ps; +#endif // C3D_WINDOWS +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение unsigned int в поток. \en Reading unsigned int to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор чтения для типов: uint (не поддерживает uint32, ulong - для них есть своя реализация) \en read operator for types: uint (doesn't support uint32, ulong - there is a separate implementation for them) +// \ru поддерживает чтение из 32 и 16-битного формата файла \en supports reading from 32- and 16-bit format of file +// --- +inline reader & operator >> ( reader & ps, unsigned int & i ) +{ +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 + if ( IsVersion16bit( ps.MathVersion() ) ) + { + // \ru чтение из 16-битной версии файла \en reading from 16-bit version of file + // \ru ради этого куска чтение/запись int отделено от чтения/записи long \en reading/writing of int is separated from reading/writing of long for the sake of this fragment + uint16 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = val; + } + else { + uint32 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = (unsigned int)val; + } + return ps; +#else // C3D_WINDOWS + if ( IsVersion16bit( ps.MathVersion() ) ) + ps.setState( io::fail ); // \ru в Linux-версии 16-битные файлы не поддерживаются \en 16-bit files are not supported in Linux + else { + uint32 val = 0; + ps.readBytes( &val, sizeof(val) ); + i = (unsigned int)val; + } + return ps; +#endif // C3D_WINDOWS +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись int32 в поток. \en Writing int32 to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор записи для типов: long, int32, LONG (не поддерживает int - для него есть своя реализация) \en write operator for types: long, int32, LONG (does not support int - there is a separate implementation for it) +// \ru данные всегда пишутся в 32-разрядном формате \en data are always written in 32-bit format +// --- +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 +// \ru ВНИМАНИЕ!!! В целях совместимости данных для задач скомпилированных под Windows и Linux \en NOTE!!! To provide data compatibility for tasks compiled for Windows and Linux +// \ru ЗАПРЕЩАЕТСЯ использовать тип данных long и unsigned long. Используйте int32 и uint32 \en IT IS FORBIDDEN to use long and unsigned long data types. Use int32 and uint32 +inline writer & operator << ( writer & ps, int32 l ) +{ + ps.writeBytes( &l, sizeof(l) ); + return ps; +} +#endif // C3D_WINDOWS + + +//---------------------------------------------------------------------------------------- +/// \ru Запись uint32 в поток. \en Writing uint32 to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор записи для типов: ulong, uint32 (не поддерживает uint - для него есть своя реализация) \en write operator for types: ulong, uint32 (does not support uint - there is a separate implementation for it) +// \ru данные всегда пишутся в 32-разрядном формате \en data are always written in 32-bit format +// --- +#ifdef C3D_WINDOWS // Linux identical int/uint and int32/uint32 +// \ru ВНИМАНИЕ!!! В целях совместимости данных для задач скомпилированных под Windows и Linux \en NOTE!!! To provide data compatibility for tasks compiled for Windows and Linux +// \ru ЗАПРЕЩАЕТСЯ использовать тип данных long и unsigned long. Используйте int32 и uint32 \en IT IS FORBIDDEN to use long and unsigned long data types. Use int32 and uint32 +inline writer& operator << ( writer& ps, uint32 l ) +{ + ps.writeBytes( &l, sizeof(l) ); + return ps; +} +#endif // C3D_WINDOWS + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение int32 в поток. \en Reading int32 to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор чтения для типов: long, int32, LONG (не поддерживает int - для него есть своя реализация) \en read operator for types: long, int32, LONG (does not support int - there is a separate implementation for it) +// \ru данные всегда читаются в 32-разрядном формате \en data are always read in 32-bit format +// --- +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 +// \ru ВНИМАНИЕ!!! В целях совместимости данных для задач скомпилированных под Windows и Linux \en NOTE!!! To provide data compatibility for tasks compiled for Windows and Linux +// \ru ЗАПРЕЩАЕТСЯ использовать тип данных long и unsigned long. Используйте int32 и uint32 \en IT IS FORBIDDEN to use long and unsigned long data types. Use int32 and uint32 +inline reader& operator >> ( reader& ps, int32 & l ) +{ + size_t size = sizeof(int32); + if ( !ps.readBytes(&l, size) ) + l = 0; + + return ps; +} +#endif // C3D_WINDOWS + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение uint32 в поток. \en Reading uint32 to the stream. \~ \ingroup Base_Tools_IO +// \ru оператор чтения для типов: ulong, uint32 (не поддерживает uint - для него есть своя реализация) \en read operator for types: ulong, uint32 (does not support uint - there is a separate implementation for it) +// \ru данные всегда читаются в 32-разрядном формате \en data are always read in 32-bit format +// --- +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 +// \ru ВНИМАНИЕ!!! В целях совместимости данных для задач скомпилированных под Windows и Linux \en NOTE!!! To provide data compatibility for tasks compiled for Windows and Linux +// \ru ЗАПРЕЩАЕТСЯ использовать тип данных long и unsigned long. Используйте int32 и uint32 \en IT IS FORBIDDEN to use long and unsigned long data types. Use int32 and uint32 +inline reader& operator >> ( reader& ps, uint32 & l ) +{ + size_t size = sizeof(uint32); + if ( !ps.readBytes(&l, size) ) + l = 0; + + return ps; +} +#endif // C3D_WINDOWS + + +//---------------------------------------------------------------------------------------- +/// \ru Запись int64 в поток. \en Writing int64 to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, int64 val ) +{ + ps.writeInt64( val ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение int64 в поток. \en Reading int64 to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, int64 & val ) +{ + ps.readInt64( val ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение signed char в поток. \en Reading signed char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, signed char & ch ) +{ + ch = (signed char)ps.readByte(); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение unsigned char в поток. \en Reading unsigned char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, unsigned char & ch ) +{ + ch = (unsigned char)ps.readByte(); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение char в поток. \en Reading char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, char & ch ) { + ch = (char)ps.readByte(); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение signed short в поток. \en Reading signed short to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, signed short & sh ) { + const size_t size = sizeof(sh); + + if ( !ps.readBytes(&sh, size) ) + sh = 0; + + return ps; +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение unsigned short в поток. \en Reading unsigned short to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, unsigned short & sh ) +{ + const size_t size = sizeof(sh); + + if ( !ps.readBytes(&sh, size) ) + sh = 0; + + return ps; +} + +#ifdef __MOBILE_VERSION__ +//---------------------------------------------------------------------------------------- +/// \ru Чтение wchar_t в поток. \en Reading wchar_t to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, wchar_t & sh ) +{ + sh = 0; //Обнулить, т.к. размер 4 байта, а читаются только 2 + //size_t size = sizeof(sh); + size_t size = 2; //В windows sizeof(wchar_t) = 2, в Android sizeof(wchar_t) = 4 + + if ( !ps.readBytes(&sh, size) ) + + sh = 0; + + return ps; +} +#endif // __MOBILE_VERSION__ + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение float в поток. \en Reading float to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, float & f ) { + size_t size = sizeof(f); + + if ( !ps.readBytes(&f, size) ) + f = 0; + + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение double в поток. \en Reading double to the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, double & d ) +{ + size_t size = sizeof(d); + + if ( !ps.readBytes(&d, size) ) + d = 0; + + // \ru Проверка числа на определенность \en Check if the number is defined + if ( c3d_isnan(d) ) + d = 0; + + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение long double из потока. \en Reading long double from the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, long double & l ) { + size_t size = sizeof(l); + + if ( !ps.readBytes(&l, size) ) + l = 0; + + return ps; +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение smart-указателя из потока. \en Reading a smart pointer from the stream. \~ \ingroup Base_Tools_IO +// --- +template +inline reader & operator >> ( reader & ps, SPtr<_Class> & sPtr ) +{ + _Class * ptr = NULL; + ps >> ptr; + sPtr.assign( ptr ); + return ps; +} + +//---------------------------------------------------------------------------------------- +/// \ru Запись smart-указателя в поток. \en Writing a smart pointer to the stream. \~ \ingroup Base_Tools_IO +// --- +template +inline writer & operator << ( writer & ps, const SPtr<_Class> & sPtr ) +{ + ps << sPtr.get(); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись signed char в поток. \en Write signed char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer & ps, signed char ch ) +{ + ps.writeByte( ch ); // \ru байт \en byte + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись unsigned char в поток. \en Write unsigned char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer & ps, unsigned char ch ) +{ + ps.writeByte( ch ); // \ru байт \en byte + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись char в поток. \en Write char to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer & ps, char ch ) +{ + ps.writeByte( ch ); // \ru байт \en byte + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись signed short в поток. \en Write signed short to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer & ps, signed short sh ) +{ + ps.writeBytes( &sh, sizeof(sh) ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись unsigned short в поток. \en Write unsigned short to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer& ps, unsigned short sh ) +{ + ps.writeBytes( &sh, sizeof(sh) ); + return ps; +} + +#ifdef __MOBILE_VERSION__ +//---------------------------------------------------------------------------------------- +/// \ru Запись wchar_t в поток. \en Write wchar_t to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, wchar_t sh ) +{ + size_t size = 2; //В windows sizeof(wchar_t) = 2, в Android sizeof(wchar_t) = 4 + ps.writeBytes( &sh, size ); + return ps; +} +#endif // __MOBILE_VERSION__ + + +//---------------------------------------------------------------------------------------- +/// \ru Запись float в поток. \en Write float to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, float f ) +{ + ps.writeBytes( &f, sizeof(f) ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись double в поток. \en Write double to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer& operator << ( writer & ps, const double & d ) +{ + ps.writeBytes( &d, sizeof(d) ); + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись long double в поток. \en Write long double to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, const long double & l ) +{ + ps.writeBytes( &l, sizeof(l) ); + return ps; +} + +//---------------------------------------------------------------------------------------- +/// \ru Записать TCHAR строку в поток. \en Write TCHAR string to the stream. \~ \ingroup Base_Tools_IO +// --- +inline void WriteTCHAR( writer & out, const TCHAR * ts, bool directSingleByte = false ) +{ + if ( directSingleByte || out.MathVersion() < UNICODE_VERSION ) + { + // \ru пишем WCHAR* как CHAR* \en write WCHAR* as CHAR* + char * s = _tcsNstr( ts ); // \ru создаем ANSI из TCHAR (если TCHAR == char, то просто дублируем) \en create ANSI from TCHAR (if TCHAR == char, then simply duplicate) + out.__writeChar( s ); // \ru пишем строку в формате ANSI \en write string in ANSI format + delete [] s; + } + else + { + // \ru пишем WCHAR* \en write WCHAR* + out.__writeWchar( ts ); + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Прочитать TCHAR строку из потока. \en Read TCHAR string from the stream. \~ \ingroup Base_Tools_IO +//--- +inline void ReadTCHAR( reader & in, TCHAR *& ts, bool directSingleByte = false ) +{ + if ( directSingleByte || in.MathVersion() < UNICODE_VERSION ) + { + // \ru читаем WCHAR* из CHAR* \en read WCHAR* from CHAR* + char * s = NULL; + __readChar( in, s ); // \ru читаем строку в формате ANSI \en read string in ANSI format + ts = _strNtcs( s ); // \ru создаем TCHAR из ANSI (если TCHAR == char, то просто дублируем) \en create TCHAR from ANSI (if TCHAR == char, then simply duplicate) + delete [] s; + } + else + { + // \ru читаем WCHAR* \en read WCHAR* + __readWchar( in, ts ); + } +} + + +//---------------------------------------------------------------------------------------- +/// \ru Записать wchar_t строку в поток. \en Write wchar_t string to the stream. \~ \ingroup Base_Tools_IO +// --- +inline void WriteWcharT( writer & out, const wchar_t* ts ) +{ + out.__writeWcharT( ts ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Прочитать TCHAR строку из потока. \en Read TCHAR string from the stream. \~ \ingroup Base_Tools_IO +//--- +inline void ReadWcharT( reader& in, wchar_t* & ts ) +{ + __readWcharT( in, ts ); +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись size_t в зависимости от версии потока. \en Write size_t subject to the stream version. \~ \ingroup Base_Tools_IO +// --- +inline void WriteCOUNT( writer & out, size_t count ) +{ + if ( IsVersion64bit( out.MathVersion() ) ) + { + uint64 count64 = count; + + if ( out.MathVersion() >= 0x0F001001L ) { + if ( count64 == SYS_MAX_T ) + count64 = SYS_MAX_UINT64; + } + + out.writeUInt64( count64 ); + } + else + { + // \ru OV_x64 проверить переполнение при записи 64-битных данных в 32-битный поток \en OV_x64 check for overflow while writing 64-bit data to 32-bit stream + if ( HiUint32( count ) != 0 ) + out.setState( io::underflow64to32 ); + + uint32 _count = (uint32)LoUint32(count); + out << _count; + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Запись ptrdiff_t в зависимости от версии потока. \en Writing ptrdiff_t subject to the stream version. \~ \ingroup Base_Tools_IO +// --- +inline void WriteINT_T( writer & out, ptrdiff_t count ) +{ + if ( IsVersion64bit( out.MathVersion() ) ) + { + out.writeInt64( count ); + } + else + { + // \ru OV_x64 проверить переполнение при записи 64-битных данных в 32-битный поток \en OV_x64 check for overflow while writing 64-bit data to 32-bit stream + if ( (int64)count > (int64)SYS_MAX_INT32 || (int64)count < (int64)SYS_MIN_INT32 ) + out.setState( io::underflow64to32 ); + + int32 _count = (int32)LoUint32(count); + out << _count; + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение size_t в зависимости от версии потока. \en Reading size_t subject to the stream version. \~ \ingroup Base_Tools_IO +// +// \ru Т.к. операторы чтения/записи для uint и uint32 разные нужно \en Since reading/writing operators are different for uint and uint32, +// \ru уметь читать оба, в зависимости от места где вызывается. \en there should be capability for reading both of them subject to the place where it is called. +// \ru Решено запись не менять, т.к. в 16 битовую задачу не записываем. \en Decided not to modify writing since we do not write to 16-bit task. +// --- +inline size_t ReadCOUNT ( reader & in, bool uint_val = true ) +{ + size_t count = 0; + if ( IsVersion64bit( in.MathVersion() ) ) + { + uint64 _count = 0; + in.readUInt64( _count ); + + if ( in.MathVersion() >= 0x0F001001L ) { + if ( _count == SYS_MAX_UINT64 ) + _count = SYS_MAX_T; + } + else { + // \Mapping\a_17356\17356_Телега.c3d PRECONDITION( _count != SYS_MAX_UINT32 ); // неоднозначность интерпретации значения // Primery_Set/Models_8/_58720. + if ( _count == SYS_MAX_UINT32 || _count == SYS_MAX_UINT64 ) + _count = SYS_MAX_T; + } + + count = (size_t)_count; + + // \ru OV_x64 проверить переполнение при чтении 64-битных данных в 32-битной задаче \en OV_x64 check for overflow while reading 64-bit data in 32-bit task + if ( HiUint32(count) != HiUint32(_count) ) + in.setState( io::underflow64to32 ); + } + else + { + // \ru оператор чтения в uint (в отличии от uint32) поддерживает чтение 16-битных версий файла \en operator of reading to uint (in contrast to uint32) supports reading 16-bit versions of file + if ( uint_val ) + { + uint _count = 0; + in >> _count; + + count = (size_t)_count; + } + else + { + uint32 _count = 0; + in >> _count; + count = (size_t)_count; + } + + if ( count == SYS_MAX_UINT32 ) + count = SYS_MAX_T; + } + + return count; +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение ptrdiff_t в зависимости от версии потока. \en Reading ptrdiff_t subject to the stream version. \~ \ingroup Base_Tools_IO +// +// \ru Т.к. операторы чтения/записи для uint и uint32 разные нужно \en Since reading/writing operators are different for uint and uint32, +// \ru уметь читать оба, в зависимости от места где вызывается. \en there should be capability for reading both of them subject to the place where it is called. +// \ru Решено запись не менять, т.к. в 16 битовую задачу не записываем. \en Decided not to modify writing since we do not write to 16-bit task. +// --- +// \ru САА K13 31.8.2010 Исправление BUG 52091 \en CAA K13 31.8.2010 Fix for BUG 52091 +// \ru 77 вызовов и из них только 2 с false!!! - поэтому по умолчанию для всех \en 77 calls and only 2 of them with false!!! - so it is default for all +inline ptrdiff_t ReadINT_T( reader & in, bool uint_val = true ) +{ + ptrdiff_t count = 0; + if ( IsVersion64bit( in.MathVersion() ) ) + { + int64 _count = 0; + in.readInt64( _count ); + count = (ptrdiff_t)_count; + + // \ru OV_x64 проверить переполнение при чтении 64-битных данных в 32-битной задаче \en OV_x64 check for overflow while reading 64-bit data in 32-bit task + if ( HiInt32(count) != HiInt32(_count) ) + in.setState( io::underflow64to32 ); + } + else + { + // \ru оператор чтения в uint (в отличии от uint32) поддерживает чтение 16-битных версий файла \en operator of reading to uint (in contrast to uint32) supports reading 16-bit versions of file + if ( uint_val ) + { + int _count = 0; + in >> _count; + count = (ptrdiff_t)_count; + } + else + { + int32 _count = 0; + in >> _count; + count = (ptrdiff_t)_count; + } + } + + return count; +} + +//OV_LNX \ru Перенесено в Asset\Tape\io_buffer.h \en Moved to Asset\Tape\io_buffer.h +//OV_LNX //---------------------------------------------------------------------------------------- +//OV_LNX /// \ru Длина данных size_t в потоке. \en Length of size_t data in the stream. \~ \ingroup Base_Tools_IO +//OV_LNX // --- +//OV_LNX inline size_t LenCOUNT( VERSION version ) +//OV_LNX { +//OV_LNX if ( IsVersion64bit(version) ) +//OV_LNX return sizeof(uint64); +//OV_LNX else +//OV_LNX return sizeof(uint32); +//OV_LNX } + +//---------------------------------------------------------------------------------------- +/// \ru Запись size_t в память в зависимости от версии потока. \en Writing size_t to the memory subject to the stream version. \~ \ingroup Base_Tools_IO +// --- +inline void WriteCOUNT( void * out, VERSION version, size_t count ) +{ + if ( IsVersion64bit(version) ) + { + const uint64 count64 = (uint64)count; + ::memcpy( out, &count64, sizeof(count64) ); + } + else + { + // \ru OV_x64 проверить переполнение при записи 64-битных данных в 32-битный поток \en OV_x64 check for overflow while writing 64-bit data to 32-bit stream + //OV_x64 if ( count > (int64)_I32_MAX || count < (int64)_I32_MIN ) + //OV_x64 out.setState( io::underflow64to32 ); + + PRECONDITION( count <= (size_t)SYS_MAX_UINT32/*_UI32_MAX*/ ); + const uint32 count32 = (uint32)LoUint32(count); + + ::memcpy( out, &count32, sizeof(count32) ); + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Запись ptrdiff_t в память в зависимости от версии потока. \en Writing ptrdiff_t to the memory subject to the stream version. \~ \ingroup Base_Tools_IO +// --- +inline void WriteCOUNT( void * out, VERSION version, ptrdiff_t count ) +{ + if ( IsVersion64bit(version) ) + { + const int64 count64 = (int64)count; + ::memcpy( out, &count64, sizeof(count64) ); + } + else + { + // \ru OV_x64 проверить переполнение при записи 64-битных данных в 32-битный поток \en OV_x64 check for overflow while writing 64-bit data to 32-bit stream + //OV_x64 if ( count > (int64)_I32_MAX || count < (int64)_I32_MIN ) + //OV_x64 out.setState( io::underflow64to32 ); + + PRECONDITION( count <= (ptrdiff_t)SYS_MAX_INT32/*_I32_MAX*/ && count >= (ptrdiff_t)SYS_MIN_INT32/*_I32_MIN*/ ); + const int32 count32 = (int32)LoUint32(count); + + ::memcpy( out, &count32, sizeof(count32) ); + } +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение size_t в память в зависимости от версии потока. \en Reading of size_t to the memory subject to the stream version. \~ \ingroup Base_Tools_IO +// --- +inline size_t ReadCOUNT ( void * in, VERSION version ) +{ + size_t count = 0; + + if ( IsVersion64bit(version) ) + { + uint64 count64 = 0; + ::memcpy( &count64, in, sizeof(count64) ); + PRECONDITION( count64 <= SYS_MAX_T/*SIZE_MAX*/ ); + count = (size_t)count64; + + // \ru OV_x64 проверить переполнение при чтении 64-битных данных в 32-битной задаче \en OV_x64 check for overflow while reading 64-bit data in 32-bit task + //OV_x64 if ( HiUint32( count ) != HiUint32( _count ) ) + //OV_x64 in.setState( io::underflow64to32 ); + } + else + { + uint32 count32 = 0; + ::memcpy( &count32, in, sizeof(count32) ); + PRECONDITION( sizeof(count32) <= sizeof(count)); // Cannot readCOUNT because sizof(uint32) > sizeof(size_t) + count = /*AR (size_t)*/count32; //-V101 + } + + return count; +} + + +//---------------------------------------------------------------------------------------- +/** Получить упакованное имя класса по значению хэша записанному в поток + + \param[in] hash - Значение хэша. + \param[in] ver - Версия потока в котором записан хэш. + + \result Возвращает упакованное имя класса. +*/ +// --- +MATH_FUNC (ClassDescriptor) GetPackedClassName( const ClassDescriptor &, const VersionContainer & ver ); + + +#ifdef STANDARD_C11 +//---------------------------------------------------------------------------------------- +/** Добавить новое соответствие значения хэша записанного в поток упакованному имени класса + + \param[in] сlassName - Упакованное имя класса. + \param[in] hash - Значение хэша. + \param[in] appIndex - Индекс приложения, которому принадлежит класс. + \param[in] lowVersion - Нижняя граница верссии. + \param[in] highVersion - Верхняя граница верссии. +*/ +// --- +MATH_FUNC (void) AddPackedClassNameForVersion( const ClassDescriptor & newClassName, const ClassDescriptor & oldClassName, uint appIndex, VERSION lowVersion, VERSION highVersion ); +#endif //STANDARD_C11 + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru для получения дампа значений Hash Value в файле hash_GRP.txt(hash_VIE.txt) \en for getting dump of Hash Value values in file hash_GRP.txt(hash_VIE.txt) +// \ru необходимо раскоментарить этот комментарий \en this comment should be uncommented +// +//////////////////////////////////////////////////////////////////////////////// +#ifdef C3D_DEBUG +//#define HASH_DOCUMENTATION +#endif + +#ifdef HASH_DOCUMENTATION + +#include + +inline void HashDocumentationOut( uint16 hashValue, const char * name, bool unique ) +{ + static uint st_calls = 0; + + const char * outName = "C:\\Logs\\hash_GRP.txt"; + std::ofstream out( outName, st_calls ? (std::ios::out|std::ios::app) : std::ios::out ); + + std::string sname( name ); + + out << _T("\t") << uint16(hashValue) << _T("\t\t") << sname.c_str(); + if ( !unique ) + out << _T("\tNOT UNIQUE!!!"); + out << _T("\n"); + + st_calls++; +} + +#endif // HASH_DOCUMENTATION + +#undef HASH_DOCUMENTATION + + + +#ifndef SIMPLENAME_AS_CLASS + +//---------------------------------------------------------------------------------------- +/// \ru Запись простого имени. \en Writing of a simple name. \~ \ingroup Base_Tools_IO +// --- +inline void WriteSimpleName( writer & out, const SimpleName & s ) { out << s; } + +//---------------------------------------------------------------------------------------- +/// \ru Чтение простого имени. \en Reading of a simple name. \~ \ingroup Base_Tools_IO +// --- +inline SimpleName ReadSimpleName( reader & in ) { SimpleName s = 0; in >> s; return s; } + +#else // SIMPLENAME_AS_CLASS + +//---------------------------------------------------------------------------------------- +/// \ru Запись простого имени. \en Writing of a simple name. \~ \ingroup Base_Tools_IO +// --- +inline void WriteSimpleName( writer & out, const SimpleName & s ) +{ + size_t sn = s; + WriteCOUNT( out, sn ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Чтение простого имени. \en Reading of a simple name. \~ \ingroup Base_Tools_IO +// --- +inline SimpleName ReadSimpleName( reader & in ) +{ + size_t sn = ReadCOUNT( in ); + return SimpleName(sn); +} + +#endif // SIMPLENAME_AS_CLASS + + +//---------------------------------------------------------------------------------------- +/// \ru Оператор записи хэша. \en Operator of writing hash. \~ \ingroup Base_Tools_IO +//--- +inline writer & operator << ( writer & out, const StrHash & strHash ) +{ + // \ru Нельзя допускать хеш с неопределенным типом и с определенным значением \en Hash with undefined type and with specified value cannot be allowed + PRECONDITION( !(IsGoodSimpleName(strHash.m_val) && strHash.m_type == StrHash::htp_undef) ); + + WriteSimpleName( out, strHash.m_val ); + + if ( out.MathVersion() >= 0x0A001005L ) + out << strHash.m_type; + return out; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Оператор чтения хэша. \en Operator of hash reading. \~ \ingroup Base_Tools_IO +//--- +inline reader & operator >> ( reader& in, StrHash & strHash ) +{ + strHash.m_val = ReadSimpleName( in ); + + if ( in.MathVersion() >= UNICODE_VERSION ) + if ( in.MathVersion() >= 0x0A001005L /*\ru введена запись типа хеша \en record of hash type is set */) + in >> strHash.m_type; + else + strHash.m_type = StrHash::htp_wchar; // \ru !!! Переходный период, могут быть разные \en !!! Period of transition, may be different + else + strHash.m_type = StrHash::htp_char; + + // \ru Нельзя допускать хеш с неопределенным типом и с определенным значением \en Hash with undefined type and with specified value cannot be allowed + PRECONDITION( !(IsGoodSimpleName(strHash.m_val) && strHash.m_type == StrHash::htp_undef) ); + + return in; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись строки в поток. \en Writing a string to the stream. \~ \ingroup Base_Tools_IO +//--- +inline writer & operator << ( writer & ps, const std::string & s ) +{ + if ( ps.MathVersion() < UNICODE_VERSION ) + { + // \ru пишем WCHAR* как CHAR* \en write WCHAR* as CHAR* + ps.__writeChar( s.c_str() ); // \ru пишем строку в формате ANSI \en write string in ANSI format + } else { + wchar_t* buf = mbsnewwcs( s.c_str() ); + WriteWcharT( ps, buf ); + delete[] buf; + } + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение строки из потока. \en Reading a string from the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, std::string & s ) +{ + if ( ps.MathVersion() < UNICODE_VERSION ) + { + char * str( NULL ); + __readChar( ps, str ); // \ru читаем строку в формате ANSI \en read string in ANSI format + if ( str ) + s = str; + else + s.clear(); + delete [] str; + } else { + wchar_t * p (NULL); + ReadWcharT( ps, p ); // \ru в зависимости от версии потока \en subject to the stream version + if ( p ) { + char* str = wcsnewmbs(p); + if ( str ) + s = str; + else + s.clear(); + delete[] str; + } + else + s.clear(); + delete [] p; + } + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись строки в поток. \en Writing a string to the stream. \~ \ingroup Base_Tools_IO +// --- +inline writer & operator << ( writer & ps, const std::wstring & s ) +{ + if ( ps.MathVersion() < UNICODE_VERSION ) + { + // \ru пишем WCHAR* как CHAR* \en write WCHAR* as CHAR* + char * str = wcsnewmbs( s.c_str() ); // \ru создаем ANSI из TCHAR (если TCHAR == char, то просто дублируем) \en create ANSI from TCHAR (if TCHAR == char, then simply duplicate) + ps.__writeChar( str ); // \ru пишем строку в формате ANSI \en write string in ANSI format + delete [] str; + } + else + WriteWcharT( ps, s.c_str() ); // \ru в зависимости от версии потока \en subject to the stream version + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Чтение строки из потока. \en Reading a string from the stream. \~ \ingroup Base_Tools_IO +// --- +inline reader & operator >> ( reader & ps, std::wstring & s ) +{ + if ( ps.MathVersion() < UNICODE_VERSION ) + { + char * str( NULL ); + __readChar( ps, str ); // \ru читаем строку в формате ANSI \en read string in ANSI format + wchar_t* p = mbsnewwcs( str ); + if ( p ) + s = p; + else + s.clear(); + delete [] p; + delete [] str; + } else { + wchar_t * p = NULL; + ReadWcharT( ps, p ); // \ru в зависимости от версии потока \en subject to the stream version + if ( p ) + s = p; + else + s.clear(); + delete [] p; + } + return ps; +} + + +//---------------------------------------------------------------------------------------- +/// \ru Запись строки в поток. \en Writing a string to the stream. \~ \ingroup Base_Tools_IO +//--- +inline writer & operator << ( writer & ps, const std::wstring * s ) +{ + WriteWcharT( ps, (s ? s->c_str() : NULL) ); // \ru в зависимости от версии потока \en subject to the stream version + return ps; +} + +//---------------------------------------------------------------------------------------- +/// \ru Прочитать кластер. \en Read the cluster. \~ \ingroup Base_Tools_IO +// --- +inline void ReadCluster( reader & in, uint16 clusterSize, Cluster & cl ) +{ + // \ru очистить поле указателя, т.к. в AllocMem есть проверка на 0 \en clear the pointer field since there is a check for 0 in AllocMem + cl.SetClusterOffset( 0 ); + // \ru распределяем кластер стандартной длины ... \en allocate a cluster of a standard length ... + cl.AllocMem( clusterSize ); + + uint16 length = 0; + in >> length; + PRECONDITION( length <= clusterSize ); + cl.m_l = length; + + // \ru ...а читаем - сколько было занято \en ...but read as much as has been occupied + in.readBytes( (uint8*)cl.m_f, length ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Записать кластер, параметр clusterSize используется для проверки корректности длины кластера. +/// \en Write the cluster, the clusterSize parameter is used to checking the cluster length. +// \~ \ingroup Base_Tools_IO +// --- +#ifdef C3D_DEBUG +inline void WriteCluster( writer & out, const Cluster & cl, uint16 clusterSize ) +#else +inline void WriteCluster( writer & out, const Cluster & cl, uint16 /*clusterSize*/ ) +#endif +{ + uint16 len = cl.m_l; + PRECONDITION( len <= clusterSize ); + out << len; + out.writeBytes( (const uint8*)cl.m_f, len ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Записать информацию о кластере. \en Write the information about the cluster. \~ \ingroup Base_Tools_IO +// --- +inline size_t WriteClusterInfo( void * out, VERSION version, const Cluster & obj ) +{ + WriteCOUNT( out, version, obj.m_f ); + + uint16 len = obj.m_l; + ::memcpy( (uint8*)out + LenCOUNT(version), &len, sizeof( len ) ); + + return Cluster::SizeOf( version ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Прочитать информацию о кластере. \en Read the information about the cluster. \~ \ingroup Base_Tools_IO +// --- +inline size_t ReadClusterInfo( void * in, VERSION version, Cluster & obj ) +{ + size_t off = ReadCOUNT( in, version ); + + uint16 len = 0; + ::memcpy( &len, (uint8*)in + LenCOUNT(version), sizeof( len ) ); + + obj.AllocFile( off, len ); // \ru запомнить смещение в файле и кол-во байт \en memorize the shift in file and the number of bytes + + return Cluster::SizeOf( version ); +} + +//------------------------------------------------------------------------------ +// \ru Записать содержимое кластера. Возвращает размер данных кластера или -1, если длина кластера больше заявленной. +// \en Write the cluster's contents. Return size of cluster's data or -1, if the cluster length is greater than the defined one. +// --- +inline size_t WriteClusterBody( void * out, VERSION version, const Cluster & obj, uint16 clusterSize ) +{ + uint8 * m = (uint8 *)out; + + // \ru кол-во заполненных байт в кластере \en the number of filled bytes in the cluster + uint16 l = obj._len(); + PRECONDITION( l <= clusterSize ); + *(uint16*)m = l; + m += sizeof(uint16); + + if ( l > clusterSize ) + return (size_t)-1; + + if ( l ) { + memcpy( m, obj._ptr(), l ); // \ru теперь данные кластера \en the cluster data now + // не используется далее m += l; + } + + return getMemLen( obj, version ) ; +} + +//------------------------------------------------------------------------------ +// \ru Прочитать содержимое кластера. Возвращает размер данных кластера или -1, если длина кластера больше заявленной. +// \en Read the cluster's contents. Return size of cluster's data or -1, if the cluster length is greater than the defined one. +// --- +inline size_t ReadClusterBody( void * in, VERSION version, Cluster & obj, uint16 clusterSize ) +{ + uint8 * m = (uint8 *)in; + + // \ru прочитать кол-во заполненных байт кластера и заполнить соответствующее поле в нем \en read the number of filled bytes in the cluster and fill its corresponding field + uint16 l = *(uint16*)m; + PRECONDITION( l <= clusterSize ); + obj.SetClusterLength( l ); + m += sizeof(uint16); + + if ( l > clusterSize ) + return (size_t)-1; + + if ( l ) { + memcpy( obj._getMemPointer(), m, l ); // \ru теперь данные кластера \en the cluster data now + // не используется далее m += l; + } + + return getMemLen( obj, version ); +} + +//------------------------------------------------------------------------------ +/** + \brief \ru Стартовать try-catch регион для I/O операций. \en Start try-catch region for I/O operations. \~ + \ingroup Base_Tools +*/ +//--- +#define C3D_IO_CATCH_START \ + try { + +//------------------------------------------------------------------------------ +/** + \brief \ru Завершить try-catch регион для I/O операций (аргумент iostrm - поток чтения или записи). + \en Complete try-catch region for I/O operations (argument iostrm - reading or writing stream). \~ + \ingroup Base_Tools +*/ +//--- +#define C3D_IO_CATCH_END(iostrm) \ + } \ + catch ( const std::bad_alloc & ) { \ + iostrm.setState( io::outOfMemory ); \ + } \ + catch ( ... ) { \ + iostrm.setState( io::fail ); \ + } + +#endif // __IO_TAPE_H diff --git a/C3d/Include/io_tree.h b/C3d/Include/io_tree.h new file mode 100644 index 0000000..ad57c61 --- /dev/null +++ b/C3d/Include/io_tree.h @@ -0,0 +1,301 @@ +//////////////////////////////////////////////////////////////////////////////// +/** +\file +\brief \ru Дерево геометрической модели. + \en Tree of geometric model. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_TREE_H +#define __IO_TREE_H + +#include +#include +#include +#include + +class reader; +class writer; +struct ClusterReference; +class TapeBase; + +namespace c3d // namespace C3D +{ + +//---------------------------------------------------------------------------------------- +// \ru Предварительное объявление структуры для данных узла дерева. +// \en The forward declaration of a structure for the tree node data. \~ +// --- +struct MbItemData; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Узел дерева модели. + \en Model tree node. \~ + \details \ru Узел дерева модели (может иметь несколько потомков). + Умеет записывать в поток и читаться из потока. \n + \en Model tree node (can have several children). + Can be written to a stream and read from a stream. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class IModelTreeNode +{ +protected: + // \ru Непосредственные потомки узла. \en The immediate children of the node. + std::set m_children; + // \ru Непосредственные предки узла. \en The immediate parents of the node. + std::set m_parents; +public: + IModelTreeNode() {} + virtual ~IModelTreeNode() {} + + // \ru Доступ к непосредственным предкам узла. \en Access to the immediate node parents. + std::set& GetParents() { return m_parents; } + const std::set& GetParents() const { return m_parents; } + + // \ru Доступ к непосредственным потомкам узла. \en Access to the immediate node children. + std::set& GetChildren() { return m_children; } + const std::set& GetChildren() const { return m_children; } + + // \ru Добавить предка. \en Add a parent. + void AddParent( IModelTreeNode* parent ) { if (parent) m_parents.insert(parent); } + + // \ru Добавить потомка. \en Add a child. + void AddChild( IModelTreeNode* child ) { if (child) { m_children.insert(child); child->AddParent(this); } } + + // \ru Доступ к данным узла. \en Access to the node data. + virtual MbItemData& GetData() = 0; + virtual const MbItemData& GetData() const = 0; + + // \ru Доступ к позиции чтения/записи узла. \en Access to the node read/write position. + virtual ClusterReference& GetPosition() = 0; + virtual const ClusterReference& GetPosition() const = 0; + + // \ru Признак частичного или полного чтения узла. + // При чтении объекта может возникнуть необходимость чтения некоторых данных его родителя. + // В этом случае объект родителя читается частично и имеет соответствующий флаг. + // \en Indicator of partial reading of the current node. + // While reading an object there can be a need to read some data from its parent. + // In this case the parent object is read partially and has a corresponding flag. + // \ru Узнать, читать ли только часть узла. + // \en Check whether to read the node partially. + virtual bool PartialRead() const = 0; + // \ru Установить признак частичного или полного чтения узла. + // \en Set indication of full or partial node reading. + virtual void SetPartialRead ( bool partial ) const = 0; + + // \ru Записать узел. \en Write the node. + virtual writer & operator >> ( writer & ) = 0; + // \ru Прочитать узел. \en Read the node. + virtual reader & operator << ( reader & ) = 0; + + // \ru Операторы для записи узла дерева поток в xml формате. \en Operators to output tree node to a stream in xml format. + friend MATH_FUNC( c3d::t_ofstream & ) operator << ( c3d::t_ofstream& file, IModelTreeNode& node ); + friend MATH_FUNC( c3d::t_ofstream & ) operator << ( c3d::t_ofstream& file, const IModelTreeNode& node ); + +OBVIOUS_PRIVATE_COPY(IModelTreeNode) +}; + +//---------------------------------------------------------------------------------------- +// \ru Предварительное объявление Дерева Исполнений. +// \en The forward declaration of Embodiments Tree. \~ +// --- +class IEmbodimentTree; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Обобщенное дерево модели. + \en Generic model tree. \~ + \details \ru Обобщенное дерево модели (может иметь несколько корней). + Умеет записываться в поток и читаться из потока. \n + Дерево Модели отражает иерархию стандартной модели (объекта MbModel). + \en Generic model tree (can have several roots). + Can be written to a stream and read from a stream. \n \~ + Model Tree presents a hierarchy of a standard model (MbModel object). + \ingroup Base_Tools_IO +*/ +// --- +class IModelTree +{ +public: + enum TreeType + { + mtt_Model, // \ru Дерево содержит модель. \en Tree contains model. + mtt_Embodiment // \ru Дерево содержит исполнения. \en Tree contains embodiments. + }; + + // \ru Тип, представляющий листовой узел с ветвью дерева, ведущей к нему, начиная с корневого узла дерева. + // \en A type which represents a leaf node with the tree branch, leading to it, starting from the root of the tree. + typedef std::pair > NodeBranch; + + // \ru Тип функции для выбора узлов дерева по фильтрам. + // \en The type of a function for selecting tree nodes by filters. + typedef bool ( CALL_DECLARATION * FilterNodesFunc ) ( std::vector&, const std::vector&, const IModelTree* ); + + // \ru Тип функции для определения, нужно ли добавлять объект в дерево модели, и заполнения данных узла. + // \en The type of a function for determining, whether to add the object to the model tree, and filling the node data. + typedef bool ( CALL_DECLARATION *NodeToAddFunc ) ( const TapeBase* mem, MbItemData& data ); + +protected: + // \ru Тип дерева. \en Tree type. + TreeType m_type; + + // \ru Функция для определения, нужно ли добавлять объект в дерево модели, и заполнения данных узла. + // \en A function for determining, whether to add the object to the model tree, and filling the node data. + NodeToAddFunc m_nodeToAddFunc; + + // \ru Функция для выбора объектов по фильтрам. + // \en A function for for selecting objects by filters. + FilterNodesFunc m_filterFunc; + + // \ru Корни дерева. \en The tree roots. + std::vector m_roots; + +public: + + IModelTree() : m_type ( mtt_Model ), m_nodeToAddFunc( NULL ), m_filterFunc( NULL ) {} + virtual ~IModelTree() {} + + // \ru Выдать тип дерева. \en Get the tree type. + TreeType GetType() const { return m_type; } + // \ru Установить тип дерева. \en Set the tree type. + void SetType( TreeType type ) { m_type = type; } + + // \ru Построить дерево из узлов, выбранных по фильтрам. В случае дерева исполнений, функция работает с первым исполнением. + // \en Build a tree with nodes, selected by filters. In case of embodiment tree, the function works with the first embodiment. + virtual std_unique_ptr GetFilteredTree ( const std::vector& filters ) const = 0; + + // \ru Построить дерево по заданным узлам. Не применимо к дереву исполнений (в этом случае возвращает NULL). + // \en Build a tree for given nodes. Not applicable to embodiment tree (in this case, returns NULL). + virtual std_unique_ptr GetFilteredTree ( std::vector& nodes ) const = 0; + + // \ru Выдать указатель на дерево исполнений. Выдает NULL, если не применимо (нет исполнений). + // \en Get pointer to embodiments tree. Return NULL if not applicable (no embodiments). + virtual const IEmbodimentTree* GetEmbodimentsTree() const = 0; + + // \ru Добавить узел. \en Add a node. + virtual void AddNode ( const TapeBase* mem, const ClusterReference& ref ) = 0; + + // \ru Нотификация об окончании чтения/записи текущего узла. + // \en Notification about the end of current node writing/reading. + virtual void CloseNode( const TapeBase* mem ) = 0; + + // \ru Установить функцию для выбора геометрического объекта для добавления в дерево модели, и заполнения данных узла. + // \en Define a function for selecting a geometric object for adding to the model tree, and filling the node data. + virtual void SetNodeToAddFunction( NodeToAddFunc callback ) { if ( callback ) m_nodeToAddFunc = callback; } + + // \ru Установить функцию для выбора узлов из дерева модели. + // \en Define a function for selecting nodes from the model tree. + virtual void SetFilterFunction( FilterNodesFunc callback ) { if ( callback ) m_filterFunc = callback; } + + // \ru Записать дерево. \en Write the tree. + virtual writer & operator >> ( writer & ) = 0; + // \ru Прочитать дерево. \en Read the tree. + virtual reader & operator << ( reader & ) = 0; + + + // \ru Доступ к корням дерева. + // Узел дерева может быть рекурсивно вложен + // (например, Instance может содержать сборку, которая содержит другой Instance, ссылающийся на эту же сборку). + // \en Access to the tree roots. + // Tree node could be nested recursively + // (e.g. Instance can contain an Assembly which contains another Instance which includes this Assembly). + const std::vector& GetRoots() const { return m_roots; } + std::vector& GetRoots() { return m_roots; } + + // \ru Версия дерева. \en Tree version. + virtual VERSION GetVersion() = 0; + virtual void SetVersion( VERSION ) = 0; + + // \ru Построить поддерево из потомков заданного узла. + // \en Build a tree from children of a given node. + static EXPORT_DECLARATION std_unique_ptr GetSubtree ( const IModelTreeNode* node ); + + // \ru Получить значимые узлы поддерева с указанным корнем (исключив узлы, которые добавлены для восстановления иерархии дерева). + // Возвращает количество значимых узлов. + // \en Get significant nodes in a subtree with the given root (excluding nodes that were added to reconstruct the tree hierarchy). + // Return a number of significant nodes. + static EXPORT_DECLARATION size_t GetSubtreeSignificantNodes ( const c3d::IModelTreeNode* node, std::set& nodes ); + + // \ru Создать экземпляр дерева. \en Create a tree instance. + static EXPORT_DECLARATION IModelTree* CreateModelTree(); + + // \ru Операторы для записи дерева в поток в xml формате. \en Operators to output a tree to a stream in xml format. + friend MATH_FUNC( c3d::t_ofstream & ) operator << ( c3d::t_ofstream& file, IModelTree& tree ); + friend MATH_FUNC( c3d::t_ofstream & ) CALL_DECLARATION operator << ( c3d::t_ofstream& file, const IModelTree& tree ); + +OBVIOUS_PRIVATE_COPY(IModelTree) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Узел дерева исполнений. + \en Embodiments tree node. \~ + \details \ru Узел дерева исполнений (может иметь несколько потомков). + \en Embodiments tree node (can have several children). + \ingroup Base_Tools_IO +*/ +// --- +class IEmbodimentNode +{ +protected: + // \ru Непосредственные потомки узла. \en The immediate children of the node. + std::set m_children; +public: + IEmbodimentNode() {} + virtual ~IEmbodimentNode() { + for ( std::set::iterator i = m_children.begin(); i != m_children.end(); ++i ) + if ( *i != NULL ) delete *i; + } + + // \ru Построить поддерево модели, содержащееся в данном исполнении. + // \en Build a subtree of a model tree which is contained in a given embodiment. + virtual std_unique_ptr GetEmbodiment() const = 0; + + // \ru Выдать узел дерева модели, соответствующий данному исполнению. + // \en Get a model tree node which corresponds to a given embodiment. + virtual const IModelTreeNode * GetModelTreeNode() const = 0; + + // \ru Доступ к информации об исполнении. \en Access to the embodiment info. + virtual const MbItemData& GetEmbodimentData() const = 0; + + // \ru Доступ к непосредственным потомкам узла. \en Access to the immediate node children. + std::set& GetChildren() { return m_children; } + const std::set& GetChildren() const { return m_children; } + + // \ru Добавить потомка. \en Add a child. + void AddChild( IEmbodimentNode* child ) { if ( child ) m_children.insert( child ); } + + OBVIOUS_PRIVATE_COPY( IEmbodimentNode ) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Дерево Исполнений. + \en Embodiment Tree. \~ + \details \ru Дерево Исполнений отражает иерархию вариантов реализации модели (исполнений). + Каждый узел дерева представляет одно исполнение. + Подразумевается, что в геометрической модели исполнение хранится, + как объект MbAssembly с выставленным атрибутом типа at_Embodiment.\n + \en Embodiment Tree presents a hierarchy of variants of model implementation (embodiments). + Each node of the tree presents an embodiment. + It is assumed that in a geometric model an embodiment is stored as + MbAssembly object with an attribute of type at_Embodiment. \n \~ + \ingroup Base_Tools_IO +*/ +class IEmbodimentTree +{ +protected: + std::vector m_roots; + +public: + IEmbodimentTree() {} + virtual ~IEmbodimentTree() {} + + // \ru Доступ к корням дерева. \en Access to the tree roots. + const std::vector& GetRoots() const { return m_roots; } + std::vector& GetRoots() { return m_roots; } + +}; + +} //namespace c3d + +#endif // __IO_TREE_H diff --git a/C3d/Include/io_version_container.h b/C3d/Include/io_version_container.h new file mode 100644 index 0000000..379869c --- /dev/null +++ b/C3d/Include/io_version_container.h @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контейнер версий. + \en Container of versions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_VERSION_CONTAINER_H +#define __IO_VERSION_CONTAINER_H + + +#include +#include + + +//----------------------------------------------------------------------------- +/** \brief \ru Контейнер версий. + \en Container of versions. \~ + \details \ru Контейнер версий объектов. \n + \en Container of versions of objects. \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS VersionContainer +{ +private: + // \ru static VersionContainer iobuf_defaultVersionCont; // Версия по умолчанию. \en static VersionContainer iobuf_defaultVersionCont; // Default version. + static VersionContainer & StaticVersionContainer(); +protected: + SArray m_self; ///< \ru Массив версий. \en Array of versions. +protected: + /// \ru Конструктор. \en Constructor. + VersionContainer( VERSION/*firstInit*/ ); +public: + /// \ru Конструктор. \en Constructor. + VersionContainer(); + /// \ru Конструктор копирования. \en Copy-constructor. + VersionContainer( const VersionContainer & other ); + /// \ru Деструктор. \en Destructor. + virtual ~VersionContainer(); + + /// \ru Получить экземпляр контейнера версий. \en Get the instance of version container. + static const VersionContainer & defaultVersionContainer(); + /// \ru Установить версии из другого контейнера \en Set versions from another container + static void SetDefaultVersion( const VersionContainer & v ); + + // \ru Вернуть главную версию (математического ядра). \en Return the main version (of the mathematical kernel). + VERSION GetMathVersion() const; + // \ru Вернуть дополнительную версию (конечного приложения). \en Return the additional version (of the target application). + VERSION GetAppVersion ( size_t ind = -1 ) const; + // \ru Очистить контейнер. \en Flush the container. + void Flush (); + // \ru Установить версию по индексу. \en Set the version by the index. + void SetVersion ( size_t index, VERSION ver ); + // \ru Записать в кусок памяти. \en Write to the memory block. + size_t ToMemory ( const char *& memory ) const; + // \ru Прочитать из куска памяти. \en Read from the memory block. + size_t FromMemory ( const char * memory ); + + /// \ru Оператор присваивания. \en An assignment operator. + VersionContainer & operator = ( const VersionContainer & other ); + + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader &) operator >> ( reader &, VersionContainer & ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer &, const VersionContainer & ); + +protected: + /// \ru Функция инициализации по другому контейнеру. \en Function of initialization by another container. + void Init( const VersionContainer & ); +}; + +#endif //__IO_VERSION_CONTAINER_H diff --git a/C3d/Include/io_version_container_rw.h b/C3d/Include/io_version_container_rw.h new file mode 100644 index 0000000..edb672f --- /dev/null +++ b/C3d/Include/io_version_container_rw.h @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контейнер версий. Чтение/запись. + \en Container of versions. Reading/writing. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __IO_VERSION_CONTAINER_RW_H +#define __IO_VERSION_CONTAINER_RW_H + +#include +#include + + +//----------------------------------------------------------------------------- +/// \ru Оператор чтения контейнера версий. \en Operator of version container reading. \~ \ingroup Base_Tools_IO +// --- +MATH_FUNC (reader &) operator >> ( reader &, VersionContainer & ); + + +//----------------------------------------------------------------------------- +/// \ru Оператор записи контейнера версий. \en Operator of version container writing. \~ \ingroup Base_Tools_IO +// --- +MATH_FUNC (writer &) operator << ( writer &, const VersionContainer & ); + + +#endif //__IO_VERSION_CONTAINER_RW_H diff --git a/C3d/Include/item_registrator.h b/C3d/Include/item_registrator.h new file mode 100644 index 0000000..423cc2f --- /dev/null +++ b/C3d/Include/item_registrator.h @@ -0,0 +1,190 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Регистраторы объектов: копирования и трансформации. + \en Registrators of objects: copying and transformation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ITEM_REGISTRATOR_H +#define __ITEM_REGISTRATOR_H + + +#include +#include + + +class MATH_CLASS MbRefItem; + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать копию объекта с использованием регистратора сдублированных объектов. + \en Create a copy of the object using the registrator of duplicated objects. \~ + \details \ru Создать копию объекта с использованием регистратора сдублированных объектов. + Если копия объекта уже зарегистрирована, то получить ее из регистратора. \n + \en Create a copy of the object using the registrator of duplicated objects. + If a copy of the object is already registered then get it from the registrator. \n \~ + \ingroup Base_Algorithms +*/ +// --- +#define __REG_DUPLICATE_IMPL( __CLASS ) \ +MbRefItem * copyItem = NULL; \ +if ( iReg == NULL || !iReg->IsReg( this, copyItem ) ) { \ + copyItem = new __CLASS; \ + if ( iReg != NULL ) \ + iReg->SetReg( this, copyItem ); \ +} + + +//------------------------------------------------------------------------------- +/** \brief \ru Регистратор копируемых объектов. + \en Registrator of copied objects. \~ + \details \ru Регистратор используется для построения корректных копий объектов, + содержащих указатели на другие геометрические объекты. \n + Объект может содержаться указателем в нескольких других объектах, подлежащих копированию. + Для предотвращения многократного копирования объекта используется регистратор. + Регистратор представляет собой два синхронных массива. + В первом массиве лежат указатели скопированных объектов, а во втором массиве лежат указатели их копий. \n + При копировании объекта с использованием регистратора проверяется наличие копируемого объекта в первом массиве. + Если такой объект присутствует, то из второго массива выдаётся указатель на его копию. + Если такой объект отсутствует, то он заносится в первый массив, а его созданная копия заносится во второй массив и выдаётся. + \en Registrator is used to construct the correct copies of objects. + which contain pointers to other geometries. \n + Object pointer can be contained in several other objects for copying. + Registrar is used to prevent multiple copying of the object. + Registrator consists of two synchronous arrays. + The first array contains pointers to copied objects, the second array contains pointers to their copies. \n + When copying the object using the registrator, the existance of the copied object inside the first array is verified. + If such object exists, then the pointer to its copy is given from the second array. + If such objects is absent, then it is stored in the first array, after that its copy is stored in the second array and then this copy is returned. \~ + \ingroup Base_Algorithms +*/ +// --- +class MATH_CLASS MbRegDuplicate { +public: + /// \ru Конструктор. \en Constructor. + MbRegDuplicate() {} + /// \ru Деструктор. \en Destructor. + virtual ~MbRegDuplicate(); +public: + /** \brief \ru Проверить, зарегистрирована ли копия объекта. + \en Check whether copy of the object is registered. \~ + \details \ru Найти зарегистрированную копию объекта. \n + \en Find a registered copy of the object. \n \~ + \param[in] srcItem - \ru Исходный объект. + \en The initial object. \~ + \param[out] cpyItem - \ru Зарегистрированная копия объекта. + \en Registered copy of the object. \~ + \return \ru Возращает true, если копия объекта уже зарегистрирована. + \en Returns true if a copy of the object is already registered. \~ + */ + virtual bool IsReg ( const MbRefItem * srcItem, MbRefItem *& cpyItem ) = 0; + /** \brief \ru Зарегистрировать копию объекта. + \en Register copy of the object. \~ + \details \ru Зарегистрировать копию объекта. \n + \en Register copy of the object. \n \~ + \param[in] srcItem - \ru Исходный объект. + \en The initial object. \~ + \param[out] cpyItem - \ru Копия объекта. + \en The object copy. \~ + */ + virtual void SetReg ( const MbRefItem * srcItem, MbRefItem * cpyItem ) = 0; + /// \ru Освободить используемую память и удалить себя. \en Free memory and remove itself. + virtual void Free() = 0; + +OBVIOUS_PRIVATE_COPY( MbRegDuplicate ) +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Авторегистратор дублирования. + \en Auto-registrator of duplication. \~ + \details \ru Автоматическое создание локального регистратора дублирования + и забота о его удалении после использования. \n + \en Automatic creation of the local registrator of duplication + and taking care of its removal after use. \n \~ + \ingroup Base_Algorithms +*/ +// --- +class MATH_CLASS MbAutoRegDuplicate { +private: + /// \ru Локальный регистратор. \en The local registrator. + MbRegDuplicate * locReg; +public: + /// \ru Конструктор. \en Constructor. + MbAutoRegDuplicate( MbRegDuplicate *& ); + /// \ru Деструктор. \en Destructor. + ~MbAutoRegDuplicate(); + +OBVIOUS_PRIVATE_COPY( MbAutoRegDuplicate ) +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Регистратор трансформируемых объектов. + \en Registrator of transformable objects. \~ + \details \ru Регистратор используется для корректной трансформации объектов, + содержащих указатели на другие геометрические объекты. \n + Объект может содержаться указателем в нескольких других объектах, подлежащих преобразованию. + Для предотвращения многократного преобразования объекта используется регистратор. + При преобразовании объекта с использованием регистратора проверяется наличие объекта в регистраторе. + Если такой объект отсутствует, то он заносится в регистратор и выполняется его преобразование, + в противном случае преобразование данного объекта не выполняется. + \en Registrator is used to correct transformation of objects, + which contain pointers to other geometries. \n + Object pointer can be contained in several other objects for transformations. + Registrar is used to prevent multiple transformation of object. + When transforming the object with registrator, the existance of the object inside the registrator is verified. + If such object is absent, it is stored to the registrator and transformed, + otherwise, a transformation of the object is not performed. \~ + \ingroup Base_Algorithms +*/ +// --- +class MATH_CLASS MbRegTransform { +public: + /// \ru Конструктор. \en Constructor. + MbRegTransform() {} + /// \ru Деструктор. \en Destructor. + virtual ~MbRegTransform(); +public: + /** \brief \ru Зарегистрировать трансформированный объект. + \en Register a transformed object. \~ + \details \ru Зарегистрировать трансформированный объект в регистраторе. \n + \en Register a transformed object in the registrator. \n \~ + \return \ru Возращает true, если объект не был ранее зарегистрирован. + \en Returns true if the object hasn't been registered yet. \~ + */ + virtual bool IsSetReg( const MbRefItem * ) = 0; + /// \ru Освободить используемую память и удалить себя. \en Free memory and remove itself. + virtual void Free() = 0; + +OBVIOUS_PRIVATE_COPY( MbRegTransform ) +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Авторегистратор трансформации. + \en Auto-registrator of transformation. \~ + \details \ru Автоматическое создание локального регистратора трансформации + и забота о его удалении после использования. \n + \en Automatic creation of the local registrator of transformation + and taking care of its removal after use. \n \~ + \ingroup Base_Algorithms +*/ +// --- +class MATH_CLASS MbAutoRegTransform { +private: + /// \ru Локальный регистратор. \en The local registrator. + MbRegTransform * locReg; +public: + /// \ru Конструктор. \en Constructor. + MbAutoRegTransform( MbRegTransform *& ); + /// \ru Деструктор. \en Destructor. + ~MbAutoRegTransform(); + +OBVIOUS_PRIVATE_COPY( MbAutoRegTransform ) +}; + + +#endif // __ITEM_REGISTRATOR_H diff --git a/C3d/Include/last.h b/C3d/Include/last.h new file mode 100644 index 0000000..57daf20 --- /dev/null +++ b/C3d/Include/last.h @@ -0,0 +1,38 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контроль утечек памяти. + \en Control of memory leaks. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _LAST_H_ +#define _LAST_H_ + +#include "math_cfg.h" // There are modules without defined paths to C3D + +#ifdef ENABLE_VLD + #include // \ru KVA V14 16.1.2012 Для компиляции КОМПАС \en KVA V14 16.1.2012 To compile the COMPAS + #include +#else + #ifdef C3D_WINDOWS //_MSC_VER + #ifdef __AFX_H__ + #ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE + #define THIS_FILE __FILE__ + #endif + #else // __AFX_H__ + #define _CRTDBG_MAP_ALLOC + #include + #include + + #ifdef _DEBUG + #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) + #endif + #endif // __AFX_H__ + #endif // C3D_WINDOWS +#endif // ENABLE_VLD + +#endif // _LAST_H_ diff --git a/C3d/Include/legend.h b/C3d/Include/legend.h new file mode 100644 index 0000000..fcd271a --- /dev/null +++ b/C3d/Include/legend.h @@ -0,0 +1,64 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вспомогательный геометрический объект в трехмерном пространстве. + \en Auxiliary geometric object in the three-dimensional space. \~ + \details \ru Базовый абстрактный класс вспомогательного геометрического объекта. \n + \en Base abstract class of auxiliary geometric object. \n \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __LEGEND_H +#define __LEGEND_H + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Вспомогательный геометрический объект. + \en Auxiliary geometric object. \~ + \details \ru Базовый абстрактный класс вспомогательного геометрического объекта. \n + Вспомогательные объекты описывают базовые точки других объектов, резьбу, выносные линии, шероховатости и условные обозначения.\n + \en Base abstract class of auxiliary geometric object. \n + Auxiliary objects describe base points of other objects: thread, extension lines, roughness and notation conventions. \n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbLegend : public MbSpaceItem +{ +protected : + /// \ru Конструктор. \en Constructor. + MbLegend(); +public: + /// \ru Деструктор. \en Destructor. + virtual ~MbLegend(); + +public: /* \ru Общие функции геометрического объекта. \en Common functions of a geometric object. */ + + virtual MbeSpaceType IsA() const = 0; // \ru Тип объекта. \en Type of the object. + virtual MbeSpaceType Type() const = 0; // \ru Тип объекта. \en Type of the object. + virtual MbeSpaceType Family() const; // \ru Семейство элемента. \en Family of the element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными? \en Determine whether the objects are equal. + virtual bool IsSimilar( const MbSpaceItem & init ) const = 0; // \ru Являются ли объекты подобными? \en Determine whether the objects are similar. + virtual bool SetEqual ( const MbSpaceItem & init ) = 0; // \ru Сделать объекты равным. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const = 0; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const = 0; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate the bounding box in a local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const = 0; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const = 0; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ) = 0; // \ru Установить свойства объекта. \en Set properties of the object. + + DECLARE_PERSISTENT_CLASS( MbLegend ); + OBVIOUS_PRIVATE_COPY( MbLegend ); +}; + +IMPL_PERSISTENT_OPS( MbLegend ) + + +#endif // __LEGEND_H diff --git a/C3d/Include/lump.h b/C3d/Include/lump.h new file mode 100644 index 0000000..ef64638 --- /dev/null +++ b/C3d/Include/lump.h @@ -0,0 +1,226 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Тело, матрица его преобразования и идентификаторы владельцев. + \en Solid, matrix of its transformation and identifiers of owners. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __LUMP_H +#define __LUMP_H + + +#include +#include +#include +#include +#include +#include + + +class MbRegDuplicate; +struct MATH_CLASS MbLump; + +namespace c3d // namespace C3D +{ +typedef SPtr LumpSPtr; +typedef SPtr ConstLumpSPtr; + +typedef std::vector LumpsVector; +typedef std::vector ConstLumpsVector; + +typedef std::vector LumpsSPtrVector; +typedef std::vector ConstLumpsSPtrVector; + +typedef std::set LumpsSet; +typedef LumpsSet::iterator LumpsSetIt; +typedef LumpsSet::const_iterator LumpsSetConstIt; +typedef std::pair LumpsSetRet; + +typedef std::set LumpsSPtrSet; +typedef LumpsSPtrSet::iterator LumpsSPtrSetIt; +typedef LumpsSPtrSet::const_iterator LumpsSPtrSetConstIt; +typedef std::pair LumpsSPtrSetRet; + +typedef std::set ConstLumpsSet; +typedef ConstLumpsSet::iterator ConstLumpsSetIt; +typedef ConstLumpsSet::const_iterator ConstLumpsSetConstIt; +typedef std::pair ConstLumpsSetRet; + +typedef std::set ConstLumpsSPtrSet; +typedef ConstLumpsSPtrSet::iterator ConstLumpsSPtrSetIt; +typedef ConstLumpsSPtrSet::const_iterator ConstLumpsSPtrSetConstIt; +typedef std::pair ConstLumpsSPtrSetRet; +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Тело, матрица его преобразования и идентификаторы владельцев. + \en Solid, matrix of its transformation and identifiers of owners. \~ + \details \ru Тело, матрица его преобразования из локальной системы координат и + идентификаторы владельцев тела. \n + \en Solid, matrix of its transformation from local coordinate system and + identifiers of solid owners. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbLump: public MbRefItem { +protected: + c3d::ConstSolidSPtr solid; ///< \ru Тело (всегда не NULL). \en Solid (always not NULL). + uint component; ///< \ru Идентификатор компонента, в котором определено тело. \en An identifier of a component which a solid is defined in. + size_t identifier; ///< \ru Идентификатор нити. \en A thread identifier. + MbMatrix3D from; ///< \ru Матрица преобразования из локальной системы координат. \en A transformation matrix from the local coordinate system. +private: + bool changed; ///< \ru Флаг необходимости обработки компонента. \en Component processing flag. + +private: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbLump( const MbLump & other, MbRegDuplicate * iReg ); +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbLump() : solid( NULL ), component( 0 ), identifier( SYS_MAX_T ), from(), changed( true ) {} + /// \ru Конструктор по данным. \en Constructor by data. + MbLump( const MbSolid & _solid, const MbMatrix3D & _from, uint _comp = 0, size_t _ident = SYS_MAX_T, bool _changed = true ); + /// \ru Деструктор. \en Destructor. + virtual ~MbLump(); + +public: + + /// \ru Базовое тело? \en Whether the solid is basic. + virtual bool IsBaseLump() const { return true; } + /// \ru Тело с признаком резки на производном виде? \en Solid with cutting type on derive view? + virtual bool IsCutLump() const { return false; } + /// \ru Тело с признаком резки? \en Solid with cutting type? + virtual bool IsMappingLump() const { return false; } + /// \ru Разрезать тело в производном виде. \en Cut solid on derive view. + virtual bool WillCutOnDeriveView() const { return true; } + /// \ru Дублирование объекта. \en Duplication of an object. + virtual MbLump & Duplicate( MbRegDuplicate * iReg = NULL ) const; + /// \ru Получить имя компонента. \en Get the name of a component. + uint GetComponent() const { return component; } + /// \ru Установить имя компонента. \en Set the name of a component. + void SetComponent( uint comp ) { component = comp; } + /// \ru Получить идентификатор. \en Get the thread identifier. + size_t GetIdentifier() const { return identifier; } + /// \ru Есть идентификатор? \en Is an thread identifier. + bool IsIdentifier() const { return (identifier != SYS_MAX_T); } + /// \ru Установить идентификатор. \en Set the thread identifier. + void SetIdentifier( size_t id ) { identifier = id; } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + const MbMatrix3D & GetMatrixFrom() const { return from; } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + MbMatrix3D & SetMatrixFrom() { return from; } + /// \ru Инициализировать тело и матрицу. \en Initialize solid and matrix. + void SetSolid( const MbSolid & _solid, const MbMatrix3D & _from, bool _changed = true ); + /// \ru Получить тело. \en Get solid. + const MbSolid & GetSolid() const { return *solid; } + + /// \ru Получить флаг необходимости обработки компонента. \en Get component processing flag. + bool GetChanged() const { return changed; } + /// \ru Установить флаг необходимости обработки компонента. \en Set component processing flag. + void SetChanged( bool c ) { changed = c; } + +/// \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbLump, MATH_FUNC_EX ) +/// \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. +OBVIOUS_PRIVATE_COPY( MbLump ) +}; + + +namespace c3d // namespace C3D +{ + +//----------------------------------------------------------------------------- +/** +Сравнение компонентов MbLump +*/ +//--- +struct LumpCompLess +{ + bool operator()(const MbLump * lhs, const MbLump * rhs) const + { + _ASSERT( lhs && rhs ); + return lhs->GetComponent() < rhs->GetComponent(); + } +}; + +typedef std::multiset ConstLumpsMultiSet; + +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Габарит тела, матрица его преобразования и идентификаторы владельцев. + \en Solid bounding box, matrix of its transformation and identifiers of owners. \~ + \details \ru Габарит тела, матрица его преобразования из локальной системы координат и + идентификаторы владельцев тела. \n + \en Solid bounding box, matrix of its transformation from local coordinate system and + identifiers of solid owners. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbLumpCube: public MbRefItem { +protected: + MbCube cube; ///< \ru Габарита тела. \en Solid bounding box. + MbMatrix3D from; ///< \ru Матрица преобразования из локальной системы координат. \en A transformation matrix from the local coordinate system. + uint component; ///< \ru Идентификатор компонента, в котором определено тело. \en An identifier of a component which a solid is defined in. + size_t identifier; ///< \ru Идентификатор нити. \en A thread identifier. + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbLumpCube() + : cube() + , from() + , component( 0 ) + , identifier( SYS_MAX_T ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbLumpCube( const MbLumpCube & other ) + : cube( other.cube ) + , from( other.from ) + , component( other.component ) + , identifier( other.identifier ) + {} + /// \ru Конструктор по данным. \en Constructor by data. + MbLumpCube( const MbCube & _cube, const MbMatrix3D & _from, uint _comp, size_t _ident ) + : cube ( _cube ) + , from ( _from ) + , component ( _comp ) + , identifier( _ident ) + {} + /// \ru Деструктор. \en Destructor. + ~MbLumpCube() {} + +public: + /// \ru Получить габарит тела. \en Get solid bounding box. + const MbCube & GetCube() const { return cube; } + /// \ru Инициализировать тело и матрицу. \en Initialize solid and matrix. + void SetCube( const MbCube & _cube, const MbMatrix3D & _from ) { cube.Init( _cube ); from.Init( _from ); } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + MbMatrix3D & SetMatrixFrom() { return from; } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + const MbMatrix3D & GetMatrixFrom() const { return from; } + + /// \ru Получить имя компонента. \en Get the name of a component. + uint GetComponent() const { return component; } + /// \ru Установить имя компонента. \en Set the name of a component. + void SetComponent( uint comp ) { component = comp; } + /// \ru Получить идентификатор. \en Get the thread identifier. + size_t GetIdentifier() const { return identifier; } + /// \ru Установить идентификатор. \en Set the thread identifier. + void SetIdentifier( size_t id ) { identifier = id; } + +public: + const MbLumpCube & operator = ( const MbLumpCube & other ) + { + cube.Init( other.cube ); + from.Init( other.from ); + component = other.component; + identifier = other.identifier; + return *this; + } +}; + + +#endif // __LUMP_H diff --git a/C3d/Include/m2b_mesh_curvature.h b/C3d/Include/m2b_mesh_curvature.h new file mode 100644 index 0000000..86f9244 --- /dev/null +++ b/C3d/Include/m2b_mesh_curvature.h @@ -0,0 +1,40 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Структура для хранения кривизн, их направлений и нормалей в вершине сетки. + \en Struct to store curvatures, principal curvature directions and normals at mesh vertex. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __M2B_MESH_CURVATURE_H +#define __M2B_MESH_CURVATURE_H + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные о кривизне и главных направлениях изменений кривизны. + \en Curvature and principal curvature direction data. \~ + \details \ru Структура для хранения информации о кривизне и главных направлениях изменений кривизны поверхности, + рассчитанной в вершине полигональной сетки. + \en Structure for store curvature and principal curvature direction data calculated at the polygon vertex. \~ + \ingroup Polygonal_Objects +*/ +// --- +struct MATH_CLASS MbCurvature +{ + double k_h; ///< \ru Средняя кривизна. \en Mean curvature. + double k_g; ///< \ru Гауссова кривизна. \en Gaussian curvature. + double k1; ///< \ru Максимальная кривизна. \en Maximum principal curvature. + double k2; ///< \ru Минимальная кривизна. \en Minimum principal curvature. + MbVector3D normal; ///< \ru Нормаль (вычислена по оператору кривизны). \en Normal (calculated by curvature operator). + MbVector3D meanNormal; ///< \ru Нормаль (вычислена как взвешенное среднее нормалей соседних граней). \en Normal (calculated as weighted mean of the normals of neighboring faces). + MbVector3D cdir1; ///< \ru Направление максимальной кривизны. \en Maximum principal curvature direction. + MbVector3D cdir2; ///< \ru Направление минимальной кривизны. \en Minimum principal curvature direction. + /// \ru Конструктор по умолчанию. \en Default constructor. + MbCurvature() : k_h( 0.0 ), k_g( 0.0 ), k1 ( 0.0 ), k2 ( 0.0 ) {} +}; + + +#endif // __M2B_MESH_CURVATURE_H diff --git a/C3d/Include/map_create.h b/C3d/Include/map_create.h new file mode 100644 index 0000000..c6a4170 --- /dev/null +++ b/C3d/Include/map_create.h @@ -0,0 +1,563 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль проецирования. Главные функции и интерфейсы. + \en The projection module. The general functions and interfaces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_CREATE_H +#define __MAP_CREATE_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbSolid; +class MATH_CLASS MbTopologyItem; +class MATH_CLASS MbGrid; +class MATH_CLASS MbFloatGrid; +class MATH_CLASS MbMapBodiesPArray; + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Построение плоских проекций по модельным объектам \en The planar projections construction on model objects +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Дополнительные проецируемые объекты. + \en The additional projected objects. \~ + + \details \ru Дополнительные проецируемые объекты содержат:\n + - аннотационные кривые,\n + - аннотационные объекты,\n + - условные обозначения,\n + - пространственные точки,\n + - пространственные кривые.\n + Внимание: \n + 1. Элементы в массивах должны лежать с захватом по счетчику ссылок. \n + 2. Объект безусловно владеет массивами. Если массивы созданы локально, то их нужно отпустить через вызов Relinquish. + \en The class of additional projected objects. \n + Contains sets of projected objects:\n + - annotation curves,\n + - annotation objects,\n + - conventional notations,\n + - spatial points,\n + - spatial curves.\n + Attention: \n + 1. The elements in the arrays must lie with the capture by the reference count. \n + 2. The object owns arrays. If the arrays were created locally, then you have to release them using the object function Relinquish. \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbProjectionsObjects { + +public: + TPointer< RPArray > annCurves; ///< \ru Аннотационные кривые (может быть нулем). \en Annotation curves (can be NULL). + TPointer< RPArray > annotations; ///< \ru Аннотационные объекты (может быть нулем). \en Annotation objects (can be NULL). + TPointer< RPArray > symbolObjects; ///< \ru Условные обозначения (может быть нулем). \en Conventional notations (can be NULL). + TPointer< RPArray > pointsData; ///< \ru Пространственные точки (может быть нулем). \en Spatial points (can be NULL). + TPointer< RPArray > curvesData; ///< \ru Пространственные кривые (может быть нулем). \en Spatial curves (can be NULL). + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + + \details \ru Конструктор пустых наборов проецируемых объектов.\n + \en Constructor of empty sets of projected objects.\n \~ + */ + MbProjectionsObjects() + : annCurves ( NULL ) + , annotations ( NULL ) + , symbolObjects( NULL ) + , pointsData ( NULL ) + , curvesData ( NULL ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbProjectionsObjects( const MbProjectionsObjects & other, MbRegDuplicate * iReg ); + +public: + /// \ru Деструктор. Отпускает захваченные объекты. \en Destructor. Detaches captured objects. + ~MbProjectionsObjects() + { + if ( annCurves ) + ::ReleaseItems( *annCurves ); + if ( annotations ) + ::ReleaseItems( *annotations ); + if ( symbolObjects ) + ::ReleaseItems( *symbolObjects ); + if ( pointsData ) + ::ReleaseItems( *pointsData ); + if ( curvesData ) + ::ReleaseItems( *curvesData ); + } + + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual MbProjectionsObjects & Duplicate( MbRegDuplicate * iReg = NULL ) const; + + /// \ru Отпустить все указатели. \en Detach all pointers. + void Relinquish() + { + annCurves.Relinquish(); + annotations.Relinquish(); + symbolObjects.Relinquish(); + pointsData.Relinquish(); + curvesData.Relinquish(); + } + + +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbProjectionsObjects, MATH_FUNC_EX ) +OBVIOUS_PRIVATE_COPY( MbProjectionsObjects ) +}; // MbProjectionsObjects + + +//------------------------------------------------------------------------------ +/** \brief \ru Структура для обмена данными между потоками. + \en A structure for data transmission between threads. \~ + + \details \ru Структура для обмена данными между потоками. \n + \en A structure for data transmission between threads. \n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS GetVestigesTransData { +public: + typedef RPArray Lumps; +private: + Lumps lumps; ///< \ru Проецируемые объекты (владеет). \en Projected objects (owns) +public: + MbPlacement3D formPlace; ///< \ru Проекционная плоскость. \en A projection plane. + double znear; ///< \ru Параметр перспективного изображения. \en A parameter of perspective image. + MbProjectionsObjects prObjects; ///< \ru Дополнительные проецируемые объекты. \en Additional projected objects + MbVEFVestiges vestiges; ///< \ru Результат. \en The result. + MbMapVisibilityMode visMode; ///< \ru Показывать невидимые линии. \en Show invisible lines. + VERSION version; ///< \ru Под какую версию проецируем. \en Version of projecting. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор с версией по умолчанию.\n + \en Constructor with default version.\n \~ + */ + GetVestigesTransData() + : lumps ( 0, 1 ) + , formPlace( ) + , znear ( UNDEFINED_DBL ) + , prObjects( ) + , vestiges ( ) + , visMode ( false, false ) + , version ( Math::DefaultMathVersion() ) + {} + + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + GetVestigesTransData( const GetVestigesTransData & other, MbRegDuplicate * iReg ); + + /// \ru Деструктор. \en Destructor. + virtual ~GetVestigesTransData() { + DeleteLumps(); + } + +public: + Lumps & SetLumps() { return lumps; } + + size_t GetLumpsCount() const { return lumps.size(); } + const MbLump * _GetLump( size_t k ) const { return lumps[k]; } + const MbLump * GetLump( size_t k ) const { return ((k < lumps.size()) ? lumps[k] : NULL); } + MbLump * _SetLump( size_t k ) { return lumps[k]; } + MbLump * SetLump( size_t k ) { return ((k < lumps.size()) ? lumps[k] : NULL); } + + template + void GetLumps( Lumps & _lumps ) const + { + size_t getCnt = lumps.size(); + if ( getCnt > 0 ) { + _lumps.reserve( getCnt ); + for ( size_t k = 0; k < getCnt; ++k ) { + SPtr lump( const_cast( lumps[k] ) ); + _lumps.push_back( lump ); + ::DetachItem( lump ); + } + } + } + + void AddLump( const MbLump & ); + + template + void AddLumps( Lumps & _lumps ) + { + size_t addCnt = _lumps.size(); + if ( addCnt > 0 ) { + lumps.reserve( addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + const MbLump * lump = _lumps[k]; + ::AddRefItem( lump ); + lumps.push_back( lump ); + } + } + } + + MbLump * DetachLump( size_t k ); + + template + void DetachLumps( Lumps & _lumps ) + { + size_t detCnt = lumps.size(); + if ( detCnt > 0 ) { + _lumps.reserve( detCnt ); + for ( size_t k = 0; k < detCnt; ++k ) { + ::DecRefItem( lumps[k] ); + SPtr lump( lumps[k] ); + _lumps.push_back( lump ); + ::DetachItem( lump ); + } + lumps.clear(); + } + } + + void DeleteLumps() { + ::ReleaseItems( lumps ); + } + + +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( GetVestigesTransData, MATH_FUNC_EX ) +OBVIOUS_PRIVATE_COPY( GetVestigesTransData ) +}; // GetVestigesTransData + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение проекций вида. + \en Construction of view projections. \~ + + \details \ru Построения проекций вида на указанную плоскость.\n + Создает набор следов объектов - тел с матрицами и дополнительных проецируемых объектов. + \en Construction of view projections to the given plane.\n + Creates a set of vestiges of objects - solids with matrices and additional projected objects. \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode runs in parallel. \~ + + \param[in] place - \ru Проекционная плоскость. + \en A projection plane. \~ + \param[in] znear - \ru Параметр перспективного изображения. Задавать равным 0.0. + \en A parameter of perspective image. Should be set to 0.0. \~ + \param[in] lumps - \ru Проецируемые объекты. + \en Projected objects. \~ + \param[in] objects - \ru Дополнительные проецируемые объекты. + \en Additional projected objects. \~ + \param[out] result - \ru Результат. + \en The result. \~ + \param[in] visMode - \ru Настройки видимости следов проецируемых объектов. + Относится к проекциям тел, пространственным точкам, пространственным кривым. + Не используется для условных обозначений. + \en Visibility mode of mapping. + Applicable to projections of solids, spatial points, spatial curves. + Not applicable to conventional notations. \~ + \param[in] version - \ru Версия построения. Последняя версия Math::DefaultMathVersion(). + \en The version of construction. The last version Math::DefaultMathVersion(). + \param[in] merge - \ru Флаг слияния подобных кривых (по умолчанию true). + \en Merge same curves (default true). \~ + \param[in] prevCubes - \ru Габариты тел до изменений. + \en Bounding boxes of solids before changes. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (void) GetVestiges ( const MbPlacement3D & place, + double znear, + const RPArray & lumps, + const MbProjectionsObjects & objects, + MbVEFVestiges & result, + const MbMapVisibilityMode & visMode, + VERSION version = Math::DefaultMathVersion(), + bool merge = true, + const std::vector * prevCubes = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief + \ru Параметры для построения одной проекции вида. + \en Parameters for the construction of one view projection.\n \~ +\ingroup Mapping +*/ +struct MbMapSettings { + typedef std::vector LumpCubes; +public: + /// \ru Проекционная плоскость. \en A projection plane. + MbPlacement3D m_place; + /// \ru Параметр перспективного изображения. Задавать равным 0.0. \en A parameter of perspective image. Should be set to 0.0. + double m_zNear; + + /** \brief \ru Настройки видимости следов проецируемых объектов. + \en Visibility mode of mapping. \~ + \details \ru Настройки видимости следов проецируемых объектов. + Относится к проекциям тел, пространственным точкам, пространственным кривым. + Не используется для условных обозначений. + \en Visibility mode of mapping. + Applicable to projections of solids, spatial points, spatial curves. + Not applicable to conventional notations. \~ + */ + MbMapVisibilityMode m_visMode; + /// \ru Флаг слияния подобных кривых (по умолчанию true). \en Merge same curves (default true). + bool m_merge; + /// \ru Габариты тел до изменений. \en Bounding boxes of solids before changes. + const LumpCubes * m_prevCubes; + +public: + MbMapSettings( MbMapVisibilityMode mode, MbPlacement3D place = MbPlacement3D::global, + double znear = 0, bool merge = true, const LumpCubes * prevCubes = NULL ) + : m_place ( place ) + , m_zNear ( znear ) + , m_visMode ( mode ) + , m_merge ( merge ) + , m_prevCubes( prevCubes ) + {} + + MbMapSettings & operator = ( const MbMapSettings & rt ) + { + m_place = rt.m_place; + m_zNear = rt.m_zNear; + m_visMode = rt.m_visMode; + m_merge = rt.m_merge; + m_prevCubes = rt.m_prevCubes; + return *this; + } + +private: + MbMapSettings(); // \ru Не реализован. \en Not implemented. +}; // MbMapSettings + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение проекций для нескольких видов. + \en Construction of several view projections. \~ + + \details \ru Построение проекций на указанные плоскости.\n + Создает наборы следов объектов (тел с матрицами и дополнительных проецируемых объектов). + \en Construction of projections to the given planes.\n + Creates sets of vestiges of objects (solids with matrices and additional projected objects). \~ + \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. \~ + + \param[in] settings - \ru Массив наборов параметров для построения проекций. + \en An array of parameter sets for the construction of view projections. \~ + \param[in] lumps - \ru Проецируемые объекты. + \en Projected objects. \~ + \param[in] objects - \ru Дополнительные проецируемые объекты. + \en Additional projected objects. \~ + \param[out] results - \ru Массив указателей на результаты (перед началом вычислений очищается с удалением объектов). + Освобождать созданные результаты должна вызывающая функция. + \en The results array (is erased prior to the calculations with objects deletion). + Destruction of the results is a responsibility of the function caller. \~ + \param[in] version - \ru Версия построения. Последняя версия Math::DefaultMathVersion(). + \en The version of construction. The last version Math::DefaultMathVersion(). +\ingroup Mapping +*/ +// --- +MATH_FUNC (void) GetVestiges ( const SArray & settings, + const RPArray & lumps, + const MbProjectionsObjects & objects, + PArray & results, + VERSION version = Math::DefaultMathVersion() ); + +//------------------------------------------------------------------------------ +/** \brief \ru Определение участков граничной кривой. + \en The definition of boundary curve regions. \~ + + \details \ru Определение участков граничной кривой местного вида или выносного вида. + \en Definition of regions of boundary curve of local view or remote view. \~ + \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. \~ + + \param[in] lumps - \ru Проецируемые объекты. + \en Projected objects. \~ + \param[in] contour - \ru Граничная кривая. В системе координат вида viewInfo. + \en A boundary curve. In the coordinate system of the view "viewInfo". \~ + \param[in] cross - \ru Точки пересечения граничной кривой с линиями чертежа - + точки разбивки кривой на области разной видимости. + \en Points of intersection between boundary curve and lines of drawing - + points of intersection of curve on regions of different visibility. \~ + + \param[in] baseViewInfo - \ru Информация о базовом виде, на котором построен местный вид или разрез:\n + тип вида:\n + mvt_View - Вид,\n + mvt_Cut - Разрез,\n + mvt_Section - Сечечние;\n + плоскость вида, разреза или сечения.\n + \en The information about base view, on which a local or sectional view:\n + a view type:\n + mvt_View - View,\n + mvt_Cut - Cutaway,\n + mvt_Section - Section;\n + a plane of view, cutaway or section.\n \~ + + + \param[in] viewInfo - \ru Информация о виде:\n + тип вида:\n + mvt_View - Местный вид, Выносной элемент,\n + mvt_Cut - Местный разрез,\n + mvt_Section - Местное сечение;\n + плоскость вида, разреза или сечения.\n + Если тип производного и базового вида != mvt_View, + то тип производного вида должен совпадать с видом базового.\n + \en The information about a view:\n + a view type:\n + mvt_View - A local view. A detail view,\n + mvt_Cut - A local cutaway,\n + mvt_Section - A local section;\n + a plane of view, cutaway or section.\n + If the type of derived and basic view is not equal to the mvt_View + then the type of the derived view must coincide with the type of the basic view.\n \~ + + + \internal \ru См. справку "Команда Местный разрез". + Если вид, на котором базируется местный разрез (сечение), является разрезом (сечением), + то тип изображения (производного вида) совпадает с типом опорного вида (базового). + \en See in documentation about the command "Local cutaway". + If a view which the local cutaway (section) is based on is a cutaway (section) + then the type of image (of derivative view) matches the type of the reference (the base) type. \~ + \endinternal + + \param[out] curves - \ru Результат - набор видимых участков граничной кривой. + \en The result - a set of visible pieces of a boundary curve. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (void) JustCutLimitCurve( const RPArray & lumps, + const MbCurve & contour, + const SArray & cross, + const MbMapViewInfo & baseViewInfo, + const MbMapViewInfo & viewInfo, + RPArray & curves ); + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать полигоны линий. + \en Calculate polygons of lines. \~ + \details \ru Рассчитать полигоны видимых и невидимых линий для сборки. + \en Calculate polygons of visible and invisible lines for assembly. \~ + \param[in] lumps - \ru Набор тел с матрицами. + \en A set of solids with matrices. \~ + \param[in] place - \ru Проекционная плоскость. + \en A projection plane. \~ + \param[in] znear - \ru Параметр перспективного отображения. Задавать равным 0.0. + \en A parameter of perspective mapping. Set to be equal to 0.0. \~ + \param[in] sag - \ru Угловая толерантность. + \en An angular tolerance. \~ + \param[out] visibleEdges - \ru Полигоны видимых линий ребер. + \en Polygons of visible lines of edges. \~ + \param[out] hiddenEdges - \ru Полигоны невидимых линий ребер. + \en Polygons of invisible lines of edges. \~ + \param[out] visibleTangs - \ru Полигоны видимых линий гладких ребер. + \en Polygons of visible lines of smooth edges. \~ + \param[out] hiddenTangs - \ru Полигоны невидимых линий гладких ребер. + \en Polygons of invisible lines of smooth edges. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (void) HiddenLinesMapping( const RPArray & lumps, + const MbPlacement3D & place, + double znear, + double sag, + PArray & visibleEdges, + PArray & hiddenEdges, + PArray & visibleTangs, + PArray & hiddenTangs ); + +//------------------------------------------------------------------------------ +/** \brief \ru Рассчитать полигоны видимых линий. + \en Calculate polygons of visible lines. \~ + \details \ru Рассчитать полигоны видимых линий и линий очерка для сборки. + \en Calculate polygons of visible lines and isocline curves for assembly. \~ + \param[in] lumps - \ru Набор тел с матрицами. + \en A set of solids with matrices. \~ + \param[in] place - \ru Проекционная плоскость. + \en A projection plane. \~ + \param[in] znear - \ru Параметр перспективного отображения. Задавать равным 0.0. + \en A parameter of perspective mapping. Set to be equal to 0.0. \~ + \param[in] sag - \ru Угловая толерантность. + \en An angular tolerance. \~ + \param[out] visibleEdges - \ru Полигоны видимых линий. + \en Polygons of visible lines. \~ + \param[out] visibleTangs - \ru Полигоны видимых линий гладких ребер. + \en Polygons of visible lines of smooth edges. \~ + \param[in] version - \ru Версия построения. + \en The version. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (void) VisualLinesMapping( const RPArray & lumps, + const MbPlacement3D & place, + double znear, + double sag, + PArray & visibleEdges, + PArray & visibleTangs, + VERSION version = Math::DefaultMathVersion() ); + +//------------------------------------------------------------------------------ +/** \brief \ru Построить силуэтные линий по триангуляционной сетке. + \en Construct silhouette lines by a triangular mesh. \~ + \details \ru Выдать силуэтные линии в виде пар указателей на существующие точки в массиве триангуляции. + \en Get silhouette lines as pairs of pointers to the existed points in the array of triangulation. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en A triangular mesh. \~ + \param[in] matrix - \ru Матрица для задания вектора взгляда. + \en A matrix for setting of view vector. \~ + \param[in] perspective - \ru Признак перспективного отображения. + \en An attribute of perspective mapping. \~ + \param[out] points - \ru Результат - набор точек. + \en The result - the set of points. \~ + \ingroup Triangulation +*/ +// --- +MATH_FUNC (void) CalculateBoundsSltFast( const MbFloatGrid & grid, + const MbMatrix3D & matrix, + bool perspective, + RPArray & points ); + +//------------------------------------------------------------------------------ +/** \brief \ru Построить силуэтные линий по триангуляционной сетке. + \en Construct silhouette lines by a triangular mesh. \~ + \details \ru Выдать силуэтные линии в виде пар точек. + \en Get silhouette lines as pairs of points. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en A triangular mesh. \~ + \param[in] matrix - \ru Матрица для задания вектора взгляда. + \en A matrix for setting of view vector. \~ + \param[in] perspective - \ru Признак перспективного отображения. + \en An attribute of perspective mapping. \~ + \param[out] points - \ru Результат - набор точек. + \en The result - the set of points. \~ + \ingroup Triangulation +*/ +// --- +MATH_FUNC (void) CalculateBoundsSlt( const MbGrid & grid, + const MbMatrix3D & matrix, + bool perspective, + SArray & points ); + +//------------------------------------------------------------------------------ +/** \brief \ru Построить линии сечения по триангуляционной сетке. + \en Construct section lines by a triangular mesh. \~ + \details \ru Выдать линии сечения в виде пар точек. + \en Get section lines as pairs of points. \~ + \param[in] grid - \ru Триангуляционная сетка. + \en A triangular mesh. \~ + \param[in] matrix - \ru Матрица для задания плоскости сечения. + \en A matrix for setting of section plane. \~ + \param[out] points - \ru Результат - набор точек. + \en The result - the set of points. \~ + \ingroup Triangulation +*/ +// --- +MATH_FUNC (void) CalculateSections( const MbGrid & grid, + const MbMatrix3D & matrix, + SArray & points ); + + +#endif // __MAP_CREATE_H diff --git a/C3d/Include/map_implementation.h b/C3d/Include/map_implementation.h new file mode 100644 index 0000000..da1d5eb --- /dev/null +++ b/C3d/Include/map_implementation.h @@ -0,0 +1,256 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Множество проекций тел. + \en The array of projections of solids. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_IMPLEMENTATION_H +#define __MAP_IMPLEMENTATION_H + + +#include +#include + + +struct MbLump; +struct MbBody; +class MbMapBody; +class MATH_CLASS MbProjectionsObjects; +class MATH_CLASS MbSpacePoints; +class MATH_CLASS MbSpaceCurves; +class MATH_CLASS MbSymbol; +class MATH_CLASS MbMapViewInfo; + + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Построение плоских проекций по модельным объектам \en The planar projections construction on model objects +// +//////////////////////////////////////////////////////////////////////////////// + + enum MbeMatrixCompareResult + { + mcr_Same, + mcr_Shift, + mcr_ShiftZ, + mcr_Other + }; + +//------------------------------------------------------------------------------ +/** \brief \ru Множество проекций тел. + \en The set of solids projections. \~ + \details \ru Множество проекций тел.\n + Содержит набор проецируемых тел. + \en The set of solids projections.\n + Contains a set of projected solids. \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbMapBodiesPArray { + +private: + RPArray mapBodies; ///< \ru Множество проекций тел \en A set of solids projections + SArray originIndices; ///< \ru Индексы оригинальных тел в mapBodies. \en indices of original body in mapBodies. + ///< \ru Все тела в mapBodies сгруппированы так ОsssОssОООssОsО, O - оригинальное тело, s - тело полученное сдвигом. + ///< \en All bodies in mapBodies was grouped like ОsssОssОООssОsО? O- original body, s - body was shifted. +public: + /// \ru Конструктор объекта с пустым набором тел. \en Constructor of an object with an empty set of solids. + MbMapBodiesPArray() : mapBodies( 0, 1 ), originIndices( 0, 1 ) {} + /// \ru Деструктор. \en Destructor. + ~MbMapBodiesPArray(); + +public: + /// \ru Число проецируемых тел. \en The number of projected solids. + size_t MapBodiesCount() const { return mapBodies.Count(); } + + /** \brief \ru Выдать тело. + \en Get a solid. \~ + \details \ru Выдать тело по индексу. Без проверки индекса. \n + \en Get a solid by an index. Without index checking. \n \~ + \param[in] index - \ru Индекс тела. + \en A solid index. \~ + */ + MbMapBody * _SetMapBody( size_t index ) const { return mapBodies[index]; } + + /** \brief \ru Выдать тело. + \en Get a solid. \~ + \details \ru Выдать тело по индексу. Без проверки индекса. \n + \en Get a solid by an index. Without index checking. \n \~ + \param[in] index - \ru Индекс тела. + \en A solid index. \~ + */ + const MbMapBody * _GetMapBody( size_t index ) const { return mapBodies[index]; } + + /** \brief \ru Построение ассоциативных проекций. + \en The construction of associative projections. \~ + \details \ru Построение ассоциативных проекций. Первая часть.\n + \en The construction of associative projections. The first part.\n \~ + \param[in] lumps - \ru Набор тел для проецирования. + \en A set of solids for projection. \~ + \param[in] into - \ru Матрица перехода в локальную систему координат. + \en A matrix of translation to the local coordinate system. \~ + \param[in] znear - \ru Параметр перспективного отображения. Задавать равным 0.0. + \en A parameter of perspective mapping. Set to be equal to 0.0. \~ + \param[in] perspective - \ru Признак перспективного отображения. Задавать равным false. + \en An attribute of perspective mapping. Set to be equal to false. \~ + \param[in] visMode - \ru Признак проецирования невидимых линий. + \en An attribute of invisible lines projection. \~ + \param[in] version - \ru Версия построения чертежа. Задавать версию Math::DefaultMathVersion(). + \en The version of construction of drawing. Set the Math::DefaultMathVersion() version. \~ + \param[in] prevCubes - \ru Габариты тел до изменений. + \en Bounding boxes of solids before changes. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + */ + void CreateFirst( const RPArray & lumps, + const MbMatrix3D & into, double znear, + bool perspective, const MbMapVisibilityMode & visMode, VERSION version, + const std::vector * prevCubes = NULL ); + + /** \brief \ru Построение ассоциативных проекций. + \en The construction of associative projections. \~ + \details \ru Построение ассоциативных проекций. Вторая часть.\n + Построение проекций и заполнение следов объектов. + \en The construction of associative projections. The second part.\n + The construction of projections and filling the vestiges. \~ + \param[out] vestiges - \ru Результат - набор следов проецируемых объектов. + \en The result is a set of vestiges of projected objects. \~ + \param[in] visMode - \ru Признак проецирования невидимых линий. + \en An attribute of the invisible lines projection. \~ + \param[in] into - \ru Матрица перехода в локальную систему координат. + \en A matrix of translation to the local coordinate system. \~ + \param[in] znear - \ru Параметр перспективного отображения. Задавать равным 0.0. + \en A parameter of perspective mapping. Set to be equal to 0.0. \~ + \param[in] perspective - \ru Признак перспективного отображения. Задавать равным false. + \en An attribute of perspective mapping. Set to be equal to false. \~ + \param[in] annotations - \ru Набор аннотационных объектов. + \en A set of annotation objects. \~ + \param[in] pointsData - \ru Набор пространственных точек. + \en A set of spatial points. \~ + \param[in] curvesData - \ru Набор пространственных кривых. + \en A set of spatial curves. \~ + \param[in] symbolObjects - \ru Набор условных обозначений. + \en A set of conventional notations. \~ + \param[in] merge - \ru Флаг слияния подобных кривых (по умолчанию true). + \en Murge same curves (true default). \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + */ + void GetVestiges( MbVEFVestiges & vestiges, + const MbMapVisibilityMode & visMode, const MbMatrix3D & into, + double znear, bool perspective, + PArraySort * annotations, + RPArray * pointsData, + RPArray * curvesData, + RPArray * symbolObjects, + bool merge = true ); + + /** \brief \ru Рассчитать полигоны линий. + \en Calculate polygons of lines. \~ + \details \ru Рассчитать полигоны видимых и невидимых линий для сборки. + \en Calculate polygons of visible and invisible lines for assembly. \~ + \param[out] arVL - \ru Полигоны видимых линий ребер. + \en Polygons of visible lines of edges. \~ + \param[out] arHL - \ru Полигоны невидимых линий ребер. + \en Polygons of invisible lines of edges. \~ + \param[out] arVT - \ru Полигоны видимых линий гладких ребер. + \en Polygons of visible lines of smooth edges. \~ + \param[out] arHT - \ru Полигоны невидимых линий гладких ребер. + \en Polygons of invisible lines of smooth edges. \~ + \param[in] sag - \ru Угловая толерантность. + \en An angular tolerance. \~ + \param[in] annotations - \ru Набор аннатационных объектов. + \en A set of annotation objects. \~ + \param[in] place - \ru Проекционная плоскость. + \en A projection plane. \~ + \param[in] into - \ru Матрица перехода в локальную систему координат. + \en A matrix of translation to the local coordinate system. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ + */ + void GetVestiges( PArray & arVL, + PArray & arHL, + PArray & arVT, + PArray & arHT, + double sag, + PArraySort * annotations, + const MbPlacement3D & place, + const MbMatrix3D & into ); + +private: + // \ru заполнить массивы линий и поверхностей \en fill arrays of lines and surfaces + void Fill ( const RPArray & lumps, const MbMatrix3D & into, + double znear, bool perspective, const MbMapVisibilityMode & visMode, + VERSION version, const std::vector * prevCubes ); + // \ru тест видимости пробной точки \en the test of a trial point visibility + int IsShadeAll ( const MbCartPoint3D &, bool section ) const; + // \ru получение очерков и разрезка \en isocline getting and cutting + // \note \ru В многопоточном режиме m_Items выполняется параллельно. \en In multithreaded mode m_Items runs in parallel. \~ + void BodiesCreateFirst(); + // \ru Определение видимости тел. \en Define solids visibility. + // \note \ru В многопоточном режиме m_Items выполняется параллельно. \en In multithreaded mode m_Items runs in parallel. \~ + void BodiesCreateSecondLocal( const PArraySort * annotations ); + // \ru добавление тела \en addition of solid + bool AddBody( MbMapBody * mapBody, size_t & iFnd ); + +OBVIOUS_PRIVATE_COPY( MbMapBodiesPArray ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение участков граничной кривой. + \en The definition of boundary curve regions. \~ + \details \ru Определение участков граничной кривой местного вида, выносного элемента, + местного разреза (или сечения). + \en The definition of regions of a local view boundary curve, a detail view, + a local cutaway (or section). \~ + \param[in] lumps - \ru Проецируемые объекты. + \en Projected objects. \~ + \param[in] contour - \ru Граничная кривая. + \en A boundary curve. \~ + \param[in] cross - \ru Точки пересечения граничной кривой с линиями чертежа. + \en Points of intersection between boundary curve and lines of drawing. \~ + \param[in] baseViewInfo - \ru Информация о базовом виде, на котором построен местный вид\разрез:\n + тип вида:\n + mvt_View - Вид,\n + mvt_Cut - Разрез,\n + mvt_Section - Сечечние;\n + плоскость вида, разреза или сечения.\n + \en The information about basic view on witch a local view\cutaway is constructed:\n + a view type:\n + mvt_View - View,\n + mvt_Cut - Cutaway,\n + mvt_Section - Section;\n + a plane of view, cutaway or section.\n \~ + \param[in] viewInfo - \ru Информация о производном виде:\n + тип вида:\n + mvt_View - Местный вид, Выносной элемент,\n + mvt_Cut - Местный разрез,\n + mvt_Section - Местное сечение;\n + плоскость вида, разреза или сечения.\n + Если тип производного и базового вида != mvt_View, то тип производного вида должен совпадать с видом базового.\n + \en The information about derived view:\n + a view type:\n + mvt_View - A local view, a detail view,\n + mvt_Cut - A local cutaway,\n + mvt_Section - A local section;\n + a plane of view, cutaway or section.\n + If the type of derived and basic view is not equal to the mvt_View then the type of the derived view must coincide with the type of the basic view.\n \~ + \param[out] curves - \ru Результат - набор участков граничной кривой. + \en The result is a set of boundary curve regions. \~ + \warning \ru Для внутреннего использования. + \en For internal use only. \~ +*/ // --- +void LimitCurveSectionsVisibility( const RPArray & lumps, // проецируемые объекты + const MbCurve & contour, + const SArray & cross, + const MbMapViewInfo & baseViewInfo, + const MbMapViewInfo & viewInfo, + RPArray & curves ); // результат + + +#endif // __MAP_IMPLEMENTATION_H diff --git a/C3d/Include/map_lump.h b/C3d/Include/map_lump.h new file mode 100644 index 0000000..c295976 --- /dev/null +++ b/C3d/Include/map_lump.h @@ -0,0 +1,1408 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Объекты для проецирования. + \en Objects for the projection. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_LUMP_H +#define __MAP_LUMP_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Настройки видимости следов проецируемых объектов. + \en Visibility mode of mapping. \~ + \details \ru Настройки видимости следов проецируемых объектов.\n + \en Visibility mode of mapping.\n \~ + \ingroup Mapping +*/ +// --- +struct MbMapVisibilityMode { +protected: + bool invisible; ///< \ru Добавлять проекции невидимых линий и точек. \en Add vestiges of invisible curves and points. + bool skipVertices; ///< \ru Не добавлять проекции вершин тела. \en Skip vestiges of vertices. + bool shadeCurves; ///< \ru Флаг затенения пространственных кривых телами (false по умолчанию). \en Shade spatial curves by bodies(false by default). + bool useBodyTransparency; ///< \ru Учитывать прозрачность тел при проецировании (false по умолчанию). \en Use bodies transparency while mapping(false by default). + bool addCenterLines; ///< \ru Добавлять проекции осевых линий поверхностей. \en Add vestiges of center lines of surfaces. +public: + MbMapVisibilityMode( bool invis, + bool skipVerts, + bool shadeSpaceCurves = false, + bool useTransparency = false, + bool addCentLines = false ) + : invisible ( invis ) + , skipVertices ( skipVerts ) + , shadeCurves ( shadeSpaceCurves ) + , useBodyTransparency ( useTransparency ) + , addCenterLines ( addCentLines ) + {} + MbMapVisibilityMode( const MbMapVisibilityMode & m ) + : invisible ( m.invisible ) + , skipVertices ( m.skipVertices ) + , shadeCurves ( m.shadeCurves ) + , useBodyTransparency ( m.useBodyTransparency ) + , addCenterLines ( m.addCenterLines ) + {} +public: + void Init( bool invis, + bool skipVerts, + bool shadeSpaceCurves = false, + bool useTransparency = false, + bool addCentLines = false ) { + invisible = invis; + skipVertices = skipVerts; + shadeCurves = shadeSpaceCurves; + useBodyTransparency = useTransparency; + addCenterLines = addCentLines; + } + bool AddInvisible() const { return invisible; } + bool SkipVertices() const { return skipVertices; } + bool ShadeSpaceCurves() const { return shadeCurves; } + bool UseBodyTransparency() const { return useBodyTransparency; } + bool AddCenterLines() const { return addCenterLines; } +public: + MbMapVisibilityMode & operator = ( const MbMapVisibilityMode & m ) { + invisible = m.invisible; + skipVertices = m.skipVertices; + shadeCurves = m.shadeCurves; + useBodyTransparency = m.useBodyTransparency; + addCenterLines = m.addCenterLines; + return *this; + } +private: + MbMapVisibilityMode(); // \ru Не реализован. \en Not implemented. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая с типом и погрешностью. + \en The curve with the type and tolerance. \~ + \details \ru Кривая с типом и погрешностью.\n + \en The curve with the type and tolerance.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS CurveWType : public TapeBase { +private: + c3d::ConstSpaceCurveSPtr curve; ///< \ru Кривая. \en A curve. + MbBaseVestige::Type type; ///< \ru Тип. \en A type. + MbBaseVestige::SubType subType; ///< \ru Подтип. \en A subtype. + double tolerance; ///< \ru Толерантность. \en A tolerance. + mutable bool hidden; ///< \ru Флаг невидимости. \en An invisibility flag. + +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en The declaration without implementation of the copy-constructor to prevent a copying by default + CurveWType( const CurveWType & other ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + CurveWType( const CurveWType & other, MbRegDuplicate * iReg ); + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор видимой кривой.\n + \en Constructor of a visible curve.\n \~ + \param[in] _curve - \ru Кривая. + \en A curve. \~ + \param[in] _type - \ru Тип плоского отображения. + \en A type of planar mapping. \~ + \param[in] _subType - \ru Подтип. + \en A subtype. \~ + \param[in] _tolerance - \ru Толерантность. + \en A tolerance. \~ + */ + CurveWType( const MbCurve3D & _curve, MbBaseVestige::Type _type, MbBaseVestige::SubType _subType, double _tolerance ) + : curve ( &_curve ) + , type ( _type ) + , subType ( _subType ) + , tolerance( _tolerance ) + , hidden ( false ) + { + } + + /// \ru Деструктор. \en Destructor. + virtual ~CurveWType() {} + /// \ru Сделать копию объекта. \en Create a copy of the object. + virtual CurveWType & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + + /// \ru Получить кривую. \en Get a curve. + const MbCurve3D & GetCurve() const { return *curve; } + /// \ru Получить тип. \en Get a type. + MbBaseVestige::Type GetType() const { return type; } + /// \ru Получить подтип. \en Get a subtype. + MbBaseVestige::SubType GetSubType() const { return subType; } + /// \ru Получить толерантность. \en Get a tolerance. + double GetTolerance() const { return tolerance; } + /// \ru Является ли невидимой. \en Whether or not invisible. + bool IsHidden() const { return hidden; } + /// \ru Установить состояние невидимости. \en Set the invisibility state. + void SetHidden( bool h ) const { hidden = h; } + +protected: + DECLARE_PERSISTENT_CLASS_NEW_DEL ( CurveWType ) +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en The declaration without implementation of the assignment operator to prevent an assignment by default + void operator = ( const CurveWType & ); +}; + +IMPL_PERSISTENT_OPS( CurveWType ) + +//------------------------------------------------------------------------------ +/** \brief \ru Множество аннотационных кривых. + \en The array of annotative curves. \~ + \details \ru Множество аннотационных кривых.\n + \en The array of annotative curves.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbAnnCurves : public MbRefItem, public TapeBase { +private: + uint component; ///< \ru Компонент, в котором определен набор кривых. \en A component in which a set of curves is defined. + size_t identifier; ///< \ru Идентификатор нити. \en A thread identifier. + c3d::ConstSolidSPtr solid; ///< \ru Тело, на котором нарезана резьба. \en A threaded solid. + MbMatrix3D from; ///< \ru Матрица пересчета в мир. \en A matrix of transformation to the world coordinate system. + TOwnPointer name; ///< \ru Имя набора кривых. \en A name of a set of curves. \~ \internal \ru Всегда есть!!! \en Always exists!!! \~ \endinternal + PArray wtCurves; ///< \ru Набор кривых с типом и погрешностью. \en A set of curves with type and tolerance. + +private: + MbAnnCurves(); // \ru не реализовано \en not implemented + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en The declaration without implementation of the copy-constructor to prevent a copying by default + MbAnnCurves( const MbAnnCurves & other ); +public: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbAnnCurves( const MbAnnCurves & other, MbRegDuplicate * iReg ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор объекта с пустым набором кривых.\n + \en Constructor of an object with an empty set of curves.\n \~ + \param[in] _name - \ru Имя набора кривых. + \en A name of a set of curves. \~ + \param[in] _comp - \ru Компонент, в котором определен набор кривых. + \en A component in which a set of curves is defined. \~ + \param[in] _ident - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] _solid - \ru Тело, в котором нарезана резьба. + \en A threaded solid. \~ + \param[in] _from - \ru Матрица пересчета в мир. + \en A matrix of transformation to the world coordinate system. \~ + */ + explicit MbAnnCurves( const MbName & _name, uint _comp, size_t _ident, const MbSolid * _solid, const MbMatrix3D & _from ) + : component ( _comp ) + , identifier( _ident ) + , solid ( _solid ) + , name ( &_name ) + , from ( _from ) + , wtCurves ( 0, 1, true ) + { + name.SetOwn(false); + } + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор объекта с пустым набором кривых, нулевым телом и единичной матрицей.\n + \en Constructor of an object with the empty set of curves, the null solid and the identity matrix.\n \~ + \param[in] _name - \ru Имя набора кривых. + \en A name of a set of curves. \~ + \param[in] _comp - \ru Компонент, в котором определен набор кривых. + \en A component in which a set of curves is defined. \~ + \param[in] _ident - \ru Идентификатор нити. + \en A thread identifier. \~ + */ + explicit MbAnnCurves( const MbName & _name, uint _comp, size_t _ident ) + : component ( _comp ) + , identifier( _ident ) + , solid ( NULL ) + , name ( &_name ) + , from ( ) + , wtCurves ( 0, 1, true ) + { + name.SetOwn(false); + } + + /// \ru Деструктор. \en Destructor. + virtual ~MbAnnCurves() + { + } + +public: + + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual MbAnnCurves & Duplicate( MbRegDuplicate * iReg = NULL ) const; + + /// \ru Получить имя компонента. \en Get the component name. + uint GetComponent() const { return component; } + /// \ru Получить идентификатор нити. \en Get the thread identifier. + size_t GetIdentifier() const { return identifier; } + /// \ru Получить указатель на тело. \en Get the pointer to the solid. + const MbSolid * GetSolid() const { return solid; } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + const MbMatrix3D & GetMatrixFrom() const { return from; } + /// \ru Получить имя набора кривых. \en Get the name of a set of curves. + const MbName & GetName() const { return *name; } + + /** \brief \ru Забрать кривую к себе. + \en Take the curve. \~ + \details \ru Добавить кривую в набор кривых и обнулить указатель.\n + \en Add a curve to the set of curves and reset the pointer.\n \~ + \param[in, out] wtCurve - \ru Кривая. + \en A curve. \~ + */ + void AbsorbCurve( CurveWType *& wtCurve ) { wtCurves.Add( wtCurve ); wtCurve = NULL; } + + /// \ru Количество кривых в наборе. \en The number of curves in the set. + size_t GetCurvesCount() const { return wtCurves.Count(); } + /// \ru Получить указатель на кривую. \en Get the pointer to the curve. + const CurveWType * GetCurve( size_t k ) const { return ((k < wtCurves.Count()) ? wtCurves[k] : NULL); } + +private: + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MbAnnCurves ) + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en The declaration without implementation of the assignment operator to prevent an assignment by default + void operator = ( const MbAnnCurves & ); +}; + +IMPL_PERSISTENT_OPS( MbAnnCurves ) + +//------------------------------------------------------------------------------ +/** \brief \ru Реализация интерфейса аннотационного вида. + \en The implementation of the annotation view interface. \~ + \details \ru Реализация интерфейса аннотационного вида.\n + \en The implementation of the annotation view interface.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSimbolthThreadView : public MbRefItem, public TapeBase { +protected : + MbAnnCurves m_annCurves; ///< \ru Аннотационные кривы. \en Annotative curves. + uint m_compHash; ///< \ru Имя компонента. \en A component name. + TOwnPointer m_name; ///< \ru Имя. \en A name. \~ \internal \ru Всегда есть. \en Always exists. \~ \endinternal + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] _component - \ru Компонент. + \en A component. \~ + \param[in] threadId - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] _name - \ru Имя. + \en A name. \~ + */ + MbSimbolthThreadView( uint _component, uint threadId, const MbName & _name ); + + /// \ru Деструктор. \en Destructor. + virtual ~MbSimbolthThreadView(); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbSimbolthThreadView( const MbSimbolthThreadView & other, MbRegDuplicate * iReg ); + +public: + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual MbSimbolthThreadView & Duplicate( MbRegDuplicate * iReg = NULL ) const; +public : + + /// \ru Получить аннотационные кривые для редактирования. \en Get annotative curves for editing. + virtual MbAnnCurves & SetAnnCurves (); + /// \ru Получить аннотационные кривые. \en Get annotative curves. + virtual const MbAnnCurves & GetAnnCurves () const; + /// \ru Получить компонент. \en Get the component. + virtual uint GetComponent () const; + /// \ru Получить имя. \en Get the name. + virtual const MbName & GetName () const; + /// \ru Получить номер нитки. \en Get a thread number. + virtual size_t GetShellThreadId() const; + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSimbolthThreadView ) +}; + +IMPL_PERSISTENT_OPS( MbSimbolthThreadView ) + +//------------------------------------------------------------------------------- +/** \brief \ru Сортировать объекты. + \en Sort the objects. \~ + \details \ru Сортировать аннотационные объекты. по имени компонента. \n + \en Sort the annotative objects by the component name. \n \~ + \param[in] pf - \ru Первый объект. + \en The first object. \~ + \param[in] ps - \ru Второй объект. + \en The second object. \~ + \return \ru 0, если имена компонентов равны,\n + -1, если имя первого объекта меньше,\n + 1, если имя первого объекта больше. + \en 0, if the names of components are equal,\n + -1, if the first object name is less than the second,\n + 1, if the first object name is greater than the second. \~ + \ingroup Mapping +*/ +// --- +inline int AnnotationSort( const MbSimbolthThreadView ** pf, const MbSimbolthThreadView ** ps ) +{ + uint vf = (*pf)->GetComponent(); + uint vs = (*ps)->GetComponent(); + return ( (vf == vs) ? 0 : ((vf < vs) ? -1 : 1) ); +} + + +//------------------------------------------------------------------------------- +/** \brief \ru Тип аннотированного объекта. + \en A type of an annotated object. \~ + \details \ru Тип аннотированного объекта.\n + \en The type of annotated object.\n \~ + \ingroup Mapping +*/ +// --- +enum AnnotatedObjectType { + aot_SymbolicThread = 0, ///< \ru Проекционный (полный) вид. \en The projective (full) view. + aot_SymbolicThread_CuttedView, ///< \ru Вид-разрез. \en The cutaway-view. + aot_SymbolicThread_SectionView ///< \ru Вид-сечение. \en The section-view. +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Интерфейс хранилища аннотированных объектов. + \en The interface of annotated objects storage. \~ + \details \ru Интерфейс хранилища аннотированных объектов.\n + \en The interface of annotated objects storage.\n \~ + \ingroup Mapping +*/ +// --- +struct MATH_CLASS ItAnnObjectStore : public MbRefItem { +public: + /** \brief \ru Получить массив резьб. + \en Get the array of threads. \~ + \details \ru Получить массив объектов типа резьба по массиву разрезанных тел.\n + \en Get the array of objects of thread type by array of cut solids. \n \~ + \param[in] bodies - \ru Тип аннотированного объекта. + \en A type of an annotated object. \~ + \param[in] threads - \ru Имя грани, с которой ассоциирован объект. + \en A face name the object is associated with. \~ + */ + virtual bool GetMathThreads( const c3d::ConstLumpsMultiSet & bodies, RPArray & threads, bool draw ) = 0; + /** \brief \ru Получить массив резьб. + \en Get the array of threads. \~ + \details \ru Получить массив объектов типа резьба по массиву разрезанных тел.\n + \en Get the array of objects of thread type by array of cut solids. \n \~ + \param[in] bodies - \ru Тип аннотированного объекта. + \en A type of an annotated object. \~ + \param[in] threads - \ru Имя грани, с которой ассоциирован объект. + \en A face name the object is associated with. \~ + */ + virtual bool GetMathThreads( const c3d::ConstLumpsMultiSet & bodies, std::vector< SPtr > & threads, bool draw ) = 0; +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Интерфейс хранилища условных обозначений. + \en The interface of storage of conventional notations. \~ + \details \ru Интерфейс хранилища условных обозначений.\n + \en The interface of storage of conventional notations.\n \~ + \ingroup Mapping +*/ +// --- +struct MATH_CLASS ItSymbolObjectStore : public MbRefItem +{ + /** \brief \ru Получить массив объектов. + \en Get the array of objects. \~ + \details \ru получить массив условных обозначений.\n + \en get the array of conventional notations.\n \~ + \param[in] place - \ru Видовая система координат. + \en A view coordinate system. \~ + */ + virtual RPArray & GetMbSymbols( const MbPlacement3D & place ) = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество пространственных точек для проецирования. + \en The array of spatial points for projection. \~ + \details \ru Множество пространственных точек для проецирования.\n + \en The array of spatial points for projection.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSpacePoints : public MbRefItem, public TapeBase { +private: + uint component; ///< \ru Компонент в котором определен набор точек. \en A component in which a set of points is defined. + uint16 style; ///< \ru Стиль. \en A style. + + MbMatrix3D from; ///< \ru Матрица пересчета в мир. \en A matrix of transformation to the world coordinate system. + MbName name; ///< \ru Имя набора, если есть. \en A set name, if it exists. + SArray points; ///< \ru Точки. \en Points. + PArray names; ///< \ru Имена точек, не копии. \en Names of points, not copies. + mutable bool hidden; ///< \ru Видимость точек для проецирования. \en Visibility of points for projection. + +private: + MbSpacePoints(); // \ru не реализовано \en not implemented + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbSpacePoints( const MbSpacePoints & other, MbRegDuplicate * iReg ); +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор пустого видимого массива пространственных точек. + \en Constructor of an empty array of visible spatial points. \~ + \param[in] _comp - \ru Компонент в котором определен набор точек. + \en A component in which a set of points is defined. \~ + \param[in] _style - \ru Стиль. + \en A style. \~ + \param[in] _from - \ru Матрица пересчета в мир. + \en A matrix of transformation to the world coordinate system. \~ + \param[in] _name - \ru Имя набора. + \en A set name. \~ + */ + MbSpacePoints( uint _comp, uint16 _style, const MbMatrix3D & _from, const MbName & _name ) + : MbRefItem( ) + , component( _comp ) + , style ( _style ) + , from ( _from ) + , name ( _name ) + , points ( 0, 1 ) + , names ( 0, 1, false ) + , hidden ( false ) + { + } + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор пустого видимого массива пространственных точек + без указания имени. + \en Constructor of an empty array of visible spatial points + without name. \~ + \param[in] _comp - \ru Компонент в котором определен набор точек. + \en A component in which a set of points is defined. \~ + \param[in] _style - \ru Стиль. + \en A style. \~ + \param[in] _from - \ru Матрица пересчета в мир. + \en A matrix of transformation to the world coordinate system. \~ + */ + MbSpacePoints( uint _comp, uint16 _style, const MbMatrix3D & _from ) + : MbRefItem( ) + , component( _comp ) + , style ( _style ) + , from ( _from ) + , name ( ) + , points ( 0, 1 ) + , names ( 0, 1, false ) + , hidden ( false ) + { + } + /// \ru Деструктор. \en Destructor. + virtual ~MbSpacePoints() {} + +public: + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual MbSpacePoints & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Получить имя компонента. \en Get the name of a component. + uint GetComponent() const { return component; } + /// \ru Получить стиль. \en Get the style. + uint16 GetStyle() const { return style; } + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + const MbMatrix3D & GetMatrixFrom() const { return from; } + /// \ru Получить имя. \en Get the name. + const MbName & GetName() const { return name; } + + /// \ru Получить флаг невидимости кривых для проецирования. \en Get the flag of invisibility of curves for projection. + bool IsHidden() const { return hidden; } + /// \ru Установить флаг невидимости кривых для проецирования. \en Set the flag of invisibility of curves for projection. + void SetHidden( bool h ) const { hidden = h; } + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /** \brief \ru Добавить точку с именем. + \en Add a point with a name. \~ + \details \ru Добавить точку с именем.\n + Выдает предупреждение, если у массива имен точек + стоит флаг удаления элементов. + \en Add a point with a name.\n + Generates a warning if the array of names of points + has a flag of elements removing. \~ + \param[in] pnt - \ru Точка. + \en A point. \~ + \param[in] nm - \ru Имя точки. + \en A point name. \~ + */ + void AddNamedPoint( const MbCartPoint3D & pnt, MbName * nm ); + + /** \brief \ru Добавить точки с именами. + \en Add points with names. \~ + \details \ru Добавить точки с именами.\n + Количество точек и имен в массивах должно совпадать. + Иначе выдает предупреждение.\n + Последовательно добавляет точки и имена в объект + с помощью вызова AddNamedPoint. + \en Add points with names.\n + The number of points in the array must be equal to the number of names. + Otherwise generates a warning.\n + Points and names are added to the object sequentially + by calling the AddNamedPoint. \~ + \param[in] pnts - \ru Набор точек. + \en A point set. \~ + \param[in] nms - \ru Набор имен. + \en A set of names. \~ + */ + template + void AddNamedPoints( const Points & pnts, const RPArray & nms ); + + /** \brief \ru Удалить точки с именами. + \en Remove points with names. \~ + \details \ru Удалить точки с именами.\n + Чистит массивы точек и имен. + \en Remove points with names.\n + Clean arrays of points and names. \~ + */ + void RemoveNamedPoints() { points.clear(); names.clear(); } + + /** \brief \ru Освободить лишнюю память. + \en Free the unnecessary memory. \~ + \details \ru Освободить лишнюю память.\n + Освобождает лишнюю память в массивах точек и имен. + \en Free the unnecessary memory.\n + Free the unnecessary memory in arrays of points and names. \~ + */ + void AdjustMemory() { + #ifdef STANDARD_C11 + points.shrink_to_fit(); names.shrink_to_fit(); + #endif + } + + /** \} */ + /**\ru \name Доступ к точкам. + \en \name Access to points. + \{ */ + + /// \ru Количество точек. \en The number of points. + size_t GetPointsCount() const { return points.size(); } + + /** \brief \ru Получить точки. + \en Get points. \~ + \details \ru Получить точки.\n + Добавляет точки в присланный массив. + \en Get points.\n + Add points into a given array. \~ + \param[out] pnts - \ru Множество для добавления точек. + \en An array for adding of points. \~ + */ + void GetPoints( SArray & pnts ) const { pnts += points; } + + /** \brief \ru Получить точку. + \en Get a point. \~ + \details \ru Получить точку по индексу.\n + Если индекс некорректный, то есть не меньше числа точек, + выдается предупреждение. + \en Get a point by an index.\n + If the index is incorrect i.e. it isn't less than the number of points, + a warning is generated. \~ + \param[in] k - \ru Индекс точки. + \en A point index. \~ + \param[out] pnt - \ru Нужная точка. + \en Required point. \~ + \return \ru true в случае, если индекс меньше числа точек в наборе. + \en returns true if the index is less than the number of points in the set. \~ + */ + bool GetPoint( size_t k, MbCartPoint3D & pnt ) const + { + if ( k < points.size() ) { + pnt = points[k]; + return true; + } + C3D_ASSERT_UNCONDITIONAL( false ); + return false; + } + + /** \} */ + /**\ru \name Доступ к именам. + \en \name Access to names. + \{ */ + + /// \ru Количество имен. \en The number of names. + size_t GetNamesCount() const { return names.size(); } + + /** \brief \ru Получить имена. + \en Get the names. \~ + \details \ru Получить имена.\n + Добавляет имена в присланный массив. + \en Get the names.\n + Add the names into a given array. \~ + \param[out] ns - \ru Множество для добавления имен. + \en An array for adding of names. \~ + */ + void GetNames( RPArray & ns ) const { ns.AddArray( names ); } + + /** \brief \ru Получить имя. + \en Get the name. \~ + \details \ru Получить имя по индексу.\n + Если индекс некорректный, то есть не меньше числа точек, + вернет NULL. + \en Get the name by an index.\n + If the index is incorrect i.e. it isn't less than the number of points, + NULL is returned. \~ + \param[in] k - \ru Индекс имени. + \en A name index. \~ + \return \ru Имя по индексу из набора имен. + \en A name by an index from the set of names. \~ + */ + const MbName * GetName( size_t k ) const { return ((k < names.size()) ? names[k] : NULL); } + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL ( MbSpacePoints ) +OBVIOUS_PRIVATE_COPY( MbSpacePoints ) +}; +IMPL_PERSISTENT_OPS( MbSpacePoints ) + +//------------------------------------------------------------------------------ +// \ru добавить точку \en add a point +// --- +inline void MbSpacePoints::AddNamedPoint( const MbCartPoint3D & pnt, MbName * nm ) +{ + points.push_back( pnt ); + names.push_back( nm ); + + if ( names.OwnsElem() ) + { + C3D_ASSERT_UNCONDITIONAL( false ); + names.OwnsElem( false ); + } +} + +//------------------------------------------------------------------------------ +// \ru Добавить точки \en Add points +// --- +template +inline void MbSpacePoints::AddNamedPoints( const Points & pnts, const RPArray & nms ) +{ + size_t cnt = pnts.size(); + C3D_ASSERT( cnt == nms.size() ); + + if ( cnt > 0 && cnt == nms.size() ) { + for ( size_t k = 0; k < cnt; k++ ) + AddNamedPoint( pnts[k], nms[k] ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество пространственных кривых для проецирования. + \en An array of spatial curves for projection. \~ + \details \ru Множество пространственных кривых для проецирования.\n + \en An array of spatial curves for projection.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSpaceCurves : public MbRefItem, public TapeBase { +private: + uint component; ///< \ru Компонент в котором определен набор кривых. \en A component in which a set of curves is defined. + uint16 style; ///< \ru Стиль. \en A style. + MbAttributeContainer attrData; ///< \ru Атрибуты. \en Attributes. \~ \internal \ru По просьбе группы Приложений (Компас) \en Apps (Kompas) at request. \~ \endinternal + + MbMatrix3D from; ///< \ru Матрица пересчета в мир. \en A matrix of transformation to the world coordinate system. + MbName name; ///< \ru Имя набора, если есть. \en A name of set, if it exists. + RPArray curves; ///< \ru Кривые (оригиналы, владеет по счетчику ссылок). \en Curves (originals, owns by the reference counter). + PArray names; ///< \ru Имена кривых, не копии. \en Names of curves, not copies. + mutable bool hidden; ///< \ru Видимость кривых для проецирования. \en The visibility of curves for projection. + +private: + MbSpaceCurves(); // \ru не реализовано \en not implemented +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор пустого видимого массива пространственных кривых. + \en Constructor of empty array of visible spatial curves. \~ + \param[in] _comp - \ru Компонент в котором определен набор точек. + \en A component in which a set of points is defined. \~ + \param[in] _style - \ru Стиль. + \en A style. \~ + \param[in] _from - \ru Матрица пересчета в мир. + \en A matrix of transformation to the world coordinate system. \~ + \param[in] _name - \ru Имя набора. + \en A name of set. \~ + */ + MbSpaceCurves( uint _comp, uint16 _style, const MbMatrix3D & _from, const MbName & _name ) + : MbRefItem( ) + , component( _comp ) + , style ( _style ) + , attrData ( ) + , from ( _from ) + , name ( _name ) + , curves ( 0, 1 ) + , names ( 0, 1, false ) + , hidden ( false ) + {} + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор пустого видимого массива пространственных кривых без указания имени. + \en Constructor of empty array of visible spatial curves without names. \~ + \param[in] _comp - \ru Компонент в котором определен набор точек. + \en A component in which a set of points is defined. \~ + \param[in] _style - \ru Стиль. + \en A style. \~ + \param[in] _from - \ru Матрица пересчета в мир. + \en A matrix of transformation to the world coordinate system. \~ + */ + MbSpaceCurves( uint _comp, uint16 _style, const MbMatrix3D & _from ) + : MbRefItem( ) + , component( _comp ) + , style ( _style ) + , attrData ( ) + , from ( _from ) + , name ( ) + , curves ( 0, 1 ) + , names ( 0, 1, false ) + , hidden ( false ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~MbSpaceCurves() { + RemoveNamedCurves(); + } +private: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbSpaceCurves( const MbSpaceCurves & other, MbRegDuplicate * iReg ); +public: + + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual MbSpaceCurves & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + /// \ru Получить имя компонента. \en Get the name of a component. + uint GetComponent() const { return component; } + /// \ru Получить стиль. \en Get the style. + uint16 GetStyle() const { return style; } + + /// \ru Получить контейнер атрибутов для чтения. \en Get the attribute container for reading. + const MbAttributeContainer & GetAttributes() const { return attrData; } + /// \ru Получить контейнер атрибутов для записи. \en Get the attribute container for writing. + MbAttributeContainer & SetAttributes() { return attrData; } + + /// \ru Получить матрицу преобразования в мир. \en Get the matrix of transformation to the world coordinate system. + const MbMatrix3D & GetMatrixFrom() const { return from; } + /// \ru Получить имя. \en Get the name. + const MbName & GetName() const { return name; } + + /// \ru Получить флаг невидимости кривых для проецирования. \en Get the flag of invisibility of curves for projection. + bool IsHidden() const { return hidden; } + /// \ru Установить флаг невидимости кривых для проецирования. \en Set the flag of invisibility of curves for projection. + void SetHidden( bool h ) const { hidden = h; } + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /** \brief \ru Добавить кривую с именем. + \en Add a curve with a name. \~ + \details \ru Добавить кривую с именем.\n + Добавляет ненулевую кривую в набор кривых. + В случае noSameCheck = false кривая добавится в массив + после проверки на отсутствие в нем. + Выдает предупреждение, если у массива имен точек + стоит флаг удаления элементов. + \en Add a curve with a name.\n + Add a non-zero curve into the set of curves. + If noSameCheck = false a curve is added into the array + after checking of its absence in it. + Generates a warning if the array of names of points + has a flag of elements removing. \~ + \param[in] curve - \ru Кривая. + \en A curve. \~ + \param[in] name - \ru Имя точки. + \en A name of point. \~ + \param[in] noSameCheck - \ru Файл отсутствия проверки наличия кривой в массиве. + \en A flag to disable checking of curve existence in the array. \~ + */ + void AddNamedCurve( MbCurve3D * curve, MbName * name, bool noSameCheck = false ); + + /** \brief \ru Добавить кривые с именами. + \en Add curves with names. \~ + \details \ru Добавить кривые с именами.\n + Количество кривых и имен должно совпадать. + Иначе выдает предупреждение.\n + Последовательно добавляет кривую с именем методом AddNamedCurve. + \en Add curves with names.\n + The count of curves must be equal to the count of names. + Otherwise generates a warning.\n + Adds sequentially a curve with a name by the "AddNamedCurve" method. \~ + \param[in] curves - curves. + \param[in] names - \ru Имя точки. + \en A name of point. \~ + \param[in] noSameCheck - \ru Файл отсутствия проверки наличия кривой в массиве. + \en A flag to disable checking of curve existence in the array. \~ + */ + template + void AddNamedCurves( const Curves & curves, const RPArray & names, bool noSameCheck = false ); + + /** \brief \ru Удалить кривые с именами. + \en Remove curves with names. \~ + \details \ru Удалить кривые с именами.\n + Чистит массивы кривых и имен. + \en Remove curves with names.\n + Cleans arrays of curves and names. \~ + */ + void RemoveNamedCurves(); + + /** \brief \ru Освободить лишнюю память. + \en Free the unnecessary memory. \~ + \details \ru Освободить лишнюю память.\n + Освобождает лишнюю память в массивах с кривыми и именами. + \en Free the unnecessary memory.\n + Frees the unnecessary memory in arrays of points and names. \~ + */ + void AdjustMemory() { + #ifdef STANDARD_C11 + curves.shrink_to_fit(); names.shrink_to_fit(); + #endif + } + + /** \} */ + /**\ru \name Доступ к кривым. + \en \name Access to curves. + \{ */ + + /// \ru Количество кривых. \en The number of curves. + size_t GetCurvesCount() const { return curves.size(); } + + /** \brief \ru Получить кривые. + \en Get the curves. \~ + \details \ru Получить кривые.\n + Добавляет кривые в присланный массив. + \en Get the curves.\n + Adds curves into a given array. \~ + \param[out] crvs - \ru Множество для добавления кривых. + \en An array for curves adding. \~ + */ + void GetCurves( RPArray & crvs ) const { crvs.AddArray( curves ); } + + /** \brief \ru Получить кривую. + \en Get a curve. \~ + \details \ru Получить кривую по индексу.\n + \en Get a curve by an index.\n \~ + \param[in] k - \ru Индекс кривой. + \en A curve index. \~ + \return \ru Указатель на кривую, если индекс меньше количества кривых,\n + иначе NULL. + \en A pointer to a curve, if the index is less than the number of curves,\n + otherwise NULL is returned. \~ + */ + const MbCurve3D * GetCurve( size_t k ) const { return ((k < curves.size()) ? curves[k] : NULL); } + + /** \} */ + /**\ru \name Доступ к именам. + \en \name Access to names. + \{ */ + + /// \ru Количество имен. \en The number of names. + size_t GetNamesCount() const { return names.size(); } + + /** \brief \ru Получить имена. + \en Get the names. \~ + \details \ru Получить имена.\n + Добавляет имена в присланный массив. + \en Get the names.\n + Add the names into a given array. \~ + \param[out] ns - \ru Множество для добавления имен. + \en An array for adding of names. \~ + */ + void GetNames( RPArray & ns ) const { ns.AddArray( names ); } + + /** \brief \ru Получить имя. + \en Get the name. \~ + \details \ru Получить имя по индексу.\n + \en Get the name by an index.\n \~ + \param[in] k - \ru Индекс имени. + \en A name index. \~ + \return \ru Указатель на имя, если индекс меньше количества имен,\n + иначе NULL. + \en A pointer to a name, if the index is less than the number of curves, + otherwise NULL is returned. \~ + */ + const MbName * GetName( size_t k ) const { return ((k < names.size()) ? names[k] : NULL); } ///< \ru Получить имя. \en Get the name. + /** \} */ + + DECLARE_PERSISTENT_CLASS_NEW_DEL ( MbSpaceCurves ) + OBVIOUS_PRIVATE_COPY( MbSpaceCurves ) +}; +IMPL_PERSISTENT_OPS( MbSpaceCurves ) + +//------------------------------------------------------------------------------ +// \ru Добавить кривую \en Add a curve +// --- +inline +void MbSpaceCurves::AddNamedCurve( MbCurve3D * crv, MbName * nm, bool noSameCheck ) +{ + if ( crv != NULL && (noSameCheck || curves.FindIt( crv ) == SYS_MAX_T ) ) { + curves.push_back( crv ); + crv->AddRef(); + names.push_back( nm ); + + if ( names.OwnsElem() ) + { + C3D_ASSERT_UNCONDITIONAL( false ); + names.OwnsElem( false ); + } + } +} + +//------------------------------------------------------------------------------ +// \ru Добавить кривые \en Add curves +// --- +template +void MbSpaceCurves::AddNamedCurves( const Curves & crvs, const RPArray & nms, bool noSameCheck ) +{ + size_t cnt = crvs.size(); + C3D_ASSERT( cnt == nms.size() ); + + if ( cnt > 0 && cnt == nms.size() ) { + for ( size_t k = 0; k < cnt; k++ ) + AddNamedCurve( crvs[k], nms[k], noSameCheck ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Тело с признаком разрезки в производном виде. + \en Solid with a sing cutting in derive view. \~ + \ingroup Mapping +*/ +// -- +struct MATH_CLASS MbCutLump: public MbLump { +public: + /** brief \ru Нужно ли разрезать тело при построении производного вида + (выносного элемента, местного разреза/сечения)? + \en Whether it is necessary to cut solid in a derive view + (a local view, a detail view, the local cutaway/section) or not? + */ + bool willCutOnDeriveView; + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbCutLump() + : MbLump() + , willCutOnDeriveView( true ) + {} + /// \ru Конструктор по данным. \en Constructor by data. + MbCutLump( const MbSolid & _solid, const MbMatrix3D & _from, uint _comp = 0, size_t _ident = SYS_MAX_T ) + : MbLump( _solid, _from, _comp, _ident ) + , willCutOnDeriveView( true ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~MbCutLump() {}; + +public: + /// \ru Тело с признаком резки на базовом виде? \en Solid with cutting type on base view? + virtual bool IsCutLump() const { return true; } + // \ru Разрезать тело в производном виде. \en Cut solid on derive view. + virtual bool WillCutOnDeriveView() const { return willCutOnDeriveView; } + + /** \brief \ru Установить признак разрезки на производном виде. + \en Set type of cutting the solid on derive view. \~ + \details \ru Установить признак разрезки на производном виде.\n + \en Set type of cutting the solid on derive view. \n \~ + \param[in] cut - \ru Разрезать тело. + \en Cut solid. + */ + void SetCuttingTypeOnDeriveView ( bool cut ) { willCutOnDeriveView = cut; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тело или набор тел, определенных в системе координат, с признаком разрезания в сечениях и разрезах. + \en A solid or a set of solids which are defined in a coordinate system with an attribute of cutting in sections and cutaways. \~ + \details \ru Тело или набор тел, определенных в системе координат, с признаком разрезания в сечениях и разрезах.\n + - При построении разрезов:\n + 1) если willCut = true - строится разрез тел;\n + 2) если willCut = false - строится полный вид тел.\n + - При построении сечений:\n + 1) если willCut = true - строится сечение тел;\n + 2) если willCut = false - тела не учитываются в результате построения.\n + \en A solid or a set of solids which are defined in a coordinate system with an attribute of cutting in sections and cutaways.\n + - When constructing the cutaways:\n + 1) if willCut = true the cutaway of solids is built;\n + 2) if willCut = false the full view of solids is built;\n + - When constructing the sections:\n + 1) if willCut = true the cutaway of solids is built;\n + 2) if willCut = false the solids are not considered in the result of the construction.\n \~ + + \internal + \ru + + + + +
willCutразрезстроим вид-разрез (не вид-сечение)
true true разрез (режем, а потом проецируем)
false true полный вид (остальные режем, а это остается целым)
true false сечение (проецируем только сечение)
false false не рисовать вообще (при сечении тело, которое не должно быть разрезано, не проецируется вообще)
+ \en willCutcutawaybuild cutaway-view (no section-view) + true true cutaway (cut and then project) + false true full view (cut the others, but it remains intact) + true false section (project only the section) + false false do not draw at all (a solid which must not be cut, isn't projected at all while cutting) + \~ + \endinternal +\ru Является наследником от объекта MbLump и содержит указатель на контейнер объектов MbLump.\n + Если в объекте одно тело с матрицей, то массив lumps пустой.\n + Если в разрезе или сечении на подсборке стоит флаг "не разрезать", то все тела подсборки входят в один + объект MbMappingLumps с общим флагом разрезки. В этом случае первое тело с матрицей лежит в базовом MbLump, + а остальные в контейнере объектов MbLump. +\en The MbMappingLumps is an inheritor of the MbLump object and contains the pointer to a container of MbLump objects.\n + If the object contains one solid with a matrix the lumps array is empty.\n + If the "do not cut" flag is in cutaway or section on subassembly all solids of subassembly are in the same + MbMappingLumps object with common flag of cutaway. In this case the first solid with a matrix is in the basic MbLump + and the others are in the container of MbLump objects. \~ + \ingroup Mapping +*/ +// \ru Наследование от MbLump нужно в 2D \en The inheritance from the MbLump is needed in 2D. +// -- +struct MATH_CLASS MbMappingLumps : public MbCutLump { + +private: + /// \ru Тела с признаками резки в производном виде. \en Solids with signs of cutting in derive view. + c3d::LumpsSPtrVector * lumps; // \ru может быть нулем \en can be zero. + + /** brief \ru Нужно ли разрезать тело при построении базового вида (разреза, сечения)? + Для всех тел в наборе. + \en Whether it is necessary to cut solid in a base view (cutaway, section) or not? + For all solids. + */ + bool willCut; + +public: + /** \brief \ru Конструктор по данным. + \en Constructor by data. \~ + \details \ru Конструктор по одному телу. + \en Constructor by one solid. \~ + \param[in] _solid - \ru Тело. + \en A solid. \~ + \param[in] _from - \ru Матрица перевода в глобальную систему координат. + \en A matrix of translation to the global coordinate system. \~ + \param[in] _willCut - \ru Признак разрезки тела в базовом виде. + \en The attribute of a solid cutaway in base view. \~ + \param[in] _comp - \ru Компонент. + \en A component. \~ + \param[in] _ident - \ru Идентификатор. + \en An identifier. \~ + */ + MbMappingLumps( const MbSolid & _solid, const MbMatrix3D & _from, bool _willCut, uint _comp = 0, size_t _ident = SYS_MAX_T ) + : MbCutLump ( _solid, _from, _comp, _ident ) + , lumps ( NULL ) + , willCut ( _willCut ) + { + } + + /** \brief \ru Конструктор по данным. + \en Constructor by data. \~ + \details \ru Конструктор по набору тел.\n + Захватывает тело MbSolid из первого элемента _lumps + и остальные элементы _lumps методом AddRef().\n + Если в _lumps один элемент, массив lumps остается NULL.\n + Если в _lumps нет элементов, тело MbSolid в базовом объекте = NULL. Таких объектов быть не должно. + \en Constructor by a set of solids.\n + Captures MbSolid solid from the first element of the _lumps + and the other elements of the _lumps by AddRef() method.\n + If the _lumps contains one element the lumps array remains NULL.\n + If the _lumps doesn't contain any elements the MbSolid solid in the base object = NULL. These objects should not be. \~ + \param[in] _lumps - \ru Контейнер тел с матрицами преобразования в глобальную систему координат,. + не должен быть пустым контейнером. + \en A container of solids with the matrices of transformation to the global coordinate system + should not be an empty container. \~ + */ + template + MbMappingLumps( const LumpsVector & _lumps ) + : MbCutLump() + , lumps( NULL ) + , willCut( false ) // конструктор по нескольким телам только в случае "не рассекать" + { + size_t count = _lumps.size(); + C3D_ASSERT( count > 0 ); + + if ( count > 0 ) { + from = _lumps[0]->GetMatrixFrom(); + component = _lumps[0]->GetComponent(); + identifier = _lumps[0]->GetIdentifier(); + solid = &_lumps[0]->GetSolid(); + + willCutOnDeriveView = _lumps[0]->WillCutOnDeriveView(); + + if ( count > 1 ) { + lumps = new c3d::LumpsSPtrVector(); + for ( size_t i = 1; i < count; ++i ) { + MbLump * lump = _lumps[i]; + lumps->push_back( c3d::LumpSPtr( lump ) ); + } + } + } + } + + /// \ru Деструктор. \en Destructor. + virtual ~MbMappingLumps(); + + /** \brief \ru Число тел. + \en The number of solids. \~ + \details \ru Число тел.\n + Минимальное количество - 1 тело. В этом случае массив lumps = NULL. + В случае, если массив lumps != NULL, количество тел равно количеству + элементов в массиве плюс один. + \en The number of solids.\n + Minimal number = 1 solid. In this case the lumps array is NULL. + In a case when the lumps array isn't NULL the number of solids is equal to + the number of elements in the array plus one. \~ + \return \ru Число тел. + \en The number of solids. \~ + */ + size_t Count() const { + size_t res = 1; + if ( lumps != NULL ) + res += lumps->size(); + return res; + } + + /** \brief \ru Тело по индексу. + \en A solid by an index. \~ + \details \ru Тело по индексу.\n + По индексу 0 выдается базовый объект.\n + По индексу i выдается объект из массива lumps с индексом i-1.\n + Индекс проверяется на корректность. + В случае некорректного индекса возвращает NULL. + \en A solid by an index.\n + The basic object is given by the "0" index.\n + An object with the index i - 1 from the lumps array is issued by the index i.\n + An index is validated for correctness. + In a case of an incorrect index the method returns NULL. \~ + \return \ru Указатель на тело с матрицей. + \en A pointer to a solid with a matrix. \~ + */ + MbLump * operator []( size_t ind ) { + if ( ind == 0 ) + return static_cast( this ); + else if ( lumps != NULL && ind - 1 < lumps->size() ) + return lumps->operator []( ind - 1 ); + return NULL; + } + + /** \brief \ru Тело по индексу. + \en A solid by an index. \~ + \details \ru Тело по индексу.\n + По индексу 0 выдается базовый объект.\n + По индексу i выдается объект из массива lumps с индексом i-1.\n + Индекс проверяется на корректность. + В случае некорректного индекса возвращает NULL. + \en A solid by an index.\n + The basic object is given by the "0" index.\n + An object with the index i - 1 from the lumps array is issued by the index i.\n + An index is validated for correctness. + In a case of an incorrect index the method returns NULL. \~ + \return \ru Константный указатель на тело с матрицей. + \en A constant pointer to a solid with a matrix. \~ + */ + const MbLump * operator []( size_t ind ) const + { + if ( ind == 0 ) + return static_cast( this ); + else if ( lumps != NULL && ind - 1 < lumps->size() ) + return lumps->operator []( ind - 1 ); + return NULL; + } + + void ChangeLump( size_t ind, MbLump * newLump ) + { + if ( ind == 0 ) { + solid = &newLump->GetSolid(); + from = newLump->GetMatrixFrom(); + component = newLump->GetComponent(); + identifier = newLump->GetIdentifier(); + } + else if ( lumps != NULL && ind - 1 < lumps->size() ) { + (*lumps)[ind - 1] = newLump; + } + } + + /** \brief \ru Базовый ли объект. + \en Whether it is the basic object or not. \~ + \details \ru Базовый ли объект.\n + Возвращает false. Возвращает true у объекта MbLump. + \en Whether it is the basic object or not.\n + Returns false. Returns true at the MbLump object. \~ + \return false + */ + virtual bool IsBaseLump() const { return false; } + + // \ru Тело с признаком резки? \en Solid with cutting type? + virtual bool IsMappingLump() const { return true; } + + /** \brief \ru Установить признак разрезки. + \en Set type of cutting the solid. \~ + \details \ru Установить признак разрезки.\n + \en Set type of cutting the solid. \n \~ + \param[in] baseView - \ru Базовый вид или производный. + \en Base or derive view. \~ + \param[in] cut - \ru Разрезать тело. + \en Cut solid. + */ + void SetCuttingType( bool cut ) { willCut = cut; } + + /** \brief \ru Признак разрезки. + \en Type of cutting the solid. \~ + \details \ru Признак разрезки.\n + \en Type of cutting the solid. \n \~ + */ + bool WillCut() const { return willCut; } + +OBVIOUS_PRIVATE_COPY( MbMappingLumps ) // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without implementation of the copy-constructor and assignment operator to prevent an assignment by default. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить значение флагов рассеченности. + \en Set cutting flags. \~ + \details \ru Установить значение флагов рассеченности.\n + \en Set cutting flags.\n \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC(void) SetCuttingFlags( RPArray & lumps, + const SArray * baseNotSected, + const SArray * deriveNotSected ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Полигон с телом. + \en A polygon with a solid. \~ + \details \ru Полигон с телом.\n + \en A polygon with a solid.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbPolygon3DSolid { +private: + uint component; ///< \ru Имя компонента, в котором определено тело. \en A name of a component in which a solid is defined. + MbPolygon3D * polygon; ///< \ru Полигон. \en A polygon. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по имени компонента и полигону.\n + \en Constructor by a component name and a polygon.\n \~ + \param[in] _comp - \ru Имя компонента. + \en A component name. \~ + \param[in] _polyg - \ru Полигон. + \en A polygon. \~ + \return false + */ + MbPolygon3DSolid( uint _comp, MbPolygon3D &_polyg ) + : component( _comp ) + , polygon ( &_polyg ) + { + } + /// \ru Деструктор. \en Destructor. + ~MbPolygon3DSolid() { + if ( polygon != NULL ) + delete polygon; + } + + /// \ru Получить полигон. \en Get the polygon. + MbPolygon3D * GetPolygon () const { return polygon; } + /// \ru Получить имя компонента. \en Get the name of a component. + uint GetComponent() const { return component; } + /// \ru Занулить полигон без удаления. \en Reset polygon without removal. + void DoNotDeletePolyg() { polygon = NULL; } + +OBVIOUS_PRIVATE_COPY( MbPolygon3DSolid ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип ассоциативного вида. + \en A type of an associative view. \~ + \details \ru Тип ассоциативного вида. \n + \en A type of an associative view. \n \~ + \ingroup Mapping +*/ +// --- +enum MbeMapViewType { + mvt_View, ///< \ru Вид. \en A view. + mvt_Cut, ///< \ru Разрез. \en A cutaway. + mvt_Section ///< \ru Сечение. \en A section. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Информация о виде. + \en The information about a view. \~ + \details \ru Информация об ассоциативном виде. Применяется для передачи + информации о виде при построении местного вида\разреза или + выносного элемента. + \en The information about an associative view. Used for transfer + The information about a view in constructing the local view\cutaway or + detail view. \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbMapViewInfo { +private: + MbeMapViewType viewType; + MbPlacement3D viewPlace; ///< \ru Плоскость разреза для viewType = mvt_Cut, viewType = mvt_Section \en A cutaway plane for viewType = mvt_Cut, viewType = mvt_Section + SPtr secContour; ///< \ru Для сложного разреза. \en For a complex section. + +public: + /// \ru Конструктор. \en Constructor. + MbMapViewInfo( MbeMapViewType type, const MbPlacement3D & place ) + : viewType ( type ) + , viewPlace ( place ) + , secContour() + {} + + /// \ru Конструктор. \en Constructor. + explicit MbMapViewInfo( MbeMapViewType type ) + : viewType ( type ) + , viewPlace () + , secContour() + {} + + ~MbMapViewInfo() + {} + + /// \ru Тип ассоциативного вида. \en A type of an associative view. + MbeMapViewType GetViewType() const { return viewType; } + + /// \ru Плоскость вида, разреза или сечения. \en The plane of a view, a cutaway or a section. + const MbPlacement3D & GetPlacement() const { return viewPlace; } + /// \ru Плоскость вида, разреза или сечения. \en The plane of a view, a cutaway or a section. + void SetPlacement( const MbPlacement3D & newPlace ) { viewPlace = newPlace; } + + /// \ru Выдать секущий контур. \en Get section contour. + const MbContourOnPlane * GetSectionContour() const { return secContour; } + /// \ru Установить секущий контур. \en Set section contour. + bool SetSectionContour( const MbContour & contour, const MbPlacement3D & place ); + +OBVIOUS_PRIVATE_COPY( MbMapViewInfo ) +}; + + +#endif // __MAP_LUMP_H diff --git a/C3d/Include/map_section.h b/C3d/Include/map_section.h new file mode 100644 index 0000000..d3878f0 --- /dev/null +++ b/C3d/Include/map_section.h @@ -0,0 +1,372 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль проецирования. Структуры данных, отображающие вид сечения множества тел. + \en The projection module. Data structures which map a view of section of a solids set. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_SECTION_H +#define __MAP_SECTION_H + + +#include +#include +#include +#include +#include +#include + + +struct MbVEFVestiges; + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество контуров, принадлежащих некоторому компоненту. + \en An array of contours belonging to the certain component. \~ + \details \ru Множество контуров, принадлежащих некоторому компоненту. \n + \en An array of contours belonging to the certain component. \n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbCompContourArray { +public: + uint compHash; ///< \ru Компонент. \en A component. + void * lump; ///< \ru Указатель на тело с матрицей. \en A pointer to a solid with a matrix. + PArray * arContours; ///< \ru Множество контуров. \en An array of contours. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по компоненту и телу.\n + \en Constructor by a component and a solid.\n \~ + \param[in] comp_ - \ru Компонент. + \en A component. \~ + \param[in] lump_ - \ru Указатель на тело с матрицей MbLump. + \en A pointer to a solid with the MbLump matrix. \~ + */ + MbCompContourArray( uint comp_, void * lump_ ); + + /// \ru Деструктор. \en Destructor. + ~MbCompContourArray(); + +public: + + /** \brief \ru Добавить контур. + \en Add a contour. \~ + \details \ru Добавить контур в массив контуров, если массив не нулевой.\n + \en Add a contour to the array of contours, if the array isn't null.\n \~ + \param[in] contour - \ru Контур. + \en A countour. \~ + */ + void Add( MbContour * contour ); + + /** \brief \ru Выдать массив контуров. + \en Get the array of contours. \~ + \details \ru Выдать массив контуров, хранящихся в объекте, + и обнулить поле объекта с массивом. + \en Get the array of contours which are stored in the object + and reset the field with the array of the object. \~ + */ + PArray * CreateContoursArray(); + + /** \brief \ru Выдать массив контуров. + \en Get the array of contours. \~ + \details \ru Добавить контуры в присланный массив. + \en Add contours to a given array. \~ + \param[out] arCont - \ru Множество для добавления контуров. + \en An array for contours adding. \~ + */ + void GetContoursArray( PArray & arCont ); + + /** \brief \ru Удалить контуры. + \en Remove contours. \~ + \details \ru Очистить массив с конутрами, если он не нулевой. + \en Clear the array of contours if it isn't null. \~ + */ + void DetachContours() { + if ( arContours != NULL ) + arContours->Flush( noDelete ); + } + +private: + MbCompContourArray( const MbCompContourArray & ); // \ru не реализовано \en not implemented + void operator = ( const MbCompContourArray & ); // \ru не реализовано \en not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для построения сечений и разрезов набора оболочек. + \en A data for constructing a set of sections and cutaways of shells. \~ + \details \ru Данные для построения сечений и разрезов набора оболочек.\n + \en A data for constructing a set of sections and cutaways of shells.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSectionMap { + +protected: + MbVEFVestiges & secMap; ///< \ru Отображение. Набор следов. \en Mapping. A set of vestiges. + PArray secBounds; ///< \ru Неупорядоченный набор секущих контуров. \en Disordered set of cutting contours. + ptrdiff_t secIndex; ///< \ru Текущий индекс. \en A current index. + MbResultType secMessage; ///< \ru Результат построения. \en A result of the construction. + RPArray secShells; ///< \ru Отображаемые оболочки (усеченные). Заполнить в конце построения. \en Mapped shells (trimmed). Fill in the end of construction. + +protected: + ItAnnObjectStore * annObjStore; ///< \ru Хранилище аннотационных объектов. \en A storage of annotation objects. + RPArray * symbolObjects; ///< \ru Условные обозначения. \en Conventional notations. + ItSymbolObjectStore * symbolObjStore; ///< \ru Хранилище условных обозначений. \en A set of conventional notations. + + RPArray * pointsData; ///< \ru Пространственные точки. \en Spatial points. + RPArray * curvesData; ///< \ru Пространственные кривые. \en Spatial curves. + +public: + /// \ru Конструктор пустого объекта. \en Constructor of an empty object. + MbSectionMap(); + /// \ru Деструктор. \en Destructor. + ~MbSectionMap(); + +public: + + /** \brief \ru Зарезирвировать место под оболочки. + \en Reserve a place for shells. \~ + \details \ru Зарезирвировать место под отображаемые оболочки. + \en Reserve a place for mapping shells. \~ + \param[in] count - \ru Количество мест для резервирования. + \en A number of places for reservation. \~ + */ + void ReserveShell( size_t count ); + + /** \brief \ru Добавить оболочку. + \en Add a shell. \~ + \details \ru Добавить оболочку в набор оболочек.\n + Добавляется, даже если равна NULL.\n + Если не нулевая - захватывается. + \en Add a shell into the set of shells.\n + A shell is added even if it is equal to NULL.\n + If a shell isn't null it is captured. \~ + \param[in] secShell - \ru Оболочка. + \en A shell. \~ + */ + void AddShell( MbFaceShell * secShell ) { ::AddRefItem( secShell ); secShells.push_back( secShell ); } + + /** \brief \ru Объект пустой. + \en Whether the object is empty. \~ + \details \ru Объект пустой.\n + \en Whether the object is empty.\n \~ + \return \ru true, если в объекте нет + ни оболочек, ни контуров, ни следов отображения. + \en returns true if the object doesn't contain + shells, contours and mapping vestiges. \~ + */ + bool IsEmpty() const; + + /** \brief \ru Установить индекс. + \en Set an index. \~ + \details \ru Установить индекс.\n + \en Set an index.\n \~ + \param[in] i - \ru Новое значение индекса. + \en New index value. \~ + */ + void SetIndex( ptrdiff_t i ) { secIndex = i; } + + /** \brief \ru Дать массив контуров. + \en Get the array of contours. \~ + \details \ru Добавить в присланный массив контуры всех наборов. + \en Add contours of all sets into a given array. \~ + \param[out] arCont - \ru Набор контуров. + \en A set of contours. \~ + */ + void GetContoursArray( PArray & arCont ) const; + + /// \ru Дать текущий индекс. \en Get the current index. + ptrdiff_t GetIndex() const { return secIndex; } + + /** \brief \ru Отображение. + \en Mapping. \~ + \details \ru Дать набор следов. + \en Get the set of vestiges. \~ + \return \ru Набор массивов следов. + \en A set of arrays of vestiges. \~ + */ + MbVEFVestiges & GetSectionMap() { return secMap; } + + /// \ru Неупорядоченный набор контуров. \en Disordered set of contours. + PArray & GetSectionBounds() { return secBounds; } + + /** \brief \ru Очистить содержание вида сечения. + \en Clean a section view. \~ + \details \ru Очистить массивы следов, наборы контуров, + отпустить оболочки и очистить массив оболочек. + \en Clean arrays of vestiges and sets of contours, + release shells and clean the array of shells. \~ + */ + void SetEmpty (); + + /** \brief \ru Установить код результата. + \en Set a result code. \~ + \details \ru Установить код результата построения. + \en Set a result code of the construction. \~ + \param[in] type - \ru Код результата операции. + \en Operation result code. \~ + */ + void SetMessage( MbResultType & type ) { secMessage = type; } + + /** \brief \ru Дать код результата. + \en Get the result code. \~ + \details \ru Дать код результата построения. + \en Get the result code of the construction. \~ + \return \ru Код результата операции. + \en Operation result code. \~ + */ + MbResultType GetMessage() const { return secMessage;} + + /** \brief \ru Преобразовать. + \en Transform. \~ + \details \ru Преобразовать объект по марице. + \en Transform the object by a matrix. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + */ + void Transform( const MbMatrix & matr ); + + /** \brief \ru Отцепить массив оболочек. + \en Detach the array of shells. \~ + \details \ru Отцепить массив оболочек и переложить их в присланный массив. + \en Detach the array of shells and put them into a given array. \~ + \param[out] shells - \ru Множество для оболочек. + \en An array for shells. \~ + */ + template + void DetachShellArray( Shells & shells ) + { + shells.reserve( shells.size() + secShells.size() ); + for ( size_t i = 0, count = secShells.size(); i < count; ++i ) { + MbFaceShell * shell = secShells[i]; + ::DecRefItem( shell ); + shells.push_back( shell ); + } + secShells.clear(); + } + + /// \ru Дать массив оболочек. \en Get the array of shells. + const RPArray & GetShellArray() const { return secShells; } + + /** \brief \ru Установить хранилище. + \en Set a storage. \~ + \details \ru Установить хранилище аннатационных объектов.\n + Отцепить старое хранилище, захватить новое. + \en Set a storage of annotation objects.\n + Detach the old storage and catch a new one. \~ + \param[out] objStore - \ru Новое хранилище аннатационных объектов. + \en A new storage of annotation objects. \~ + */ + void SetAnnObjectStore( ItAnnObjectStore * objStore ); + + /// \ru Получить хранилище аннатационных объектов. \en Get the storage of annotation objects. + ItAnnObjectStore * GetAnnObjectStore() const { return annObjStore; } + + /** \brief \ru Получить условные обозначения. + \en Get conventional notations. \~ + \details \ru Получить массив условных обозначений.\n + \en Get the array of conventional notations.\n \~ + \return \ru Условные обозначения. + \en Conventional notations. \~ + */ + RPArray * GetSymbolObjects () const { return symbolObjects; }; + + /** \brief \ru Добавить условные обозначения. + \en Add conventional notations. \~ + \details \ru Добавить информацию об условных обозначениях.\n + Добавить в массив условных обозначений присланные условные обозначения. + \en Add the information about conventional notations.\n + Add the given conventional notations into the array of conventional notations. \~ + \param[in] arInit - \ru Условные обозначения. + \en Conventional notations. \~ + */ + void SetSymbolObjects ( RPArray & arInit ); + + /// \ru Получить хранилище условных обозначений. \en Get the storage of conventional notations. + ItSymbolObjectStore * GetSymbolObjectStore() const { return symbolObjStore; } + + /** \brief \ru Установить хранилище. + \en Set a storage. \~ + \details \ru Установить хранилище условных обозначений.\n + Отцепить старое хранилище, захватить новое. + \en Set a storage of conventional notations.\n + Detach the old storage and catch a new one. \~ + \param[out] objStore - \ru Новое хранилище условных обозначений. + \en A new storage of conventional notations. \~ + */ + void SetSymbolObjectStore( ItSymbolObjectStore * objStore ); + + /** \brief \ru Добавить пространственные точки. + \en Add spatial points. \~ + \details \ru Добавить пространственные точки.\n + Добавить в массив точек новые точки. + \en Add spatial points.\n + Add new points into the array of points. \~ + \param[in] points - \ru Точки. + \en Points. \~ + */ + void SetSpacePoints( RPArray & points ); + + /** \brief \ru Добавить пространственные кривые. + \en Add spatial curves. \~ + \details \ru Добавить пространственные кривые.\n + Добавить в массив кривых новые кривые. + \en Add spatial curves.\n + Add new curves into the array of curves. \~ + \param[in] curves - \ru Кривые. + \en Curves. \~ + */ + void SetSpaceCurves( RPArray & curves ); + + /** \brief \ru Есть ли в объекте точки. + \en Whether any point is in the object. \~ + \details \ru Есть ли в объекте пространственные точки.\n + \en Whether any spatial point is in the object.\n \~ + \return \ru true, если массив точек не нулевой и не пустой. + \en returns true if the array of points isn't null and isn't empty. \~ + */ + bool IsSpacePoints() const { return (pointsData != NULL && pointsData->size() > 0); } + + /** \brief \ru Есть ли в объекте кривые. + \en Whether any curve is in an object. \~ + \details \ru Есть ли в объекте пространственные кривые.\n + \en Whether any spatial curve is in an object.\n \~ + \return \ru true, если массив кривых не нулевой и не пустой. + \en returns true if the array of curves isn't null and isn't empty. \~ + */ + bool IsSpaceCurves() const { return (curvesData != NULL && curvesData->size() > 0); } + + const RPArray * GetSpacePoints() const { return pointsData; } ///< \ru Получить указатель на пространственные точки. \en Get spatial points. + const RPArray * GetSpaceCurves() const { return curvesData; } ///< \ru Получить указатель на пространственные кривые. \en Get spatial curves. + +OBVIOUS_PRIVATE_COPY( MbSectionMap ) +}; + +//------------------------------------------------------------------------------ +// \ru установить хранилище \en set a storage +// --- +inline void MbSectionMap::SetAnnObjectStore( ItAnnObjectStore * _annObjStore ) +{ + ::AddRefItem( _annObjStore ); + ::ReleaseItem( annObjStore ); + annObjStore = _annObjStore; +} + +//----------------------------------------------------------------------------- +// +//--- +inline void MbSectionMap::SetSymbolObjectStore( ItSymbolObjectStore * _symbolObjStore ) +{ + ::AddRefItem( _symbolObjStore ); + ::ReleaseItem( symbolObjStore ); + symbolObjStore = _symbolObjStore; +} + + +#endif // __MAP_SECTION_H diff --git a/C3d/Include/map_section_complex.h b/C3d/Include/map_section_complex.h new file mode 100644 index 0000000..ae0e54b --- /dev/null +++ b/C3d/Include/map_section_complex.h @@ -0,0 +1,256 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Инструмент для итерационного построения видов многосегментного сечения. + \en The tool for the iterative construction of multi-segment section. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_SECTION_COMPLEX_H +#define __MAP_SECTION_COMPLEX_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbContour; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSectionMap; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс итератора видов сечений. + \en The interface of iterator of section views. \~ + \details \ru Интерфейс итератора видов сечений.\n + \en The interface of iterator of section views.\n \~ + \ingroup Mapping +*/ +// --- +struct MATH_CLASS MbSectionMapIteratorAbs { + + /// \ru Удалить. \en Remove. + virtual void Release() = 0; + /// \ru Сбросить итератор в начало. \en Set the iterator to the begining. + virtual void Reset() = 0; + /// \ru Есть ли еще итерации. \en Whether there are any iteration. + virtual bool More() const = 0; + + /** \brief \ru Следующее сечение. + \en The next section. \~ + \details \ru Следующее сечение.\n + \en The next section.\n \~ + \return \ru Всегда не нулевой указатель. + \en Always non-null pointer. \~ + */ + virtual MbSectionMap * Next() = 0; + + /// \ru Результат последнего действия (итерации). \en The last iteration result. + virtual MbResultType GetLastResult() const = 0; + + /// \ru Установить интерфейс хранилища аннатационных объектов. \en Set the interface of the annotation objects storage. + virtual void SetAnnObjectStore ( ItAnnObjectStore * ) = 0; + /// \ru Установить условные обозначения. \en Set conventional notations. + virtual void SetSymbolObjects ( RPArray & ) = 0; + /// \ru Установить интерфейс хранилища условных обозначений. \en Set the interface of the conventional notations storage. + virtual void SetSymbolObjectStore( ItSymbolObjectStore * ) = 0; + + /// \ru Установить пространственные точки. \en Set spatial points. + virtual void SetSpacePoints( RPArray & ) = 0; + /// \ru Установить пространственные кривые. \en Set spatial curves. + virtual void SetSpaceCurves( RPArray & ) = 0; + +}; // MbSectionMapIteratorAbs + + +//------------------------------------------------------------------------------ +/** \brief \ru Итератор видов сечений тела. + \en The iterator of section views of solid. \~ + \details \ru Итератор видов сечений тела. Реализационный. \n + Замечания по итератору:\n + - контур разреза\сечения не должен быть самопересекающимся;\n + - контур разреза\сечения состоит только из отрезков;\n + - виды, сечений, порождаемых итератором видов не зависят друг от друга,\n + но влияют на построение линий разрыва между соседними видами. + \en The iterator of section views of solid. Implementational. \n + Remarks on iterator:\n + - a contour of cutaway\section must not be self-intersecting;\n + - a contour of cutaway\section consists only of segments;\n + - section views generated by iterator of views don't depend on each other\n + but affect on the construction of discontinuity lines between neighboring views. \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSectionMapIterator { + +public: + + /** \brief \ru Итератор по множеству моделей тел. + \en The iterator by a set of solids models. \~ + \details \ru Итератор по множеству моделей тел.\n + \en The iterator by a set of solids models.\n \~ + \param[in] lumps - \ru Набор тел с матрицами и признаками рассечения. + \en A set of solids with matrices and dissections attributes. \~ + \param[in] place - \ru Плоскость секущего вида. + \en A plane of secant view. \~ + \param[in] isViewCut - \ru Признак вида-разреза (а не сечения). + \en An attribute of a cutaway-view (not section). \~ + \param[in] isDismantel - \ru Разнесенный вид сборки. + \en Dismantled view of the assembly. \~ + \param[in] ncontour - \ru Контур разреза\сечения. + \en A cutaway\section contour. \~ + \param[in] ncontourNames - \ru Именователь контура. + \en A name-maker of contour. \~ + \param[in] part - \ru Сторона отсечения. Имеет значение знак числа. + \en A cut-off side. It have a value of the number sign. \~ + \param[in] visMode - \ru Настройки видимости следов проецируемых объектов. + \en Visibility mode of mapping. \~ + \param[in] obj_version - \ru Математическая версия. + \en Mathematical version. \~ + \return \ru Итератор видов сечений. + \en The iterator of section views. \~ + */ + static MbSectionMapIteratorAbs & Create ( RPArray & lumps, + const MbPlacement3D & place, + bool isViewCut, + bool isDismantel, + const MbContour & ncontour, + const MbSNameMaker & ncontourNames, + ptrdiff_t part, + const MbMapVisibilityMode & visMode, + VERSION obj_version ); // _BUG_18777_DEF_ + + /** \brief \ru Валидность контура. + \en The validity of the contour. \~ + \details \ru Валидность контура для построения сечений.\n + Контур валидный, если он:\n + - не имеет самопересечений,\n + - состоит из отрезков,\n + - если каждый отрезок имеет габарит с длиной и шириной, превышающими погрешность. + \en The validity of the contour for the construction of sections.\n + The contour is valid if it:\n + - has no self-intersections,\n + - consists of segments,\n + - if an each segment has a bounding box with the length and width which are greater than the tolerance. \~ + \return \ru Код разельтата. + \en A result code. \~ + */ + static MbResultType ContourValidityCheck( const MbContour & contour ); + + /** \brief \ru Распознать ортоперпендекулярное сечение. + \en Recognize an ortho-perpendicular section. \~ + \details \ru Распознать ортоперпендекулярное сечение.\n + При этом контур должен удовлетворять условиям:\n + - быть валидным для построения сечения,\n + - состоять более чем из двух сегментов,\n + - первый и последний сегменты должны быть параллельны и сонаправлены,\n + - каждый сегмент контура должен быть или перпендикулярен предыдущему сегменту, + или параллелен и сонаправлен с предыдущим сегментом,\n + - должна присутствовать хотя бы одна пара взаимноперпендикулярных соседних сегментов. + \en Recognize an ortho-perpendicular section.\n + The contour must satisfy conditions:\n + - to be valid for the section construction,\n + - to consist of more than two segments,\n + - the first and the second segments must be parallel and co-directed,\n + - an each contour segment must be perpendicular to the previous segment, + or parallel and co-directed to the previous segment,\n + - must have at least one pair of mutually perpendicular adjacent segments. \~ + \return \ru Признак ортоперпендикулярного сечения. + \en An attribute of ortho-perpendicular section. \~ + */ + static bool IsOrthonormalSectionContour( const MbContour & contour ); +}; // MbSectionMapIterator + + +//------------------------------------------------------------------------------ +/** \brief \ru Итератор местных видов сечений тела. + \en The iterator of local views of sections of solid. \~ + \details \ru Итератор местных видов сечений тела.\n + \en The iterator of local views of sections of solid.\n \~ + \ingroup Mapping + */ +// --- +class MATH_CLASS MbLocalSectionMapIterator { + +public: + /** \brief \ru Итератор по множеству моделей тел. + \en The iterator by a set of solids models. \~ + \details \ru Итератор по множеству моделей тел.\n + \en The iterator by a set of solids models.\n \~ + \param[in] lumps - \ru Набор тел с матрицами и признаками рассечения. + \en A set of solids with matrices and dissections attributes. \~ + \param[in] place - \ru Плоскость секущего вида. + \en A plane of secant view. \~ + \param[in] isViewCut - \ru Признак вида-разреза (а не сечения). + \en An attribute of a cutaway-view (not section). \~ + \param[in] contour - \ru Контур разреза\сечения. + \en A cutaway\section contour. \~ + \param[in] contourNames - \ru Именователь контура. + \en A name-maker of contour. \~ + \param[in] invisible - \ru Строить невидимые линии. + \en Build invisible lines. \~ + \return \ru Итератор местных видов сечений. + \en The iterator of local views of sections. \~ + */ + static MbSectionMapIteratorAbs & Create ( RPArray & lumps, + const MbPlacement3D & place, + bool isViewCut, + bool isDismantel, + const MbContour & contour, + const MbSNameMaker & contourNames, + const MbMapVisibilityMode & visMode ); +}; // MbLocalSectionMapIterator + + +//------------------------------------------------------------------------------ +/** \brief \ru Построение плоскости простого сечения/разреза. + \en Construction of a plane of simple section/cutaway. \~ + \details \ru Построение плоскости сечения/разреза, если линия разреза состоит из одного сегмента. + \en Construction of a plane of section/cutaway if a cutaway line consists of one segment. \~ + \param[in] m_place - \ru Плоскость линии разреза. + \en A plane of cutaway line. \~ + \param[in] m_segment - \ru Сегмент линии разреза. + \en A segment of a cutaway line. \~ + \param[in] m_left - \ru Направление взгляда. + \en Direction of view.\~ + \param[out] secPlace - \ru Плоскость сечения. + \en A plane of a section. \~ +*/ +//--- +MATH_FUNC(bool) FormFirstSectionPlane( const MbPlacement3D & m_place, const MbCurve & m_segment, bool m_left, + MbPlacement3D & secPlace ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Преобразование плоскости вида к плоскости отображения проекции. + \en The view plane convert to the plane of the projection. \~ + \details \ru Преобразование плоскости вида к плоскости отображения проекции. + Нормаль плоскости вида направлена против вектора взгляда. + \en The view plane convert to the plane of the projection. + Normal to the view plane is directed against the view vector. \~ + \param[in\out] place - \ru Плоскость вида\Плоскость отображения проекции. + \en A view plane\A plane of the projection. \~ + \param[in] viewDir - \ru Вектор взгляда. + \en A view vector. \~ +*/ +// --- +inline void MappingVPtoMP( MbPlacement3D & place, const MbVector & viewDir ) +{ + if ( ::fabs(viewDir.x) > Math::lengthEpsilon || ::fabs(viewDir.y) > Math::lengthEpsilon ) { + MbVector vDir( viewDir ); + vDir.Normalize(); + vDir.Perpendicular(); + MbVector3D rotateV; + place.VectorOn( vDir, rotateV ); + MbAxis3D rotateAxis ( place.GetOrigin(), rotateV ); + place.Rotate( rotateAxis, -M_PI_2 ); + } +} + + +#endif // __MAP_SECTION_COMPLEX_H diff --git a/C3d/Include/map_thread.h b/C3d/Include/map_thread.h new file mode 100644 index 0000000..e2ada68 --- /dev/null +++ b/C3d/Include/map_thread.h @@ -0,0 +1,178 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение отображения резьбы. + \en The thread mapping definition. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_THREAD_H +#define __MAP_THREAD_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Структура для строителя отображения резьбы. + \en A structure for the thread mapping creator. \~ + \details \ru Структура для строителя отображения резьбы. + \en A structure for the thread mapping creator. \~ + \ingroup Mapping +*/ +// --- +struct ThreadMapperStruct { +public: + const MbThread & thread; ///< \ru Резьба в мировой системе координат. \en A thread in the world coordinate system. + const MbSolid & solid; ///< \ru Тело для резьбы (в системе координат тела). \en A solid for thread (in a solid coordinate system). + const MbMatrix3D & matrFrom; ///< \ru Матрица преобразования из системы координат тела в систему координат мира. \en A matrix of transformation from a solid coordinate system to the world coordinate system. + MbPlacement3D placeView; ///< \ru Система координат вида в мировой системе координат. \en A view coordinate system in the world coordinate system. + MbeThrMapType thrMapType; ///< \ru Тип отображения резьбы. \en A type of thread mapping. + const VERSION version; ///< \ru Версия построения (математическая). \en A version of construction (mathematical). + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] thr - \ru Резьба + \en A thread \~ + \param[in] lump - \ru Тело с матрицей преобразования. + \en A solid with a matrix of transformation. \~ + */ + ThreadMapperStruct( const MbThread & thr, const MbLump & lump, + const VERSION ver = Math::DefaultMathVersion() ) + : thread ( thr ) + , solid ( lump.GetSolid() ) + , matrFrom ( lump.GetMatrixFrom() ) + , placeView ( ) + , thrMapType( tmt_CompleteView ) + , version ( ver ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] thr - \ru Резьба + \en A thread \~ + \param[in] sol - \ru Тело. + \en A solid. \~ + \param[in] mFrom - \ru Матрица преобразования тела в мировую систему координат. + \en A matrix of solid transformation to the world coordinate system. \~ + */ + ThreadMapperStruct( const MbThread & thr, const MbSolid & sol, const MbMatrix3D & mFrom, + const VERSION ver = Math::DefaultMathVersion()) + : thread ( thr ) + , solid ( sol ) + , matrFrom ( mFrom ) + , placeView ( ) + , thrMapType( tmt_CompleteView ) + , version ( ver ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] thr - \ru Резьба + \en A thread \~ + \param[in] lump - \ru Тело с матрицей преобразования. + \en A solid with a matrix of transformation. \~ + \param[in] plView - \ru Система координат вида. + \en A view coordinate system. \~ + \param[in] tmType - \ru Тип отображения резьбы. + \en A type of thread mapping. \~ + */ + ThreadMapperStruct( const MbThread & thr, const MbLump & lump, const MbPlacement3D & plView, MbeThrMapType tmType, + const VERSION ver = Math::DefaultMathVersion() ) + : thread ( thr ) + , solid ( lump.GetSolid() ) + , matrFrom ( lump.GetMatrixFrom() ) + , placeView ( plView ) + , thrMapType( tmType ) + , version ( ver ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] thr - \ru Резьба + \en A thread \~ + \param[in] sol - \ru Тело. + \en A solid. \~ + \param[in] mFrom - \ru Матрица преобразования тела в мировую систему координат. + \en A matrix of solid transformation to the world coordinate system. \~ + \param[in] plView - \ru Система координат вида. + \en A view coordinate system. \~ + \param[in] tmType - \ru Тип отображения резьбы. + \en A type of thread mapping. \~ + */ + ThreadMapperStruct( const MbThread & thr, const MbSolid & sol, const MbMatrix3D & mFrom, + const MbPlacement3D & plView, MbeThrMapType tmType, + const VERSION ver = Math::DefaultMathVersion() ) + : thread ( thr ) + , solid ( sol ) + , matrFrom ( mFrom ) + , placeView ( plView ) + , thrMapType( tmType ) + , version ( ver ) + {} + + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without implementation of the copy-constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( ThreadMapperStruct ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить линии отображения резьбы. + \en Calculate thread mapping lines. \~ + \details \ru Вычислить линии отображения резьбы тела (с интерфейсом).\n + \n + Условия получения набора кривых для отображения:\n + 1. Ось резьбы должна быть перпендикулярна или колинеарна оси Z вида.\n + 2. Массивы кривых в _symbView должны быть пустыми. + \en Calculate solid thread mapping lines (with interface).\n + \n + Conditions for obtaining a set of curves for mapping:\n + 1. A thread axis must be perpendicular or colinear to the Z-axis of a view.\n + 2. Arrays of curves in the _symbView must be empty. \~ + \param[in] _thrStruct - \ru Данные для построения. + \en Data for construction. \~ + \param[out] _symbView - \ru Указатель на интерфейс вида.\n + Содержит набор кривых отображения резьбы в системе координат тела, + видимость которых определяется при проецированнии. + \en A pointer to a view interface.\n + Contains a set of curves of thread mapping in a solid coordinate system + with visibility defining in projection. \~ + \return \ru true в случае успеха операции. + \en returns true if the operation succeeded. \~ + \ingroup Mapping +*/ +//--- +MATH_FUNC (bool) PerformThreadMapping( const ThreadMapperStruct & _thrStruct, + MbSimbolthThreadView & _symbView ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить линии отображения резьбы. + \en Calculate thread mapping lines. \~ + \details \ru Вычислить линии отображения резьбы тела (без интерфейса).\n + \en Calculate solid thread mapping lines (without interface).\n \~ + \param[in] _thrStruct - \ru Данные для построения.\n + \en Data for construction.\n \~ + \param[out] annCurves - \ru Множество аннотационных кривых.\n + \en The array of annotative curves.\n \~ + \return \ru true в случае успеха операции. + \en returns true if the operation succeeded. \~ + \ingroup Mapping +*/ +//--- +MATH_FUNC ( bool ) PerformThreadMapping( const ThreadMapperStruct & _thrStruct, MbAnnCurves & annCurves ); + + +#endif // __MAP_THREAD_H \ No newline at end of file diff --git a/C3d/Include/map_vestige.h b/C3d/Include/map_vestige.h new file mode 100644 index 0000000..7e41dfe --- /dev/null +++ b/C3d/Include/map_vestige.h @@ -0,0 +1,1277 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cледы трехмерных объектов. + \en Vestiges of three-dimensional objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MAP_VESTIGE_H +#define __MAP_VESTIGE_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MbEdgeVestige; +class MbVertexVestige; + + +//------------------------------------------------------------------------------ +/** \brief Тип пространственной геометрии кривой. + \details Тип пространственной геометрии кривой. \n + \ingroup Mapping +*/ +enum MbMapSpaceCurveType { + mst_Unset = 0, ///< тип геометрии кривой неопределен + mst_Degenerate, ///< кривая в проекции вырождается в точку + mst_Line, ///< кривая в проекции вырождается в линию + mst_Circle, ///< кривая в проекции вырождается в окружность + mst_Ellipse, ///< кривая в проекции вырождается в эллипс + mst_Arbitrary, ///< произвольный тип кривой +}; +// --- + +//------------------------------------------------------------------------------ +/** \brief \ru След трехмерного объекта. + \en The vestige of three-dimensional object. \~ + \details \ru Базовый класс для классов следа трехмерного объекта.\n + \en The base class for classes of three-dimensional object vestige.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbBaseVestige : public TapeBase { +protected: + uint comp; ///< \ru Компонент. \en A component. + size_t ident; ///< \ru Идентификатор нити. \en A thread identifier. + uint16 style; ///< \ru Базовый стиль. \en A basis style. \~ \internal \ru По просьбе группы 3D (Компас) \en 3D (Kompas) at request. \~ \endinternal + MbAttributeContainer attrData; ///< \ru Атрибуты. \en Attributes. \~ \internal \ru По просьбе группы Приложений (Компас) \en Apps (Kompas) at request. \~ \endinternal +protected: + const MbTopologyItem * item; ///< \ru Топологический объект(используется только как временный внутри проецирования). \en Topological object (is used only as a temporary object in projection). + TOwnPointer name; ///< \ru Имя. \en A name. + +public: + + /** \brief \ru Классификация плоского отображения. + \en The classification of a planar mapping. \~ + \details \ru Классификация плоского отображения. \n + \en The classification of a planar mapping. \n \~ + */ + enum Type { + vt_None, ///< \ru Тип неопределен. \en A type is undefined. + vt_SmoothEdge, ///< \ru Линия перехода (гладкое ребро). \en A transition line (smooth edge). + vt_Edge, ///< \ru Отображение ребра или линия очерка поверхности. \en Mapping of edge or isocline curve of surface. + vt_SectionLine, ///< \ru Линия разреза (ребра тела, полученные сечением). \en A cutaway line (section edges). + vt_AnnThreadThin, ///< \ru Аннотационный объект резьба тонкая. \en An annotative object - a thread is thin. + vt_AnnThreadThick, ///< \ru Аннотационный объект резьба толстая. \en An annotative object - a thread is thick. + vt_AnnThreadDashed, ///< \ru Аннотационный объект резьба штриховая. \en An annotative object - a thread is dashed. + vt_BoundLeft, ///< \ru Левая граница вида. \en The left boundary of a view. + vt_BoundRight, ///< \ru Правая граница вида. \en The right boundary of a view. + vt_Vertex, ///< \ru Вершина. \en A vertex. + vt_SpacePoint, ///< \ru Пространственная точка. \en A spatial point. + vt_SpaceCurve, ///< \ru Пространственная кривая. \en A spatial curve. + vt_CenterLine, ///< \ru Осевая (центральная) линия. \en A center line. + }; + + /** \brief \ru Классификатор подтипов аннотационных ребер. + \en The classifier of annotative edges subtypes. \~ + \details \ru Классификатор подтипов аннотационных ребер. \n + \en The classifier of annotative edges subtypes. \n \~ + */ + enum SubType { + vst_None = 0, ///< \ru Подтип неопределен. \en A subtype is undefined. + vst_BaseBeg, ///< \ru Основной начальный. \en A base initial type. + vst_BaseEnd, ///< \ru Основной конечный. \en A base final type. + vst_ButtBeg, ///< \ru Торцевой начальный. \en A butt initial type. + vst_ButtEnd, ///< \ru Торцевой конечный. \en A butt final type. + vst_CLAxis, ///< \ru Прямолинейная ось. \en A straight axis type. + vst_CLPath, ///< \ru Криволинейная траектория. \en A curved path type. + }; + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор для топологического объекта.\n + \en Constructor for a topological object.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + */ + MbBaseVestige( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem ) + : comp ( otherComp ) + , ident ( otherIdent ) + , style ( SYS_MAX_UINT16 ) + , attrData ( ) + , item ( &otherItem ) + , name ( &otherItem.GetName() ) + { name.SetOwn( false ); } + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор для аннотационного объекта.\n + \en Constructor for an annotative object.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + */ + MbBaseVestige( uint otherComp, size_t otherIdent, const MbName & otherName, const MbTopologyItem * otherItem ) + : comp ( otherComp ) + , ident ( otherIdent ) + , style ( SYS_MAX_UINT16 ) + , attrData ( ) + , item ( otherItem ) + , name ( &otherName ) + { name.SetOwn( false ); } + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор для пространственной точки или кривой.\n + \en Constructor for a spatial point or curve.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + */ + MbBaseVestige( uint otherComp, size_t otherIdent, const MbName & otherName ) + : comp ( otherComp ) + , ident ( otherIdent ) + , style ( SYS_MAX_UINT16 ) + , attrData ( ) + , item ( NULL ) + , name ( &otherName ) + { name.SetOwn( false ); } + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbBaseVestige( const MbBaseVestige & other, MbRegDuplicate * iReg ); + /// \ru Конструктор. \en Constructor. + MbBaseVestige() + : comp ( 0 ) + , ident ( SYS_MAX_T ) + , style ( SYS_MAX_UINT16 ) + , item ( NULL ) + , name ( NULL ) + { name.SetOwn(false); } + virtual ~MbBaseVestige() {} + +public: + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; ///< \ru Создать копию объекта. \en Create a copy of the object. +public: + uint GetComponent() const { return comp; } + size_t GetIdentifier() const { return ident; } + uint16 GetStyle() const { return style; } + const MbAttributeContainer & GetAttributes() const { return attrData; } + + void CopyIdData( const MbBaseVestige & obj ) { comp = obj.comp; ident = obj.ident; } + + void SetProperties ( uint16 st ) { style = st; } + void SetProperties ( uint16 st, const MbAttributeContainer & ac ) { style = st; attrData.AttributesAssign( ac ); } + void CopyProperties( const MbBaseVestige & obj ) { style = obj.style; attrData.AttributesAssign( obj.attrData ); } + +public: + const MbTopologyItem * GetItem() const { return item; } ///< \ru Топологический объект. \en A topological object. + const MbName * GetVestigeName() const { return name; } ///< \ru Имя. \en A name. + +private: + bool operator == ( const MbBaseVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbBaseVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbBaseVestige ) +OBVIOUS_PRIVATE_COPY( MbBaseVestige ) +}; + +IMPL_PERSISTENT_OPS( MbBaseVestige ) + +//------------------------------------------------------------------------------ +/** \brief \ru След вершины. + \en The vestige of a vertex. \~ + \details \ru След вершины.\n + \en The vestige of a vertex.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbVertexVestige : public MbBaseVestige { + friend struct MbVEFVestiges; +protected: + MbCartPoint point; ///< \ru Проекция вершины. \en A vertex projection. + bool bvisible; ///< \ru Флаг видимости. \en A visibility flag. +private: + uint8 vesType; ///< \ru Тип вершины. \en A vertex type. + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор вершины.\n + \en Constructor of a vertex.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] vis - \ru Флаг видимости. + \en A visibility flag. \~ + */ + MbVertexVestige( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, bool vis ) + : MbBaseVestige( otherComp, otherIdent, otherItem ) + , point ( ) + , bvisible( vis ) + , vesType ( vt_Vertex ) + {} + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор пространственной точки.\n + \en Constructor of a spatial point.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[in] vis - \ru Флаг видимости. + \en A visibility flag. \~ + */ + MbVertexVestige( uint otherComp, size_t otherIdent, const MbName & otherName, bool vis, bool isDegenerateCurve ) + : MbBaseVestige( otherComp, otherIdent, otherName ) + , point ( ) + , bvisible( vis ) + , vesType ( isDegenerateCurve ? (uint8)vt_SpaceCurve : (uint8)vt_SpacePoint ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbVertexVestige( const MbVertexVestige & other, MbRegDuplicate * iReg ) + : MbBaseVestige( other, iReg ) + , point ( other.point ) + , bvisible ( other.bvisible ) + , vesType ( other.vesType ) + {} + /// \ru Конструктор. \en Constructor. + MbVertexVestige() + : MbBaseVestige() + , point ( ) + , bvisible( true ) + , vesType ( vt_None ) + {} +public: + /// \ru Создать копию объекта. \en Create a copy of the object. + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; +public: + /// \ru Тип отображения. \en Mapping type. + Type GetType() const { return (Type)vesType; } + /// \ru Это видимая точка? \en Is point visible? + bool IsVisible() const { return bvisible; } + /// \ru Получить точку. \en Get the point. + const MbCartPoint & GetPoint() const { return point; } + /// \ru Преобразовать точку по матрице. \en Transform the point. + void TransformPoint( const MbMatrix & mtr ) { point.Transform( mtr ); } + +private: + bool operator == ( const MbVertexVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbVertexVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbVertexVestige ) +OBVIOUS_PRIVATE_COPY( MbVertexVestige ) +}; + +IMPL_PERSISTENT_OPS( MbVertexVestige ) + +struct MbCurveVestige; +void ReplaceCurveVestigeDuplicates( MbCurveVestige & ); + +//------------------------------------------------------------------------------ +/** \brief \ru Информация о следе кривой. + \en The information about a curve vestige. \~ + \details \ru Информация о следе кривой.\n + Для вложения в след ребра (MbVestigeEdge) и в след грани (MbVestigeEdge).\n + \en The information about a curve vestige.\n + For including to the edge vestige (MbVestigeEdge) and face vestige (MbVestigeEdge).\n \~ + \ingroup Mapping +*/ +// --- +struct MATH_CLASS MbCurveVestige : public TapeBase { +protected: + SPtr totalPrj; ///< \ru Полная проекция (может быть NULL). \en A full projection (can be NULL). \~ \internal \ru Владеет. \en Owns. \~ \endinternal + std::vector arTotal; ///< \ru Все проекции в упорядоченной форме. \en All projections in an ordered form. \~ \internal \ru Не владеет. \en Doesn't own. \~ \endinternal + + // \ru Двумерные кривые лежат копиями, поэтому массивы владеющие. \en Two-dimensional uv-curves are copies therefore arrays are owners + // \ru Если кривых нет то указатель останется нулевым. \en If no curves then the pointer remains NULL. + TPointer< PArray > arVisPrj; ///< \ru Видимые проекции. \en Visible projections. + TPointer< PArray > arHidPrj; ///< \ru Не видимые проекции. \en Invisible projections. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по умолчанию.\n + Создает объект с нулевой проекцией. + \en Default constructor.\n + Creates an object with the null projection. \~ + */ + MbCurveVestige() + : totalPrj( NULL ) + , arTotal ( ) + , arVisPrj( NULL ) + , arHidPrj( NULL ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbCurveVestige( const MbCurveVestige & other, MbRegDuplicate * iReg ); + /// \ru Деструктор. \en Destructor. + virtual ~MbCurveVestige() { ClearAll(); } +public: + /// \ru Создать копию объекта. \en Create a copy of the object. + virtual MbCurveVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + /** \brief \ru Очистить проекции. + \en Clear projections. \~ + \details \ru Очистить проекции.\n + Очищает список проекций в arTotal, + обнуляет указатели totalPrj, arVisPrj, arHidPrj. + \en Clear projections.\n + Clears the list of projections in the arToral, + resets the totalPrj, arVisPrj, arHidPrj. \~ + */ + void ClearAll() + { + arTotal.clear(); + totalPrj = NULL; + arVisPrj = NULL; + arHidPrj = NULL; + } + /// \ru Пустое ли отображение кривой? \en Is an empty curve vestige? + bool IsEmpty() const + { + return ( totalPrj == NULL ) && + ( arTotal.size() < 1 ) && + ( !arVisPrj || arVisPrj->empty() ) && + ( !arHidPrj || arHidPrj->empty() ); + } + /// \ru Количество видимых частей проекции. \en The number of visible parts of the projection. + size_t GetVisiblePartsCount() const { return ( ( !!arVisPrj ) ? arVisPrj->size() : 0 ); } + /// \ru Количество невидимых частей проекции. \en The number of hidden parts of the projection. + size_t GetHiddenPartsCount () const { return ( ( !!arHidPrj ) ? arHidPrj->size() : 0 ); } + /// \ru Количество всех частей проекции. \en The number of all parts of the projection. + size_t GetAllPartsCount () const { return arTotal.size(); } + + /// \ru Создан ли массив для видимых частей проекции. \en Is the array for visible parts of the projection created? + bool IsVisibleCurvesArray() const { return !!arVisPrj; } + /// \ru Создан ли массив для невидимых частей проекции. \en Is the array for hidden parts of the projection created? + bool IsHiddenCurvesArray () const { return !!arHidPrj; } + + /// \ru Получить видимую часть проекции. \en Get visible part of projection. + const MbCurve * _GetVisibleCurve( size_t k ) const { return (( !!arVisPrj ) ? (*arVisPrj)[k] : NULL); } + /// \ru Получить невидимую часть проекции. \en Get hidden part of projection. + const MbCurve * _GetHiddenCurve ( size_t k ) const { return (( !!arHidPrj ) ? (*arHidPrj)[k] : NULL); } + + /// \ru Положить в массив указатели видимых частей проекции. \en Put pointers of visible parts of projection into the array. + template + void GetVisibleCurves( Curves & dst ) const; + /// \ru Положить в массив указатели невидимых частей проекции. \en Put pointers of hidden parts of projection into the array. + template + void GetHiddenCurves ( Curves & dst ) const; + + /// \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + void AddYourGabaritTo( MbRect & ) const; + /// \ru Преобразование согласно матрице. \en The transformation according to a matrix. + void Transform( const MbMatrix & ); + + /** \brief \ru Добавить часть проекции. + \en Add a part of projection. \~ + \details \ru Добавить новую часть общей проекции, имеющий признак видимости.\n + \en Add a new part of the general projection which has a visibility attribute.\n \~ + \param[in] segment - \ru Часть проекции. + \en A projection part. \~ + \param[in] visible - \ru Признак видимости. + \en A visibility attribute. \~ + */ + void AddSegment( MbCurve & segment, bool visible ); + /** \brief \ru Добавить копию часть проекции. + \en Add copy of a part of projection. \~ + \details \ru Добавить копию новой части общей проекции, имеющей признак видимости.\n + \en Add copy of a new part of the general projection which has a visibility attribute.\n \~ + \param[in] segment - \ru Часть проекции. + \en A projection part. \~ + \param[in] visible - \ru Признак видимости. + \en A visibility attribute. \~ + */ + void AddSegmentCopy( const MbCurve & segment, bool visible ); + + /** \brief \ru Забрать все проекционные кривые из структуры. + \en Pick up all curves. \~ + \details \ru Забрать все проекционные кривые из структуры и очистить ее. + \en Pick up all curves of this structure and clear it. \~ + */ + bool PickUpMapCurves( RPArray & crvArr, SArray & visArr ); + /// \ru Забрать видимую часть проекции (не обнуляет в массиве всех проекций). \en Pick up visible part of projection (it doesn't set zero in all projections array). + MbCurve * _PickupVisibleCurve( size_t ); + /// \ru Забрать невидимую часть проекции (не обнуляет в массиве всех проекций). \en Pick up hidden part of projection (it doesn't set zero in all projections array). + MbCurve * _PickupHiddenCurve ( size_t ); + /// \ru Поглотить данные структуры и очистить ее. \en Absorb data of this structure and clear it. + bool EatupOther( MbCurveVestige & ); + /// \ru Отцепить все кривые из структуры и очистить ее. \en Detach all curves of this structure and clear it. + void DetachAllCurves( PArray *& visCurves, PArray *& hidCurves, SPtr & totalPrj ); + + /// \ru Получение полной проекции. \en Merge total projection. + const MbCurve * MergeTotalMap ( MbMapSpaceCurveType spaceCurveGeomType ); + /// \ru Обновление полной проекции. \en Update total projection. + const MbCurve * UpdateTotalMap( MbMapSpaceCurveType spaceCurveGeomType ); + + /// \ru Починить одиночное соответствие полной проекции и ее частями. \en Repair correspondence between total projection and parts of the projection. + bool RepairSpecificCorrespondence( bool uncertainIsVisible ); + + /// \ru Есть ли указатель на полную проекцию? \en Is there a pointer to the full projection? + bool IsTotalProjection() const { return (totalPrj != NULL); } + /// \ru Указатель на полную проекцию. \en The pointer to a full projection. + MbCurve * DetachTotalProjection() { return ::DetachItem( totalPrj ); } + /// \ru Установить полную проекцию. \en Set a full projection. + void SetTotalProjection( MbCurve & ); + + /// \ru Указатель на полную проекцию. \en The pointer to a full projection. + const MbCurve * GetFullProjection() const; + /// \ru Обнулить указатель на полную проекцию. \en Set to null the pointer to a full projection. + MbCurve * DetachFullProjection(); + + friend void ReplaceCurveVestigeDuplicates( MbCurveVestige & ); + +private: + bool operator == ( const MbCurveVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbCurveVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL ( MbCurveVestige ) +OBVIOUS_PRIVATE_COPY( MbCurveVestige ) +}; + +IMPL_PERSISTENT_OPS( MbCurveVestige ) + +//------------------------------------------------------------------------------ +// указатель на полную проекцию +// --- +inline +const MbCurve * MbCurveVestige::GetFullProjection() const +{ + C3D_ASSERT( arTotal.size() == GetVisiblePartsCount() + GetHiddenPartsCount() ); + + MbCurve * curve = totalPrj; + + if ( curve == NULL ) { + if ( !!arVisPrj && (arVisPrj->size() == 1) ) + curve = arVisPrj->operator[]( 0 ); + else if ( !!arHidPrj && (arHidPrj->size() == 1) ) + curve = arHidPrj->operator[]( 0 ); + } + return curve; +} + +//------------------------------------------------------------------------------ +// \ru Забрать видимую часть проекции. \en Pick up visible part of projection. +//--- +inline MbCurve * MbCurveVestige::_PickupVisibleCurve( size_t k ) +{ + if ( arVisPrj != NULL ) { + PArray & crvs = *arVisPrj; + MbCurve * crv = crvs[k]; + ::AddRefItem( crv ); // захват и отпускание на случай перехода на владение по счетчику ссылок + crvs[k] = NULL; + ::DecRefItem( crv ); + return crv; + } + return NULL; +} + +//------------------------------------------------------------------------------ +// \ru Забрать видимую часть проекции. \en Pick up visible part of projection. +//--- +inline MbCurve * MbCurveVestige::_PickupHiddenCurve( size_t k ) +{ + if ( arHidPrj != NULL ) { + PArray & crvs = *arHidPrj; + MbCurve * crv = crvs[k]; + ::AddRefItem( crv ); // захват и отпускание на случай перехода на владение по счетчику ссылок + crvs[k] = NULL; + ::DecRefItem( crv ); + return crv; + } + return NULL; +} + +//------------------------------------------------------------------------------ +// \ru Отцепить все кривые из структуры и очистить ее. \en Detach all curves of this structure and clear it. +//--- +inline void MbCurveVestige::DetachAllCurves( PArray *& visCurves, PArray *& hidCurves, SPtr & wholePrj ) +{ + wholePrj = totalPrj; + totalPrj = NULL; + + arTotal.clear(); + visCurves = !!arVisPrj ? arVisPrj.Relinquish() : NULL; + hidCurves = !!arHidPrj ? arHidPrj.Relinquish() : NULL; +} + +//------------------------------------------------------------------------------ +// \ru Положить в массив указатели видимых частей проекции. \en Put pointers of visible parts of projection into the array. +//--- +template +void MbCurveVestige::GetVisibleCurves( Curves & dst ) const +{ + if ( !!arVisPrj ) { + PArray & src = *arVisPrj; + dst.reserve( dst.size() + src.size() ); + std::copy( src.begin(), src.end(), std::back_inserter( dst ) ); + } +} + +//------------------------------------------------------------------------------ +// \ru Положить в массив указатели невидимых частей проекции. \en Put pointers of hidden parts of projection into the array. +//--- +template +void MbCurveVestige::GetHiddenCurves( Curves & dst ) const +{ + if ( !!arHidPrj ) { + PArray & src = *arHidPrj; + dst.reserve( dst.size() + src.size() ); + std::copy( src.begin(), src.end(), std::back_inserter( dst ) ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru След ребра или кривой. + \en The vestige of an edge or a curve. \~ + \details \ru След ребра или кривой. + Несет в себе информацию о следе одной кривой.\n + \en The vestige of an edge or a curve. + Carries the information about the vestige of one curve.\n \~ + \internal \ru МА - На самом деле след не ребра, + а единичное отображение топологического объекта\n + (как правило ребра) + \en МА - it is not an edge vestige, + it is unit mapping of a topological object\n + (of edge usually) \~ \endinternal + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbEdgeVestige : public MbBaseVestige { + friend struct MbVEFVestiges; +public: + MbCurveVestige curveInfo; ///< \ru Информация о следе кривой. \en The information about a curve vestige. +private: + uint8 vesType; ///< \ru Тип отображения. \en A mapping type. + uint8 vesSubType; ///< \ru Подтип (для ветвления именования). \en A subtype for naming branching. + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор для ребра.\n + \en Constructor for an edge.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] isSmooth - \ru Является ли ребро гладким или нет. + \en Is edge is smooth or not. \~ + \param[in] isSection - \ru Является ли ребро линией разреза или нет. + \en Is edge is cutaway line or not. \~ + */ + explicit + MbEdgeVestige( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, bool isSmooth, bool isSection ) + : MbBaseVestige( otherComp, otherIdent, otherItem ) + , curveInfo ( ) + , vesType ( (uint8)(isSmooth ? vt_SmoothEdge : vt_Edge) ) + , vesSubType ( vst_None ) + { + if ( isSection ) + vesType = (uint8)vt_SectionLine; + } + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор для пространственной точки или кривой.\n + \en Constructor for a spatial point or curve.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя. + \en A name. \~ + \param[in] isCenterLine - \ru Является ли кривая осевой линией или нет. + \en Is curve is center line or not. \~ + */ + explicit + MbEdgeVestige( uint otherComp, size_t otherIdent, const MbName & otherName, bool isCenterLine ) + : MbBaseVestige( otherComp, otherIdent, otherName ) + , curveInfo ( ) + , vesType ( (uint8)(isCenterLine ? vt_CenterLine : vt_SpaceCurve) ) + , vesSubType ( vst_None ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbEdgeVestige( const MbEdgeVestige & other, MbRegDuplicate * iReg ) + : MbBaseVestige( other, iReg ) + , curveInfo ( other.curveInfo, iReg ) + , vesType ( other.vesType ) + , vesSubType ( other.vesSubType ) + {} + /// \ru Конструктор. \en Constructor. + MbEdgeVestige() + : MbBaseVestige() + , curveInfo() + , vesType( vt_None ) + , vesSubType( vst_None ) + {} +public: + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; +public: + /// \ru Получить тип отображения. \en Get mapping type. + Type GetType() const { return (Type)vesType; } + /// \ru Получить подтип отображения. \en Get mapping subtype. + SubType GetSubType() const { return (SubType)vesSubType; } + /// \ru Установить тип отображения. \en Set mapping type. + void SetType( Type vt ) { vesType = (uint8)vt; } + /// \ru Установить подтип отображения. \en Set mapping subtype. + void SetSubType( SubType vt ) { vesSubType = (uint8)vt; } + + /// \ru Добавить MbEdgeVestige в массив. \en Add the MbEdgeVestige to an array. \~ + friend MbEdgeVestige * AddVestigeCurve( uint otherComp, size_t otherIdent, const MbName & otherName, RPArray & arr, bool isCenterLine ); + +private: + bool operator == ( const MbEdgeVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbEdgeVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbEdgeVestige ) +OBVIOUS_PRIVATE_COPY( MbEdgeVestige ) +}; +IMPL_PERSISTENT_OPS( MbEdgeVestige ) + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить MbEdgeVestige в массив. + \en Add the MbEdgeVestige to an array. \~ + \details \ru Добавить MbEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[out] array - \ru Массив ребер. + \en Array of edges. \~ + \param[in] isCenterLine - \ru Является ли ребро осевой линией или нет. + \en Is curve is center line or not. \~ + \ingroup Mapping +*/ +// --- +inline MbEdgeVestige * AddVestigeCurve( uint otherComp, + size_t otherIdent, + const MbName & otherName, + RPArray & arr, + bool isCenterLine ) +{ + MbEdgeVestige * vestige = new MbEdgeVestige( otherComp, otherIdent, otherName, isCenterLine ); + if ( vestige ) { + arr.Add( vestige ); + } + return vestige; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru След грани. + \en The vestige of a face. \~ + \details \ru След грани.\n + Несет в себе информацию о следах очерков этой грани. + \en The vestige of a face.\n + Carriers the information about the vestiges of this face outlines. \~ + \internal \ru МА - На самом деле след не грани, + а множественное отображение топологического объекта\n + (как правило грани или разбитого на части отображения ребра (при построении сечений) ) + \en МА - it is not a vestige of a face, + it is a multiple mapping of a topological object\n + (of a face or partitioned edge mapping usually) \~ \endinternal + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbFaceVestige : public MbBaseVestige { + friend struct MbVEFVestiges; +public: + PArray curveInfos; ///< \ru Информация о следах очерков этой грани. \en The information about vestiges of this face outlines. \~ \internal \ru Владеет. \en Owns. \~ \endinternal +private: + uint8 vesType; ///< \ru Тип отображения. \en A mapping type. + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор следа грани.\n + \en Constructor of a face vestige.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + */ + MbFaceVestige( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem ) + : MbBaseVestige( otherComp, otherIdent, otherItem ) + , curveInfos ( 0, 1, true ) + , vesType ( vt_Edge ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbFaceVestige( const MbFaceVestige & other, MbRegDuplicate * iReg ); +public: + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; +public: + /// \ru Тип отображения. \en Mapping type. + Type GetType() const { return (Type)vesType; } + +private: + bool operator == ( const MbFaceVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbFaceVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFaceVestige ) +OBVIOUS_PRIVATE_COPY( MbFaceVestige ) +}; +IMPL_PERSISTENT_OPS( MbFaceVestige ) + + +//------------------------------------------------------------------------------ +/** \brief \ru След аннотационного объекта. + \en The vestige of an annotative object. \~ + \details \ru След аннотационного объекта.\n + \en The vestige of an annotative object.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbAnnotationEdgeVestige : public MbBaseVestige { + friend struct MbVEFVestiges; +public: + MbCurveVestige curveInfo; ///< \ru Информация о следе кривой. \en The information about a curve vestige. +protected: + uint8 vesType; ///< \ru Тип отображения. \en A mapping type. + uint8 vesSubType; ///< \ru Подтип (для ветвления именования). \en A subtype for naming branching. + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор следа аннотационного объекта.\n + \en Constructor of an annotative object vestige.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] otherName - \ru Имя. + \en A name. \~ + \param[in] type - \ru Тип аннотационных ребер. + \en A type of annotative edges. \~ + \param[in] subType - \ru Подтип аннотационных ребер. + \en A subtype of annotative edges. \~ + */ + MbAnnotationEdgeVestige( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, const MbName & otherName, + Type type, SubType subType ) + : MbBaseVestige( otherComp, otherIdent, otherName, otherItem ) + , curveInfo ( ) + , vesType ( (uint8)type ) + , vesSubType ( (uint8)subType ) + { + } + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbAnnotationEdgeVestige( const MbAnnotationEdgeVestige & other, MbRegDuplicate * iReg ); + +public: + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + /// \ru Тип отображения. \en Mapping type. + Type GetType() const { return (Type)vesType; } + /// \ru Подтип аннотационных ребер. \en A subtype of annotative edges. + SubType GetSubType() const { return (SubType)vesSubType; } + + /// \ru Добавить MbAnnotationEdgeVestige в массив. \en Add the MbAnnotationEdgeVestige to an array. \~ + friend MbAnnotationEdgeVestige * AddVestigeAnnotationEdge( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, + const MbName & otherName, MbBaseVestige::Type type, MbBaseVestige::SubType subType, + RPArray & array ); + +private: + bool operator == ( const MbAnnotationEdgeVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbAnnotationEdgeVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbAnnotationEdgeVestige ) +OBVIOUS_PRIVATE_COPY( MbAnnotationEdgeVestige ) +}; +IMPL_PERSISTENT_OPS( MbAnnotationEdgeVestige ) + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить MbAnnotationEdgeVestige в массив. + \en Add the MbAnnotationEdgeVestige to an array. \~ + \details \ru Добавить MbAnnotationEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbAnnotationEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[in] type - \ru Тип аннотационных ребер. + \en A subtype of annotative edges. \~ + \param[in] subType - \ru Подтип аннотационных ребер. + \en A subtype of annotative edges. \~ + \param[out] array - \ru Массив аннотационных ребер. + \en Array of annotative edges. \~ + \ingroup Mapping +*/ +// --- +inline +MbAnnotationEdgeVestige * AddVestigeAnnotationEdge( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, + const MbName & otherName, MbBaseVestige::Type type, MbBaseVestige::SubType subType, + RPArray & array ) +{ + MbAnnotationEdgeVestige * vestige = new MbAnnotationEdgeVestige( otherComp, otherIdent, otherItem, otherName, type, subType ); + if ( vestige ) { + array.Add( vestige ); + } + return vestige; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru След условного обозначения. + \en The vestige of a conventional notation. \~ + \details \ru След условного обозначения.\n + \en The vestige of a conventional notation.\n \~ + \ingroup Mapping +*/ +// --- +class MATH_CLASS MbSymbolVestige : public MbBaseVestige { + friend struct MbVEFVestiges; +protected: + bool bvisible; ///< \ru Флаг видимости. \en A visibility flag. + TPointer matrix; ///< \ru Матрица трансформации плоскости сечения из внутреннего представления во внешнее. \en A matrix of transformation of a section plane from internal representation to external one. + +protected: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор следа условного обозначения с определенным признаком видимости.\n + \en Constructor of a conventional notation vestige with a defined visibility attribute.\n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] otherName - \ru Имя. + \en A name. \~ + \param[in] _bvisible - \ru Признак видимости. + \en A visibility attribute. \~ + */ + MbSymbolVestige( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, const MbName & otherName, bool _bvisible = true ) + : MbBaseVestige( otherComp, otherIdent, otherName, otherItem ) + , bvisible( _bvisible ) + , matrix ( NULL ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbSymbolVestige( const MbSymbolVestige & other, MbRegDuplicate * iReg ); + /// \ru Конструктор. \en Constructor. + MbSymbolVestige() + : MbBaseVestige() + , bvisible( true ) + , matrix ( NULL ) + {} + +public: + virtual ~MbSymbolVestige() {} + virtual MbBaseVestige & Duplicate( MbRegDuplicate * iReg = NULL ) const; + +public: + /// \ru Это видимая точка? \en Is point visible? + bool IsVisible() const { return bvisible; } + /// \ru Установить матрицу трансформации. \en Set a transformation matrix. + void SetMatrix( const MbMatrix & initMatrix ); + /// \ru Матрица трансформации. \en Transformation matrix. + MbMatrix * GetMatrix() const { return matrix; } + +private: + bool operator == ( const MbSymbolVestige & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbSymbolVestige & ); // \ru Не реализован. \en Not implemented. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSymbolVestige ) +OBVIOUS_PRIVATE_COPY( MbSymbolVestige ) +}; + +IMPL_PERSISTENT_OPS( MbSymbolVestige ) + +//------------------------------------------------------------------------------ +// +// --- +inline void MbSymbolVestige::SetMatrix( const MbMatrix & initMatrix ) +{ + C3D_ASSERT( matrix == NULL ); + if ( matrix == NULL ) + matrix = new MbMatrix( initMatrix ); + else + *matrix = initMatrix; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Набор массивов, выдаваемых наружу при получении всех линий. + \en The set of arrays which are given after getting of all lines. \~ + \details \ru Набор массивов, выдаваемых наружу при получении всех линий тел(а) + с селектированием на видимые и невидимые.\n + \en The set of arrays which are given after getting off all solid(s) lines + with the separation to visible and invisible.\n \~ + \ingroup Mapping +*/ +// --- +struct MATH_CLASS MbVEFVestiges { +//protected: + PArray vertexVestiges; ///< \ru Следы вершин. \en Vestiges of vertices. + PArray edgeVestiges; ///< \ru Следы ребер. \en Vestiges of edges. + PArray faceVestiges; ///< \ru Следы граней. \en Vestiges of faces. + PArray annotateVestiges; ///< \ru Следы аннотационных объектов. \en Vestiges of annotative objects. + PArray symbolVestiges; ///< \ru Следы условного обозначения. \en Vestiges of a conventional notation. + PArray pointVestiges; ///< \ru Следы пространственных точек. \en Vestiges of spatial points. + PArray curveVestiges; ///< \ru Следы пространственных кривых. \en Vestiges of spatial curves. + +public: + /// \ru Конструктор. \en Constructor. + MbVEFVestiges() + : vertexVestiges ( 0, 1, true ) + , edgeVestiges ( 0, 1, true ) + , faceVestiges ( 0, 1, true ) + , annotateVestiges( 0, 1, true ) + , symbolVestiges ( 0, 1, true ) + , pointVestiges ( 0, 1, true ) + , curveVestiges ( 0, 1, true ) + {} + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + MbVEFVestiges( const MbVEFVestiges & other, MbRegDuplicate * iReg ); + /// \ru Деструктор. \en Destructor. + virtual ~MbVEFVestiges() {} + +public: + /// \ru Создать копию объекта. \en Create a copy of the object. + virtual MbVEFVestiges & Duplicate( MbRegDuplicate * iReg = NULL ) const; + /// \ru Очистить массивы следов. \en Clear arrays of vestiges. + void SetEmpty() + { + vertexVestiges.Flush(); + edgeVestiges.Flush(); + faceVestiges.Flush(); + annotateVestiges.Flush(); + symbolVestiges.Flush(); + pointVestiges.Flush(); + curveVestiges.Flush(); + } + /// \ru Освободить неиспользуемую память. \en Adjust memory. + void Adjust() + { + vertexVestiges.Adjust(); + edgeVestiges.Adjust(); + faceVestiges.Adjust(); + annotateVestiges.Adjust(); + symbolVestiges.Adjust(); + pointVestiges.Adjust(); + curveVestiges.Adjust(); + } + bool IsEmpty() const + { + return (vertexVestiges.Count() < 1) && + (edgeVestiges.Count() < 1) && + (faceVestiges.Count() < 1) && + (annotateVestiges.Count() < 1) && + (symbolVestiges.Count() < 1) && + (pointVestiges.Count() < 1) && + (curveVestiges.Count() < 1); + } + +public: + /** \brief \ru Добавить MbVertexVestige в массив. + \en Add the MbVertexVestige to an array. \~ + \details \ru Добавить MbVertexVestige в массив через закрытые конструкторы. \n + \en Add the MbVertexVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] uv - \ru Точка - след вершины. + \en Point - vertex vestige. \~ + \param[in] uv - \ru Состояние видимости. + \en Visibility state. \~ + */ + MbVertexVestige * AddVestigeVertex( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, const MbCartPoint & uv, bool vis ); + + /** \brief \ru Добавить MbVertexVestige в массив. + \en Add the MbVertexVestige to an array. \~ + \details \ru Добавить MbVertexVestige в массив через закрытые конструкторы. \n + \en Add the MbVertexVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[in] uv - \ru Точка - след пространственной точки. + \en Point - vestige of a spatial point. \~ + \param[in] vis - \ru Флаг видимости. + \en A visibility flag. \~ + */ + MbVertexVestige * AddVestigePoint( uint otherComp, size_t otherIdent, const MbName & otherName, const MbCartPoint & uv, bool vis, bool isDegeneratedCurve ); + + /** \brief \ru Добавить MbEdgeVestige в массив. + \en Add the MbEdgeVestige to an array. \~ + \details \ru Добавить MbEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] isSmooth - \ru Тип ребра (гладкое или нет). + \en A type of edge (smooth or not). \~ + \param[in] isSection - \ru Ребро от сечения или разреза. + \en Edge of section. \~ + */ + MbEdgeVestige * AddVestigeEdge( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, bool isSmooth, bool isSection ); + + /** \brief \ru Добавить MbEdgeVestige в массив. + \en Add the MbEdgeVestige to an array. \~ + \details \ru Добавить MbEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + */ + MbEdgeVestige * AddVestigeCurve( uint otherComp, size_t otherIdent, const MbName & otherName, bool isCenterLine = false ); + + /** \brief \ru Добавить MbEdgeVestige в массив. + \en Add the MbEdgeVestige to an array. \~ + \details \ru Добавить MbEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] mapCurves - \ru Следы кривой. + \en Spatial curve vestiges. \~ + \param[in] visible - \ru Состояние видимости. + \en A visibility state. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + */ + MbEdgeVestige * AddVestigeCurve( uint otherComp, size_t otherIdent, const RPArray & mapCurves, bool visible, const MbName & otherName ); + + /** \brief \ru Добавить MbFaceVestige в массив. + \en Add the MbFaceVestige to an array. \~ + \details \ru Добавить MbFaceVestige в массив через закрытые конструкторы. \n + \en Add the MbFaceVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + */ + MbFaceVestige * AddVestigeFace( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem ); + + /** \brief \ru Добавить MbAnnotationEdgeVestige в массив. + \en Add the MbAnnotationEdgeVestige to an array. \~ + \details \ru Добавить MbAnnotationEdgeVestige в массив через закрытые конструкторы. \n + \en Add the MbAnnotationEdgeVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] otherName - \ru Имя топологического объекта. + \en A name of a topological object. \~ + \param[in] type - \ru Подтип аннотационных ребер. + \en A subtype of annotative edges. \~ + \param[in] subType - \ru Подтип аннотационных ребер. + \en A subtype of annotative edges. \~ + */ + MbAnnotationEdgeVestige * AddVestigeAnnotationEdge( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, + const MbName & otherName, MbBaseVestige::Type type, MbBaseVestige::SubType subType ); + + /** \brief \ru Добавить MbSymbolVestige в массив. + \en Add the MbSymbolVestige to an array. \~ + \details \ru Добавить MbSymbolVestige в массив через закрытые конструкторы. \n + \en Add the MbSymbolVestige to an array by the private constructors. \n \~ + \param[in] otherComp - \ru Компонент. + \en A component. \~ + \param[in] otherIdent - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] otherItem - \ru Топологический объект. + \en A topological object. \~ + \param[in] otherName - \ru Имя. + \en A name. \~ + \param[in] _bvisible - \ru Признак видимости. + \en A visibility attribute. \~ + */ + MbSymbolVestige * AddVestigeSymbol( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, const MbName & otherName, bool _bvisible = true ); + +private: + bool operator == ( const MbVEFVestiges & ); // \ru Не реализован. \en Not implemented. + bool operator != ( const MbVEFVestiges & ); // \ru Не реализован. \en Not implemented. + +DECLARE_NEW_DELETE_CLASS( MbVEFVestiges ) +DECLARE_NEW_DELETE_CLASS_EX( MbVEFVestiges ) +KNOWN_OBJECTS_RW_REF_OPERATORS_EX ( MbVEFVestiges, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class +OBVIOUS_PRIVATE_COPY( MbVEFVestiges ) +}; + + +//------------------------------------------------------------------------------ +// +// --- +inline MbVertexVestige * MbVEFVestiges::AddVestigeVertex( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, const MbCartPoint & uv, bool vis ) +{ + MbVertexVestige * vestige = new MbVertexVestige( otherComp, otherIdent, otherItem, vis ); + if ( vestige ) { + vestige->point = uv; + vertexVestiges.Add( vestige ); + } + return vestige; +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbVertexVestige * MbVEFVestiges::AddVestigePoint( uint otherComp, size_t otherIdent, const MbName & otherName, const MbCartPoint & uv, bool vis, bool isDegeneratedCurve ) +{ + MbVertexVestige * vestige = new MbVertexVestige( otherComp, otherIdent, otherName, vis, isDegeneratedCurve ); + if ( vestige ) { + vestige->point = uv; + pointVestiges.Add( vestige ); + } + return vestige; +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbEdgeVestige * MbVEFVestiges::AddVestigeEdge( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem, bool isSmooth, bool isSection ) +{ + MbEdgeVestige * vestige = new MbEdgeVestige( otherComp, otherIdent, otherItem, isSmooth, isSection ); + if ( vestige ) { + edgeVestiges.Add( vestige ); + } + return vestige; +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbEdgeVestige * MbVEFVestiges::AddVestigeCurve( uint otherComp, size_t otherIdent, const MbName & otherName, bool isCenterLine ) { + return ::AddVestigeCurve( otherComp, otherIdent, otherName, curveVestiges, isCenterLine ); +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbEdgeVestige * MbVEFVestiges::AddVestigeCurve( uint otherComp, size_t otherIdent, const RPArray & mapCurves, bool visible, + const MbName & otherName ) +{ + MbEdgeVestige * ev = NULL; + + ev = ::AddVestigeCurve( otherComp, otherIdent, otherName, curveVestiges, false ); + // BUG_93683 ev = ::AddVestigeEdge( otherComp, otherIdent, otherName, MbBaseVestige::vt_Edge, edgeVestiges ); + + if ( ev != NULL ) { + MbCurveVestige & vc = ev->curveInfo; + for ( size_t m = 0, mapCurvesCnt = mapCurves.Count(); m < mapCurvesCnt; m++ ) { + MbCurve * mapCurve = mapCurves[m]; + if ( mapCurve != NULL ) + vc.AddSegment( *mapCurve, visible ); + } + } + + return ev; +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbFaceVestige * MbVEFVestiges::AddVestigeFace( uint otherComp, size_t otherIdent, const MbTopologyItem & otherItem ) +{ + MbFaceVestige * vestige = new MbFaceVestige( otherComp, otherIdent, otherItem ); + if ( vestige ) + faceVestiges.Add( vestige ); + return vestige; +} + +//------------------------------------------------------------------------------ +// +// --- +inline +MbAnnotationEdgeVestige * MbVEFVestiges::AddVestigeAnnotationEdge( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, + const MbName & otherName, MbBaseVestige::Type type, MbBaseVestige::SubType subType ) +{ + return ::AddVestigeAnnotationEdge( otherComp, otherIdent, otherItem, otherName, type, subType, annotateVestiges ); +} + +//------------------------------------------------------------------------------ +// +// --- +inline MbSymbolVestige * MbVEFVestiges::AddVestigeSymbol( uint otherComp, size_t otherIdent, const MbTopologyItem * otherItem, const MbName & otherName, bool _bvisible ) +{ + MbSymbolVestige * vestige = new MbSymbolVestige( otherComp, otherIdent, otherItem, otherName, _bvisible ); + if ( vestige ) + symbolVestiges.Add( vestige ); + return vestige; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Доступ к элементу массива. + \en The access to an array element. \~ + \details \ru Доступ к элементу массива по индексу.\n + \en The access to an array element by an index.\n \~ + \param[in] i - \ru Индекс. + \en An index. \~ + \param[in] array - \ru Множество следов вершин. + \en An array of vertices vestiges. \~ + \return \ru След вершины по индексу + \en A vestige of a vertex by an index. \~ + \ingroup Mapping +*/ +// --- +inline MbVertexVestige & GetVertexI( size_t i, RPArray & array ) { + return *array[i]; +} + + +//------------------------------------------------------------------------------ +/// \ru Получение полной проекции. \en Merge total projection. +// --- +MbCurve * MergeTotalMap( const std::vector &, MbMapSpaceCurveType = mst_Unset ); + + +//------------------------------------------------------------------------------ +/// \ru Слияние наложений линий очерка. \en Merge impositions of silhouette lines of the face. +// --- +MATH_FUNC (bool) MergeFaceVestiges( MbVEFVestiges &, const MbMatrix3D * ); + + +#endif // __MAP_VESTIGE_H diff --git a/C3d/Include/marker.h b/C3d/Include/marker.h new file mode 100644 index 0000000..24150b4 --- /dev/null +++ b/C3d/Include/marker.h @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Маркер. + \en Marker. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MARKER_H +#define __MARKER_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Маркер со свойствами геометрического объекта. + \en Marker with properties of a geometric object. \~ + \par \ru Определение + Маркером называется тройка объектов: точка и пара ортонормированных векторов. + Например, в системе КОМПАС-3D маркером задается "присоединительная точка", + которая применяется в качестве геометрического коннектора для сопряжения и + позиционирования тел в пространстве.\n + \en Definition + The marker is a triple of objects: a point and a pair of orthonormalized vectors. + For example, in the COMPAS-3D system marker sets the "connecting point", + which is used as geometric connector for conjugation and + positioning of solids in space.\n \~ + + \details \ru Термин "Маркер" позаимствован из книги Г.Крамера, Geometric constraint solving in kinematics.\n + С помощью маркера можно задавать вспомогательные построения, передавать + геометрию кинематических соединений или сопряжений. Маркер всегда принадлежит + какому-то подпространству, например, ЛСК твердого тела.\n + Для маркера всегда выполняется требование; его вектора (в отличие от локальной + системы координат) всегда ортонормированы. Ось Z всегда нормирована, ось X всегда + ортогональна Z (может быть, что X = 0). Маркер может задавать любые геометрические + объекты, которые удобно задать точкой или векторами; это унифицированная форма записи + таких объектов, как точка, прямая, плоскость, ортонормированная правая СК и т.д. + При дополнении маркера радиусом он используется, как сжатая форма записи цилиндра, + окружности, сферы, тора и т.д. \n + \en The term "Marker" is taken from the book "Geometric constraint solving in kinematics" (G.Kramera ).\n + With the help of marker it is possible to set auxiliary constructions and to transmit + geometry of kinematic compounds or conjugations. The marker always belongs + to some subspace, for example, to LSC of solid. \n + For the marker the following requirement is always satisfied: its vectors (as opposed to the local + coordinate system) are always orthonormalized. Z-axis is always normalized, X-axis is always + orthogonal to Z (it could be that X = 0). Marker can set any geometric + objects which are easy to set by point or vectors, this is a unified form of writing + of objects as point, line, plane, right orthonormal CS etc. + When adding a radius to a marker it is used as a compressed form of writing of cylinder, + circle, sphere, torus etc. \n \~ + \sa #MtMarker, #MtUnifiedGeom, #MtMatingGeometry, #MtMatingGeom + \ingroup Legend +*/ +// --- +class MATH_CLASS MbMarker: public MbLegend +{ + MbCartPoint3D origin; ///< \ru Точка маркера. \en Marker point. + MbVector3D axisZ; ///< \ru Нормированный вектор оси OZ. \en Normalized vector of OZ-axis. + MbVector3D axisX; ///< \ru Ортонормированный вектор оси OX. \en Orthonormalized vector of OX-axis. + +public: + /// \ru Конструктор копирования. \en Copy constructor. + MbMarker( const MbMarker & ); + /// \ru Конструктор по точке и вектору. \en Constructor by a point and a vector. + MbMarker( const MbCartPoint3D &, const MbVector3D & ); + /// \ru Конструктор по точке и векторам. \en Constructor by a point and vectors. + MbMarker( const MbCartPoint3D &, const MbVector3D &, const MbVector3D & ); + /// \ru Деструктор. \en Destructor. + virtual ~MbMarker(); + +public: + + // \ru Общие функции геометрического объекта \en Common functions of a geometric object + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en Type of the object. + virtual MbeSpaceType Type() const; // \ru Тип объекта. \en Type of the object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными? \en Determine whether objects are similar. + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равным. \en Make objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + // \ru Свойства \en Properties + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \ru \name Функции маркера. + \en \name Functions of marker. + \{ */ + /// \ru Получить точку маркера. \en Get point of marker. + const MbCartPoint3D & GetOrigin() const { return origin; } + /// \ru Получить ось маркера. \en Get axis of marker. + const MbVector3D & GetAxisX() const { return axisX; } + /// \ru Получить вторую ось маркера. \en Get the second axis of marker. + const MbVector3D & GetAxisZ() const { return axisZ; } + /// \ru Задать нулевую ось X. \en Set the X-axis to null. + void SetNullX() { axisX.SetZero(); } + /// \ru Перевернуть ось Z. \en Invert the Z-axis. + MbMarker & InvertZ(); + + /** \} */ + +private: + MbMarker & operator = ( const MbMarker & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMarker ) +}; + + +IMPL_PERSISTENT_OPS( MbMarker ) + + +#endif // __MARKER_H diff --git a/C3d/Include/math_cfg.h b/C3d/Include/math_cfg.h new file mode 100644 index 0000000..26c5a32 --- /dev/null +++ b/C3d/Include/math_cfg.h @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение системы и платформы. + \en System and platform definition. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MATH_CFG_H +#define __MATH_CFG_H + +#if defined( WIN32 ) && !defined ( _WIN32 ) + #define _WIN32 +#endif + +#if defined( _WIN32 ) && !defined ( WIN32 ) + #define WIN32 +#endif + +#ifdef _WIN32 + #ifndef C3D_WINDOWS + #define C3D_WINDOWS + #endif +#elif defined(__FreeBSD__) + #ifndef C3D_FreeBSD + #define C3D_FreeBSD + #endif +#elif defined(__APPLE__) && defined(__MACH__) + #ifndef C3D_MacOS + #define C3D_MacOS + #endif +#elif defined(__gnu_linux__) || defined(__linux__) + #ifndef C3D_LINUX + #define C3D_LINUX + #endif +#endif + +#if !defined ( C3D_WINDOWS ) //_MSC_VER + // Only for LINUX + #if (defined(__x86_64__) || defined(__64BIT__) || defined(__arm64__) || (__WORDSIZE == 64)) + #define PLATFORM_64 + #else + #define PLATFORM_32 + #endif + +// \ru для совместимости с компиляцией интерфейсов объявленных в конвертерах \en to be compatible with the compilation of interfaces which are declared in converters + #ifndef __stdcall + #define __stdcall + #endif // __stdcall + +#else // C3D_WINDOWS + +// Only for WINDOWS + #if (defined(_WIN64) || defined(WIN64)) + #define PLATFORM_64 + #else + #define PLATFORM_32 + #endif + +#endif //C3D_WINDOWS + + +#endif // __MATH_CFG_H + diff --git a/C3d/Include/math_define.h b/C3d/Include/math_define.h new file mode 100644 index 0000000..7c63110 --- /dev/null +++ b/C3d/Include/math_define.h @@ -0,0 +1,606 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Базовые макросы и функции. + \en Base macros and functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef MATH_DEFINE_H +#define MATH_DEFINE_H + + +#include + +#ifdef C3D_WINDOWS //_MSC_VER // define PRECONDITION + #include + #define PRECONDITION _ASSERT ///< \ru Определение PRECONDITION. \en The PRECONDITION definition. \~ \ingroup Base_Tools +#else // C3D_WINDOWS + #include + #define _ASSERT assert + #ifndef PRECONDITION + #ifdef C3D_DEBUG + #include + inline void __precondition( bool expr, const char* file, int line, const char* func, const char* expression ) { + if ( !expr ) fprintf(stderr, "In file %s, line %d:\nfailed PRECONDITION `%s' in function: %s.\n", file, line, expression, func); + } + #define PRECONDITION(expr) __precondition(expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr) ///< \ru Определение PRECONDITION. \en The PRECONDITION definition. \~ \ingroup Base_Tools + #else + #define PRECONDITION(expr) ((void)0) ///< \ru Определение PRECONDITION. \en The PRECONDITION definition. \~ \ingroup Base_Tools + #endif // C3D_DEBUG + #endif // PRECONDITION +#endif // C3D_WINDOWS + +#include // \ru Внимание! Читаем внимательно! Если вытереть отсюда, то подключить везде, где есть функции из этого файла! \en Attention! Read carefully! If remove this from here, then it should be included anywhere where the functions from this file exist! +#include +#include +#include +#include + +namespace c3d // namespace C3D +{ +typedef std::pair IndicesPair; ///< \ru Пара целочисленных неотрицательных индексов. \en Pair of non-negative integer indices. +typedef std::pair NumbersPair; ///< \ru Пара целочисленных номеров. \en Pair of integer numbers. +typedef std::pair UintPair; ///< \ru Пара 32-битных целочисленных неотрицательных индексов. \en Pair of 32-bit non-negative integer indices. +typedef std::pair BoolPair; ///< \ru Пара флагов. \en Bool pair. +typedef std::pair DoublePair; ///< \ru Пара действительных чисел двойной точности с плавающей запятой. \en Pair of doubles. +typedef std::pair IndicesPairDouble; ///< \ru Пара индексов и числа. \en A pair of indices and double. +typedef std::pair DoubleIndicesPair; ///< \ru Число и пара индексов. \en Double and a pair of indices. + +typedef std::pair IndexBool; ///< \ru Пара номер-флаг. \en Index-double pair. +typedef std::pair BoolIndex; ///< \ru Пара флаг-номер. \en Double-index pair. +typedef std::pair IndexDouble; ///< \ru Пара номер-число. \en Index-double pair. +typedef std::pair DoubleIndex; ///< \ru Пара число-номер. \en Double-index pair. +typedef std::pair FlagDouble; ///< \ru Пара флаг-число. \en Flag-double pair. +typedef std::pair DoubleFlag; ///< \ru Пара число-флаг. \en Double-flag pair. +typedef FlagDouble BoolDouble; ///< \ru Пара флаг-число. \en Flag-double pair. +typedef DoubleFlag DoubleBool; ///< \ru Пара число-флаг. \en Double-flag pair. + +typedef std::vector IndicesVector; ///< \ru Вектор целочисленных неотрицательных индексов. \en Vector of non-negative integer indices. +typedef std::vector NumbersVector; ///< \ru Вектор целочисленных номеров. \en Vector of integer numbers. +typedef std::vector UintVector; ///< \ru Вектор 32-битных целочисленных неотрицательных индексов. \en Vector of 32-bit non-negative integer indices. +typedef std::vector BoolVector; ///< \ru Вектор флагов. \en Bool vector. +typedef std::vector DoubleVector; ///< \ru Вектор double. \en Double vector. + +typedef std::vector< IndicesPair > IndicesPairsVector; ///< \ru Вектор пар целочисленных неотрицательных индексов. \en Vector of pairs of non-negative integer indices. +typedef std::vector< NumbersPair > NumbersPairsVector; ///< \ru Вектор пар целочисленных индексов. \en Vector of pairs of integer indices. +typedef std::vector< DoublePair > DoublePairsVector; ///< \ru Вектор пар double. \en Vector of double pairs. + +typedef std::set IndicesSet; ///< \ru Набор целочисленных неотрицательных индексов. \en Set of non-negative integer indices. +typedef IndicesSet::iterator IndicesSetIt; +typedef IndicesSet::const_iterator IndicesSetConstIt; +typedef std::pair IndicesSetRet; + +typedef std::set NumbersSet; ///< \ru Набор целочисленных номеров. \en Set of integer numbers. +typedef NumbersSet::iterator NumbersSetIt; +typedef NumbersSet::const_iterator NumbersSetConstIt; +typedef std::pair NumbersSetRet; + +typedef std::set UintSet; ///< \ru Набор 32-битных целочисленных неотрицательных индексов. \en Set of 32-bit non-negative integer indices. +typedef UintSet::iterator UintSetIt; +typedef UintSet::const_iterator UintSetConstIt; +typedef std::pair UintSetRet; + +//------------------------------------------------------------------------------ +// +// --- +template +bool IsNullPointer( const ItemPtr * itemPtr ) { + return ((NULL == itemPtr) ? true : false); +} + +//------------------------------------------------------------------------------ +// +// --- +template +void UniqueSortVector( Elements & items ) +{ + if ( items.size() > 1 ) { + std::sort( items.begin(), items.end() ); + items.erase( std::unique( items.begin(), items.end() ), items.end() ); + } +} + +//------------------------------------------------------------------------------ +// +// --- +template +size_t BinarySearch( Elements & items, const Element & item ) +{ + size_t ind = SYS_MAX_T; + + typename Elements::iterator it = std::lower_bound( items.begin(), items.end(), item ); + if ( (it != items.end()) && !(item < *it) ) { + ind = std::distance( items.begin(), it ); + } + return ind; +} + +} // namespace C3D + + +#ifdef C3D_WINDOWS //_MSC_VER +//------------------------------------------------------------------------------ +/** \brief \ru Определение CALL_DECLARATION. + \en The CALL_DECLARATION definition. \~ + \details \ru Определение CALL_DECLARATION. \n + \en The CALL_DECLARATION definition. \n \~ + \ingroup Base_Tools +*/ +// --- +#define CALL_DECLARATION __cdecl +//------------------------------------------------------------------------------ +/** \brief \ru Определение EXPORT_DECLARATION. + \en The EXPORT_DECLARATION definition. \~ + \details \ru Определение EXPORT_DECLARATION. \n + \en The EXPORT_DECLARATION definition. \n \~ + \ingroup Base_Tools +*/ +// --- +#define EXPORT_DECLARATION __declspec(dllexport) +#else // C3D_WINDOWS +//------------------------------------------------------------------------------ +/** \brief \ru Определение CALL_DECLARATION. + \en The CALL_DECLARATION definition. \~ + \details \ru Определение CALL_DECLARATION. \n + \en The CALL_DECLARATION definition. \n \~ + \ingroup Base_Tools +*/ +// --- +#define CALL_DECLARATION +//------------------------------------------------------------------------------ +/** \brief \ru Определение EXPORT_DECLARATION. + \en The EXPORT_DECLARATION definition. \~ + \details \ru Определение EXPORT_DECLARATION. \n + \en The EXPORT_DECLARATION definition. \n \~ + \ingroup Base_Tools +*/ +// --- +#define EXPORT_DECLARATION + +#endif // C3D_WINDOWS + +//#ifdef C3D_WINDOWS //_MSC_VER // std_min() / std_max() +// +//#define std_max(a,b) (std::max)(a,b) +//#define std_min(a,b) (std::min)(a,b) +//#define std_maxRef(a,b) (std::max)(a,b) +//#define std_minRef(a,b) (std::min)(a,b) +// +//#ifndef NOMINMAX +//#include +//#endif // NOMINMAX +// +//#else // _MSC_VER + +#include + +#define std_max(a,b) (std::max)(a,b) +#define std_min(a,b) (std::min)(a,b) +#define std_maxRef(a,b) (std::max)(a,b) +#define std_minRef(a,b) (std::min)(a,b) + +//#endif // _MSC_VER + +//------------------------------------------------------------------------------ +// \ru Для совместимости с VC < 2005 \en To be compatible with VC < 2005 +//--- +#if defined(_MSC_VER) && (_MSC_VER < 1400) + #define TEMPLATE_TYPENAME +#else + #define TEMPLATE_TYPENAME template +#endif // _MSC_VER + +//------------------------------------------------------------------------------ +// \ru Синтаксис дружественной шаблонной функции шаблона \en Syntax of friendly template function of a template +#if !(defined (_MSC_VER)) || __BORLANDC__ + + #define TEMPLATE_FRIEND friend // \ru по стандарту C++98 \en by the C++98 standard + #define TEMPLATE_SUFFIX + #define TEMPLATE_SUFFIX2 + #define FORVARD_DECL_TEMPLATE_TYPENAME( _FUNC ) template _FUNC + #define FORVARD_DECL_TEMPLATE_TYPENAME2( _FUNC ) template _FUNC + +#else // _MSC_VER + + #define TEMPLATE_FRIEND template friend // \ru для VS2005 \en for VS2005 + #define TEMPLATE_SUFFIX + #define TEMPLATE_SUFFIX2 + #define FORVARD_DECL_TEMPLATE_TYPENAME( _FUNC ) + #define FORVARD_DECL_TEMPLATE_TYPENAME2( _FUNC ) + +#endif // _MSC_VER + + +//------------------------------------------------------------------------------ +/** \brief \ru Объявление оператора присваивания и конструктора копирования. + \en The declaration of assignment operator and copy constructor. \~ + \details \ru Объявление приватных оператора присваивания и конструктора копирования. + Используется для запрета неявной реализации этой функциональности, т.к. + при отсутствии в классах явного дублирующего конструктора и оператора присваивания + автоматически генерируются неявные - в основном, через копирование памяти, + что может привести к некорректному поведению системы. + \en The declaration of private assignment operator and copy constructor. + This is used to prohibit an implicit implementation of this functionality because + if there is no an explicit copy constructor or an assignment operator + implicit copy constructor and assigment operator are generated automatically mostly by copying of memory, + that can lead to incorrect behaviour of the system. \~ + \ingroup Base_Tools +*/ +//--- +#define OBVIOUS_PRIVATE_COPY( ClassName ) \ +private: \ + ClassName & operator = ( const ClassName & ); \ + ClassName( const ClassName & ); + + +//------------------------------------------------------------------------------ +/// \ru Получить количество элементов массива. \en Get the number of array elements. \~ \ingroup Base_Tools +//--- +#define COUNTOF(array) (sizeof(array)/sizeof(array[0])) + + +//------------------------------------------------------------------------------ +// \ru Объявить тест кейс как дружественный по отношению к классу, для \en Declare the test case as friendly to the class in order +// \ru того чтобы была возможность доступа к закрытым членам этого класса. \en to be able to access to the private members of the class. +//--- +#define DECLARE_FRIEND_TEST_CASE( SuiteName, CaseName ) friend class SuiteName ## _ ## CaseName ## _Test + + +//------------------------------------------------------------------------------ +// \ru Макросы __TODO__ и __WARN__ предназначены для \en Macros __ TODO__ and __ WARN__ are designed for +// \ru генерации сообщений совместно с #pragma message \en generation of messages with #pragma message +// \ru и позволяют в среде MsDev переходить на строку \en and allow to move to the next line in the MsDev environment +// \ru кода с сообщением по двойному клику в окне Output \en with the message by double click in the Output window +// +// \ru примеры: \en examples: +// \ru #pragma message( __TODO__ "Восстановить закрытый код" ) \en #pragma message( __TODO__ "Restore the private code" ) +// \ru #pragma message( __WARN__ "Отсутствует проверка на NULL" ) \en #pragma message( __WARN__ "There is no check for NULL" ) +//--- +#ifdef _MSC_VER // __TODO__ / __WARN__ + +#define __ANYTOSTR__(x) #x +#define __DEFTOSTR__(x) __ANYTOSTR__(x) +#define __TODO__ __FILE__ "("__DEFTOSTR__(__LINE__)") : TODO: " +#define __WARN__ __FILE__ "("__DEFTOSTR__(__LINE__)") : warning: " + +#else // _MSC_VER +// For linux and borland +#define __TODO__ +#define __WARN__ + +#endif // _MSC_VER + +//------------------------------------------------------------------------------ +// \ru Макрос для вывода диагностических и отладочных сообщений ядра в стандартный поток вывода ошибок stderr. +// \en Macro for outputting diagnostic and debug kernel messages to standard error output stream stderr. +// --- + +#define C3D_WARNING(expr) \ + fprintf(stderr, "WARNING: In file %s(line: %d), in function %s:\n\t%s\n\n", \ + __FILE__, __LINE__, __FUNCTION__, c3d::ToSTDstring(c3d::string_t(expr)).c_str() ); + +//------------------------------------------------------------------------------ +/** \brief \ru Объявление экспортности или импортности классов. + \en The declaration of export or import classes. \~ + \details \ru Объявление экспортности в данном модуле или импортности в других подключаемых модулях. \n + \en The declaration of export in this module or import in other plugged modules. \n \~ + \ingroup Base_Tools +*/ +// --- +// \ru Модуль геометрического моделирования. \en Geometric modeling module. +#ifdef C3D_WINDOWS //_MSC_VER +#if defined ( _BUILDMATHDLL ) + #define MATH_CLASS __declspec( dllexport ) + #define MATH_FUNC(retType) __declspec( dllexport ) retType CALL_DECLARATION + #define MATH_FUNC_EX __declspec( dllexport ) // \ru для KNOWN_OBJECTS_RW_REF_OPERATORS_EX и KNOWN_OBJECTS_RW_PTR_OPERATORS_EX \en for KNOWN_OBJECTS_RW_REF_OPERATORS_EX and KNOWN_OBJECTS_RW_PTR_OPERATORS_EX +#else + #define MATH_CLASS __declspec( dllimport ) + #define MATH_FUNC(retType) __declspec( dllimport ) retType CALL_DECLARATION + #define MATH_FUNC_EX __declspec( dllimport ) +#endif +#else // C3D_WINDOWS + #define MATH_CLASS + #define MATH_FUNC(retType) retType + #define MATH_FUNC_EX +#endif + +// \ru Модуль геометрических ограничений. \en Geometric constraints module. +#define GCE_CLASS MATH_CLASS +#define GCM_CLASS MATH_CLASS +#define GCE_FUNC MATH_FUNC +#define GCM_FUNC MATH_FUNC + +// \ru Модуль конвертеров. \en Converters module. +#define CONV_CLASS MATH_CLASS +#define CONV_FUNC MATH_FUNC +#define CONV_FUNC_EX MATH_FUNC_EX + +// \ru Поддержка кода. \en Support of the code. +#ifndef NULL +#define NULL 0 +#endif + + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/// \ru Максимальное количество элементов матрицы MxN. \en Maximum number of MxN matrix elements. +//--- +const size_t MATRIX_MAX_COUNT = 1000000000; // 1e9 + +//------------------------------------------------------------------------------ +/// \ru Максимальный размер массива. \en Maximum size of array. +//--- +const size_t ARRAY_MAX_COUNT = 1000000; // 1e6 + +//------------------------------------------------------------------------------ +/** + \brief \ru Проверить точки на равенство. + \en Check points for equality. \~ + \details \ru Точки считаются равными, если их координаты отличаются на величину, + не превышающую заданную погрешность. + \en Points are considered as equal if their coordinates differ by a value + which doesn't exceed a given tolerance. \~ + \param[in] p1 - \ru Первая декартова точка. + \en The first cartesian point. \~ + \param[in] p2 - \ru Вторая декартова точка. + \en The second cartesian point. \~ + \param[in] eps - \ru Метрическая погрешность совпадения точек. + \en Metric tolerance of points coincidence. \~ + \return \ru true, если точки совпадают, \n иначе false. + \en True if points coincide, \n false otherwise. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool EqualPoints( const Point & p1, const Point & p2, double eps ) { + return p1.IsSame( p2, eps ); +} + +//------------------------------------------------------------------------------ +/** + \brief \ru Проверить точки на равенство. + \en Check points for equality. \~ + \param[in] p1 - \ru Первая декартова точка. + \en The first cartesian point. \~ + \param[in] p2 - \ru Вторая декартова точка. + \en The second cartesian point. \~ + \param[in] xEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси X. + \en The metric tolerance of points coincidence along the X axis. \~ + \param[in] yEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Y. + \en The metric tolerance of points coincidence along the Y axis. \~ + \return \ru true, если точки совпадают, \n иначе false. + \en True if points coincide, \n false otherwise. \~ + \ingroup Algorithms_2D +*/ +// --- +template +bool EqualPoints( const Point & p1, const Point & p2, double xEpsilon, double yEpsilon ) { + return (::fabs(p1.x - p2.x) < xEpsilon && ::fabs(p1.y - p2.y) < yEpsilon); +} + +//------------------------------------------------------------------------------ +/** + \brief \ru Проверить точки на равенство. + \en Check points for equality. \~ + \param[in] p1 - \ru Первая декартова точка. + \en The first cartesian point. \~ + \param[in] p2 - \ru Вторая декартова точка. + \en The second cartesian point. \~ + \param[in] xEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси X. + \en The metric tolerance of points coincidence along the X axis. \~ + \param[in] yEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Y. + \en The metric tolerance of points coincidence along the Y axis. \~ + \param[in] zEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Z. + \en The metric tolerance of points coincidence along the Y axis. \~ + \return \ru true, если точки совпадают, \n иначе false. + \en True if points coincide, \n false otherwise. \~ + \ingroup Algorithms_3D +*/ +// --- +template +bool EqualPoints( const Point & p1, const Point & p2, double xEpsilon, double yEpsilon, double zEpsilon ) { + return (::fabs(p1.x - p2.x) < xEpsilon && ::fabs(p1.y - p2.y) < yEpsilon && ::fabs(p1.z - p2.z) < zEpsilon); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить векторы на равенство с заданной точностью. + \en Check equality of vectors with given tolerance. \~ + \details \ru Проверка равенства векторов с заданной точностью. + Векторы считаются равными, если их координаты отличаются на величину, не превышающую заданную погрешность. + \en Check equality of vectors with given tolerance. + Vectors are equal if their coordinates differs less than given tolerance. \~ + \param[in] p1 - \ru Первый вектор. + \en The first vector. \~ + \param[in] p2 - \ru Второй вектор. + \en The second vector. \~ + \param[in] eps - \ru Погрешность координат. + \en Coordinate tolerance. \~ + \return \ru Возвращает true, если векторы равны. + \en Returns true if the vectors are equal. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool EqualVectors( const Vector & p1, const Vector & p2, double eps ) { + return p1.IsSame( p2, eps ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить векторы на равенство с заданной точностью. + \en Check equality of vectors with given tolerance. \~ + \details \ru Проверка равенства векторов с заданной точностью. + Векторы считаются равными, если их координаты отличаются на величину, не превышающую заданную погрешность. + \en Check equality of vectors with given tolerance. + Vectors are equal if their coordinates differs less than given tolerance. \~ + \param[in] p1 - \ru Первый вектор. + \en The first vector. \~ + \param[in] p2 - \ru Второй вектор. + \en The second vector. \~ + \param[in] xEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси X. + \en The metric tolerance of points coincidence along the X axis. \~ + \param[in] yEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Y. + \en The metric tolerance of points coincidence along the Y axis. \~ + \return \ru Возвращает true, если векторы равны. + \en Returns true if the vectors are equal. \~ + \ingroup Algorithms_2D +*/ +// --- +template +bool EqualVectors( const Vector & p1, const Vector & p2, double xEpsilon, double yEpsilon ) +{ + return (::fabs(p1.x - p2.x) < xEpsilon && ::fabs(p1.y - p2.y) < yEpsilon); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить векторы на равенство с заданной точностью. + \en Check equality of vectors with given tolerance. \~ + \details \ru Проверка равенства векторов с заданной точностью. + Векторы считаются равными, если их координаты отличаются на величину, не превышающую заданную погрешность. + \en Check equality of vectors with given tolerance. + Vectors are equal if their coordinates differs less than given tolerance. \~ + \param[in] p1 - \ru Первый вектор. + \en The first vector. \~ + \param[in] p2 - \ru Второй вектор. + \en The second vector. \~ + \param[in] xEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси X. + \en The metric tolerance of points coincidence along the X axis. \~ + \param[in] yEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Y. + \en The metric tolerance of points coincidence along the Y axis. \~ + \param[in] zEpsilon - \ru Метрическая погрешность совпадения точек вдоль оси Z. + \en The metric tolerance of points coincidence along the Y axis. \~ + \return \ru Возвращает true, если векторы равны. + \en Returns true if the vectors are equal. \~ + \ingroup Algorithms_3D +*/ +// --- +template +bool EqualVectors( const Vector & p1, const Vector & p2, double xEpsilon, double yEpsilon, double zEpsilon ) +{ + return (::fabs(p1.x - p2.x) < xEpsilon && ::fabs(p1.y - p2.y) < yEpsilon && ::fabs(p1.z - p2.z) < zEpsilon); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Сравнить матрицы. + \en Compare matrices \~ + \details \ru Толерантное сравнение двух матриц. + \en Tolerant comparison of two matrices. \~ + \param[in] m1, m2 - \ru Исходные матрицы. + \en Initial matrices. \~ + \param[in] accuracy - \ru Толерантность. + \en A tolerance. \~ + \return \ru true, если матрицы равны, \n false в противном случае. + \en Returns true if matrices are equal, \n false otherwise. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool EqualMatrices( const Matrix & m1, const Matrix & m2, double accuracy ) { + return m1.IsSame( m2, accuracy ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверка кубов на равенство с управляемой погрешностью. + \en Check for equality of boxes with controlled tolerance. \~ + \details \ru Проверка кубов на равенство с управляемой погрешностью.\n + \en Check for equality of boxes with controlled tolerance. \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +template +bool EqualCubes( const BBox & c1, const BBox & c2, double eps ) +{ + if ( !c1.IsEmpty() && !c2.IsEmpty() ) + return c1.IsSame( c2, eps ); + return false; +} + +//------------------------------------------------------------------------------- +/** \brief \ru Вычисление косинуса и синуса. + \en Calculation of the cosine and sine. \~ + \details \ru В 1.7 раза быстрее, чем отдельное вычисление sin и cos, + проверено под release с оптимизацией. + \en 1.7 times faster than a single calculation of sin and cos, + Tested in release configuration with optimization. \~ + \param[in] tt - \ru Угол (в радианах). + \en Angle (in radians). \~ + \param[out] cosT - \ru Косинус угла tt. + \en Cosine of the angle tt. \~ + \param[out] sinT - \ru Синус угла tt. + \en Sine of the angle tt. \~ + \ingroup Base_Algorithms +*/ +// --- +inline void GetCosSin( const double & tt, double & cosT, double & sinT ) +{ +// A single approach for PLATFORM_64 / !PLATFORM_64 +//#if !defined(PLATFORM_64) && defined(_MSC_VER) // Use inline _asm +// __asm { +// mov eax, tt +// mov ebx, cosT +// mov ecx, sinT +// FLD qword ptr [eax] +// FSINCOS +// FSTP qword ptr [ebx] +// FSTP qword ptr [ecx] +// } +//#else // PLATFORM_64 + cosT = ::cos( tt ); + sinT = ::sin( tt ); +//#endif // PLATFORM_64 +} + +//------------------------------------------------------------------------------- +// \ru Погасить отладочное требование. \en . Mute debug assert. +// --- +inline void DummyAssert( bool ) { +} + +} // namespace C3D + + +//------------------------------------------------------------------------------- +// \ru Работа с OpenMP. // \en Work with OpenMP. +// --- +#ifndef _OPENMP +//------------------------------------------------------------------------------- +// \ru Заглушки для OpenMP. \en Stubs for OpenMP. +// --- +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + typedef struct{ void * _lk; } omp_lock_t; + typedef struct{ void * _lk; } omp_nest_lock_t; + inline void CALL_DECLARATION omp_set_num_threads ( int ) {} + inline int CALL_DECLARATION omp_get_num_threads ( void ) { return 1; } + inline int CALL_DECLARATION omp_get_max_threads ( void ) { return 1; } + inline int CALL_DECLARATION omp_get_thread_num ( void ) { return 0; } + inline int CALL_DECLARATION omp_get_num_procs ( void ) { return 1; } + inline void CALL_DECLARATION omp_set_dynamic ( int ) {} + inline int CALL_DECLARATION omp_get_dynamic ( void ) { return 0; } + inline int CALL_DECLARATION omp_in_parallel ( void ) { return 0; } + inline void CALL_DECLARATION omp_set_nested ( int ) {} + inline int CALL_DECLARATION omp_get_nested ( void ) { return 0; } + inline void CALL_DECLARATION omp_init_lock ( omp_lock_t* ) {} + inline void CALL_DECLARATION omp_destroy_lock ( omp_lock_t* ) {} + inline void CALL_DECLARATION omp_set_lock ( omp_lock_t* ) {} + inline void CALL_DECLARATION omp_unset_lock ( omp_lock_t* ) {} + inline int CALL_DECLARATION omp_test_lock ( omp_lock_t* ) { return 1; } + inline void CALL_DECLARATION omp_init_nest_lock ( omp_nest_lock_t* ) {} + inline void CALL_DECLARATION omp_destroy_nest_lock ( omp_nest_lock_t* ) {} + inline void CALL_DECLARATION omp_set_nest_lock ( omp_nest_lock_t* ) {} + inline void CALL_DECLARATION omp_unset_nest_lock ( omp_nest_lock_t* ) {} + inline int CALL_DECLARATION omp_test_nest_lock ( omp_nest_lock_t* ) { return 1; } + inline double CALL_DECLARATION omp_get_wtime ( void ) { return 1.0; } + inline double CALL_DECLARATION omp_get_wtick ( void ) { return 1.0; } +#if defined(__cplusplus) +} +#endif // __cplusplus +#else // _OPENMP + #include +#endif // _OPENMP + +#endif // MATH_DEFINE_H diff --git a/C3d/Include/math_doxigen.h b/C3d/Include/math_doxigen.h new file mode 100644 index 0000000..2162966 --- /dev/null +++ b/C3d/Include/math_doxigen.h @@ -0,0 +1,421 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Группы для документирования с помощью Doxygen. + \en Groups for documenting by Doxygen. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MATH_DOXIGEN_H +#define __MATH_DOXIGEN_H + + +//----------------------------------------------------------------------------- +// +// +// \ru Группы геометрического ядра \en Groups of the Geometric Kernel \~ +// +// +//----------------------------------------------------------------------------- + +/** + \ru \defgroup Geometric_Modelling C3D Modeler: Модуль геометрического моделирования + \en \defgroup Geometric_Modelling C3D Modeler: The Geometric Modelling Module + \~ \ingroup Geometric_Kernel +*/ + + +/** + \ru \defgroup Geometric_Constraints C3D Solver: Модуль геометрических ограничений + \en \defgroup Geometric_Constraints C3D Solver: The Geometric Constraints Module + \~ \ingroup Geometric_Kernel +*/ + + +/** + \ru \defgroup Data_Exchange C3D Converter: Модуль конвертеров + \en \defgroup Data_Exchange C3D Converter: The Converters Module + \~ \ingroup Geometric_Kernel +*/ + + +//----------------------------------------------------------------------------- +// +// \ru Подгруппа Geometric_Modelling - Модуль геометрического моделирования \en The Geometric Modelling Module \~ +// +//----------------------------------------------------------------------------- +/** + \ru \defgroup Geometric_Items Геометрические объекты + \en \defgroup Geometric_Items Geometric Objects + \~ \ingroup Geometric_Modelling +*/ +/** + \ru \defgroup Base_Items Объекты алгоритмов + \en \defgroup Base_Items Algorithm Objects + \~ \ingroup Geometric_Modelling +*/ +/** + \ru \defgroup Modelling_Functions Методы геометрических построений + \en \defgroup Modelling_Functions Geometric Construction Methods + \~ \ingroup Geometric_Modelling +*/ +/** + \ru \defgroup Geometric_Computation Методы геометрических вычислений + \en \defgroup Geometric_Computation Geometric Computations Methods + \~ \ingroup Geometric_Modelling +*/ +/** + \ru \defgroup Base_Tools Библиотека шаблонов и сериализации + \en \defgroup Base_Tools Templates and Serializations Library + \~ \ingroup Geometric_Modelling +*/ + + +//----------------------------------------------------------------------------------- +// \ru Подгруппа Geometric_Items - Геометрические объекты \en Geometric Objects \~ +//----------------------------------------------------------------------------------- +/** + \ru \defgroup Model_Items Объекты геометрической модели + \en \defgroup Model_Items Geometric Model Objects + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Topology_Items Топологические объекты + \en \defgroup Topology_Items Topological Objects + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Surfaces Поверхности + \en \defgroup Surfaces Surfaces + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Curves_3D Кривые + \en \defgroup Curves_3D Curves + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Point_3D Точка + \en \defgroup Point_3D Point + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Legend Вспомогательные объекты + \en \defgroup Legend Ancillary Items + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Curves_2D Двумерные кривые + \en \defgroup Curves_2D Two-Dimensional uv-Curves + \~ \ingroup Geometric_Items +*/ +/** + \ru \defgroup Region_2D Двумерные области + \en \defgroup Region_2D Two-Dimensional Regions + \~ \ingroup Geometric_Items +*/ + + +//----------------------------------------------------------------------------- +// \ru Подгруппа Base_Items - базовые объекты \en Base Objects \~ +//----------------------------------------------------------------------------- +/** + \ru \defgroup Mathematic_Base_3D Трёхмерные базовые объекты + \en \defgroup Mathematic_Base_3D Three-Dimensional Base Objects + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Mathematic_Base_2D Двумерные базовые объекты + \en \defgroup Mathematic_Base_2D Two-Dimensional Base Objects + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Model_Creators Строители + \en \defgroup Model_Creators Creators + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Model_Attributes Атрибуты + \en \defgroup Model_Attributes Attributes + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Functions Скалярные функции + \en \defgroup Functions Scalar Functions + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Build_Parameters Параметры операций + \en \defgroup Build_Parameters Operation Parameters + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Model_Properties Свойства + \en \defgroup Model_Properties Properties + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Data_Structures Структуры данных + \en \defgroup Data_Structures Data Structures + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Parser Разбор строки + \en \defgroup Parser Parser + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Names Имена + \en \defgroup Names Names + \~ \ingroup Base_Items +*/ +/** + \ru \defgroup Model Модель + \en \defgroup Model Model + \~ \ingroup Base_Items +*/ + + +//----------------------------------------------------------------------------------- +// \ru Подгруппа Modelling_Functions - Методы геометрических построений \en Methods of Geometric Constructions \~ +//----------------------------------------------------------------------------------- +/** + \ru \defgroup Solid_Modeling Построение тел + \en \defgroup Solid_Modeling Solid Modeling + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Shell_Modeling Построение оболочек + \en \defgroup Shell_Modeling Shell Modeling + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Sheet_Metal_Modeling Построения листовых тел + \en \defgroup Sheet_Metal_Modeling Sheet Metal Modeling + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Direct_Modeling Прямое редактирование тел + \en \defgroup Direct_Modeling Direct Solid Modeling + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Surface_Modeling Построение поверхностей + \en \defgroup Surface_Modeling Construction of Surfaces + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Curve3D_Modeling Построение кривых в трёхмерном пространстве + \en \defgroup Curve3D_Modeling Construction of Curves + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Curve_Modeling Построение кривых в двумерном пространстве + \en \defgroup Curve_Modeling Construction of uv-Curves in Two-Dimensional Space + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Point_Modeling Операции с точками + \en \defgroup Point_Modeling Operations with Points + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Base_Algorithms Базовые алгоритмы + \en \defgroup Base_Algorithms Base Algorithms + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Algorithms_3D Алгоритмы в трёхмерном пространстве + \en \defgroup Algorithms_3D Algorithms in Three-Dimensional Space + \~ \ingroup Modelling_Functions +*/ +/** + \ru \defgroup Algorithms_2D Алгоритмы в двумерном пространстве + \en \defgroup Algorithms_2D Algorithms in Two-Dimensional Space + \~ \ingroup Modelling_Functions +*/ + + +//---------------------------------------------------------------------------- +// \ru Подгруппа Geometric_Computation - Методы геометрических расчетов \en Geometric Computations Methods \~ +//---------------------------------------------------------------------------- +/** + \ru \defgroup Polygonal_Objects Полигональные объекты + \en \defgroup Polygonal_Objects Polygonal Objects + \~ \ingroup Geometric_Computation +*/ +/** + \ru \defgroup Triangulation Триангуляция + \en \defgroup Triangulation Triangulation + \~ \ingroup Geometric_Computation +*/ +/** + \ru \defgroup Mapping Построение плоских проекций + \en \defgroup Mapping Construction of Plane Projections + \~ \ingroup Geometric_Computation +*/ +/** + \ru \defgroup Inertia_Computation Вычисление инерционных характеристик + \en \defgroup Inertia_Computation Mass-Inertial Properties + \~ \ingroup Geometric_Computation +*/ +/** + \ru \defgroup Collision_Detection Определение столкновений + \en \defgroup Collision_Detection Collision Detection + \~ \ingroup Geometric_Computation +*/ +/** + \ru \defgroup Drawing Визуализация объектов + \en \defgroup Drawing Objects Visualization + \~ \ingroup Geometric_Computation +*/ + + +//----------------------------------------------------------------------------- +// \ru Подгруппа Base_Tools - Библиотека шаблонов и сериализации \en Library of Templates and Serializations \~ +//----------------------------------------------------------------------------- +/** + \ru \defgroup Base_Tools_Containers Контейнеры + \en \defgroup Base_Tools_Containers Containers + \~ \ingroup Base_Tools +*/ +/** + \ru \defgroup Base_Tools_SmartPointers Автоматические указатели + \en \defgroup Base_Tools_SmartPointers Smart Pointers + \~ \ingroup Base_Tools +*/ +/** + \ru \defgroup Base_Tools_String Работа со строками + \en \defgroup Base_Tools_String Work with Strings + \~ \ingroup Base_Tools +*/ +/** + \ru \defgroup Base_Tools_IO Работа с потоками + \en \defgroup Base_Tools_IO Work with Streams + \~ \ingroup Base_Tools +*/ + + +//----------------------------------------------------------------------------- +// +// \ru Подгруппа Geometric_Constraints - Модуль геометрических ограничений \en The Geometric Constraints Module \~ +// +//----------------------------------------------------------------------------- +/** + \ru \defgroup Mating Геометрические ограничения трёхмерных объектов + \en \defgroup Mating Geometric Constraint Solver in Three-Dimensional Space + \~ \ingroup Geometric_Constraints +*/ +/** + \ru \defgroup MathGC Геометрические ограничения двумерных объектов + \en \defgroup MathGC Geometric Constraint Solver in Two-Dimensional Space + \~ \ingroup Geometric_Constraints +*/ + +//----------------------------------------------------------------------------- +// \ru Подгруппа трехмерного геометрического решателя \en The subgroup of three-dimensional geometric constraint manager (GCM) +//----------------------------------------------------------------------------- +/** + \ru \defgroup GCM_3D_API Базовые функции и типы данных + \en \defgroup GCM_3D_API Basic functions and data types + \~ \ingroup Mating +*/ +/** + \ru \defgroup GCM_3D_ObjectAPI Объектный интерфейс + \en \defgroup GCM_3D_ObjectAPI Object-oriented interface + \~ \ingroup Mating +*/ +/** + \ru \defgroup GCM_3D_Routines Вспомогательные процедуры + \en \defgroup GCM_3D_Routines Auxiliary routines + \~ \ingroup Mating +*/ + +//----------------------------------------------------------------------------- +// \ru Подгруппа двумерного геометрического решателя \en The subgroup of two-dimensional geometric constraint engine (GCE) +//----------------------------------------------------------------------------- +/** + \ru \defgroup Constraints2D_API Интерфейс + \en \defgroup Constraints2D_API Solver Interface + \~ \ingroup MathGC +*/ + +//----------------------------------------------------------------------------------- +// +// \ru Подгруппа Data_Exchange - Модуль конвертеров \en The Converters Module \~ +// +//----------------------------------------------------------------------------------- +/** + \ru \defgroup Exchange_Interface Интерфейс конвертеров + \en \defgroup Exchange_Interface Converters Interface + \~ \ingroup Data_Exchange +*/ +/** + \internal + \ru \defgroup Exchange_Base Базовые объекты конвертеров + \en \defgroup Exchange_Base Converters Basic Objects + \~ \ingroup Data_Exchange + \endinternal +*/ +/** + \internal + \ru \defgroup Exchange_Util Вспомогательные объекты конвертеров + \en \defgroup Exchange_Util Converters Ancillary Facilities + \~ \ingroup Data_Exchange + \endinternal +*/ +/** + \internal + \ru \defgroup Exchange_Algorithms Алгоритмы конвертеров + \en \defgroup Exchange_Algorithms Converters Algorithms + \~ \ingroup Data_Exchange + \endinternal +*/ +/** + \ru \defgroup Exchange_Formats Поддерживаемые форматы данных + \en \defgroup Exchange_Formats Supported Data Formats + \~ \ingroup Data_Exchange +*/ + + +//----------------------------------------------------------------------------------- +// \ru Подгруппа Exchange_Formats - Поддерживаемые конвертером форматы данных \en Converters Supported Data Formats \~ +//----------------------------------------------------------------------------------- +/** + \ru \defgroup Parasolid_Exchange Parasolid конвертер + \en \defgroup Parasolid_Exchange Parasolid Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup ACIS_Exchange ACIS конвертер + \en \defgroup ACIS_Exchange ACIS Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup IGES_Exchange IGES конвертер + \en \defgroup IGES_Exchange IGES Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup STEP_Exchange STEP конвертер + \en \defgroup STEP_Exchange STEP Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup STL_Exchange STL конвертер + \en \defgroup STL_Exchange STL Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup VRML_Exchange VRML конвертер + \en \defgroup VRML_Exchange VRML Converter + \~ \ingroup Exchange_Formats +*/ +/** + \ru \defgroup DXF_Exchange DXF конвертер 3D + \en \defgroup DXF_Exchange DXF Converter for 3D + \~ \ingroup Exchange_Formats +*/ + + +#endif // __MATH_DOXIGEN_H diff --git a/C3d/Include/math_namespace.h b/C3d/Include/math_namespace.h new file mode 100644 index 0000000..4780322 --- /dev/null +++ b/C3d/Include/math_namespace.h @@ -0,0 +1,21 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пространство имен C3D. + \en C3D namespace. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MATH_NAMESPACE_H +#define __MATH_NAMESPACE_H + + +//------------------------------------------------------------------------------ +/// \ru Объявление пространства имен C3D. \en C3D namespace declaration. +//--- +namespace c3d { +} + + +#endif // __MATH_NAMESPACE_H diff --git a/C3d/Include/math_version.h b/C3d/Include/math_version.h new file mode 100644 index 0000000..9acb56a --- /dev/null +++ b/C3d/Include/math_version.h @@ -0,0 +1,174 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Математическая версия. + \en Mathematical version. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +// \ru AS *nix: RC не переваривает BOM (пропадает #ifndef) \en AS *nix: RC does not understand BOM (#ifndef disappears) +// \ru строка пропущена специально \en the line is skipped advisedly +#ifndef __MATH_VERSION_H +#define __MATH_VERSION_H + +#include +#include + + +#define MATH_5_11_R03_VERSION 0x0590005CL ///< \ru Версия файла - 5.11. \en The file version - 5.11. \~ \ingroup Base_Tools +#define MATH_5_BC_VERSION 0x0590005FL ///< \ru Версия файла - 5.0 \en The file version - 5.0 \~ \ingroup Base_Tools + +#define MATH_6_0_VERSION 0x06000009L ///< \ru Версия файла - 6.0. \en The file version - 6.0. \~ \ingroup Base_Tools +#define MATH_6_PLUS_VERSION 0x06000032L ///< \ru Версия файла - 6.1. \en The file version - 6.1. \~ \ingroup Base_Tools + +#define MATH_7_0_VERSION 0x07000005L ///< \ru Версия файла - 7.0. \en The file version - 7.0. \~ \ingroup Base_Tools +#define MATH_7_PLUS_VERSION 0x0701012CL ///< \ru Версия файла - 7.1. \en The file version - 7.1. \~ \ingroup Base_Tools + +#define MATH_8_0_VERSION 0x0800001AL ///< \ru Версия файла - 8.0. \en The file version - 8.0. \~ \ingroup Base_Tools +#define MATH_8_PLUS_VERSION 0x08000133L ///< \ru Версия файла - 8.1. \en The file version - 8.1. \~ \ingroup Base_Tools + +#define MATH_9_0_VERSION 0x09000005L ///< \ru Версия файла - 9.0. \en The file version - 9.0. \~ \ingroup Base_Tools +#define MATH_9_SP1_VERSION 0x09000008L ///< \ru Версия файла - 9.1. \en The file version - 9.1. \~ \ingroup Base_Tools + +#define LAST_NOUNICODE_VERSION 0x0A000018L ///< \ru Версия файла - 10.0 NoUnicode. \en The file version - 10.0 NoUnicode. \~ \ingroup Base_Tools +#define UNICODE_VERSION 0x0A001000L ///< \ru Версия файла - 10.0 Unicode. \en The file version - 10.0 Unicode. \~ \ingroup Base_Tools + +#define MATH_10_VERSION 0x0A001021L ///< \ru Версия файла - 10.0. \en The file version - 10.0. \~ \ingroup Base_Tools +#define MATH_10_SP1_VERSION 0x0A001023L ///< \ru Версия файла - 10.1. \en The file version - 10.1. \~ \ingroup Base_Tools + +#define MATH_11_VERSION 0x0B000031L ///< \ru Версия файла - 11.0. \en The file version - 11.0. \~ \ingroup Base_Tools +#define MATH_11_SP1_VERSION 0x0B000032L ///< \ru Версия файла - 11.1. \en The file version - 11.1. \~ \ingroup Base_Tools + +#define MATH_12_VERSION 0x0C00004DL ///< \ru Версия файла - 12.0. \en The file version - 12.0. \~ \ingroup Base_Tools +#define MATH_12_SP1_VERSION 0x0C00004EL ///< \ru Версия файла - 12.1. \en The file version - 12.1. \~ \ingroup Base_Tools + +#define MATH_13_START_VERSION 0x0D000000L ///< \ru Версия файла - 13.0 (начало версии). \en The file version - 13.0 (start of version). \~ \ingroup Base_Tools +#define MATH_13_VERSION 0x0D000060L ///< \ru Версия файла - 13.0. \en The file version - 13.0. \~ \ingroup Base_Tools +#define MATH_13_SP1_VERSION 0x0D001016L ///< \ru Версия файла - 13.1. \en The file version - 13.1. \~ \ingroup Base_Tools +#define MATH_13_SP2_VERSION 0x0D002004L ///< \ru Версия файла - 13.2. \en The file version - 13.2. \~ \ingroup Base_Tools +#define MATH_13_SP3_START_VERSION 0x0D003000L ///< \ru Версия файла - 13.3 (начало версии). \en The file version - 13.3 (start of version). \~ \ingroup Base_Tools +#define MATH_13_SP3_VERSION 0x0D003001L ///< \ru Версия файла - 13.3. \en The file version - 13.3. \~ \ingroup Base_Tools + +#define MATH_14_START_VERSION 0x0E000000L ///< \ru Версия файла - 14.0 (начало версии). \en The file version - 14.0 (start of version). \~ \ingroup Base_Tools +#define MATH_14_VERSION 0x0E000021L ///< \ru Версия файла - 14.0. \en The file version - 14.0. \~ \ingroup Base_Tools +#define MATH_14_SP1_START_VERSION 0x0E001000L ///< \ru Версия файла - 14.1 (начало версии). \en The file version - 14.1 (start of version). \~ \ingroup Base_Tools +#define MATH_14_SP1_VERSION 0x0E001011L ///< \ru Версия файла - 14.1. \en The file version - 14.1. \~ \ingroup Base_Tools +#define MATH_14_SP2_START_VERSION 0x0E002000L ///< \ru Версия файла - 14.2 (начало версии). \en The file version - 14.2 (start of version). \~ \ingroup Base_Tools +#define MATH_14_SP2_VERSION 0x0E002001L ///< \ru Версия файла - 14.2. \en The file version - 14.2. \~ \ingroup Base_Tools + +#define MATH_15_START_VERSION 0x0F000000L ///< \ru Версия файла - 15.0 (начало версии). \en The file version - 15.0 (start of version). \~ \ingroup Base_Tools +#define MATH_15_VERSION 0x0F000014L ///< \ru Версия файла - 15.0. \en The file version - 15.0. \~ \ingroup Base_Tools +#define MATH_15_SP1_START_VERSION 0x0F001000L ///< \ru Версия файла - 15.1 (начало версии). \en The file version - 15.1 (start of version). \~ \ingroup Base_Tools +#define MATH_15_SP1_VERSION 0x0F001010L ///< \ru Версия файла - 15.1. \en The file version - 15.1. \~ \ingroup Base_Tools +#define MATH_15_SP2_START_VERSION 0x0F002000L ///< \ru Версия файла - 15.2 (начало версии). \en The file version - 15.2 (start of version). \~ \ingroup Base_Tools +#define MATH_15_SP2_VERSION 0x0F002010L ///< \ru Версия файла - 15.2. \en The file version - 15.2. \~ \ingroup Base_Tools + +#define MATH_16_START_VERSION 0x10000000L ///< \ru Версия файла - 16.0 (начало версии). \en The file version - 16.0 (start of version). \~ \ingroup Base_Tools +#define C3D_16_VERSION 0x10000008L ///< \ru Версия файла - C3D 16.0. \en The file version - C3D 16.0. \~ \ingroup Base_Tools +#define MATH_16_VERSION 0x1000000DL ///< \ru Версия файла - 16.0. \en The file version - 16.0. \~ \ingroup Base_Tools +#define MATH_16_SP1_START_VERSION 0x10001000L ///< \ru Версия файла - 16.1 (начало версии). \en The file version - 16.1 (start of version). \~ \ingroup Base_Tools +#define MATH_16_SP1_VERSION 0x10001002L ///< \ru Версия файла - 16.1. \en The file version - 16.1. \~ \ingroup Base_Tools + +#define MATH_17_START_VERSION 0x11000000L ///< \ru Версия файла - 17.0 (начало версии). \en The file version - 17.0 (start of version). \~ \ingroup Base_Tools +#define C3D_2016_VERSION 0x1100000FL ///< \ru Версия файла - C3D 2016. \en The file version - C3D 2016. \~ \ingroup Base_Tools +#define MATH_17_VERSION 0x1100001FL ///< \ru Версия файла - 17.0. \en The file version - 17.0. \~ \ingroup Base_Tools +#define C3D_2017_VERSION MATH_17_VERSION ///< \ru Версия файла - C3D 2017. \en The file version - C3D 2017. \~ \ingroup Base_Tools +#define MATH_17_SP1_VERSION 0x11001001L ///< \ru Версия файла - 17.1. \en The file version - 17.1. \~ \ingroup Base_Tools + +#define MATH_18_START_VERSION 0x12000000L ///< \ru Версия файла - 18.0 (начало версии). \en The file version - 18.0 (start of version). \~ \ingroup Base_Tools +#define C3D_2018_VERSION 0x1200000DL ///< \ru Версия файла - C3D 2018. \en The file version - C3D 2018. \~ \ingroup Base_Tools +#define MATH_18_VERSION 0x12000010L ///< \ru Версия файла - 18.0. \en The file version - 18.0. \~ \ingroup Base_Tools + +#define MATH_19_START_VERSION 0x13000000L ///< \ru Версия файла - 19.0 (начало версии). \en The file version - 19.0 (start of version). \~ \ingroup Base_Tools +#define MATH_18_SP1_VERSION 0x13000005L ///< \ru Версия файла - 18.1. \en The file version - 18.1. \~ \ingroup Base_Tools +#define C3D_2019_VERSION 0x1300000FL ///< \ru Версия файла - C3D 2019. \en The file version - C3D 2019. \~ \ingroup Base_Tools + + +//------------------------------------------------------------------------------ +/// \ru Является ли версия файла 16-битной. \en Whether there is a 16-bit file version. \~ \ingroup Base_Tools +// --- +MATH_FUNC (bool) IsVersion16bit( VERSION version ); + +//------------------------------------------------------------------------------ +/// \ru Является ли версия файла 32-битной. \en Whether there is a 32-bit file version. \~ \ingroup Base_Tools +// --- +MATH_FUNC (bool) IsVersion32bit( VERSION version ); + +//------------------------------------------------------------------------------ +/// \ru Является ли версия файла 64-битной. \en Whether there is a 64-bit file version. \~ \ingroup Base_Tools +// --- +MATH_FUNC (bool) IsVersion64bit( VERSION version ); + + +//------------------------------------------------------------------------------ +/// \ru Текущая версия потока. \en The current version. \~ \ingroup Base_Tools +// --- +MATH_FUNC (VERSION) GetCurrentMathFileVersion(); + + +//------------------------------------------------------------------------------ +/// \ru Можно ли потенциально сохранить в заданную версию? \en Can it be saved to this math version? \~ \ingroup Base_Tools +// --- +MATH_FUNC( bool ) CanWriteToMathFileVersion( VERSION dstVertsion, bool * canUseWriterEx = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Список потенциально допустимых предыдущих версий для записи. +\en List of potentially writable previous releases. \~ +\ingroup Base_Tools +*/ +//--- +enum MbeWritableReleaseVersion +{ + wrv_FirstRelease = MATH_17_SP1_VERSION, ///< \ru Версия потока первого допустимого релиза. \en Version of the first valid release. + + wrv_MATH_17_SP1 = MATH_17_SP1_VERSION, ///< \ru Версия файла - 17.1. \en The file version - 17.1. + wrv_C3D_2018 = C3D_2018_VERSION, ///< \ru Версия файла - C3D 2018. \en The file version - C3D 2018. + wrv_MATH_18 = MATH_18_VERSION, ///< \ru Версия файла - 18.0. \en The file version - 18.0. + wrv_MATH_18_SP1 = MATH_18_SP1_VERSION, ///< \ru Версия файла - 18.1. \en The file version - 18.1. + wrv_C3D_2019 = C3D_2019_VERSION, ///< \ru Версия файла - C3D 2019. \en The file version - C3D 2019. + + wrv_PrevRelease = wrv_MATH_18_SP1, ///< \ru Версия потока предпоследнего релиза. \en The previous release version. + wrv_LastRelease = wrv_C3D_2019, ///< \ru Версия потока последнего релиза. \en The last release version. + wrv_MaxPossible = SYS_MAX_UINT32 ///< \ru Использовать последнюю версия потока. \en Use current working version. +}; + + +//------------------------------------------------------------------------------ +/// \ru Версия потока предпоследнего релиза. \en The previous release version. \~ \ingroup Base_Tools +// --- +inline VERSION GetPrevReleaseMathFileVersion() { + return (VERSION)wrv_PrevRelease; +} + + +//------------------------------------------------------------------------------ +/// \ru Версия потока последнего релиза. \en The last release version. \~ \ingroup Base_Tools +// --- +inline VERSION GetLastReleaseMathFileVersion() { + return (VERSION)wrv_LastRelease; +} + + +//------------------------------------------------------------------------------ +/// \ru Текущая версия компактного формата файла. +// Компактный формат записи объектов не использует дерево модели и пишет регистрируемые объекты внутри содержащих их объектов. +// \en The current version of compact file format. +// Compact file format does not use the model tree, and writes objects within the containing object. +// \~ \ingroup Base_Tools +// --- +MATH_FUNC (VERSION) GetCurrentCompactFormatVersion(); + + +//------------------------------------------------------------------------------ +/// \ru Текущая версия расширенного формата файла. +// Расширенный формат строит и использует дерево модели и позволяет выборочное чтение объектов. +// \en The current version of extended file format. +// Extended file format builds and uses the model tree and allows selective reading of objects. +// \~ \ingroup Base_Tools +// --- +MATH_FUNC(VERSION) GetCurrentExtendedFormatVersion(); + + +#endif // __MATH_VERSION_H diff --git a/C3d/Include/math_x.h b/C3d/Include/math_x.h new file mode 100644 index 0000000..f559cfb --- /dev/null +++ b/C3d/Include/math_x.h @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Подключение математических функций в LINUX и WINDOWS, а также для компилятора Intel. + \en Connection of mathematical functions in LINUX and WINDOWS, and for Intel compiler. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MATHX_H +#define __MATHX_H + +#include + +#if !defined ( C3D_WINDOWS ) //_MSC_VER + + // Only for LINUX + #if defined ( __INTEL_COMPILER ) + // Only INTEL COMPILER for LINUX + #include + #define _CMATH_ + #else // __INTEL_COMPILER + // Other COMPILER for LINUX + #include + #endif //__INTEL_COMPILER + #include + #include + + #define _hypot hypot + + #ifndef __SIZEOF_WCHAR_T__ + #define __SIZEOF_WCHAR_T__ 4 + #endif + + #define DEPRECATE_DECLARE + +#else // C3D_WINDOWS + + // Only for WINDOWS + #ifndef __SIZEOF_WCHAR_T__ + #define __SIZEOF_WCHAR_T__ 2 + #endif + + #if defined ( __INTEL_COMPILER ) + // Only INTEL COMPILER for WINDOWS + #include + + #define _hypot hypot + #define _CMATH_ + #else // __INTEL_COMPILER + // Only MS COMPILER for WINDOWS + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES // \ru для подключения #define математических констант из math.h \en for connection #define of mathematical constants from math.h + #endif + #include + +//----------------------------------------------------------------------------- +namespace c3d { + # define _HYPOT_EPSILON 1.0E-20 + template + T _hypot(T x, T y) + { + // Normalize x and y, so that both are positive and x >= y: + x = fabs(x); + y = fabs(y); + + if ( y > x ) { + if(y * _HYPOT_EPSILON >= x) + return y; + + T rat = x / y; + return y * sqrt(1 + rat*rat); + } + else { + if(x * _HYPOT_EPSILON >= y) + return x; + + T rat = y / x; + return x * sqrt(1 + rat*rat); + } + } // template T _hypot(T x, T y) +} +//----------------------------------------------------------------------------- + #define _hypot c3d::_hypot + + #endif //__INTEL_COMPILER + +#define DEPRECATE_DECLARE __declspec( deprecated( "This item is deprecated!" ) ) + +#endif //C3D_WINDOWS + + +#endif // __MATHX_H diff --git a/C3d/Include/mb_axis3d.h b/C3d/Include/mb_axis3d.h new file mode 100644 index 0000000..67d933c --- /dev/null +++ b/C3d/Include/mb_axis3d.h @@ -0,0 +1,147 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Ось - вектор, привязанный к фиксированной точке. + \en The axis-vector which is attached to a fixed point. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_AXIS3D_H +#define __MB_AXIS3D_H + + +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbPlacement3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ось - вектор, привязанный к фиксированной точке. + \en The axis-vector which is attached to a fixed point. \~ + \details \ru Фиксированная точка - начало оси. Вектор задает положительное направление. + Используется для поворота объектов в пространстве \n + \en The fixed point is the axis origin. The vector defines a positive direction. + Is used for a rotation of objects in the space \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbAxis3D +{ + MbCartPoint3D origin; ///< \ru Положение начала. \en An origin position. + MbVector3D axisZ; ///< \ru Направление оси (вектор единичной длины). \en An axis direction (unit length vector). + +public: // \ru Оси мировой системы координат \en Axes of the world coordinate system + static const MbAxis3D xAxis; + static const MbAxis3D yAxis; + static const MbAxis3D zAxis; + +public : + /// \ru Пустой конструктор, ось расположена в начале глобальных координат и совпадает с третьей осью глобальных координат. \en Empty constructor. The axis is in the origin of global coordinates and coincides with the third axis of global coordinates. + MbAxis3D() : origin( 0, 0, 0 ), axisZ( 1, 0, 0 ) {}; + /// \ru Конструктор по точке и вектору. \en Constructor by a point and a vector. + MbAxis3D( const MbCartPoint3D & pnt0, const MbVector3D & dir ) : origin( pnt0 ), axisZ( dir ) { axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); } + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbAxis3D( const MbCartPoint3D & pnt0, const MbCartPoint3D & pnt ) : origin( pnt0 ), axisZ( pnt0, pnt ) { axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); } + /// \ru Конструктор по плейсменту и двум точкам на нем. \en Constructor by a placement and two points on it. + MbAxis3D( const MbPlacement3D & place, const MbCartPoint & p1, const MbCartPoint & p2 ); + /// \ru Конструктор по другой оси. \en Constructor by another axis. + MbAxis3D( const MbAxis3D & axis ) : origin( axis.origin ), axisZ( axis.axisZ ) {} + /// \ru Конструктор по вектору. \en The constructor by a vector. + explicit MbAxis3D( const MbVector3D & v ) : origin(), axisZ( v ) { axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); } + +public : + + /// \ru Инициализация по другой оси. \en The initialization by another axis. + void Init( const MbAxis3D & axis ) { origin = axis.origin; axisZ = axis.axisZ; } + /// \ru Инициализация по точке и вектору. \en The initialization by a point and a vector + void Init( const MbCartPoint3D & pnt0, const MbVector3D & dir ) { origin = pnt0; axisZ = dir; axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); } + /// \ru Инициализация по двум точкам. \en The initialization by two points. + void Init( const MbCartPoint3D & pnt0, const MbCartPoint3D & pnt ) { origin = pnt0; axisZ.Init( pnt0, pnt ); axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); } + /// \ru Инициализация только по направлению с сохранением "начала" \en The initialization only by a direction with saving of the "origin" + MbAxis3D & SetAxisZ( const MbVector3D & zAx ) { axisZ = zAx; axisZ.Normalize(); C3D_ASSERT( !axisZ.IsDegenerate( LENGTH_EPSILON ) ); return *this; } + + /** + \ru \name Функции трехмерного объекта + \en \name The functions of a three-dimensional object + \{ */ + /// \ru Преобразование согласно матрице. \en The transformation according to a matrix. + void Transform( const MbMatrix3D & ); + /// \ru Сдвиг. \en Move. + void Move ( const MbVector3D & to ) { origin.Move( to ); } + /// \ru Поворот вокруг оси. \en The rotation around an axis. + void Rotate ( const MbAxis3D &, double angle ); + /// \ru Сделать копию элемента. \en Create a copy of the element. + MbAxis3D & Duplicate() const; + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + double DistanceToPoint( const MbCartPoint3D & ) const; + /// \ru Вычислить квадрат расстояния до точки. \en Calculate the square of the distance to a point. + double DistanceToPoint2( const MbCartPoint3D & ) const; + /// \ru Вычислить расстояние до отрезка. \en Calculate the distance to a segment. + double DistanceToSegment( const MbCartPoint3D & p1, const MbCartPoint3D & p2, MbCartPoint3D & p ) const; + /// \ru Вычислить квадрат расстояния до отрезка. \en Calculate the square of the distance to a segment. + double DistanceToSegment2( const MbCartPoint3D & p1, const MbCartPoint3D & p2, MbCartPoint3D & p ) const; + + /// \ru Проекция точки на ось. \en The point projection on the axis. + double PointProjection( const MbCartPoint3D & p0, MbCartPoint3D & proj ) const; + /// \ru Проверка соосности. \en The check of complanarity. + bool Complanar ( const MbPlacement3D & p, double eps = Math::angleRegion ) const; + /// \ru Проверка коллинеарности осей. \en The check of axes collinearity. + bool Colinear ( const MbAxis3D &a, double eps = Math::angleRegion ) const; + /// \ru Положить ось на плейсемент. \en Set the axis on a placement. + void SetOnPlacement ( const MbPlacement3D & ); + /// \ru Масштабирование оси. \en Scaling of the axis. + void Scale( double sx, double sy, double sz ); + /// \ru Дать пространственную точку по параметру на оси. \en Get the space point by a parameter on axis. + void PointOn( const double & t, MbCartPoint3D & p ) const { p.Set( origin, axisZ, t ); } + MbCartPoint3D PointOn( const double & t ) const { return origin + axisZ*t; } + + /** \} */ + /** \ru \name Функции доступа к полям + \en \name Functions for access to fields + \{ */ + /// \ru Получить начало оси. \en Get the axis origin. + const MbCartPoint3D & GetOrigin() const { return origin; } + /// \ru Получить вектор оси. \en Get the axis vector. + const MbVector3D & GetAxisZ () const { return axisZ; } + /// \ru Изменить начало оси. \en Edit the axis origin. + MbCartPoint3D & SetOrigin() { return origin; } + /// \ru Изменить вектор оси. \en Edit the axis vector. + MbVector3D & SetAxisZ () { return axisZ; } + + /// \ru Оператор присваивания. \en An assignment operator. + void operator = ( const MbAxis3D & init ) { origin = init.origin; axisZ = init.axisZ; } + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbAxis3D & other, double accuracy ) const; + /** \} */ + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbAxis3D, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbAxis3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbAxis3D ) +}; // MbAxis3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbAxis3D::IsSame( const MbAxis3D & other, double accuracy ) const +{ + return ( origin.IsSame( other.origin, accuracy ) && + axisZ.IsSame( other.axisZ, accuracy ) ); +} + + +#endif // __MB_AXIS3D_H diff --git a/C3d/Include/mb_cart_point.h b/C3d/Include/mb_cart_point.h new file mode 100644 index 0000000..ef9d07a --- /dev/null +++ b/C3d/Include/mb_cart_point.h @@ -0,0 +1,1189 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Декартова двумерная точка. + \en The cartesian two-dimensional point. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_CART_POINT_H +#define __MB_CART_POINT_H + + +#include + + +class MATH_CLASS MbFloatPoint; + + +//------------------------------------------------------------------------------ +/** \brief \ru Декартова двумерная точка. + \en The cartesian two-dimensional point. \~ + \details \ru Двумерная точка описывается двумя координатами. Определены различные + логические, арифметические и геометрические операции точек с точками и векторами. + Точка названа в честь французского учёного геометра Рене Декарта (Rene Descartes, по латыни Renatus Cartesius). \n + \en The two-dimensional point is defined by two coordinates. Different + logical, arithmetical and geometrical operations of points with points and vectors are defined. + The point is named in honor of French scientist Rene Descartes (lat. Renatus Cartesius). \n \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbCartPoint +{ +public : + double x; ///< \ru Первая координата точки. \en A first coordinate of point. + double y; ///< \ru Вторая координата точки. \en A second coordinate of point. + + /// \ru Начало координат или { 0, 0 }. \en The origin or { 0, 0 }. + static const MbCartPoint origin; + + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Создает точку с нулевыми координатами. + \en Creates a point with zero coordinates. \~ + */ + MbCartPoint () : x(0), y(0) {} + + /// \ru Конструктор копирования. \en Copy-constructor. + MbCartPoint ( const MbCartPoint & p ) : x( p.x ), y( p.y ) {} + /// \ru Конструктор по вектору. \en Constructor by a vector. + MbCartPoint ( const MbVector & p ) : x( p.x ), y( p.y ) {} + /// \ru Конструктор по координатам. \en Constructor by coordinates. + MbCartPoint ( double initX, double initY ) : x(initX), y(initY) {} + + /** \brief \ru Конструктор по точке в локальной системе координат. + \en Constructor by a point in a local coordinate system. \~ + \details \ru Для перевода точки в глобальную систему координат задаётся матрица перехода + из локальной системы. + \en A transition matrix is given for transforming of a point to the global coordinate system + from a local coordinate system. \~ + \param[in] p - \ru Точка в локальной системе координат. + \en A point in the local coordinate system. \~ + \param[in] matr - \ru Матрица перехода из локальной системы координат в глобальную. + \en A transition matrix from the local coordinate system to the global coordinate system. \~ + */ + MbCartPoint ( const MbCartPoint & p, const MbMatrix & matr ) : x(p.x), y(p.y) { Transform(matr); } + + /// \ru Конструктор по float-точке. \en Constructor by float point. + MbCartPoint ( const MbFloatPoint & ); + + /// \ru Обнулить координаты. \en Set coordinates to zero. + void SetZero() { x = y = 0; } + /// \ru Инициализировать по другой точке. \en Initialize by another point. + template + MbCartPoint & Init( const Point & p ) { x = p.x; y = p.y; return *this; } + /// \ru Инициализировать по координатам. \en Initialize by coordinates. + MbCartPoint & Init( double initX, double initY ) { x = initX; y = initY; return *this; } + + /// \ru Найти расстояние от точки до точки. \en Find the distance between points. + double DistanceToPoint( const MbCartPoint & to ) const; + + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + MbCartPoint & Transform( const MbMatrix & matr ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + MbCartPoint & Move( const MbVector & to ) { x += to.x; y += to.y; return *this; } + /// \ru Сдвинуть на заданные приращения. \en Translate by given increments. + MbCartPoint & Move( double dx, double dy ) { x += dx; y += dy; return *this; } + + /// \ru Найти квадрат расстояния от точки до точки. \en Find the squared distance between points. + double DistanceToPoint2( const MbCartPoint & to ) const; + + /** + \ru \name Сдвиги, вращения, отражения. + \en \name Translations, rotations, reflections. + \{ */ + + /** \brief \ru Сдвинуть по направлению, заданному второй точкой. + \en Translate along the direction which is defined by a second point. \~ + \param[in] p2 - \ru Исходная точка, определяющая направления сдвига. + \en An initial point, which defines the direction of the translation. \~ + \param[in] delta - \ru Величина сдвига. + \en Magnitude of the translation. \~ + */ + void MoveAlongLine( const MbCartPoint & p2, double delta ); + + /** \brief \ru Сдвинуть по направлению, заданному углом. + \en Translate along the direction which is defined by an angle. \~ + \param[in] angle - \ru Угол, определяющий направление сдвига. + \en An angle which defines the direction of the translation. \~ + \param[in] delta - \ru Величина сдвига. + \en Magnitude of the translation. \~ + */ + void MoveAlongLine( double angle, double delta ); + + /** \brief \ru Сдвинуть по направлению, заданному вектором. + \en Translate along the direction which is defined by a vector. \~ + \param[in] angle - \ru Вектор, определяющий направление сдвига. + \en A vector which defines the direction of the translation. \~ + \param[in] delta - \ru Величина сдвига. + \en Magnitude of the translation. \~ + */ + void MoveAlongLine( const MbDirection & angle, double delta ); + + /** \brief \ru Сдвинуть по направлению, заданному вектором. + \en Translate along the direction which is defined by a vector. \~ + \param[in] angle - \ru Вектор, определяющий направление сдвига. + \en A vector which defines the direction of the translation. \~ + \param[in] delta - \ru Величина сдвига. + \en Magnitude of the translation. \~ + */ + void MoveAlongLine( const MbVector & vect, double delta ); + + /** \brief \ru Сдвинуть точку по направлению к заданной на расстояние dist. + \en Translate the point towards a given point to the distance "dist". \~ + \param[in] p1 - \ru Исходная точка, определяющая направления сдвига. + \en An initial point, which defines the direction of the translation. \~ + \param[in] dist - \ru Величина сдвига. + \en Magnitude of the translation. \~ + */ + void MoveUntilDist( const MbCartPoint & p1, double dist ); + + /** \brief \ru Сдвинуть по направлению. + \en Translate along the direction. \~ + \details \ru Сдвиг по направлению точки to на расстояние, определяемое + отношением величины ratio к расстоянию между точками. + \en Translation along the direction of the "to" point to the distance which is defined + by the ratio of "ratio" and distance between points. \~ + \param[in] to - \ru Точка. + \en A point. \~ + \param[in] ratio - \ru Доля расстояния. + \en A distance part. \~ + */ + void GoNearToPoint( const MbCartPoint & to, double ratio ); // \ru Сдвиг в направлении точки to \en Translation along the direction of point "to" + + /** \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Угол определяет вектор вращения, а точка - центр. + \en An angle defines a rotation vector and a point defines a center. \~ + \param[in] pnt - \ru Точка. + \en A point. \~ + \param[in] angle - \ru Угол вращения. + \en A rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, double angle ); + + /** \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Угол определяется вектором вращения. + \en An angle is defined by a rotation vector. \~ + \param[in] pnt - \ru Точка - центр вращения. + \en A point is a rotation center. \~ + \param[in] angle - \ru Вектор вращения. + \en A rotation vector. \~ + */ + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + + /** \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Угол определяет вектор вращения. + \en An angle defines a rotation vector. \~ + \param[in] angle - \ru Угол вращения. + \en A rotation angle. \~ + */ + void Rotate( double angle ); + + /** \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Угол определяется вектором вращения. + \en An angle is defined by a rotation vector. \~ + \param[in] angle - \ru Вектор вращения. + \en A rotation vector. \~ + */ + void Rotate( const MbDirection & angle ); + + /** \brief \ru Зеркально отразить точку от заданной. + \en Reflect a point specularly from a given point. \~ + \param[in] from - \ru Точка, от которой требуется отразить исходную. + \en A point from which it is necessary to reflect the initial point. \~ + \return \ru Отраженную точку. + \en Returns a reflected point. \~ + */ + MbCartPoint Mirror( const MbCartPoint & from ) const; + + /** \brief \ru Зеркально отразить точку от прямой. + \en Reflect a point specularly from a line. \~ + \param[in] p1, p2 - \ru Точки, задающие прямую. + \en Points which define a line. \~ + \return \ru Отраженную точку. + \en Returns a reflected point. \~ + */ + MbCartPoint Mirror( const MbCartPoint & p1, const MbCartPoint & p2 ) const; + + /** \brief \ru Зеркально отразить точку от прямой. + \en Reflect a point specularly from a line. \~ + \details \ru Отражение происходит от прямой в направлении, задаваемом базовой точкой. + \en The reflection from a line in the direction which is defined by the base point. \~ + \param[in] p1 - \ru Точка, задающая направление отражения. + \en A point which defines the direction of the reflection. \~ + \param[in] dir - \ru Вектор, задающий прямую, от которой делается отражение. + \en A vector defines a line from which the reflection is made. \~ + */ + void Mirror( const MbCartPoint & p1, const MbDirection & dir ); + /** \} */ + + /// \ru Количество координат точки. \en The number of point coordinates. + static size_t GetDimension() { return 2; } + /** + \ru \name Логические и арифметические операции. + \en \name Logical and arithmetical operations. + \{ */ + /// \ru Доступ к координате по индексу. \en Access to a coordinate by an index. + double & operator [] ( size_t i ) { return i ? y : x; } + /// \ru Значение координаты по индексу. \en The value of a coordinate by an index. + double operator [] ( size_t i ) const { return i ? y : x; } + + /// \ru Проверить на равенство в рамках точности. \en Check for equality with tolerance. + bool operator == ( const MbCartPoint & with ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbCartPoint & with ) const; + /// \ru Проверить на точное равенство. \en Check for an accurate equality. + bool Equal( const MbCartPoint & with ) const; + + /// \ru Проверить на меньше. \en Check for "less". + bool operator < ( const MbCartPoint & ) const; + /// \ru Проверить на больше. \en Check for "greater". + bool operator > ( const MbCartPoint & ) const; + + /// \ru Cложить две точки. \en Sum two points. + MbVector operator + ( const MbCartPoint & pnt ) const; + /// \ru Вычесть из точки точку. \en Subtract a point from the point. + MbVector operator - ( const MbCartPoint & pnt ) const; + /// \ru Cложить точку с вектором. \en Add a point to a vector. + MbCartPoint operator + ( const MbDirection & d ) const; + /// \ru Вычесть вектор из точки. \en Subtract a vector from a point. + MbCartPoint operator - ( const MbDirection & d ) const; + + /// \ru Унарный минус. \en The unary minus. + MbCartPoint operator - (); + /// \ru Умножить точку на число. \en Multiply a point by a number. + MbCartPoint operator * ( double factor ) const; + /// \ru Разделить точку на число. \en Divide a point by a number. + MbCartPoint operator / ( double factor ) const; + /// \ru Вычислить точку как копию данной точки, преобразованную матрицей. \en Calculate the point as this copy transformed by the matrix. + MbCartPoint operator * ( const MbMatrix & ) const; + + /// \ru Cложить две точки. \en Sum two points. + void operator += ( const MbCartPoint & pnt ); + /// \ru Вычесть из точки точку. \en Subtract a point from the point. + void operator -= ( const MbCartPoint & pnt ); + /// \ru Умножить точку на число. \en Multiply a point by a number. + void operator *= ( double factor ); + /// \ru Разделить точку на число. \en Divide a point by a number. + void operator /= ( double factor ); + + // \ru Тела функций находится в файле "vector.h" \en Implementations of functions are located in the "vector.h" file + /// \ru Cложить точку с вектором. \en Add a point to a vector. + void operator += ( MbVector & v ); + /// \ru Вычесть вектор из точки. \en Subtract a vector from a point. + void operator -= ( MbVector & v ); + + /// \ru Cложить точку с вектором. \en Add a point to a vector. + MbCartPoint operator + ( const MbVector & vector ) const; + /// \ru Вычесть вектор из точки. \en Subtract a vector from a point. + MbCartPoint operator - ( const MbVector & vector ) const; + /// \ru Присвоить точке значения компонент вектора. \en Assign values of vector components to the point. + void operator = ( const MbVector & ); + /// \ru Присвоить точке значения компонент вектора. \en Assign values of vector components to the point. + void operator = ( const MbDirection & ); + /// \ru Присвоить точке значений float-точки. \en Assign the float-point value to the point. + void operator = ( const MbFloatPoint & ); + /** \} */ + + /** \brief \ru Расстояние от точки до отрезка. + \en The distance from a point to a segment. \~ + \details \ru Отрезок задается по двум входным точкам. + \en A segment is defined by two input points, \~ + \param[in] p1, p2 - \ru Начальная и конечная точки отрезка. + \en Start and end points of a segment. \~ + \return \ru Искомое расстояние. + \en The required distance. \~ + */ + double DistanceToLineSeg( const MbCartPoint & p1, const MbCartPoint &p2 ) const; + /// \ru Длина вектора ( 0, p(x,y) ). \en The vector length ( 0, p(x,y) ). + double Length() const; + + /** \brief \ru Масштабировать координаты. + \en Scale the coordinates. \~ + \param[in] sx, sy - \ru Масштабирующие коэффициенты для компонент x и y соответственно. + \en Scaling coefficients for components x & y respectively. \~ + */ + void Scale( double sx, double sy ) { x *= sx, y *= sy; } + + /** + \ru \name Функции сложения и умножения точек с точками и с векторами. + \en \name The functions of addition and multiplication of points with points and vectors. + \{ */ + // \ru Присвоение значений \en Values assignment + + /** \brief \ru Приравнять координаты сумме координат точки и вектора. + \en Equate coordinates to sum of point coordinates and vector coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и вектора v2, умноженного на число t2. + \en Equate coordinates to sum of v1 point coordinates and v2 vector coordinates multiplied by t2. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2 - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] t2 - \ru Число, на которое умножаются координаты исходного вектора v2. + \en Coordinates of the initial vector v2 are multiplied by this number. \~ + */ + void Set( const MbCartPoint & v1, const MbVector & v2, double t2 ); + + /** \brief \ru Приравнять координаты сумме координат точки и двух векторов. + \en Equate coordinates to sum of point coordinates and two vectors coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и векторов v2 и v3, + умноженных на числа t2 и t3, соответственно. + \en Equate coordinates to sum of v1 point coordinates and v2 and v3 vectors coordinates + multiplied by the numbers t2 and t3 respectively. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t2, t3 - \ru Числа, на которые умножаются координаты векторов v2 и v3 соответственно. + \en Coordinates of v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + void Set( const MbCartPoint & v1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ); + + /** \brief \ru Приравнять координаты сумме координат двух точек. + \en Equate coordinates to sum of two points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1 и v2, умноженных на числа t1 и t2, соответственно. + \en Equate coordinates to sum of v1 and v2 points coordinates multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты точек v1 и v2 соответственно. + \en Coordinates of v1 and v2 points are multiplied by these numbers respectively. \~ + */ + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2 ); + /** + \brief \ru Приравнять координаты сумме координат трех точек. + \en Equate coordinates to sum of three points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Equate coordinates to sum of v1, v2 and v3 points coordinates + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты точек v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 points are multiplied by these numbers respectively. \~ + */ + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ); + + /** \brief \ru Приравнять координаты сумме координат четырех точек. + \en Equate coordinates to sum of four points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Equate coordinates to sum of v1, v2, v3 and v4 points coordinates + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты точек v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 points are multiplied by these numbers respectively. \~ + */ + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ); + + /** \brief \ru Приравнять координаты сумме координат точки и двух векторов. + \en Equate coordinates to sum of point coordinates and two vectors coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и векторов v2 и v3, + умноженных на числа t2 и t3, соответственно. + \en Equate coordinates to sum of v1 point coordinates and v2 and v3 vectors coordinates + multiplied by the numbers t2 and t3 respectively. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t2, t3 - \ru Числа, на которые умножаются координаты векторов v2 и v3 соответственно. + \en Coordinates of v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + void Set( const MbCartPoint & v1, const MbDirection & v2, double t2, + const MbDirection & v3, double t3 ); + + // \ru Добавление значений \en Values addition + /** \brief \ru Увеличить координаты на значения компонент вектора. + \en Increase coordinates by values of vector components. \~ + \details \ru Увеличить координаты на значения компонент вектора v1, умноженных на число t1. + \en Increase coordinates by values of v1 vector components multiplied by t1. \~ + \param[in] v1 - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] t1 - \ru Число, на которое умножаются координаты исходного вектора v1. + \en Coordinates of the initial vector v1 are multiplied by this number. \~ + */ + void Add( const MbVector & v1, double t1 ); + + /** \brief \ru Увеличить координаты на значения компонент двух векторов. + \en Increase coordinates by values of two vectors components. \~ + \details \ru Увеличить координаты на значения компонент векторов v1 и v2, + умноженных на числа t1 и t2, соответственно. + \en Increase coordinates by values of v1 and v2 vectors components + multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты векторов v1 и v2 соответственно. + \en Coordinates of v1 and v2 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2 ); + + /** \brief \ru Увеличить координаты на значения компонент векторов v1, v2 и v3, умноженных на числа t1, t2 и t3, соответственно. + \en Increase coordinates by values of v1, v2 and v3 vectors components multiplied by t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты векторов v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ); + + /** \brief \ru Увеличить координаты на значения компонент трех векторов. + \en Increase coordinates by values of three vectors components. \~ + \details \ru Увеличить координаты на значения компонент векторов v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Increase coordinates by values of v1, v2 and v3 vectors components + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты векторов v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ); + + /** \brief \ru Увеличить координаты на значения компонент двух векторов. + \en Increase coordinates by values of two vectors components. \~ + \details \ru Увеличить координаты на значения компонент векторов v1 и v2, + умноженных на числа t1 и t2, соответственно. + \en Increase coordinates by values of v1 and v2 vectors components + multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты векторов v1 и v2 соответственно. + \en Coordinates of v1 and v2 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ); + + /** \brief \ru Увеличить координаты на значения координат точки. + \en Increase coordinates by values of point coordinates. \~ + \details \ru Увеличить координаты на значения координат точки v1, умноженных на число t1. + \en Increase coordinates by values of v1 point coordinates multiplied by t1. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] t1 - \ru Число, на которое умножаются координаты исходной точки v1. + \en Coordinates of the initial point v1 are multiplied by this number. \~ + */ + void Add( const MbCartPoint & v1, double t1 ); + + /** \brief \ru Увеличить координаты на значения координат трех точек. + \en Increase coordinates by values of three points coordinates. \~ + \details \ru Увеличить координаты на значения координат точек v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Increase coordinates by values of v1, v2 and v3 points coordinates + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты точек v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 points are multiplied by these numbers respectively. \~ + */ + void Add( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ); + + /** \brief \ru Увеличить координаты на значения координат четырех точек. + \en Increase coordinates by values of four points coordinates. \~ + \details \ru Увеличить координаты на значения координат точек v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Increase coordinates by values of v1, v2, v3 and v4 points coordinates + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты точек v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 points are multiplied by these numbers respectively. \~ + */ + void Add( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ); + /** \} */ + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbCartPoint & other, double accuracy ) const; + /// \ru Является ли точка неопределенной? \en Is the point undefined? + bool IsUndefined() const { return (x == UNDEFINED_DBL || y == UNDEFINED_DBL); } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbCartPoint ) + DECLARE_NEW_DELETE_CLASS( MbCartPoint ) + DECLARE_NEW_DELETE_CLASS_EX( MbCartPoint ) +}; // MbCartPoint + + +//------------------------------------------------------------------------------ +// \ru Расстояние от точки до точки. \en The distance between two points. +// --- +inline double MbCartPoint::DistanceToPoint( const MbCartPoint & to ) const { + return ::_hypot( x - to.x, y - to.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Квадрат расстояния от точки до точки. \en The squared distance between two points. +// --- +inline double MbCartPoint::DistanceToPoint2( const MbCartPoint & to ) const { + double dx = ( x - to.x ); + double dy = ( y - to.y ); + return ( dx * dx + dy * dy ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек. \en The addition of two points. +// --- +inline void MbCartPoint::operator += ( const MbCartPoint & pnt ) { + x += pnt.x; + y += pnt.y; +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек. \en The subtraction of two points. +// --- +inline void MbCartPoint::operator -= ( const MbCartPoint & pnt ) { + x -= pnt.x; + y -= pnt.y; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение точки на число. \en The multiplication of a point by a number. +// --- +inline void MbCartPoint::operator *= ( double factor ) { + x *= factor; + y *= factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление точки на число. \en The division of a point by a number. +// --- +inline void MbCartPoint::operator /= ( double factor ) { + x /= factor; + y /= factor; +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус. \en The unary minus. +// --- +inline MbCartPoint MbCartPoint::operator - () { + return MbCartPoint ( - x, - y ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение точки на число. \en The multiplication of a point by a number. +// --- +inline MbCartPoint MbCartPoint::operator * ( double factor ) const { + return MbCartPoint( x * factor, y * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Деление точки на число. \en The division of a point by a number. +// --- +inline MbCartPoint MbCartPoint::operator / ( double factor ) const { + return MbCartPoint( x / factor, y / factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на точное равенство. \en Check for an accurate equality. +// --- +inline bool MbCartPoint::Equal( const MbCartPoint & with ) const { + return ( x == with.x && y == with.y ); //-V550 +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство. \en The check for equality. +// --- +inline bool MbCartPoint::operator == ( const MbCartPoint & with ) const +{ + double eps = Math::LengthEps; + bool res = ( ::fabs( x - with.x ) <= eps ) && + ( ::fabs( y - with.y ) <= eps ); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство. \en The check for inequality. +// --- +inline bool MbCartPoint::operator != ( const MbCartPoint & with ) const { + return !(*this == with); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на меньше. \en The check for "less". +// --- +inline bool MbCartPoint::operator < ( const MbCartPoint & with ) const { + return ( (x - with.x) < -Math::LengthEps ) || + ( (::fabs(x - with.x) <= Math::LengthEps) && ((y - with.y) < -Math::LengthEps) ); + // double inaccuracy + // return ( x < with.x - Math::LengthEps ) || + // ( (::fabs(x - with.x) <= Math::LengthEps) && (y < with.y - Math::LengthEps) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на больше. \en The check for "greater". +// --- +inline bool MbCartPoint::operator > ( const MbCartPoint & with ) const { + return ( (x - with.x) > Math::LengthEps ) || + ( (::fabs(x - with.x) <= Math::LengthEps) && ((y - with.y) > Math::LengthEps) ); + // double inaccuracy + // return ( x > with.x + Math::LengthEps ) || + // ( (::fabs(x - with.x) <= Math::LengthEps) && (y > with.y + Math::LengthEps) ); +} + + +//------------------------------------------------------------------------------ +// \ru Длина вектора. \en The vector length. +// --- +inline double MbCartPoint::Length() const { + return ::_hypot( x, y ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек. \en The addition of two points. +// --- +inline MbVector MbCartPoint::operator + ( const MbCartPoint & pnt ) const { + return MbVector( x + pnt.x, y + pnt.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек. \en The subtraction of two points. +// --- +inline MbVector MbCartPoint::operator - ( const MbCartPoint & pnt ) const { + return MbVector ( x - pnt.x, y - pnt.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение точки и вектора. \en The addition of a point and a vector. +// --- +inline MbCartPoint MbCartPoint::operator + ( const MbVector & vector ) const +{ + return MbCartPoint( x + vector.x, y + vector.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор \en Operator +// --- +inline MbCartPoint MbCartPoint::operator + ( const MbDirection & d ) const +{ + return MbCartPoint( x + d.ax, y + d.ay ); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор \en Operator +// --- +inline void MbCartPoint::operator += ( MbVector & v ) +{ + x += v.x; + y += v.y; +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание вектора из точки. \en The subtraction of a vector from a point. +// --- +inline MbCartPoint MbCartPoint::operator - ( const MbVector & vector ) const +{ + return MbCartPoint( x - vector.x, y - vector.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор \en Operator +// --- +inline MbCartPoint MbCartPoint::operator - ( const MbDirection & d ) const +{ + return MbCartPoint( x - d.ax, y - d.ay ); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор \en Operator +// --- +inline void MbCartPoint::operator -= ( MbVector & v ) +{ + x -= v.x; + y -= v.y; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точки значений вектора. \en The assignment of vector values to the point. +// --- +inline void MbCartPoint::operator = ( const MbVector & v ) +{ + x = v.x; + y = v.y; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точки значений. \en The assignment of values to the point. +// --- +inline void MbCartPoint::operator = ( const MbDirection & d ) +{ + x = d.ax; + y = d.ay; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг точки по направлению заданному углом. \en The translation of a point along the direction which is given by an angle. +// --- +inline void MbCartPoint::MoveAlongLine( double angle, double delta ) +{ + MbDirection d( angle ); // \ru Вектор направления \en Direction vector + x += d.ax * delta; + y += d.ay * delta; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг в направлении на расстояние. \en The translation along the direction by offset. +// --- +inline void MbCartPoint::MoveAlongLine( const MbDirection & angle, double delta ) +{ + x += angle.ax * delta; + y += angle.ay * delta; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг в направлении на расстояние. \en The translation along the direction by offset. +// --- +inline void MbCartPoint::MoveAlongLine( const MbVector & vect, double delta ) +{ + MbDirection angle; + angle = vect; + x += angle.ax * delta; + y += angle.ay * delta; +} + + +//------------------------------------------------------------------------------ +// \ru Сместиться в направлении точки to на расстояние, \en Displace along the direction of "to" point to a distance +// \ru Определяемое его отношением к расстоянию между точками \en Which is defined by its ratio to the distance between the points +// --- +inline void MbCartPoint::GoNearToPoint( const MbCartPoint & to, double ratio ) +{ + x += ( to.x - x ) * ratio; + y += ( to.y - y ) * ratio; +} + + +//------------------------------------------------------------------------------ +// \ru Поворот \en Rotation +// --- +inline void MbCartPoint::Rotate( const MbCartPoint & c, double angle ) { + Rotate( c, MbDirection( ::cos( angle ), ::sin( angle ) ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Поворот \en Rotation +// --- +inline void MbCartPoint::Rotate( double angle ) { + Rotate( MbDirection( ::cos( angle ), ::sin( angle ) ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Зеркальное отражение точки от заданной \en Specular reflection of a point from a given point +// --- +inline MbCartPoint MbCartPoint::Mirror( const MbCartPoint & from) const { + return MbCartPoint ( from.x - ( x - from.x ), from.y - ( y - from.y ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Зеркальное отражение точки от прямой - базовая точка-направление \en Specular reflection of a point from a line (base point and direction) +// --- +inline void MbCartPoint::Mirror( const MbCartPoint & p1, const MbDirection & dir ) +{ + double d2 = ( dir.ax * ( y - p1.y ) - dir.ay * ( x - p1.x ) ) * 2; + + x += dir.ay * d2; + y -= dir.ax * d2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint & v1, const MbVector & v2, double t2 ) +{ + x = v1.x + v2.x * t2; + y = v1.y + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint &v1, + const MbVector & v2, double t2, const MbVector & v3, double t3 ) +{ + x = v1.x + v2.x * t2 + v3.x * t3; + y = v1.y + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint & v1, + const MbDirection & v2, double t2, const MbDirection & v3, double t3 ) +{ + x = v1.x + v2.ax * t2 + v3.ax * t3; + y = v1.y + v2.ay * t2 + v3.ay * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbVector & v1, double t1 ) +{ + x += v1.x * t1; + y += v1.y * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbVector & v1, double t1, const MbVector & v2, double t2 ) +{ + x += v1.x * t1 + v2.x * t2; + y += v1.y * t1 + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ) +{ + x += v1.ax * t1 + v2.ax * t2; + y += v1.ay * t1 + v2.ay * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbCartPoint::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbCartPoint & v1, double t1 ) { + x += v1.x * t1; + y += v1.y * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint::Add( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbCartPoint::IsSame( const MbCartPoint & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Двумерный вектор. \en The two-dimensional vector. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Конструктор точки по вектору \en Constructor of a point by a vector +// --- +inline MbVector::MbVector( const MbCartPoint & p ) + : x( p.x ) + , y( p.y ) +{ +} + +//------------------------------------------------------------------------------ +// \ru Инициализировать по заданным точкам. \en Initialize by given points. +// --- +inline MbVector & MbVector::Init( const MbCartPoint & p1, const MbCartPoint & p2 ) +{ + x = p2.x - p1.x; + y = p2.y - p1.y; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Сложение вектора и точки \en The addition of a vector and a point +// --- +inline MbVector MbVector::operator + ( const MbCartPoint & pnt ) const +{ + return MbVector(x + pnt.x, y + pnt.y); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание из вектора точки \en The subtraction of a point from a vector +// --- +inline MbVector MbVector::operator - ( const MbCartPoint & pnt ) const +{ + return MbVector( x - pnt.x, y - pnt.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений точки \en Assignment of point values to a vector +// --- +inline MbVector & MbVector::operator = ( const MbCartPoint & pnt ) +{ + x = pnt.x; + y = pnt.y; + return *this; +} + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2 ) +{ + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector::Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Двумерный нормализованный вектор. \en The two-dimensional normalized vector. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Присвоение нормализованному вектору значений точки \en Assignment of point values to a normalized vector +// --- +inline void MbDirection::operator = ( const MbCartPoint & pnt ) +{ +// ax = pnt.x; +// ay = pnt.y; + double d = ::_hypot( pnt.x, pnt.y ); + + if ( d > NULL_EPSILON ) { + ax = pnt.x / d; + ay = pnt.y / d; + } + else { + ax = ay = 0.0; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Чтение точки из потока. \en Reading of point from the stream. +// --- +inline reader & CALL_DECLARATION operator >> ( reader & in, MbCartPoint & obj ) { + in >> obj.x; + in >> obj.y; + + return in; +} + + +//------------------------------------------------------------------------------ +/// \ru Запись точки в поток. \en Writing of point to the stream. +// --- +inline writer & CALL_DECLARATION operator << ( writer & out, const MbCartPoint & obj ) { + out << obj.x; + out << obj.y; + + return out; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/** + \brief \ru Проверить длины на равенство. + \en Check lengths for equality. \~ + \param[in] lx, ly - \ru Сравниваемые длины. + \en Compared lengths. \~ + \param[in] minLen - \ru Минимально возможная длина. + \en A minimum possible length. \~ + \param[in] minDev - \ru Метрическая погрешность равенства длин. + \en A metric accuracy of lengths equality. \~ + \return \ru true, если длины равны, \n иначе false. + \en True if lengths are equal, \n false otherwise. \~ + \ingroup Algorithms_2D +*/ +//--- +inline +bool EqualLengths( double lx, double ly, double minLen = METRIC_EPSILON, double minDev = LENGTH_EPSILON ) { + return ( ::fabs(lx - ly) < minDev && lx > minLen && ly > minLen ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка корректности точки по величине компонент \en The check of point correctness by a component magnitude +//--- +#ifdef C3D_WINDOWS // _MSC_VER +#pragma optimize( "", off ) +#endif // C3D_WINDOWS +template +bool IsValidPoint( const Point & p ) +{ + bool isValid = true; + size_t cnt = p.GetDimension(); + for ( size_t k = 0; isValid && k < cnt; k++ ) { + const double & t = p[k]; + if ( t <= -MB_MAXDOUBLE || t >= MB_MAXDOUBLE ) + isValid = false; + else if ( t != t ) // реакция на бесконечность + isValid = false; + } + return isValid; +} +#ifdef C3D_WINDOWS // _MSC_VER +#pragma optimize( "", on ) +#endif // C3D_WINDOWS + +} // namespace C3D + + +#endif // __MB_CART_POINT_H diff --git a/C3d/Include/mb_cart_point3d.h b/C3d/Include/mb_cart_point3d.h new file mode 100644 index 0000000..680cbbb --- /dev/null +++ b/C3d/Include/mb_cart_point3d.h @@ -0,0 +1,1086 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Трехмерная точка. + \en The three-dimensional point. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_CART_POINT3D_H +#define __MB_CART_POINT3D_H + + +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbFloatPoint3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Трехмерная точка. + \en The three-dimensional point. \~ + \details \ru Трехмерная точка (картезианская точка) описывается тремя координатами в декартовой системе координат. + Точка названа картезианской в честь французского учёного геометра Рене Декарта (Rene Descartes, по латыни Renatus Cartesius). \n + Точку можно описать радиусом-вектором. Радиус-вектор описывает преобразование, + переводящее начальную точку декартовой системы координат в точку пространства с заданными координатами в этой декартовой системе координат. \n + \en The three-dimensional point (cartesian point) is defined by three coordinates in a cartesian coordinate system. + The point is named cartesian in honor of French scientist Rene Descartes (lat. Renatus Cartesius). \n + A point can be defined by radius-vector. A radius-vector describes transform + which translates a start point of a cartesian coordinate system to a space point with the given coordinates in this system. \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbCartPoint3D +{ +public : + double x; ///< \ru Первая координата точки. \en A first coordinate of point. + double y; ///< \ru Вторая координата точки. \en A second coordinate of point. + double z; ///< \ru Третья координата точки. \en A third coordinate of point. + + /// \ru Начало координат или { 0, 0, 0 }. \en The origin or { 0, 0, 0 }. + static const MbCartPoint3D origin; + +public : + /// \ru Конструктор без параметров, точка расположена в начале глобальных координат. \en Constructor without parameters. A point is located at the origin of global coordinates. + MbCartPoint3D () : x(0.0), y(0.0), z(0.0) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbCartPoint3D ( const MbCartPoint3D & p ) : x(p.x), y(p.y), z(p.z) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbCartPoint3D ( const MbFloatPoint3D & ); + /// \ru Конструктор по координатам. \en Constructor by coordinates. + MbCartPoint3D ( double xx, double yy, double zz ) : x(xx), y(yy), z(zz) {} + /** + \brief \ru Конструктор по точке в локальной системе координат. + \en Constructor by a point in a local coordinate system. \~ + \details \ru Для перевода точки в глобальную систему координат задаётся матрица перехода + из локальной системы. + \en A transition matrix is given for transforming of a point to the global coordinate system + from a local coordinate system. \~ + \param[in] p - \ru Точка в локальной системе координат. + \en A point in the local coordinate system. \~ + \param[in] matr - \ru Матрица перехода из локальной системы координат в глобальную. + \en A transition matrix from the local coordinate system to the global coordinate system. \~ + */ + MbCartPoint3D ( const MbCartPoint3D & p, const MbMatrix3D & matr ); + /** + \brief \ru Конструктор по двумерной точке. + \en Constructor by a two-dimensional point. \~ + \details \ru Двумерная точка лежит в плоскости XOY заданной локальной системы координат. + \en A two-dimensional point is located in the XOY plane defined by a local coordinate system. \~ + \param[in] p - \ru Двумерная точка. + \en A two-dimensional point. \~ + \param[in] place - \ru Исходная локальная система координат. + \en The initial local coordinate system. \~ + */ + MbCartPoint3D ( const MbCartPoint & p, const MbPlacement3D & place ); + + /** + \brief \ru Инициализация по двумерной точке. + \en The initialization by two-dimensional point. \~ + \details \ru Двумерная точка лежит в плоскости XOY заданной локальной системы координат. + \en A two-dimensional point is located in the XOY plane defined by a local coordinate system. \~ + \param[in] p - \ru Двумерная точка. + \en A two-dimensional point. \~ + \param[in] place - \ru Исходная локальная система координат. + \en The initial local coordinate system. \~ + */ + void Init( const MbCartPoint & p, const MbPlacement3D & place ); + /// \ru Инициализация по двумерной точке. \en The initialization by two-dimensional point. + void Init( const MbCartPoint & p ); + /// \ru Инициализировать по другой точке. \en Initialize by another point. + template + MbCartPoint3D & Init( const Point & p ) { x = p.x; y = p.y; z = p.z; return *this; } + /// \ru Инициализировать по координатам. \en Initialize by coordinates. + MbCartPoint3D & Init( double xx, double yy, double zz ) { x = xx; y = yy; z = zz; return *this; } + + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + MbCartPoint3D & Transform( const MbMatrix3D & ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + MbCartPoint3D & Move( double dx, double dy, double dz ) { x += dx; y += dy; z += dz; return *this; } + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + MbCartPoint3D & Move( const MbVector3D & to ) { x += to.x; y += to.y; z += to.z; return *this; } + /// \ru Повернуть вокруг оси. \en Rotate around an axis. + MbCartPoint3D & Rotate( const MbAxis3D &, double angle ); + /// \ru Расстояние до точки. \en The distance to a point. + double DistanceToPoint( const MbCartPoint3D & ) const; + + /// \ru Обнулить координаты. \en Set coordinates to zero. + void SetZero() { x = y = z = 0; } + /// \ru Квадрат расстояния от точки до точки. \en The squared distance between two points. + double DistanceToPoint2( const MbCartPoint3D & to ) const; + /// \ru Сдвинуть по направлению точки to на расстояние delta. \en Translate in the direction of the "to" point on the "delta" distance. + void MoveAlongLine ( const MbCartPoint3D & to, double delta ); + /// \ru Сдвинуть по направлению. \en Translate along the direction. + void GoNearToPoint ( const MbCartPoint3D & to, double ratio ); + /// \ru Инициализация максимальными координатами. \en The initialization by the maximum coordinates. + void Maximum ( const MbCartPoint3D & p ); + /// \ru Инициализация минимальными координатами. \en The initialization by the minimal coordinates. + void Minimum ( const MbCartPoint3D & p ); + + /** + \brief \ru Увеличить координаты x и y в ( znear / z ) раз. + \en Increase coordinates x and y in ( znear / z ) times. \~ + \details \ru Увеличение координат производится для учета перспективного преобразования. + Точка должна находится в локальной или видовой системе координат. z - координата точки + не может быть равна нулю. + \en The increase of coordinates is produced for a perspective transformation. + A point must be located in a local or view coordinate system. Z-coordinate of a point + can't be equal to zero. \~ + \param[in] znear - \ru Величина znear/z определяет масштаб увеличения. + \en The value znear/z defines the scale factor. \~ + */ + void Perspective( double znear ); + /// \ru Зеркальное отражение точки относительно плоскости. \en The specular reflection of a point relative to a plane. + void Mirror( const MbCartPoint3D & p0, const MbVector3D & dir ); + + /** + \ru \name Логические и арифметические операции. + \en \name Logical and arithmetical operations. + \{ */ + /// \ru Добавить вектор. \en Add a vector. + void operator += ( const MbVector3D & ); + /// \ru Вычесть вектор. \en Subtract a vector. + void operator -= ( const MbVector3D & ); + /// \ru Добавить координаты точки. \en Add point coordinates. + void operator += ( const MbCartPoint3D & ); + /// \ru Вычесть координаты точки. \en Subtract point coordinates. + void operator -= ( const MbCartPoint3D & ); + /// \ru Умножить координаты на число. \en Multiply coordinates by a factor. + void operator *= ( double factor ); + /// \ru Разделить координаты на число. \en Divide coordinates by a factor. + void operator /= ( double factor ); + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbCartPoint3D & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbCartPoint3D & ) const; + /// \ru Проверить на меньше. \en Check for "less". + bool operator < ( const MbCartPoint3D & ) const; + /// \ru Проверить на больше. \en Check for "greater". + bool operator > ( const MbCartPoint3D & ) const; + + /// \ru Присвоить точке координаты другой точки. \en Assign coordinates of another point to the point. + MbCartPoint3D & operator = ( const MbCartPoint3D & ); + /// \ru Присвоить точке координаты другой точки. \en Assign coordinates of another point to the point. + MbCartPoint3D & operator = ( const MbFloatPoint3D & ); + /// \ru Присвоить точке компоненты вектора. \en Assign vector components to the point. + MbCartPoint3D & operator = ( const MbVector3D & ); + /// \ru Присвоить точке значения однородных координат. \en Assign values of uniform coordinates to the point. + MbCartPoint3D & operator = ( const MbHomogeneous3D & ); + + /// \ru Сложить точку и вектор. \en Add a point and vector. + MbCartPoint3D operator + ( const MbVector3D & ) const; + /// \ru Вычесть из точки вектор. \en Subtract a vector from the point. + MbCartPoint3D operator - ( const MbVector3D & ) const; + /// \ru Сложить две точки. \en Add two points. + MbVector3D operator + ( const MbCartPoint3D & ) const; + /// \ru Вычесть из точки точку. \en Subtract a point from the point. + MbVector3D operator - ( const MbCartPoint3D & ) const; + /// \ru Унарный минус. \en The unary minus. + MbCartPoint3D operator - (); + /// \ru Вычислить точку как копию данной точки, преобразованную матрицей. \en Calculate the point as this copy transformed by the matrix. + MbCartPoint3D operator * ( const MbMatrix3D & ) const; + + /// \ru Доступ к координате по индексу. \en Access to a coordinate by an index. + double & operator [] ( size_t i ) { return i ? (--i ? z : y) : x; } + /// \ru Значение координаты по индексу. \en The value of a coordinate by an index. + double operator [] ( size_t i ) const { return i ? (--i ? z : y) : x; } + /** \} */ + /// \ru Количество координат точки. \en The number of point coordinates. + static size_t GetDimension() { return 3; } + + /** + \ru \name Функции сложения и умножения точек с точками и с векторами. + \en \name The functions of addition and multiplication of points with points and vectors. + \{ */ + /// \ru Приравнять координаты сумме координат точки и вектора. \en Equate coordinates to sum of point coordinates and vector coordinates. + /** + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2 - \ru Исходный вектор. + \en The initial vector. \~ + */ + MbCartPoint3D & SetAdd( const MbCartPoint3D & v1, const MbVector3D & v2 ); + /// \ru Приравнять координаты разности координат точки и вектора. \en Equate difference between the coordinates of point and vector to coordinates. + /** + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2 - \ru Исходный вектор. + \en The initial vector. \~ + */ + MbCartPoint3D & SetDec( const MbCartPoint3D & v1, const MbVector3D & v2 ); + /** + \brief \ru Приравнять координаты сумме координат точки и вектора. + \en Equate coordinates to sum of point coordinates and vector coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и вектора v2, умноженного на число t2. + \en Equate coordinates to sum of v1 point coordinates and v2 vector coordinates multiplied by t2. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2 - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] t2 - \ru Число, на которое умножаются координаты исходного вектора v2. + \en Factor the coordinates of the initial vector v2 are multiplied by. \~ + */ + MbCartPoint3D & Set( const MbCartPoint3D & v1, const MbVector3D & v2, double t2 ); + /** + \brief \ru Приравнять координаты сумме координат точки и двух векторов. + \en Equate coordinates to sum of point coordinates and two vectors coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и векторов v2 и v3, + умноженных на числа t2 и t3, соответственно. + \en Equate coordinates to sum of v1 point coordinates and v2 and v3 vectors coordinates + multiplied by the numbers t2 and t3 respectively. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t2, t3 - \ru Числа, на которые умножаются координаты векторов v2 и v3 соответственно. + \en Coordinates of v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbCartPoint3D & v1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ); + + /** + \brief \ru Приравнять координаты сумме компонент двух векторов. + \en Equate sum of the components of two vectors to coordinates. \~ + \details \ru Приравнять координаты сумме компонент векторов v1 и v2, умноженных на числа t1 и t2, соответственно. + \en Equate coordinates to sum of v1 and v2 vectors components multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты векторов v1 и v2 соответственно. + \en Coordinates of v1 and v2 vectors are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ); + /** + \brief \ru Приравнять координаты сумме компонент четырех векторов. + \en Equate coordinates to sum of the components of four vectors. \~ + \details \ru Приравнять координаты сумме компонент векторов v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Equate coordinates to sum of v1, v2, v3 and v4 vectors components + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты векторов v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 vectors are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ); + + /** + \brief \ru Приравнять координаты сумме координат двух точек. + \en Equate coordinates to sum of two points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1 и v2, умноженных на числа t1 и t2, соответственно. + \en Equate coordinates to sum of v1 and v2 points coordinates multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты точек v1 и v2 соответственно. + \en Coordinates of v1 and v2 points are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ); + /** + \brief \ru Приравнять координаты сумме координат трех точек. + \en Equate coordinates to sum of three points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Equate coordinates to sum of v1, v2 and v3 points coordinates + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты точек v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 points are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ); + /** + \brief \ru Приравнять координаты сумме координат четырех точек. + \en Equate coordinates to sum of four points coordinates. \~ + \details \ru Приравнять координаты сумме координат точек v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Equate coordinates to sum of v1, v2, v3 and v4 points coordinates + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты точек v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 points are multiplied by these numbers respectively. \~ + */ + MbCartPoint3D & Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ); + + /** + \brief \ru Увеличить координаты на значения компонент вектора. + \en Increase coordinates by values of vector components. \~ + \details \ru Увеличить координаты на значения компонент вектора v1, умноженных на число t1. + \en Increase coordinates by values of v1 vector components multiplied by t1. \~ + \param[in] v1 - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] t1 - \ru Число, на которое умножаются координаты исходного вектора v1. + \en Coordinates of the initial vector v1 are multiplied by this number. \~ + */ + void Add( const MbVector3D & v1, double t1 ); + /** + \brief \ru Увеличить координаты на значения компонент двух векторов. + \en Increase coordinates by values of two vectors components. \~ + \details \ru Увеличить координаты на значения компонент векторов v1 и v2, + умноженных на числа t1 и t2, соответственно. + \en Increase coordinates by values of v1 and v2 vectors components + multiplied by the numbers t1 and t2 respectively. \~ + \param[in] v1, v2 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2 - \ru Числа, на которые умножаются координаты векторов v1 и v2 соответственно. + \en Coordinates of v1 and v2 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ); + /** + \brief \ru Увеличить координаты на значения компонент трех векторов. + \en Increase coordinates by values of three vectors components. \~ + \details \ru Увеличить координаты на значения компонент векторов v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Increase coordinates by values of v1, v2 and v3 vectors components + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты векторов v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ); + /** + \brief \ru Увеличить координаты на значения компонент четырех векторов. + \en Increase coordinates by components values of four vectors. \~ + \details \ru Увеличить координаты на значения компонент векторов v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Increase coordinates by components values of vectors v1, v2, v3 and v4 + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные векторы. + \en The initial vectors. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты векторов v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 vectors are multiplied by these numbers respectively. \~ + */ + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ); + + /** + \brief \ru Увеличить координаты на значения координат точки. + \en Increase coordinates by values of point coordinates. \~ + \details \ru Увеличить координаты на значения координат точки v1, умноженных на число t1. + \en Increase coordinates by values of v1 point coordinates multiplied by t1. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] t1 - \ru Число, на которое умножаются координаты исходной точки v1. + \en Coordinates of the initial point v1 are multiplied by this number. \~ + */ + void Add( const MbCartPoint3D & v1, double t1 ); + /** + \brief \ru Увеличить координаты на значения координат трех точек. + \en Increase coordinates by values of three points coordinates. \~ + \details \ru Увеличить координаты на значения координат точек v1, v2 и v3, + умноженных на числа t1, t2 и t3, соответственно. + \en Increase coordinates by values of v1, v2 and v3 points coordinates + multiplied by the numbers t1, t2 and t3 respectively. \~ + \param[in] v1, v2, v3 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3 - \ru Числа, на которые умножаются координаты точек v1, v2 и v3 соответственно. + \en Coordinates of v1, v2 and v3 points are multiplied by these numbers respectively. \~ + */ + void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ); + /** + \brief \ru Увеличить координаты на значения координат четырех точек. + \en Increase coordinates by values of four points coordinates. \~ + \details \ru Увеличить координаты на значения координат точек v1, v2, v3 и v4, + умноженных на числа t1, t2, t3 и t4, соответственно. + \en Increase coordinates by values of v1, v2, v3 and v4 points coordinates + multiplied by the numbers t1, t2, t3 and t4 respectively. \~ + \param[in] v1, v2, v3, v4 - \ru Исходные точки. + \en Initial points. \~ + \param[in] t1, t2, t3, t4 - \ru Числа, на которые умножаются координаты точек v1, v2, v3 и v4 соответственно. + \en Coordinates of v1, v2, v3 and v4 points are multiplied by these numbers respectively. \~ + */ + void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ); + /** \} */ + + /// \ru Масштабировать координаты. \en Scale the coordinates. + /** + \param[in] sx, sy, sz - \ru Масштабирующие коэффициенты для компонент x, y и z соответственно. + \en Scale factors for x,y and z components respectively. \~ + */ + void Scale( double sx, double sy, double sz ) { x *= sx, y *= sy, z *= sz; } + /// \ru Масштабировать координаты. \en Scale the coordinates. + /** + \param[in] s - \ru Масштабирующий коэффициент. + \en A scale factor. \~ + */ + void Scale( double s ) { x *= s, y *= s, z *= s; } + double MaxFactor() const; ///< \ru Дать максимальную по модулю координату \en Get the maximum absolute coordinate + /** + \brief \ru Округлить с точностью до eps. + \en Rounded with eps tolerance. \~ + \details \ru Округляются координаты точки с заданное точностью. + \en Point coordinates are rounded with a given tolerance. \~ + \param[in] total - \ru Если true, то округлять в любом случае. + \en If true round anyway. \~ + \param[in] eps - \ru Точность округления. + \en A round-off tolerance. \~ + \return \ru true, если округление было выполнено. + \en Returns true if round-off has been done. \~ + */ + bool SetRoundedValue( bool total, double eps ); + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbCartPoint3D & other, double accuracy ) const; + /// \ru Является ли точка неопределенной? \en Is the point undefined? + bool IsUndefined() const { return (x == UNDEFINED_DBL || y == UNDEFINED_DBL || z == UNDEFINED_DBL); } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbCartPoint3D, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class + DECLARE_NEW_DELETE_CLASS( MbCartPoint3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbCartPoint3D ) +}; // MbCartPoint3D + + +//------------------------------------------------------------------------------ +/** + \details \ru Вычислить квадрат расстояния от точки до точки. + \en Calculate the squared distance from point to point. \~ + \param[in] to - \ru Точка. + \en A point. \~ + \return \ru Квадрат расстояния от точки до точки. + \en The squared distance between two points. \~ +*/ +// --- +inline double MbCartPoint3D::DistanceToPoint2( const MbCartPoint3D & to ) const { + double coordDiff[3] = { ( x - to.x ), ( y - to.y ), ( z - to.z ) }; + coordDiff[0] *= coordDiff[0]; + coordDiff[1] *= coordDiff[1]; + coordDiff[2] *= coordDiff[2]; + return coordDiff[0] + coordDiff[1] + coordDiff[2]; +} + + +//------------------------------------------------------------------------------ +// расстояние от точки до точки +// --- +inline double MbCartPoint3D::DistanceToPoint( const MbCartPoint3D & to ) const { + return ::sqrt( DistanceToPoint2(to) ); +} + + +//------------------------------------------------------------------------------ +/** + \details \ru Сдвиг по направлению точки to на расстояние, определяемое отношением величины ratio + к расстоянию между точками. + \en The translation in the direction of point "to" to the distance which is defined by the ratio of "ratio" and + the distance between points. \~ + \param[in] to - \ru Точка. + \en A point. \~ + \param[in] ratio - \ru Доля расстояния. + \en A distance part. \~ +*/ +// --- +inline void MbCartPoint3D::GoNearToPoint( const MbCartPoint3D & to, double ratio ) { + x += ( to.x - x ) * ratio; + y += ( to.y - y ) * ratio; + z += ( to.z - z ) * ratio; +} + + +//------------------------------------------------------------------------------ +/** + \details \ru Зеркальное отражение точки относительно плоскости с началом p0 и нормалью dir. + \en The specular reflection of a point relative to a plane with origin "p0" and normal "dir". \~ + \param[in] p0 - \ru Точка плоскости симметрии. + \en A point of plane of symmetry. \~ + \param[in] dir - \ru Направление нормали плоскости симметрии. + \en A direction of normal of plane of symmetry. \~ +*/ +// --- +inline void MbCartPoint3D::Mirror( const MbCartPoint3D & p0, const MbVector3D & dir ) { + MbVector3D ndir( dir ); + MbVector3D vect( p0, *this ); + ndir.Normalize(); + ndir *= 2*( vect * ndir ); + *this -= ndir; +// *this += 2 * ndir *( ( *this - p0 ) * ndir ) - *this; +} + + +//------------------------------------------------------------------------------ +/** + \details \ru Координата x (или y,z) точки инициализируется максимальным значением получаемым из сравнения + соответствующей координаты исходной точки и точки заданной в аргументе функции. + \en A coordinate x (or y, z) of a point is initialized by maximum value which is got from comparison of + corresponding coordinate of initial point and point given in function argument. \~ + \param[in] p - \ru Заданная точка. + \en A given point. \~ +*/ +// --- +inline void MbCartPoint3D::Maximum( const MbCartPoint3D & p ) { + x = std_max( x, p.x ); + y = std_max( y, p.y ); + z = std_max( z, p.z ); +} + + +//------------------------------------------------------------------------------ +/** + \details \ru Координата x (или y,z) точки инициализируется минимальным значением получаемым из сравнения + соответствующей координаты исходной точки и точки заданной в аргументе функции. + \en A coordinate x (or y, z) of a point is initialized by minimal value which is got from comparison of + corresponding coordinate of initial point and point given in function argument. \~ + \param[in] p - \ru Заданная точка. + \en A given point. \~ +*/ +// --- +inline void MbCartPoint3D::Minimum( const MbCartPoint3D & p ) { + x = std_min( x, p.x ); + y = std_min( y, p.y ); + z = std_min( z, p.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус \en The unary minus +// --- +inline MbCartPoint3D MbCartPoint3D::operator - () { + return MbCartPoint3D( -x, -y, -z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение точки и вектора \en Sum of a vector and a point +// --- +inline MbCartPoint3D MbCartPoint3D::operator + ( const MbVector3D & vector ) const { + return MbCartPoint3D( x + vector.x, y + vector.y, z + vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание вектора из точки \en The subtraction of a vector from a point +// --- +inline MbCartPoint3D MbCartPoint3D::operator - ( const MbVector3D & vector ) const { + return MbCartPoint3D( x - vector.x, y - vector.y, z - vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек \en Sum of two points +// --- +inline MbVector3D MbCartPoint3D::operator + ( const MbCartPoint3D & pnt ) const { + return MbVector3D( x + pnt.x, y + pnt.y, z + pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек \en The subtraction of two points +// --- +inline MbVector3D MbCartPoint3D::operator - ( const MbCartPoint3D & pnt ) const { + return MbVector3D ( x - pnt.x, y - pnt.y, z - pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек \en Sum of two points +// --- +inline void MbCartPoint3D::operator += ( const MbVector3D & with ) { + x += with.x; + y += with.y; + z += with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек \en The subtraction of two points +// --- +inline void MbCartPoint3D::operator -= ( const MbVector3D & with ) { + x -= with.x; + y -= with.y; + z -= with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек \en Sum of two points +// --- +inline void MbCartPoint3D::operator += ( const MbCartPoint3D & with ) { + x += with.x; + y += with.y; + z += with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек \en The subtraction of two points +// --- +inline void MbCartPoint3D::operator -= ( const MbCartPoint3D & with ) { + x -= with.x; + y -= with.y; + z -= with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение точки на число \en The multiplication of a point by a number +// --- +inline void MbCartPoint3D::operator *= ( double factor ) { + x *= factor; + y *= factor; + z *= factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление точки на число \en The division of a point by a number +// --- +inline void MbCartPoint3D::operator /= ( double factor ) { + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication + C3D_ASSERT( factor != 0.0 ); //-V550 + double invFactor = ( 1.0 / factor ); + x *= invFactor; + y *= invFactor; + z *= invFactor; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство. \en The check for equality. +// --- +inline bool MbCartPoint3D::operator == ( const MbCartPoint3D & with ) const +{ + double eps = Math::region; + bool res = ( ::fabs( x - with.x ) <= eps ) && + ( ::fabs( y - with.y ) <= eps ) && + ( ::fabs( z - with.z ) <= eps ); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство. \en The check for inequality. +// --- +inline bool MbCartPoint3D::operator != ( const MbCartPoint3D & with ) const { + return !( *this == with ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на меньше. \en The check for "less". +// --- +inline bool MbCartPoint3D::operator < ( const MbCartPoint3D & with ) const { + double eps = Math::region; + if ( (x - with.x) < -eps ) + return true; + double dx_abs = ::fabs(x - with.x); // \ru Исключаем повторные вызовы ::fabs (производительность). \en Avoid repeated calls of ::fabs (performance). + return ( (dx_abs <= eps) && ((y - with.y) < -eps) ) || + ( (dx_abs <= eps) && (::fabs(y - with.y) <= eps) && ((z - with.z) < -eps) ); + // double inaccuracy + // return ( x < with.x - eps ) || + // ( (::fabs(x - with.x) <= eps) && (y < with.y - eps) ) || + // ( (::fabs(x - with.x) <= eps) && (::fabs(y - with.y) <= eps) && (z < with.z - eps) ); + // //return ( x < with.x && y < with.y && z < with.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на больше. \en The check for "greater". +// --- +inline bool MbCartPoint3D::operator > ( const MbCartPoint3D & with ) const { + double eps = Math::region; + if ( (x - with.x) > eps ) + return true; + double dx_abs = ::fabs(x - with.x); // \ru Исключаем повторные вызовы ::fabs (производительность). \en Avoid repeated calls of ::fabs (performance). + return ( (dx_abs <= eps) && ((y - with.y) > eps) ) || + ( (dx_abs <= eps) && (::fabs(y - with.y) <= eps) && ((z - with.z) > eps) ); + // double inaccuracy + // return ( x > with.x + eps ) || + // ( (::fabs(x - with.x) <= eps) && (y > with.y + eps) ) || + // ( (::fabs(x - with.x) <= eps) && (::fabs(y - with.y) <= eps) && (z > with.z + eps) ); + // //return ( x > with.x && y > with.y && z > with.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений. \en Assignment of values to point. +// --- +inline MbCartPoint3D & MbCartPoint3D::operator = ( const MbCartPoint3D & v ) { + x = v.x; + y = v.y; + z = v.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений вектора. \en Assignment of vector values to point. +// --- +inline MbCartPoint3D & MbCartPoint3D::operator = ( const MbVector3D & v ) +{ + x = v.x; + y = v.y; + z = v.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Приравнять координаты сумме координат точки v1 и вектора v2. \en Equate coordinates to sum of point v1 and vector v2 coordinates. +// --- +inline MbCartPoint3D & MbCartPoint3D::SetAdd( const MbCartPoint3D & v1, const MbVector3D & v2 ) { + x = ( v1.x + v2.x ); + y = ( v1.y + v2.y ); + z = ( v1.z + v2.z ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::SetDec( const MbCartPoint3D & v1, const MbVector3D & v2 ) +{ + x = ( v1.x - v2.x ); + y = ( v1.y - v2.y ); + z = ( v1.z - v2.z ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbCartPoint3D & v1, const MbVector3D & v2, double t2 ) { + x = v1.x + v2.x * t2; + y = v1.y + v2.y * t2; + z = v1.z + v2.z * t2; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbCartPoint3D & v1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ) { + x = v1.x + v2.x * t2 + v3.x * t3; + y = v1.y + v2.y * t2 + v3.y * t3; + z = v1.z + v2.z * t2 + v3.z * t3; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; + z = v1.z * t1 + v2.z * t2 + v3.z * t3; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbCartPoint3D & MbCartPoint3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbVector3D &v1, double t1 ) { + x += v1.x * t1; + y += v1.y * t1; + z += v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ) { + x += v1.x * t1 + v2.x * t2; + y += v1.y * t1 + v2.y * t2; + z += v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; + z += v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z += v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbCartPoint3D & v1, double t1 ) { + x += v1.x * t1; + y += v1.y * t1; + z += v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; + z += v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление значений \en Values addition +// --- +inline void MbCartPoint3D::Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z += v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------- +// \ru Максимальная по модулю координата \en Maximum absolute coordinate +// --- +inline double MbCartPoint3D::MaxFactor() const { + double ax = ::fabs( x ); + double ay = ::fabs( y ); + double az = ::fabs( z ); + return ( ((ax > ay) && (ax > az)) ? ax : ((ay > az) ? ay : az) ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector3D::Set( const MbCartPoint3D & v1, double t1 ) { + x = v1.x * t1; + y = v1.y * t1; + z = v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; + z = v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbVector3D::Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ) { + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить координаты на значения координат точки v1, умноженных на число t1. \en Increase coordinates by values of v1 point coordinates multiplied by t1. +// --- +inline void MbVector3D::Add( const MbCartPoint3D & v1, double t1 ) { + x += v1.x * t1; + y += v1.y * t1; + z += v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить координаты на значения координат точек v1 и v2, умноженных на числа t1 и t2, соответственно. \en Increase coordinates by values of v1 and v2 points coordinates multiplied by t1 and t2 respectively. +// --- +inline void MbVector3D::Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ) { + x += v1.x * t1 + v2.x * t2; + y += v1.y * t1 + v2.y * t2; + z += v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить координаты на значения координат точек v1, v2 и v3, умноженных на числа t1, t2 и t3, соответственно. \en Increase coordinates by values of v1, v2 and v3 points coordinates multiplied by t1, t2 and t3 respectively. +// --- +inline void MbVector3D::Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; + z += v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить координаты на значения координат точек v1, v2, v3 и v4, умноженных на числа t1, t2, t3 и t4, соответственно. \en Increase coordinates by values of v1, v2, v3 and v4 points coordinates multiplied by t1, t2, t3 and t4 respectively. +// --- +inline void MbVector3D::Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ) { + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z += v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация вектора по двум точкам. \en The initialization of a vector by two points. +// --- +inline void MbVector3D::Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ) { + x = p2.x - p1.x; + y = p2.y - p1.y; + z = p2.z - p1.z; +} + + +//------------------------------------------------------------------------------ +/// \ru Умножение точки на число. \en The multiplication of a point by a number. +/** + \param[in] pnt - \ru Точка. + \en A point. \~ + \param[in] factor - \ru Число. + \en A number. \~ + \return \ru Точку, умноженную на число. + \en Returns a point multiplied by a number. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +inline MbCartPoint3D operator * ( const MbCartPoint3D & pnt, double factor ) { + return MbCartPoint3D( pnt.x * factor, pnt.y * factor, pnt.z * factor ); +} + + +//------------------------------------------------------------------------------ +/// \ru Деление точки на число. \en The division of a point by a number. +/** + \param[in] pnt - \ru Точка. + \en A point. \~ + \param[in] factor - \ru Число. + \en A number. \~ + \return \ru Точку, разделенную на число. + \en Returns a point divided by a number. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +inline MbCartPoint3D operator / ( const MbCartPoint3D & pnt, double factor ) { + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication + C3D_ASSERT( factor != 0.0 ); //-V550 + double invFactor = ( 1.0 / factor ); + return MbCartPoint3D( pnt.x * invFactor, pnt.y * invFactor, pnt.z * invFactor ); +} + + +//------------------------------------------------------------------------------ +/// \ru Умножение координат точки на число. \en The multiplication of point coordinates by a number. +/** + \param[in] factor - \ru Число. + \en A number. \~ + \param[in] pnt - \ru Точка. + \en A point. \~ + \return \ru Точка с увеличенными в число раз координатами. + \en A point with coordinates multiplied by factor. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +inline MbCartPoint3D operator * ( double factor, const MbCartPoint3D & pnt ) { + return MbCartPoint3D( pnt.x * factor, pnt.y * factor, pnt.z * factor ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbCartPoint3D::IsSame( const MbCartPoint3D & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(z - other.z) < accuracy) ); +} + + +#endif // __MB_CART_POINT3D_H diff --git a/C3d/Include/mb_class_traits.h b/C3d/Include/mb_class_traits.h new file mode 100644 index 0000000..a3494dd --- /dev/null +++ b/C3d/Include/mb_class_traits.h @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file \brief \ru Характеристики типов для математических классов ядра "Mb..." + \en Type traits of the math basic classes of the kernel "Mb..." \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_CLASS_TRAITS_H +#define __MB_CLASS_TRAITS_H + +#include +#include +#include + + +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbArc; +class MATH_CLASS MbNurbs; +class MATH_CLASS MbLine; +class MATH_CLASS MbPlaneInstance; +class MATH_CLASS MbSpaceInstance; +class MATH_CLASS MbAssembly; +class MATH_CLASS MbInstance; +class MbSolid; +class MATH_CLASS MbWireFrame; +class MATH_CLASS MbMesh; +class MATH_CLASS MbLineSegment3D; +class MATH_CLASS MbArc3D; +class MATH_CLASS MbFace; +class MATH_CLASS MbEdge; +class MATH_CLASS MbVertex; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Характеристики классов геометрического ядра C3D. + \en Class traits of C3D geometric kernel. + \attention \ru Экспериментальный класс. Пока приведены не все типы классов. + \en Experimental class. While not all listed types of classes. \~ +*/ +//--- +template +struct MbClassTraits +{ +private: + // \ru Идентификатор класса математического ядра. \en Identifier of class of the geometric kernel. + static const MbeSpaceType typeId = st_Undefined; +}; + +/* + 2D-curve sub-classes. +*/ +template<> +struct MbClassTraits { static const MbePlaneType typeId = pt_LineSegment; }; +template<> +struct MbClassTraits { static const MbePlaneType typeId = pt_Arc; }; +template<> +struct MbClassTraits { static const MbePlaneType typeId = pt_Nurbs; }; +template<> +struct MbClassTraits { static const MbePlaneType typeId = pt_Line; }; +/* + C3D model sub-classes. Inherited from MbItem. +*/ +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_PlaneInstance; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_SpaceInstance; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_Assembly; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_Instance; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_Solid; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_WireFrame; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_Mesh; }; +/* + 3D-curve sub-classes. +*/ +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_LineSegment3D; }; +template<> +struct MbClassTraits { static const MbeSpaceType typeId = st_Arc3D; }; + +/* + Topology sub-classes. +*/ +template<> +struct MbClassTraits { static const MbeTopologyType typeId = tt_Face; }; +template<> +struct MbClassTraits { static const MbeTopologyType typeId = tt_Edge; }; +template<> +struct MbClassTraits { static const MbeTopologyType typeId = tt_Vertex; }; + +//---------------------------------------------------------------------------------------- +// \ru Статическое приведение из типа к (разадресация типа) \en Static cast from type to +//--- +template struct Deref { private: typedef _Type Type; }; +template struct Deref { typedef _Type Type; }; +template struct Deref<_Type*> { typedef _Type Type; }; +template struct Deref<_Type&> { typedef _Type Type; }; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Динамическое приведение типа, основанное на функции Derived::IsA(). + \en Dynamic type cast based on the function Derived::IsA(). +*/ +//--- +template< class DerivedPtr, class ParentType > +DerivedPtr isa_cast ( ParentType * obj ) +{ + if ( (obj != NULL) && obj->IsA() == MbClassTraits::Type>::typeId ) + { + return static_cast( obj ); + } + return static_cast( NULL ); +} + +//---------------------------------------------------------------------------------------- +// +//--- +template< class DerivedPtr, class ParentPtr > +DerivedPtr _IsaCast( ParentPtr * obj, const MbTopItem * tItem ) +{ + if ( (obj != tItem) && obj->RefType() == rt_TopItem ) + { + tItem = static_cast( obj ); + } + return isa_cast( tItem ); +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Динамическое приведение типа, основанное на функции Derived::IsA(). + \en Dynamic type cast based on the function Derived::IsA(). +*/ +//--- +template< class DerivedPtr > +DerivedPtr isa_cast ( const MbRefItem * obj ) +{ + DerivedPtr resPtr = NULL; + return _IsaCast( obj, resPtr ); +} + +#endif // __MB_CLASS_TRAITS_H + +// eof \ No newline at end of file diff --git a/C3d/Include/mb_cross_point.h b/C3d/Include/mb_cross_point.h new file mode 100644 index 0000000..bedf5de --- /dev/null +++ b/C3d/Include/mb_cross_point.h @@ -0,0 +1,249 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Точка на кривой. Точка пересечения двух кривых. + \en Point on a curve. Intersection point of two curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_CROSS_POINT_H +#define __MB_CROSS_POINT_H + + +#include +#include + + +class MATH_CLASS MbCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Точка на кривой. + \en Point on a curve. \~ + \details \ru Точка на кривой, представленная в виде указателя на кривую и параметра точки на кривой.\n + \en Point on a curve is represented as a pointer to the curve and a parameter of a point on the curve.\n \~ + \ingroup Point_Modeling +*/ +// --- +template +class MbPointOnCurve { +public : + double t; ///< \ru Параметрическая координата точки на кривой. \en Parametric coordinate of a point on a curve. + const Curve * curve; ///< \ru Указатель на кривую. \en Pointer to the curve. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPointOnCurve(); + /// \ru Конструктор по параметру и кривой. \en Constructor by a parameter and a curve. + MbPointOnCurve( double initT, const Curve * initC ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPointOnCurve( const MbPointOnCurve & other ); + /// \ru Деструктор. \en Destructor. + ~MbPointOnCurve(); +public: + /// \ru Инициализировать точку по параметру и кривой. \en Initialize a point by a parameter and a curve. + void Init( double initT, const Curve * initC ); + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const MbPointOnCurve & other ); +}; + + +//------------------------------------------------------------------------------ +// \ru Конструктор по умолчанию. \en Default constructor. +// --- +template +MbPointOnCurve::MbPointOnCurve() + : t ( 0.0 ) + , curve( NULL ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор по параметру и кривой. \en Constructor by a parameter and a curve. +// --- +template +MbPointOnCurve::MbPointOnCurve( double initT, const Curve * initC ) + : t ( initT ) + , curve( initC ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор по копирования. \en Copy-constructor. +// --- +template +MbPointOnCurve::MbPointOnCurve( const MbPointOnCurve & other ) + : t ( other.t ) + , curve( other.curve ) +{} + + +//------------------------------------------------------------------------------ +// \ru Деструктор \en Destructor +// --- +template +MbPointOnCurve::~MbPointOnCurve() +{} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать точку по параметру и кривой. \en Initialize a point by a parameter and a curve. +// --- +template +void MbPointOnCurve::Init( double initT, const Curve * initC ) +{ + t = initT; + curve = initC; +} + + +//------------------------------------------------------------------------------ +// \ru Оператор присваивания. \en Assignment operator. +// --- +template +void MbPointOnCurve::operator = ( const MbPointOnCurve & other ) +{ + t = other.t; + curve = other.curve; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Точка пересечения двух кривых. + \en Intersection point of two curves. \~ + \details \ru Точка пересечения двух кривых, состоящая из двумерной точки пересечения, + ее параметрических координат на пересекающихся кривых и типа пересечения (простое пересечение или касание). \n + \en Intersection point of two curves consisting of a two-dimensional intersection point, + its parametric coordinates on intersecting curves and type of intersection (simple intersection or tangent intersection). \n \~ + \ingroup Point_Modeling +*/ +// --- +class MATH_CLASS MbCrossPoint { +public : + MbCartPoint p; ///< \ru Двумерные координаты точки пересечения двух кривых. \en Two-dimensional coordinates of intersection points of two curves. + MbPointOnCurve on1; ///< \ru Параметрическая координата точки на первой кривой. \en Parametric coordinate of point on the first curve. + MbPointOnCurve on2; ///< \ru Параметрическая координата точки на второй кривой. \en Parametric coordinate of a point on the second curve. + MbeIntersectionType form; ///< \ru Тип точки пересечения (ipt_Simple - нормальное пересечение, ipt_Tangent - касание). \en Type of intersection point (ipt_Simple - simple intersection, ipt_Tangent - tangent). +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbCrossPoint() + : p() + , on1() + , on2() + , form( ipt_Simple ) + {} + /// \ru Конструктор по точке пересечения и ее параметрическим координатам на каждой кривой. \en Constructor by intersection point and its parametric coordinates on each curve. + MbCrossPoint( const MbCartPoint & pnt, const MbPointOnCurve & pOn1, const MbPointOnCurve & pOn2 ) + : p( pnt ) + , on1( pOn1 ) + , on2( pOn2 ) + , form( ipt_Simple ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbCrossPoint( const MbCrossPoint & other ) + : p( other.p ) + , on1( other.on1 ) + , on2( other.on2 ) + , form( other.form ) + {} + /// \ru Деструктор. \en Destructor. + ~MbCrossPoint() + {} +public: + /// \ru Поменять местами кривые с параметрами. \en Swap curves with parameters. + void Swap(); + /// \ru Иницализировать точку по двумерной точке пересечения и параметрам пересечения. \en Initialize a point by a two-dimensional intersection point and parameters of intersection. + void Init( const MbCartPoint & pnt, const MbPointOnCurve & pOn1, const MbPointOnCurve & pOn2 ); + + /// \ru Установить тип пересечения. \en Set type of intersection. + void SetFormType( MbeIntersectionType iType ); + /// \ru Получить тип пересечения. \en Get type of intersection. + MbeIntersectionType GetFormType() const; + + /// \ru Является точка пересечения касанием. \en Whether the intersection point is a tangent intersection. + bool IsTangent() const; + /// \ru Оператор сравнения. \en Comparison operator. + bool operator == ( const MbCrossPoint & ) const; + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const MbCrossPoint & other ); + +}; // MbCrossPoint + + +//------------------------------------------------------------------------------ +// \ru Поменять параметры точки пересечения \en Swap parameters of the intersection point. +// --- +inline void MbCrossPoint::Swap() +{ + double tTmp = on1.t; + on1.t = on2.t; + on2.t = tTmp; + + const MbCurve * swap = on1.curve; + on1.curve = on2.curve; + on2.curve = swap; +} + + +//------------------------------------------------------------------------------ +// \ru Иницализировать точку по двумерной точке пересечения и параметрам пересечения. \en Initialize a point by a two-dimensional intersection point and parameters of intersection. +// --- +inline void MbCrossPoint::Init( const MbCartPoint & pnt, const MbPointOnCurve & pOn1, const MbPointOnCurve & pOn2 ) +{ + p = pnt; + on1 = pOn1; + on2 = pOn2; + form = ipt_Simple; +} + + +//------------------------------------------------------------------------------ +// \ru Установить тип пересечения. \en Set type of intersection. +// --- +inline void MbCrossPoint::SetFormType( MbeIntersectionType iType ) { + form = iType; +} + + +//------------------------------------------------------------------------------ +// \ru Получить тип пересечения. \en Get type of intersection. +// --- +inline MbeIntersectionType MbCrossPoint::GetFormType() const { + return form; +} + + +//------------------------------------------------------------------------------ +// \ru Является точка пересечения касанием. \en Whether the intersection point is a tangent intersection. +// --- +inline bool MbCrossPoint::IsTangent() const { + return (form == ipt_Tangent); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор сравнения. \en Comparison operator. +// --- +inline bool MbCrossPoint::operator == ( const MbCrossPoint & point ) const +{ + return ( ::fabs(p.x - point.p.x) < Math::LengthEps && + ::fabs(p.y - point.p.y) < Math::LengthEps && + ::fabs(on1.t - point.on1.t) < Math::paramEpsilon && + ::fabs(on2.t - point.on2.t) < Math::paramEpsilon); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор присваивания. \en Assignment operator. +// --- +inline void MbCrossPoint::operator = ( const MbCrossPoint & other ) +{ + p = other.p; + on1 = other.on1; + on2 = other.on2; + form = other.form; +} + + +#endif // __MB_CROSS_POINT_H diff --git a/C3d/Include/mb_cube.h b/C3d/Include/mb_cube.h new file mode 100644 index 0000000..8ea6017 --- /dev/null +++ b/C3d/Include/mb_cube.h @@ -0,0 +1,836 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Габаритный куб геометрического объекта. + \en The bounding box (cube) of a geometric object. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_CUBE_H +#define __MB_CUBE_H + + +#include +#include +#include + + +#define CUBE_CONTROL_POINTS_COUNT 26 ///< \ru Количество характерных точек куба. \en The number of control points of cube. +#define CUBE_VERTEX_COUNT 8 ///< \ru Количество вершин куба. \en The number of cube vertices. +#define CUBE_EDGES_COUNT 12 ///< \ru Количество рёбер куба. \en The number of cube edges. +#define CUBE_FACES_COUNT 6 ///< \ru Количество граней куба. \en The number of cube faces. + + +class MATH_CLASS MbRect; +class MATH_CLASS MbCube; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; + +namespace c3d // namespace C3D +{ + typedef std::pair CubePtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index. + typedef std::pair ConstCubePtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index. + typedef std::vector CubesPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices. + typedef std::vector ConstCubesPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices. + typedef std::vector CubesVector; ///< \ru Вектор габаритных кубов. \en Vector of bounding boxes. +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Габаритный параллелепипед. + \en The bounding box. \~ + \details \ru Габаритный параллелепипед - это область 3D-пространства, ограниченная + прямым параллелепипедом, грани которого параллельным плоскостям системы координат.\n + Используется для быстрой оценки близости или непересечения трёхмерных объектов, + содержащихся в параллелепипеде. Габаритный параллелепипед описывается парой точек, + расположенных на главной диагонали куба. + \en The bounding box is a domain (block) of 3D-space bounded by parallelepiped + with edges parallel to the axes of coordinate system.\n + It is used for quick estimation of the proximity or non-intersection of three-dimensional objects, + which are contained in the "cube". Faces of "cube" are parallel to planes of coordinate system. + The bounding box is described by a pair of points which are located on the main diagonal of a box. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbCube { +public : + MbCartPoint3D pmin; ///< \ru Точка диагонали параллелепипеда с минимальными координатами. \en A point of a box diagonal with minimal coordinates. + MbCartPoint3D pmax; ///< \ru Точка диагонали параллелепипеда с максимальными координатами. \en A point of a box diagonal with maximal coordinates. + +public : + /// \ru Пустой конструктор \en The empty constructor + MbCube() { SetEmpty(); } + /// \ru Конструктор копирования. \en Copy constructor. + MbCube( const MbCube & init ) : pmin( init.pmin ), pmax( init.pmax ) {} + /// \ru Конструктор по координатам \en The constructor by coordinates + /** + \param[in] xmin, ymin, zmin - \ru Координаты точки угла куба с минимальными координатами. + \en Coordinates of a box corner point with minimal coordinates. \~ + \param[in] xmax, ymax, zmax - \ru Координаты точки угла куба с максимальными координатами. + \en Coordinates of a box corner point with maximal coordinates. \~ + \param[in] normalize - \ru Нормализовать себя. + \en Normalize itself. \~ + */ + MbCube( double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, bool normalize = false ) : pmin( xmin, ymin, zmin ), pmax( xmax, ymax, zmax ) { if ( normalize ) Normalize(); } + /// \ru Конструктор по двум точкам. \en The constructor by two points. + /** + \param[in] p0 - \ru Точка угла куба с минимальными координатами. + \en A point of a box corner with minimal coordinates. \~ + \param[in] p1 - \ru Точка угла куба с максимальными координатами. + \en A point of a box corner with maximal coordinates. \~ + \param[in] normalize - \ru Нормализовать себя. + \en Normalize itself. \~ + */ + MbCube( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize = false ) : pmin( p0 ), pmax( p1 ) { if ( normalize ) Normalize(); } + + /** + \brief \ru Проверка на пустоту. \en The check for emptiness. + \details \ru Габаритный параллелепипед считается пустым, если он не содержит ни одной точки 3D-пространства. + \en A bounding box is empty if it doesn't contain any points of 3D-space \~ + */ + bool IsEmpty() const; + /// \ru Установить пустым ("вывернутым"). \en Set empty ("reverted"). + void SetEmpty(); + + /// \ru Инициализировать по координатам. \en Initialize by coordinates. + /** + \param[in] xmin, ymin, zmin - \ru Координаты точки угла куба с минимальными координатами. + \en Coordinates of a box corner point with minimal coordinates. \~ + \param[in] xmax, ymax, zmax - \ru Координаты точки угла куба с максимальными координатами. + \en Coordinates of a box corner point with maximal coordinates. \~ + \param[in] normalize - \ru Нормализовать себя. + \en Normalize itself. \~ + */ + void Set( double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax, + bool normalize = false ); + /// \ru Инициализировать по двум точкам. \en Initialize by two points. + /** + \param[in] p0 - \ru Точка угла куба с минимальными координатами. + \en A point of a box corner with minimal coordinates. \~ + \param[in] p1 - \ru Точка угла куба с максимальными координатами. + \en A point of a box corner with maximal coordinates. \~ + \param[in] normalize - \ru Нормализовать себя. + \en Normalize itself. \~ + */ + void Set( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize = false ); + + /** + \ru \name Функции доступа к полям + \en \name Functions for access to fields. + \{ */ + /// \ru Установить минимальную координату по X. \en Set the minimal coordinate by X. + void SetXMin( double s ) { pmin.x = s; } + /// \ru Установить минимальную координату по Y. \en Set the minimal coordinate by Y. + void SetYMin( double s ) { pmin.y = s; } + /// \ru Установить минимальную координату по Z. \en Set the minimal coordinate by Z. + void SetZMin( double s ) { pmin.z = s; } + /// \ru Установить максимальную координату по X. \en Set the maximal coordinate by X. + void SetXMax( double s ) { pmax.x = s; } + /// \ru Установить максимальную координату по Y. \en Set the maximal coordinate by Y. + void SetYMax( double s ) { pmax.y = s; } + /// \ru Установить максимальную координату по Z. \en Set the maximal coordinate by Z. + void SetZMax( double s ) { pmax.z = s; } + + /// \ru Дать минимальную координату по X. \en Give the minimal coordinate by X. + double GetXMin() const { return pmin.x; } + /// \ru Дать минимальную координату по Y. \en Give the minimal coordinate by Y. + double GetYMin() const { return pmin.y; } + /// \ru Дать минимальную координату по Z. \en Give the minimal coordinate by Z. + double GetZMin() const { return pmin.z; } + /// \ru Дать максимальную координату по X. \en Give the maximal coordinate by X. + double GetXMax() const { return pmax.x; } + /// \ru Дать максимальную координату по Y. \en Give the maximal coordinate by Y. + double GetYMax() const { return pmax.y; } + /// \ru Дать максимальную координату по Z. \en Give the maximal coordinate by Z. + double GetZMax() const { return pmax.z; } + /** \} */ + + /// \ru Инициализировать по другому габариту. \en Initialize by another bounding box. + void Init( const MbCube & init ) { Set( init.pmin, init.pmax, false ); } + /** + \brief \ru Инициализировать по двум точкам. + \en Initialize by two points. \~ + \details \ru Инициализированный куб нормализуется. + \en Initialized box is normalized. \~ + \param[in] p0 - \ru Точка угла куба с минимальными координатами. + \en A point of a box corner with minimal coordinates. \~ + \param[in] p1 - \ru Точка угла куба с максимальными координатами. + \en A point of a box corner with maximal coordinates. \~ + */ + void Init( const MbCartPoint3D & p0, const MbCartPoint3D & p1 ) { Set( p0, p1, true ); } + /** + \brief \ru Добавить габарит. + \en Add bounding box. \~ + \details \ru Габарит добавляется в локальной системе координат исходного куба. + \en A bounding box is added in the local coordinate system of the initial box. \~ + \param[in] r - \ru Габарит. + \en A bounding box. \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + */ + void AddRect( const MbRect & r, const MbPlacement3D & place ); + /** + \brief \ru Проекция на плейсмент. + \en A projection onto the placement. \~ + \details \ru Вычисляет прямоугольник, охватывающий проекцию куба на плейсмент. + \en Calculates a rectangle covering a projection of box onto the placement. \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[out] rect - \ru Прямоугольник, охватывающий искомую проекцию. + \en A rectangle covering a required projection. \~ + */ + void ProjectionRect( const MbPlacement3D & place, MbRect & rect ) const; + + /** + \ru \name Перегрузка логических операций. + \en \name Overload of logical operations. + \{ */ + /// \ru Присвоить значение. \en Assign a value. + void operator = ( const MbCube & ); + /// \ru Включить в себя точку. \en Enclose a point. + template + MbCube & operator |= ( const Point & ); + /// \ru Включить в себя габаритный куб. \en Enclose a bounding box. + MbCube & operator |= ( const MbCube & ); + /// \ru Оператор равенства. \en The equality operator. + bool operator == ( const MbCube & ) const; + /// \ru Оператор неравенства. \en The inequality operator. + bool operator != ( const MbCube & ) const; + /** \} */ + + /// \ru Нормализовать себя. \en Normalize itself. + void Normalize (); + + /** + \brief \ru Определить положение куба относительно плоскости. + \en Define the box position relative to the plane. \~ + \details \ru Определить положение куба относительно плоскости XY локальной системы координат, направление оси Z локальной системы координат при этом не учитывается. + \en Define the box position relative to the plane XY of a local coordinate system, the Z axis of the local coordinate system is not taken into account here. \~ + \param[in] pl - \ru Локальная система координат, задающая плоскость. + \en A local coordinate system which defines a plane. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru iloc_OnItem - куб пересекает плоскость XY локальной системы координат,\n + iloc_InItem - куб расположен над плоскостью XY локальной системы координат,\n + iloc_OutOfItem - куб расположен под плоскостью XY локальной системы координат. + \en Iloc_OnItem - box intersects the XY plane of a local coordinate system,\n + iloc_InItem - box is located over the XY plane of a local coordinate system,\n + iloc_OutOfItem - box is located under the XY plane of a local coordinate system. \~ + */ + MbeItemLocation GetLocation( const MbPlacement3D & pl, double eps ) const; + + /** + \brief \ru Определить положение куба относительно трубы. + \en Define the box position relative to the tube. \~ + \details \ru Определить, расположен ли куб внутри трубы прямоугольного сечения, + заданного прямоугольником в плоскости XY локальной системы координат. + \en Determine whether the box is inside the tube of rectangular section, + given by a rectangle in the XY plane of a local coordinate system. \~ + \param[in] place - \ru Локальная система координат, в в плоскости XY которой лежит сечение трубы. + \en A local coordinate system in the XY plane of which a tube section is located. \~ + \param[in] rect - \ru Прямоугольник, задающая сечение трубы. + \en A rectangle which defines a tube section. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если куб расположен внутри трубы. + \en Returns true if the box is inside the tube. \~ + */ + bool InsideLocation( const MbPlacement3D & place, MbRect & rect, double eps ) const; + + /// \ru Включить в себя точку, заданную как XYZ. \en Enclose a point specified as XYZ. + /** + \param[in] x, y, z - \ru Координаты точки, которую требуется включить в габарит. + \en Coordinates of a point which has to be included in the box. \~ + */ + void Include( double x, double y, double z ); + + /// \ru Включить в себя точку. \en Enclose a point. + template + void Include( const Point & ); + + /** + \ru \name Булевы операции куба с точкой, линией, плоскостью и другим кубом. + \en \name The boolean operations of a box with a point, line, plane and another box. + \{ */ + + + /// \ru Проверить, лежит ли точка внутри габаритного параллелепипеда. \en Check whether a point is inside the box or not. + /** + \return \ru true, если лежит. + \en Returns true if it is inside. \~ + */ + template + bool Contains( const Point & ) const; + + /// \ru Проверить, лежит ли точка внутри габаритного параллелепипеда. \en Check whether a point is inside the box or not. + /** + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если лежит. + \en Returns true if it is inside. \~ + */ + template + bool Contains( const Point &, double eps ) const; + + /// \ru Проверить, содержит ли один параллелепипед другой. \en Check whether a box is inside another box or not. + /** + \return \ru true, если данный габаритный параллелепипед содержит другой. + \en Returns true if a box contains another. \~ + */ + bool Contains( const MbCube & ) const; + + /// \ru Пересекается ли габаритный параллелепипед с другим параллелепипедом. \en Whether the box intersects another box or not. + /** + \param[in] other - \ru Другой параллелепипед. + \en Another box. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересекается. + \en Returns true if it intersects. \~ + */ + bool Intersect( const MbCube & other, double eps = (c3d::MIN_RADIUS + c3d::MIN_RADIUS) ) const; + + /// \ru Пересекается ли куб с плоскостью XY локальной системы координат. \en Whether the box intersects the XY plane of a local coordinate system or not. + /** + \param[in] pl - \ru Плейсмент, задающий плоскость. + \en A placement which defines a plane. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересекается. + \en Returns true if it intersects. \~ + */ + bool Intersect( const MbPlacement3D & pl, double eps = c3d::MIN_RADIUS ) const; + + /** + \brief \ru Пересекается ли куб с линией. + \en Whether the box intersects the line or not. \~ + \details \ru Линия задается точкой и вектором. + \en A line is given by a point and vector. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересекается. + \en Returns true if it intersects. \~ + */ + bool Intersect( const MbCartPoint3D &, const MbVector3D &, double eps = Math::metricRegion ) const; + + /// \ru Найти пересечение прямой с "поверхностью" куба. \en Find an intersection of a line with the box "surface". + /** + \param[in] p - \ru Точка на прямой. + \en The point on the line. \~ + \param[in] axis - \ru Вектор, задающий направление прямой. + \en A vector which defines the direction of the line. \~ + \param[out] param - \ru Точки пересечения. + \en Intersection points. \~ + \param[in] delta - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересечение есть, \n false в противном случае. + \en Returns true if intersection exists, \n false otherwise. \~ + */ + bool Intersect( const MbCartPoint3D & p, const MbVector3D & axis, + SArray & param, double delta = Math::metricRegion ) const; + + /// \ru Пересечение куба и окружности. \en The intersection of the box with a circle. + /** + \param[in] placement - \ru Плейсмент окружности. + \en A circle placement. \~ + \param[in] radius - \ru Радиус окружности. + \en The circle radius. \~ + \param[out] param - \ru Точки пересечения. + \en Intersection points. \~ + \param[in] delta - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересечение есть, \n false в противном случае. + \en Returns true if intersection exists, \n false otherwise. \~ + */ + bool Intersect( const MbPlacement3D & placement, double radius, + SArray & param, double delta = Math::metricRegion ) const; + + /// \ru Куб пересечения двух кубов. \en A box of intersection of two boxes. + /** + \param[in] cube1, cube2 - \ru Исходные кубы. + \en Input boxes. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru true, если пересечение есть, \n false в противном случае. + \en Returns true if intersection exists, \n false otherwise. \~ + */ + bool Intersection( const MbCube & cube1, const MbCube & cube2, double eps = c3d::MIN_RADIUS ); + + /// \ru Куб объединения двух кубов. \en A box of union of two boxes. + /** + \param[in] cube1, cube2 - \ru Исходные кубы. + \en Input boxes. \~ + \return \ru false, если итоговый куб пуст, \n true в противном случае. + \en Returns false if the result box is empty, \n true otherwise. \~ + */ + bool Union ( const MbCube & cube1, const MbCube & cube2 ); + /** \} */ + + /// \ru Дать объем куба. \en Give the volume of a box. + double GetVolume ( double eps = Math::metricRegion ) const; + /// \ru Дать половину площади граней куба. \en Give half of the area of the cube faces. + double GetSquare ( double eps = Math::metricRegion ) const; + /// \ru Дать размер стороны X куба. \en Give the size of the X side of a box. + double GetLengthX() const { return pmax.x - pmin.x; } + /// \ru Дать размер стороны Y куба. \en Give the size of the Y side of a box. + double GetLengthY() const { return pmax.y - pmin.y; } + /// \ru Дать размер стороны Z куба. \en Give the size of the Z side of a box. + double GetLengthZ() const { return pmax.z - pmin.z; } + /// \ru Дать размер диагонали куба. \en Give the size of box diagonal. + double GetDiagonal() const; + + /** \brief \ru Вычислить расстояние до ближайшей грани габаритного суба. + \en Calculate the distance to the nearest boundary of the bounding box. \~ + \details \ru Найденное расстояние до ближайшей границы имеет отрицательное значение, если точка находится внутри, и положительное - если снаружи. + \en The calculated distance is negative if the point is inside, and is positive if it is outside. \~ + \param[in] point - \ru Исследуемая точка. + \en The investigated point. \~ + \return \ru Возвращает расстояние до границы. + \en Returns the distance to the boundary. \~ + */ + double DistanceToPoint( const MbCartPoint3D & point ) const; + + /** \brief \ru Вычислить расстояние до куба. + \en Calculate the distance to the cube. \~ + \details \ru Возвращается ноль если кубы пересекаются или один содержится в другом. + \en It returns zero if the cubes intersect or one is contained in the other. \~ + \param[in] cube - \ru Другой куб. + \en Other cube. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \return \ru Возвращает расстояние до границы. + \en Returns the distance to the boundary. \~ + */ + double DistanceToCube( const MbCube & cube, double eps = Math::metricRegion ) const; + + /// \ru Расширить куб во все стороны на величину delta. \en Expand the box in all directions on a "delta" amount. + void Enlarge ( double delta ); + /// \ru Расширить куб во все стороны на соответствующую величину. \en Expand the box in all directions on a corresponding amount. + void Enlarge ( double dx, double dy, double dz ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move ( const MbVector3D & to ); + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Transform( const MbMatrix3D & matrix ); + /// \ru Масштабировать. \en Scale. + void Scale ( double sx, double sy, double sz ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbCube & other, double accuracy ) const; + + /// \ru Количество координат точки. \en The number of point coordinates. + static size_t GetDimension() { return 3; } + /// \ru Доступ к минимальной координате по индексу. \en Access to a coordinate by an index. + double GetMin( size_t k ) const { return k ? (--k ? pmin.z : pmin.y) : pmin.x; } + /// \ru Доступ к максимальной координате по индексу. \en Access to a coordinate by an index. + double GetMax( size_t k ) const { return k ? (--k ? pmax.z : pmax.y) : pmax.x; } + + /// \ru Дать себя. \en Give itself. + const MbCube & GetCube() const { return *this; } + + // \ru Общая нумерация характерных точек куба: \en General numeration of box control points: + // \ru 0-7 вершины, 8-19 середины рёбер, 20-25 центры граней \en 0-7 vertices, 8-19 middles of edges, 20-25 centers of faces + // Z + // | + // 4------15------7 + // /| /| + // 12| 25 14| + // / 16 20 / 19 + // 5---+--13------6 | + // | 22| | 23| + // | 0------11--+---3 - Y + // 17 / 21 18 / + // | 8 24 | 10 + // |/ |/ + // 1-------9------2 + // / + // X + // \ru Выдать характерные точки куба \en Give control points of the box + /// \ru Количество вершин. \en Number of vertices. + size_t GetVerticesCount() const { return 8; } + /// \ru Выдать вершину куба по индексу. \en Get a box vertex by an index. + /** + \param[in] index - \ru Исходный индекс. 0 <= index <= 7. + \en An initial index. 0 <= index <= 7. \~ + \param[out] p - \ru Искомая вершина. + \en Required vertex. \~ + */ + void GetVertex( ptrdiff_t index, MbCartPoint3D & p ) const; + /// \ru Выдать центр ребра по индексу. \en Give the center of an edge by an index. + /** + \param[in] index - \ru Исходный индекс. 0 <= index <= 12 (общий номер минус CUBE_VERTEX_COUNT). + \en An initial index. 0 <= index <= 12 ("general number" minus CUBE_VERTEX_COUNT). \~ + \param[out] p - \ru Координаты центра ребра. + \en Coordinates of an edge center. \~ + */ + void GetEdgeCentre( ptrdiff_t index, MbCartPoint3D & p ) const; + /// \ru Выдать центр грани по индексу. \en Give the center of a face by an index. + /** + \param[in] index - \ru Исходный индекс. 0 <= index <= 5 (общий номер минус CUBE_VERTEX_COUNT минус CUBE_EDGES_COUNT). + \en An initial index. 0 <= index <= 5 ("general number" minus CUBE_VERTEX_COUNT minus CUBE_EDGES_COUNT). \~ + \param[out] p - \ru Координаты центра ребра. + \en Coordinates of an edge center. \~ + */ + void GetFaceCentre( ptrdiff_t index, MbCartPoint3D & p ) const; + /// \ru Выдать центр куба. \en Give the box center. + void GetCentre( MbCartPoint3D & p ) const { p.Set( pmax, 0.5, pmin, 0.5 ); } + /// \ru Выдать центр куба. \en Give the box center. + void GetCenter( MbCartPoint3D & p ) const { p.Set( pmax, 0.5, pmin, 0.5 ); } + /// \ru Центр габарита. \en The center of bounding box. + MbCartPoint3D Centre() const; + + /** + \brief \ru Дать характерную точку куба по ее номеру. + \en Give a box control point by its number. \~ + \details \ru Общая нумерация характерных точек куба: 0-7 вершины, 8-19 середины рёбер, 20-25 центры граней. + \en General numeration of box control points: 0-7 vertices, 8-19 middles of edges, 20-25 centers of faces. \~ + \param[in] pIndex - \ru Номер характерных точек. + \en A number of control points. \~ + \param[out] p - \ru Координаты характерной точки. + \en Coordinates of control point. \~ + \return \ru false, если куб пуст или индекс принимает недопустимое значение, \n true в противном случае. + \en Returns false if the box is empty or the index has an invalid value, \n true otherwise. \~ + */ + bool GetControlPoint( size_t pIndex, MbCartPoint3D & p ) const; + /** + \brief \ru Выдать все характерные точки куба. + \en Give all control points of the box. \~ + \details \ru Все характерные точки куба: 8 вершин, 12 середин рёбер, 6 центров граней. + \en All control points of the box: 8 vertices, 12 middles of edges, 6 centers of faces. \~ + \param[out] points - \ru Характерные точки. + \en Control points. \~ + \return \ru Число характерных точек. Ноль, если куб пуст. + \en The number of control points. Null if the box is empty. \~ + */ + size_t GetControlPoints( SArray & points ) const; + /// \ru Выдать номер ближайшей характерной точки куба. \en Give the number of the nearest control point of the box. + /** + \param[in] p - \ru Исходная точка, к которой ищется ближайшая характерная точка куба. + \en An initial point for which the nearest control point of the box is searched. \~ + \return \ru Номер точки. + \en A number of a point. \~ + */ + size_t GetNearestControlIndex( const MbCartPoint3D & p ) const; + /** + \brief \ru Дать номер противолежащей точки. + \en Give the number of the opposite point. \~ + \details \ru Для точки куба с номером index дать номер противолежащей точки, + которая может использоваться в качестве фиксированной. + \en For a box point with the "index" number give the number of the opposite point, + which can be used as fixed. \~ + \param[in] index - \ru Номер исходной точки. + \en The number of the initial point. \~ + \return \ru Номер противолежащей точки. + \en A number of the opposite point. \~ + */ + size_t GetFixedControlIndex ( size_t index ) const; + /** + \brief \ru Рассчитать матрицу деформации. + \en Calculate a deformation matrix. \~ + \details \ru Матрица деформации рассчитывается по-новому положению point характерной точки куба с индексом pIndex. + \en A deformation matrix is calculated according to the new position of box control point "point" with the index "pIndex". \~ + \param[in] pIndex - \ru Номер смещаемой точки (0-7 вершины, 8-19 середины рёбер, 20-25 центры граней). + \en A number of a moved point (0-7 vertices, 8-19 middles of edges, 20-25 centers of faces). \~ + \param[in] point - \ru Точка, с которой нужно совместить точку куба с номером pIndex. + \en A point with which the box point with the "pIndex" number has to be joined. \~ + \param[in] fixedPoint - \ru Неподвижная точка преобразования, используется, если useFixed = true. + \en A fixed point. It is used if useFixed = true. \~ + \param[in] useFixed - \ru Использовать неподвижную точку (true), если useFixed = false, то неподвижной будет противолежащая точка куба. + \en Use a fixed point (true); if useFixed = false, then the opposite point of the box will be fixed. \~ + \param[in] isotropy - \ru Одинаковые масштабы по осям (true), масштабы, пропорциональны проекциям смещения рассматриваемой точки на стороны куба (false) + \en The same scales of the axes (true); the scales are proportional to the shift projections of the considered point on the sides of the box (false) \~ + \param[out] matrix - \ru Рассчитанная матрица преобразования. + \en Calculated transformation matrix. \~ + \return \ru true, если искомая матрица была найдена. + \en Returns true if the matrix was found. \~ + */ + bool CalculateMatrix( size_t pIndex, const MbCartPoint3D & point, const MbCartPoint3D & fixedPoint, + bool useFixed, bool isotropy, MbMatrix3D & matrix ) const; + public: + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbCube ) + DECLARE_NEW_DELETE_CLASS( MbCube ) + DECLARE_NEW_DELETE_CLASS_EX( MbCube ) +}; + + +//------------------------------------------------------------------------------ +// \ru Центр габарита \en The center of bounding box +//--- +inline MbCartPoint3D MbCube::Centre() const +{ + return MbCartPoint3D().Set( pmax, 0.5, pmin, 0.5 ); +} + + +//------------------------------------------------------------------------------ +// \ru Установить пустым ("вывернутым") \en Set empty ("reverted") +// --- +inline void MbCube::SetEmpty() +{ + pmin.x = pmin.y = pmin.z = MB_MAXDOUBLE; + pmax.x = pmax.y = pmax.z = -MB_MAXDOUBLE; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на пустоту \en The check for emptiness. +// --- +inline bool MbCube::IsEmpty() const { + return ( pmin.x > pmax.x ) || ( pmin.y > pmax.y ) || ( pmin.z > pmax.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Установить значения куба \en Set a box values. +// --- +inline void MbCube::Set( double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax, + bool normalize ) +{ + if ( normalize ) { + pmin.x = std_min( xmin, xmax ); + pmin.y = std_min( ymin, ymax ); + pmin.z = std_min( zmin, zmax ); + pmax.x = std_max( xmin, xmax ); + pmax.y = std_max( ymin, ymax ); + pmax.z = std_max( zmin, zmax ); + } + else { + pmin.x = xmin; + pmin.y = ymin; + pmin.z = zmin; + pmax.x = xmax; + pmax.y = ymax; + pmax.z = zmax; + } +} + + +//------------------------------------------------------------------------------ +// \ru Установить значения куба \en Set a box values. +// --- +inline void MbCube::Set( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize ) +{ + if ( normalize ) { + pmin.x = std_min( p0.x, p1.x ); + pmin.y = std_min( p0.y, p1.y ); + pmin.z = std_min( p0.z, p1.z ); + pmax.x = std_max( p0.x, p1.x ); + pmax.y = std_max( p0.y, p1.y ); + pmax.z = std_max( p0.z, p1.z ); + } + else { + pmin = p0; + pmax = p1; + } +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение \en Assignment +// --- +inline void MbCube::operator = ( const MbCube & other ) { + pmin = other.pmin; + pmax = other.pmax; +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку \en Enclose a point. +// --- +template +inline MbCube & MbCube::operator |= ( const Point & p ) +{ + pmin.x = std_min( pmin.x, (double)p.x ); + pmin.y = std_min( pmin.y, (double)p.y ); + pmin.z = std_min( pmin.z, (double)p.z ); + pmax.x = std_max( pmax.x, (double)p.x ); + pmax.y = std_max( pmax.y, (double)p.y ); + pmax.z = std_max( pmax.z, (double)p.z ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку,заданную как XYZ \en Enclose a point specified as XYZ. +// --- +inline void MbCube::Include( double x, double y, double z ) +{ + pmin.x = std_min( pmin.x, x ); + pmin.y = std_min( pmin.y, y ); + pmin.z = std_min( pmin.z, z ); + pmax.x = std_max( pmax.x, x ); + pmax.y = std_max( pmax.y, y ); + pmax.z = std_max( pmax.z, z ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку \en Enclose a point +//--- +template +inline void MbCube::Include( const Point & pnt ) { + Include( pnt.x, pnt.y, pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя габаритный куб \en Enclose a bounding box. +// --- +inline MbCube & MbCube::operator |= ( const MbCube & other ) +{ + pmin.x = std_min( pmin.x, other.pmin.x ); + pmin.y = std_min( pmin.y, other.pmin.y ); + pmin.z = std_min( pmin.z, other.pmin.z ); + pmax.x = std_max( pmax.x, other.pmax.x ); + pmax.y = std_max( pmax.y, other.pmax.y ); + pmax.z = std_max( pmax.z, other.pmax.z ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка равенства с другим габаритом. \en The check for equality with another box. +// --- +inline bool MbCube::operator == ( const MbCube & other ) const +{ + return c3d::EqualPoints( pmin, other.pmin, Math::lengthEpsilon ) && + c3d::EqualPoints( pmax, other.pmax, Math::lengthEpsilon ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка неравенства с другим кубом. \en The check for inequality with another box. +// --- +inline bool MbCube::operator != ( const MbCube & other) const { + return !( other == *this ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная точка лежит внутри куба \en Check whether a given point is inside the box or not +// --- +template +inline bool MbCube::Contains( const Point & p ) const +{ + return ( ( (double)p.x >= pmin.x ) && ( (double)p.x <= pmax.x ) && + ( (double)p.y >= pmin.y ) && ( (double)p.y <= pmax.y ) && + ( (double)p.z >= pmin.z ) && ( (double)p.z <= pmax.z ) ); +} + +//------------------------------------------------------------------------------- +// \ru Проверка на то, что заданная точка лежит внутри габарита. \en Check whether a given point is inside the box or not. +// --- +template +inline bool MbCube::Contains( const Point & p, double eps ) const +{ + return ( ((double)p.x > (pmin.x - eps)) && ((double)p.x < (pmax.x + eps)) && + ((double)p.y > (pmin.y - eps)) && ((double)p.y < (pmax.y + eps)) && + ((double)p.z > (pmin.z - eps)) && ((double)p.z < (pmax.z + eps)) ); +} + + +//------------------------------------------------------------------------------ +/// \ru Проверить, содержит ли один параллелепипед другой. \en Check whether a box is inside another box or not. +//--- +inline bool MbCube::Contains( const MbCube & box ) const +{ + return Contains( box.pmin ) && Contains( box.pmax ); +} + + +//------------------------------------------------------------------------------ +// \ru Нормализовать себя \en Normalize itself +// --- +inline void MbCube::Normalize() +{ + double tmp; + if ( pmin.x > pmax.x ) + { tmp = pmin.x; pmin.x = pmax.x; pmax.x = tmp; } + if ( pmin.y > pmax.y ) + { tmp = pmin.y; pmin.y = pmax.y; pmax.y = tmp; } + if ( pmin.z > pmax.z ) + { tmp = pmin.z; pmin.z = pmax.z; pmax.z = tmp; } +} + + +//------------------------------------------------------------------------------ +// \ru Расширить куб во все стороны \en Expand the box in all directions +// --- +inline void MbCube::Enlarge( double delta ) +{ + pmin.x -= delta; + pmin.y -= delta; + pmin.z -= delta; + + pmax.x += delta; + pmax.y += delta; + pmax.z += delta; +} + + +//------------------------------------------------------------------------------ +// \ru Расширить куб во все стороны. \en Expand the box in all directions +// --- +inline void MbCube::Enlarge( double dx, double dy, double dz ) +{ + pmin.x -= dx; + pmin.y -= dy; + pmin.z -= dz; + + pmax.x += dx; + pmax.y += dy; + pmax.z += dz; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг \en Translation +// --- +inline void MbCube::Move( const MbVector3D & to ) +{ + if ( !IsEmpty() ) { + pmin.Move( to ); + pmax.Move( to ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Расстояние до точки \en The distance to a point +// --- +inline double MbCube::DistanceToPoint( const MbCartPoint3D & pnt ) const +{ + double dx = std_max( pmin.x - pnt.x, pnt.x - pmax.x ); + double dy = std_max( pmin.y - pnt.y, pnt.y - pmax.y ); + double dz = std_max( pmin.z - pnt.z, pnt.z - pmax.z ); + double dd = std_max( dx, dy ); + return std_max( dd, dz ); +} + + +//------------------------------------------------------------------------------ +/// \ru Чтение куба из потока \en Reading of the box from a stream +// --- +inline reader & CALL_DECLARATION operator >> ( reader & in, MbCube & obj ) +{ + in >> obj.pmin; + in >> obj.pmax; + return in; +} + + +//------------------------------------------------------------------------------ +/// \ru Запись куба в поток \en Writing of the box into the stream +// --- +inline writer & CALL_DECLARATION operator << ( writer & out, const MbCube & obj ) +{ + out << obj.pmin; + out << obj.pmax; + return out; +} + + +#endif // __MB_CUBE_H diff --git a/C3d/Include/mb_data.h b/C3d/Include/mb_data.h new file mode 100644 index 0000000..0a98e72 --- /dev/null +++ b/C3d/Include/mb_data.h @@ -0,0 +1,557 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Данные. + \en Data. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_DATA_H +#define __MB_DATA_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для вычисления шага. + \en Data for step calculation. \~ + \details \ru Данные для вычисления шага при триангуляции поверхностей и граней. \n + \en Data for step calculation during face triangulation. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbStepData { + +private: + /** \brief \ru Способ вычисления приращения параметра при движении по объекту. + \en The method of calculation of parameter increment by the object. \~ + \details \ru Способ вычисления приращения параметра при движении по кривой или поверхности. + Для визуализации геометрической формы используется способ ist_SpaceStep. \n + Для операций построения используется способ ist_DeviationStep. \n + Для 3D принтеров используется способ ist_MetricStep и могут быть добавлены первые два. \n + Для привязки объектов к параметрам поверхности следует добавить способ ist_ParamStep, + Для определения столкновений элементов модели используется способ ist_CollisionStep, + Для вычисления инерционных характеристик используется способ ist_MipStep. + \en Methods of calculation of parameter increment by the object. \n \~ + Step by sag ist_SpaceStep is used for visualizations. + Step by deviation angle ist_DeviationStep is used for calculation. + Step by length ist_MetricStep is used for 3D printer (plus by sag and by deviation angle). \n + Special step ist_ParamStep is added for binding with surface parameters. + Special step ist_CollisionStep is used for collision detection of model elements. + Special step ist_MipStep is used for calculation of inertial characteristics. \~ + */ + uint8 stepType; + double sag; ///< \ru Максимально допустимый прогиб кривой или поверхности в соседних точках на расстоянии шага. \en The maximum permissible sag of the curve or surface at adjacent points away step. \~ + double angle; ///< \ru Максимально допустимое угловое отклонение касательных кривой или нормалей поверхности в соседних точках на расстоянии шага. \en The maximum angular deviation of the curve or surface normal in the neighboring points on the distance of a step. \~ + double length; ///< \ru Максимально допустимое расстояние между соседними точками на расстоянии шага. \en The maximum distance between points a step away. \~ + size_t maxCount; ///< \ru Максимальное количество ячеек в строке и ряду триангуляционной сетки (если 0, то не задано). \en Maximum count of cell in row and column for triangulation grid (if 0, then unlimited). \~ + +public: + + /// \ru Конструктор с заданным типом шага. \en Constructor by step type. + MbStepData( MbeStepType t, double s ); + /// \ru Пустой конструктор. \en Empty constructor. + MbStepData() + : stepType( ist_SpaceStep ) + , sag ( Math::visualSag ) + , angle ( Math::deviateSag ) + , length ( MAXIMON ) + , maxCount( 0 ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbStepData( const MbStepData & other ) + : stepType( other.stepType ) + , sag ( other.sag ) + , angle ( other.angle ) + , length ( other.length ) + , maxCount( other.maxCount ) + {} + /// \ru Деструктор. \en Destructor. + ~MbStepData() {} + +public: + /// \ru Установить способ вычисления шага. \en Set the method of calculation of parameter increment by the object. \~ + void SetStepType( MbeStepType t, bool add = true ) { if ( add ) { stepType |= t; } else { stepType = (uint8)t; } } + /// \ru Установить максимально допустимый прогиб на расстоянии шага. \en Set the maximum permissible sag at adjacent points away step. \~ + void SetSag ( double s ) { sag = s; } + /// \ru Установить максимально допустимое угловое отклонение в соседних точках. \en Set the maximum angular deviation in the neighboring points on the distance of a step. \~ + void SetAngle ( double a ) { angle = a; } + /// \ru Установить максимально допустимое расстояние между соседними точками на расстоянии шага. \en Set the maximum distance between points a step away. \~ + void SetLength ( double l ) { length = l; } + /// \ru Установить максимально допустимое количество ячеек в строке или ряду триангуляционной сетки. \en Set the maximum count of cell in row and column for triangulation grid. \~ + void SetMaxCount( size_t c ) { maxCount = c; } + + /// \ru Дать максимально допустимый прогиб на расстоянии шага. \en Get the maximum permissible sag at adjacent points away step. \~ + double GetSag () const { return sag; } + /// \ru Дать максимально допустимое угловое отклонение в соседних точках. \en Get the maximum angular deviation in the neighboring points on the distance of a step. \~ + double GetAngle () const { return angle; } + /// \ru Дать максимально допустимое расстояние между соседними точками на расстоянии шага. \en Get the maximum distance between points a step away. \~ + double GetLength () const { return length; } + /// \ru Дать максимально допустимое количество ячеек в строке или ряду триангуляционной сетки. \en Get the maximum count of cell in row and column for triangulation grid. \~ + size_t GetMaxCount() const { return maxCount; } + + /// \ru Указанный шаг задан. \en This step is set. + bool StepIs( MbeStepType sType ) const { return !!(stepType & sType); } + + /// \ru Задан шаг по максимальному прогибу. \en Step by maximum deflection defined. \~ + bool SagIncluded() const { return //!!(stepType & ist_ParamStep) || + !!(stepType & ist_SpaceStep) || + !!(stepType & ist_CollisionStep); } + /// \ru Задан шаг по угловому отклонению. \en Step by angular deviation defined. \~ + bool AngleIncluded() const { return !!(stepType & ist_DeviationStep) || + !!(stepType & ist_MipStep); } + /// \ru Задан шаг по максимальному расстоянию. \en Step by maximum distance defined. \~ + bool LengthIncluded() const { return !!(stepType & ist_MetricStep); } + + /// \ru Установить данные для вычисления шага при триангуляции. \en Set data for step calculation during triangulation. + void Init( MbeStepType t, double s, double a, double l, size_t c = 0 ) + { + stepType = (uint8)t; + sag = s; + angle = a; + length = l; + maxCount = c; +} + + /// \ru Установить данные для вычисления шага при триангуляции. \en Set data for step calculation during triangulation. + void InitStepBySag( double s ) + { + stepType = (uint8)ist_SpaceStep; + sag = ::fabs(s); + angle = Math::deviateSag; + length = MAXIMON; + maxCount = 0; + } + + /// \ru Функция копирования данных. \en Copy function of data. + void Init( const MbStepData & other ) + { + stepType = other.stepType; + sag = other.sag; + angle = other.angle; + length = other.length; + maxCount = other.maxCount; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbStepData & operator = ( const MbStepData & other ) + { + stepType = other.stepType; + sag = other.sag; + angle = other.angle; + length = other.length; + maxCount = other.maxCount; + return *this; + } + + /// \ru Сбросить данные для вычисления шага. \en Reset data for step calculation. + void Reset() + { + stepType = (uint8)ist_SpaceStep; + sag = Math::visualSag; + angle = Math::deviateSag; + length = MAXIMON; + maxCount = 0; + } + + /// \ru Функция сравнения. \en Equal function. + bool IsEqual( const MbStepData & other, double epsilon ) const; + /// \ru Вырожденный ли объект? \en Is empty? + bool IsEmpty( double epsilon ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbStepData, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \details \ru Дополнительные данные для построения полигонального объекта и триангуляции поверхностей и граней. \n + \en Way for polygonal object constructing or face triangulation. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbFormNote { + +private: + bool exact; ///< \ru Выполнить построение полигональных объектов на числах double (true) на числах float (false). \en Polygonal objects will created on double data (true) on float data (false). + bool wire; ///< \ru Строить изолинии поверхностей. \en Construct isolines of surfaces. \~ + bool grid; ///< \ru Строить триангуляцию поверхностей. \en Construct triangulations of surfaces. \~ + bool seam; ///< \ru Дублировать точки триангуляции на швах (true) замкнутых поверхностей, не дублировать точки триангуляции на швах (false). \en Flag for not ignore the seam edges. \~ + bool quad; ///< \ru Строить четырёхугольники (true) при триангуляции поверхностей (по возможности). \en Build quadrangles (true) in triangulations of surfaces (if possible). \~ + +public: + + /// \ru Пустой конструктор. \en Empty constructor. + MbFormNote() + : exact( false ) + , wire( false ) + , grid( true ) + , seam( true ) + , quad( false ) + {} + /// \ru Конструктор с заданным типом шага. \en Constructor by step type. + MbFormNote( bool w, bool g, bool s = true, bool e = false, bool q = false ) + : exact( e ) + , wire( w ) + , grid( g ) + , seam( s ) + , quad( q ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbFormNote( const MbFormNote & other ) + : exact( other.exact ) + , wire( other.wire ) + , grid( other.grid ) + , seam( other.seam ) + , quad( other.quad ) + {} + /// \ru Деструктор. \en Destructor. + ~MbFormNote() {} + +public: + /// \ru Выполнить построение полигональных объектов на числах double (true) на числах float (false). \en Polygonal objects will created on double data (true) on float data (false). + void SetExact( bool e ) { exact = e; } + /// \ru Установить флаг построения изолиний поверхностей. \en Set flag construction isolines of surfaces. \~ + void SetWire( bool w ) { wire = w; } + /// \ru Установить флаг cтроить триангуляцию поверхностей. \en Set flag constructing triangulations of surfaces. \~ + void SetGrid( bool g ) { grid = g; } + /// \ru Установить флаг шовных ребер. \en Set flag for seam edges. \~ + void SetSeam( bool s ) { seam = s; } + /// \ru Установить флаг cтроить четырёхугольники при триангуляции поверхностей (по возможности).. \en Set flag for build quadrangles in triangulations of surfaces (if possible). \~ + void SetQuad( bool q ) { quad = q; } + + /// \ru Выполнить построение полигональных объектов на числах double (true) на числах float (false). \en Polygonal objects will created on double data (true) on float data (false). + bool DoExact() const { return exact; } + /// \ru Дать флаг построения изолиний поверхностей. \en Whether to construct isolines of surfaces? \~ + bool Wire() const { return wire;} + /// \ru Cтроить триангуляцию поверхностей? \en Whether to construct triangulations of surfaces? \~ + bool Grid() const { return grid; } + /// \ru Дублировать точки триангуляции на швах? \en Get flag for seam edges. \~ + bool Seam() const { return seam; } + /// \ru Строить четырёхугольники при триангуляции поверхностей (по возможности).? \en Whether to build quadrangles in triangulations of surfaces (if possible)? \~ + bool Quad() const { return quad; } + + /// \ru Установить Данные для вычисления шага при триангуляции. \en Set data for step calculation during triangulation. + void Init( bool w, bool g, bool s, bool e = false, bool q = false ) { + exact = e; + wire = w; + grid = g; + seam = s; + quad = q; + } + + /// \ru Функция копирования данных. \en Copy function of data. + void Init( const MbFormNote & other ) { + exact = other.exact; + wire = other.wire; + grid = other.grid; + seam = other.seam; + quad = other.quad; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbFormNote & operator = ( const MbFormNote & other ) { + exact = other.exact; + wire = other.wire; + grid = other.grid; + seam = other.seam; + quad = other.quad; + return *this; + } + + /// \ru Функция сравнения. \en Equal function. + bool IsEqual( const MbFormNote & other ) const; + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для управления двумерными объектами. + \en The data for two-dimensional object control. \~ + \details \ru Данные содержат контрольные точки двумерных объектов. \n + \en The data consist of two-dimensional control points for object. \n \~ +\ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbControlData { + +private: + SArray total; ///< \ru Точки, перемещаемые вместе. \en Points conveyed along. \~ + SArray share; ///< \ru Точки, перемещаемые по отдельности. \en Points transported separately. \~ + mutable size_t totalIndex; ///< \ru Индекс текущей точки total. \en The index of current point total. \~ + mutable size_t shareIndex; ///< \ru Индекс текущей точки share. \en The index of current point share. \~ + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbControlData() : total( 0, 1 ), share(0, 1), totalIndex( 0 ), shareIndex(0) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbControlData( const MbControlData & other ) + : total( other.total ) + , share( other.share ) + , totalIndex( other.totalIndex ) + , shareIndex( other.shareIndex ) + {} + /// \ru Деструктор. \en Destructor. + ~MbControlData() {} + +public: + /// \ru Зарезервировать память. \en Size reserve. \~ + void ReserveTotal( size_t c ) { total.Reserve( c ); } + /// \ru Зарезервировать память. \en Size reserve. \~ + void ReserveShare( size_t c ) { share.Reserve( c ); } + + /// \ru Добавить точку. \en Add a point conveyed along. \~ + void AddTotal( const MbCartPoint & p ) { total.push_back(p); } + /// \ru Добавить точки. \en Add points. \~ + template + void AddTotals( const PointsVector & points ) + { + size_t addCnt = points.size(); + if ( addCnt > 0 ) { + total.reserve( total.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) + total.push_back( points[k] ); + } + } + /// \ru Добавить точку. \en Add a point. \~ + void AddShare( const MbCartPoint & p ) { share.push_back(p); } + /// \ru Добавить точки. \en Add points. \~ + template + void AddShares( const PointsVector & points ) + { + size_t addCnt = points.size(); + if ( addCnt > 0 ) { + share.reserve( share.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) + share.push_back( points[k] ); + } + } + + /// \ru Выдать количество точек. \en Get points count conveyed along. \~ + size_t TotalCount() const { return total.Count(); } + /// \ru Выдать количество точек. \en Get points count. \~ + size_t ShareCount() const { return share.Count(); } + + /// \ru Обнулить индексы. \en Reset index. + void ResetIndex() const { totalIndex = 0; shareIndex = 0; } + + /// \ru Выдать очередную точку. \en Get current point for totalIndex++. + bool GetTotal( MbCartPoint & p ) const; + /// \ru Выдать очередную точку. \en Get current point for shareIndex++. + bool GetShare( MbCartPoint & p ) const; + /// \ru Выдать точку по индексу. \en Get point by index conveyed along. + bool GetTotal( size_t i, MbCartPoint & p ) const; + /// \ru Выдать точку по индексу. \en Get point by index. + bool GetShare( size_t i, MbCartPoint & p ) const; + /// \ru Выдать общее точек. \en Get all points count. \~ + size_t Count() const { return total.Count() + share.Count(); } + /// \ru Выдать точку по индексу. \en Get point by index conveyed along. + bool GetPoint( size_t i, MbCartPoint & p ) const; + /// \ru Установить точку по индексу. \en Set point by index conveyed along. + bool SetPoint( size_t i, MbCartPoint & p ); + /// \ru Выдать все точки. \en Get points. + SArray & SetTotalPoints() { return total; } + /// \ru Выдать все точки. \en Get points. + SArray & SetSharePoints() { return share; } + /// \ru Освободить память. \en Free memory. + void HardFlush() { total.HardFlush(); share.HardFlush(); totalIndex = 0; shareIndex = 0; } + + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Transform( const MbMatrix & matrix ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move( const MbVector & to ); + /// \ru Повернуть вокруг точки. \en Rotate around a point. + void Rotate( const MbCartPoint & point, double angle ); + + /// \ru Дать точку по индексу. \en Set point by index. + MbCartPoint & operator []( size_t i ) const; + /// \ru Оператор присваивания. \en Assignment operator. + MbControlData & operator = ( const MbControlData & other ) + { + total = other.total; + share = other.share; + totalIndex = other.totalIndex; + shareIndex = other.shareIndex; + return *this; + } + /// \ru Вырожденный ли объект? \en Is empty? + bool IsEmpty() const { return ( total.Count() == 0 && share.Count() == 0 ); } +}; // MbControlData + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для управления трехмерными объектами. + \en The data for three-dimensional object control. \~ + \details \ru Данные содержат контрольные точки трехмерных объектов. \n + \en The data consist of three-dimensional control points for object. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbControlData3D { + +private: + SArray total; ///< \ru Точки, перемещаемые вместе. \en Points conveyed along. \~ + SArray share; ///< \ru Точки, перемещаемые по отдельности. \en Points transported separately. \~ + mutable size_t totalIndex; ///< \ru Индекс текущей точки total. \en The index of current point total. \~ + mutable size_t shareIndex; ///< \ru Индекс текущей точки share. \en The index of current point share. \~ + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbControlData3D() : total( 0, 1 ), share(0, 1), totalIndex( 0 ), shareIndex(0) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbControlData3D( const MbControlData3D & other ) + : total( other.total ) + , share( other.share ) + , totalIndex( other.totalIndex ) + , shareIndex( other.shareIndex ) + {} + /// \ru Деструктор. \en Destructor. + ~MbControlData3D() {} + +public: + /// \ru Зарезервировать память. \en Size reserve. \~ + void ReserveTotal( size_t c ) { total.Reserve( c ); } + /// \ru Зарезервировать память. \en Size reserve. \~ + void ReserveShare( size_t c ) { share.Reserve( c ); } + + /// \ru Добавить точку. \en Add a point conveyed along. \~ + void AddTotal( const MbCartPoint3D & p ) { total.Add(p); } + /// \ru Добавить точки. \en Add points. \~ + template + void AddTotals( const PointsVector & points ) + { + size_t addCnt = points.size(); + if ( addCnt > 0 ) { + total.reserve( total.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) + total.push_back( points[k] ); + } + } + /// \ru Добавить точку. \en Add a point. \~ + void AddShare( const MbCartPoint3D & p ) { share.Add(p); } + /// \ru Добавить точки. \en Add points. \~ + template + void AddShares( const PointsVector & points ) + { + size_t addCnt = points.size(); + if ( addCnt > 0 ) { + share.reserve( share.size() + addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) + share.push_back( points[k] ); + } + } + /// \ru Выдать количество точек. \en Get points count conveyed along. \~ + size_t TotalCount() const { return total.Count(); } + /// \ru Выдать количество точек. \en Get points count. \~ + size_t ShareCount() const { return share.Count(); } + + /// \ru Обнулить индексы. \en Reset index. + void ResetIndex() const { totalIndex = 0; shareIndex = 0; } + /// \ru Выдать очередную точку. \en Get current point for totalIndex++. + bool GetTotal( MbCartPoint3D & p ) const; + /// \ru Выдать очередную точку. \en Get current point for shareIndex++. + bool GetShare( MbCartPoint3D & p ) const; + /// \ru Выдать точку по индексу. \en Get point by index conveyed along. + bool GetTotal( size_t i, MbCartPoint3D & p ) const; + /// \ru Выдать точку по индексу. \en Get point by index. + bool GetShare( size_t i, MbCartPoint3D & p ) const; + /// \ru Выдать общее точек. \en Get all points count. \~ + size_t Count() const { return total.Count() + share.Count(); } + /// \ru Выдать точку по индексу. \en Get point by index conveyed along. + bool GetPoint( size_t i, MbCartPoint3D & p ) const; + /// \ru Установить точку по индексу. \en Set point by index conveyed along. + bool SetPoint( size_t i, MbCartPoint3D & p ); + /// \ru Выдать все точки. \en Get points. + SArray & SetTotalPoints() { return total; } + /// \ru Выдать все точки. \en Get points. + SArray & SetSharePoints() { return share; } + /// \ru Освободить память. \en Free memory. + void HardFlush() { total.HardFlush(); share.HardFlush(); totalIndex = 0; shareIndex = 0; } + + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Transform( const MbMatrix3D & matrix ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move( const MbVector3D & to ); + /// \ru Повернуть вокруг оси. \en Rotate around an axis. + void Rotate( const MbAxis3D & axis, double angle ); + + /// \ru Дать точку по индексу. \en Set point by index. + MbCartPoint3D & operator []( size_t i ) const; + /// \ru Оператор присваивания. \en Assignment operator. + MbControlData3D & operator = ( const MbControlData3D & other ) + { + total = other.total; + share = other.share; + totalIndex = other.totalIndex; + shareIndex = other.shareIndex; + return *this; + } + /// \ru Вырожденный ли объект? \en Is empty? + bool IsEmpty() const { return ( total.Count() == 0 && share.Count() == 0 ); } +}; // MbControlData3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные управления построением гладких кривых на базе трехмерной ломаной. + \en The data for the construction of smooth curves based on a three-dimensional polyline. \~ + \details \ru Данные содержат параметры построения сплайнов с плавным изменением кривизны. \n + \en The data contains parameters for constructing splines with smooth curvature changes. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbFairCurveData { + +public: + int arrange; ///< \ru Перераспределение точек по контуру (0 - без перераспределения, 1 - с перераспределением). \en Redistribution of points (0 - without of distribution, 1 - with distribution) . \~ + int subdivision; ///< \ru Коэффициент уплотнения кривой (0 - без уплотнения, 1 - однократное уплотнение, 2 - двукратное уплотнение). \en Curve subdivision coefficient (0 - without subdivision, 1 - single subdivision, 2 - double subdivision). \~ + int accountCurvature; ///< \ru Учет кривизны в концевых точках (0 - не учитывать, 1 - в начальной точке, 2 - в конечной точке, 3 - учитывать оба конца). \en Accounting for curvature at end points (0 - do not take into account, 1 - at the starting point, 2 - at the ending point, 3 - take into account both ends). \~ + int accountInflexVector; ///< \ru Учет вектора в точке перегиба (0 - направление звена S-полигона, 1 - направление касательной). \en How to take into account the vector at the inflection point (0 - direction of segment of S-polygon, 1 - direction of tangent to curve). \~ + int approx; ///< \ru Метод аппроксимации (0 - B-сплайновая кривая по узловым точкам, 1 - изогеометрическая B-сплайновая кривая, 2 - изогеометрическая NURBzS кривая). \en Approx method (0 - B-spline curve on nodes, 1 - isogeometric B-spline curve, 2 - isogeometric NURBzS curve). \~ + int degreeBSpline; ///< \ru Степень B-сплайновой кривой m (3<=m<=10). \en The degree m (3<=m<=10) of B-Spline curve. \~ + int outFormat; ///< \ru Выходной формат сплайна (2 - S-полигон, 3 - GB-полигон). \en Output format of spline (2 - S-polygon, 3 - GB-polygon). \~ + int nSegments; ///< \ru Количество сегментов сплайна. \en Number of segments of spline. \~ + int numSegment; ///< \ru Номер сегмента. \en Number of segment. \~ + double tParam; ///< \ru Внутренний параметр точки сегмента сплайна. \en Point internal param on segment of spline. \~ + int warning; ///< \ru Предупреждение о работе. \en The operation warning. \~ + int error; ///< \ru Ошибка о работе. \en The operation error. \~ + double clothoidRMin; ///< \ru Радиус кривизны на конце начального участка клотоиды. \en Curvature radius on end of initial part of Clothoid. \~ + double clothoidLMax; ///< \ru Максимальная длина начального участка клотоиды. \en Max length of initial part of Clothoid. \~ + int clothoidSegms; ///< \ru Количество сегментов аппроксимирующей клотоиду кривой. \en Number of segments of curve approximated the Clothoid. \~ + + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbFairCurveData() {} + + ~MbFairCurveData() {} + + /// \ru Оператор присваивания. \en Assignment operator. + MbFairCurveData & operator = ( const MbFairCurveData & other ) + { + arrange = other.arrange; + subdivision = other.subdivision; + accountCurvature = other.accountCurvature; + accountInflexVector = other.accountInflexVector; + approx = other.approx; + degreeBSpline = other.degreeBSpline; + outFormat = other.outFormat; + nSegments = other.nSegments; + numSegment = other.numSegment; + tParam = other.tParam;; + warning = other.warning; + error = other.error; + clothoidRMin = other.clothoidRMin; + clothoidLMax = other.clothoidLMax; + clothoidSegms = other.clothoidSegms; + return *this; + } +}; // MbFairCurveData + + +#endif // __MB_DATA_H diff --git a/C3d/Include/mb_dimension.h b/C3d/Include/mb_dimension.h new file mode 100644 index 0000000..f48fa9c --- /dev/null +++ b/C3d/Include/mb_dimension.h @@ -0,0 +1,276 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение размеров. + \en Dimensions definition. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_DIMENSION_H +#define __MB_DIMENSION_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Размер. + \en Dimension. \~ + \details \ru Общий класс размеров.\n + \en Common class of dimensions.\n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbDimension : public MbLegend { +public: + /// \ru Конструктор. \en Constructor + MbDimension(); + + /// \ru Деструктор. \en Destructor. + virtual ~MbDimension(); + +protected: + MbDimension( const MbDimension & ); ///< \ru Конструктор копирования. \en Copy-constructor. + +public: + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType Type() const; + virtual bool IsSimilar ( const MbSpaceItem & ) const; + +private: // \ru Не реализованные методы класса \en Non-implemented methods of class + void operator = ( const MbDimension & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS( MbDimension ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Линейный размер. + \en Linear dimension. \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbLinearDimension : public MbDimension { +private: + MbCartPoint3D base1; ///< \ru Первая точка привязки размера. \en First dimension anchor point. + MbCartPoint3D base2; ///< \ru Вторая точка привязки размера. \en Second dimension anchor point. + MbCartPoint3D startDimensionCurve; ///< \ru Точка начала размерной линии. \en Starting point of dimension line. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] base1 - \ru Первая точка привязки размера. + \en First dimension anchor point. \~ + \param[in] base2 - \ru Вторая точка привязки размера. + \en Second dimension anchor point. \~ + \param[in] startDimension - \ru Точка начала размерной линии. + \en Starting point of dimension line. \~ + */ + MbLinearDimension(const MbCartPoint3D& base1, const MbCartPoint3D& base2, const MbCartPoint3D& startDimensionCurve); + +protected: + MbLinearDimension(const MbLinearDimension& ); ///< \ru Конструктор копирования. \en Copy-constructor. + +public: + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; + virtual MbSpaceItem & Duplicate(MbRegDuplicate * = NULL) const; + virtual bool IsSame(const MbSpaceItem & /*other*/, double /*accuracy*/ = LENGTH_EPSILON) const; + virtual bool SetEqual(const MbSpaceItem &); + virtual void Transform(const MbMatrix3D &, MbRegTransform * = NULL); + virtual void Move(const MbVector3D &, MbRegTransform * = NULL); + virtual void Rotate(const MbAxis3D &, double, MbRegTransform * = NULL); + virtual double DistanceToPoint(const MbCartPoint3D &) const; + virtual void AddYourGabaritTo(MbCube &) const; + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + // \ru Тестовые функции геометрического объекта \en Test functions of a geometric object + virtual MbProperty & CreateProperty(MbePrompt /*n*/) const; // \ru Создать собственное свойство \en Create own property + virtual void GetProperties(MbProperties &); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties(const MbProperties &); // \ru Записать свойства объекта \en Set properties of object + +public: + /// \ru Инициализировать по двум точкам привязки и точке начала размерной линии. \en Initialize by two reference points and the starting point of the dimension line. + void Init(const MbCartPoint3D& base1, const MbCartPoint3D& base2, const MbCartPoint3D& startDimensionCurve); + + /// \ru Получить первую точку привязки размера. \en Get the first dimension snap point. + MbCartPoint3D GetBasePoint1() const { return base1; } + void SetBasePoint1(const MbCartPoint3D& val) { base1 = val; } + + /// \ru Получить вторую точку привязки размера. \en Get the second dimension snap point. + MbCartPoint3D GetBasePoint2() const { return base2; } + void SetBasePoint2(const MbCartPoint3D& val) { base2 = val; } + + /// \ru Получить первую точку привязки размера. \en Get the first dimension snap point. + MbCartPoint3D GetStartDimensionCurvePoint() const { return startDimensionCurve; } + void SetStartDimensionCurvePoint(const MbCartPoint3D& val) { startDimensionCurve = val; } + +private: // \ru Не реализованные методы класса \en Non-implemented methods of class + void operator = ( const MbLinearDimension & ); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS(MbLinearDimension) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Угловой размер. + \en Angular dimension. \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbAngularDimension : public MbDimension { +private: + MbCartPoint3D base1; ///< \ru Первая точка привязки размера. \en First dimension anchor point. + MbCartPoint3D base2; ///< \ru Вторая точка привязки размера. \en Second dimension anchor point. + MbCartPoint3D center; ///< \ru Точка центра. \en Center point. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] base1 - \ru Первая точка привязки размера. + \en First dimension anchor point. \~ + \param[in] center - \ru Точка центра. + \en Center point. \~ + \param[in] base2 - \ru Вторая точка привязки размера. + \en Second dimension anchor point. \~ + */ + MbAngularDimension(const MbCartPoint3D& center, const MbCartPoint3D& base1, const MbCartPoint3D& base2); + +protected: + MbAngularDimension(const MbAngularDimension& ); ///< \ru Конструктор копирования. \en Copy-constructor. + +public: + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; + virtual MbSpaceItem & Duplicate(MbRegDuplicate * = NULL) const; + virtual bool IsSame(const MbSpaceItem & /*other*/, double /*accuracy*/ = LENGTH_EPSILON) const; + virtual bool SetEqual(const MbSpaceItem &); + virtual void Transform(const MbMatrix3D &, MbRegTransform * = NULL); + virtual void Move(const MbVector3D &, MbRegTransform * = NULL); + virtual void Rotate(const MbAxis3D &, double, MbRegTransform * = NULL); + virtual double DistanceToPoint(const MbCartPoint3D &) const; + virtual void AddYourGabaritTo(MbCube &) const; + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + // \ru Тестовые функции геометрического объекта \en Test functions of a geometric object + virtual MbProperty & CreateProperty(MbePrompt /*n*/) const; // \ru Создать собственное свойство \en Create own property + virtual void GetProperties(MbProperties &); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties(const MbProperties &); // \ru Записать свойства объекта \en Set properties of object + +public: + /// \ru Инициализировать по двум точкам привязки и точке центра. \en Initialize by two reference points and center point. + void Init(const MbCartPoint3D& center, const MbCartPoint3D& base1, const MbCartPoint3D& base2); + + /// \ru Получить первую точку привязки размера. \en Get the first dimension snap point. + MbCartPoint3D GetBasePoint1() const { return base1; } + void SetBasePoint1(const MbCartPoint3D& val) { base1 = val; } + + /// \ru Получить вторую точку привязки размера. \en Get the second dimension snap point. + MbCartPoint3D GetBasePoint2() const { return base2; } + void SetBasePoint2(const MbCartPoint3D& val) { base2 = val; } + + /// \ru Получить точку центра. \en Get center point. + MbCartPoint3D GetCenterPoint() const { return center; } + void SetCenterPoint(const MbCartPoint3D& val) { center = val; } + +private: // \ru Не реализованные методы класса \en Non-implemented methods of class + void operator = (const MbAngularDimension &); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS(MbAngularDimension) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Радиальный размер. + \en Radial dimension. \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbRadialDimension : public MbDimension +{ +private: + MbCartPoint3D center; ///< \ru Точка центра окружности. \en Center point of circle. + MbCartPoint3D circle; ///< \ru Точка на окружности. \en Point on a circle. + MbPlacement3D placement; ///< \ru Местная система координат размера. \en Local coordinate system of the dimension. + bool diametral; ///< \ru Признак того что размер диаметральный. \en Sign of the fact that the diametrical dimension. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] center - \ru Точка центра окружности. + \en Center point of circle. \~ + \param[in] circle - \ru Точка на окружности. + \en Point on a circle. \~ + \param[in] dimensionPlacement - \ru Местная система координат размера. + \en Local coordinate system of the dimension. \~ + \param[in] diametral - \ru Признак того что размер диаметральный. + \en Sign of the fact that the diametrical dimension. \~ + */ + MbRadialDimension(const MbCartPoint3D& center, const MbCartPoint3D& circle, const MbPlacement3D& dimensionPlacement, bool diametral); + +protected: + MbRadialDimension(const MbRadialDimension&); ///< \ru Конструктор копирования. \en Copy-constructor. + +public: + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; + virtual MbSpaceItem & Duplicate(MbRegDuplicate * = NULL) const; + virtual bool IsSame(const MbSpaceItem & /*other*/, double /*accuracy*/ = LENGTH_EPSILON) const; + virtual bool SetEqual(const MbSpaceItem &); + virtual void Transform(const MbMatrix3D &, MbRegTransform * = NULL); + virtual void Move(const MbVector3D &, MbRegTransform * = NULL); + virtual void Rotate(const MbAxis3D &, double, MbRegTransform * = NULL); + virtual double DistanceToPoint(const MbCartPoint3D &) const; + virtual void AddYourGabaritTo(MbCube &) const; + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + // \ru Тестовые функции геометрического объекта \en Test functions of a geometric object + virtual MbProperty & CreateProperty(MbePrompt /*n*/) const; // \ru Создать собственное свойство \en Create own property + virtual void GetProperties(MbProperties &); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties(const MbProperties &); // \ru Записать свойства объекта \en Set properties of object + +public: + /// \ru Инициализировать по центру, точке на окружности, плейсменту. \en Initialize by Initialize by center, point on circle and placement. + void Init(const MbCartPoint3D& center, const MbCartPoint3D& circle, const MbPlacement3D& dimensionPlacement, bool diametral); + + /// \ru Получить точку центра окружности. \en Get center point of circle. + MbCartPoint3D GetCenterPoint() const { return center; } + void SetCenterPoint(const MbCartPoint3D& val) { center = val; } + + /// \ru Получить точку на окружности. \en Get point on a circle. + MbCartPoint3D GetCirclePoint() const { return circle; } + void SetCirclePoint(const MbCartPoint3D& val) { circle = val; } + + /// \ru Получить vестная система координат размера. \en Get local coordinate system of the dimension. + MbPlacement3D GetPlacement() const { return placement; } + void SetPlacement(const MbPlacement3D& val) { placement = val; } + + /// \ru Получить признак того что размер диаметральный. \en Get sign of the fact that the diametrical dimension. + bool IsDiametral() const { return diametral; } + void SetDiametral(bool val) { diametral = val; } + +private: // \ru Не реализованные методы класса \en Non-implemented methods of class + void operator = (const MbRadialDimension &); // \ru Не реализовано \en Not implemented + + DECLARE_PERSISTENT_CLASS(MbRadialDimension) +}; + + +#endif // __MB_DIMENSION_H diff --git a/C3d/Include/mb_enum.h b/C3d/Include/mb_enum.h new file mode 100644 index 0000000..eb3cc67 --- /dev/null +++ b/C3d/Include/mb_enum.h @@ -0,0 +1,646 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Перечисления. + \en The enumerations. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_ENUM_H +#define __MB_ENUM_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Результат выполнения итерационного метода. + \en The result of the iterative method. \~ + \details \ru Результат выполнения итерационного метода сообщает о нахождении решения. + \en The result of the iterative method reports about finding solutions. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeNewtonResult { + nr_Failure = -1, ///< \ru Решение не найдено. \en The solution wasn't found. + nr_Special = 0, ///< \ru Решение не сошлось за заданное количество итераций. \en The solution has not converged for a specified number of iterations. + nr_Success = 1, ///< \ru Решение найдено. \en The solutions was found. + nr_Specific = 2, ///< \ru Требуется уточнение. \en Correction is required. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Положение объекта. + \en The position of an object. \~ + \details \ru Положение объекта относительно другого объекта. + \en The position of an object relative to another object. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeItemLocation { + iloc_Undefined = -3, ///< \ru Не определялось. \en Not defined. + iloc_Unknown = -2, ///< \ru Не получилось определить. \en Failed to define. + iloc_OutOfItem = -1, ///< \ru Вне объекта. \en Outside the object. + iloc_OnItem = 0, ///< \ru На объекте (на границе). \en On the object (on the boundary). + iloc_InItem = 1, ///< \ru Внутри объекта. \en Inside the object. + iloc_ByItem = 2, ///< \ru Условно внутри объекта (для незамкнутых оболочек). \en Conditionally inside the object (for non-closed shells). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Положение двумерной точки. + \en Two-dimensional point position. \~ + \details \ru Положение двумерной точки относительно двумерной кривой. + \en Two-dimensional point position relative to the curve. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeLocation { + loc_Undefined = iloc_Unknown, ///< \ru Положение не определено, кривая разомкнута. \en Failed to define, curve is not closed. + loc_Outside = iloc_OutOfItem, ///< \ru Точка снаружи замкнутой кривой. \en Outside the curve. + loc_OnCurve = iloc_OnItem, ///< \ru Точка на кривой. \en On the curve. + loc_Inside = iloc_InItem, ///< \ru Точка внутри замкнутой кривой. \en Inside the curve. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Состояние объекта после модификации. + \en Object condition after modification. \~ + \details \ru Используется для определения состояние кривой после резки. + \en Used to determine the state of the curve after the cutting. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeState { + dp_NoChanged = 0, ///< \ru Объект не изменился. \en The object is not changed. + dp_Changed, ///< \ru Объект изменился. \en The object has changed. + dp_Degenerated, ///< \ru Объект выродился. \en The object has degenerated. \~ +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Состояние выполнения процесса. + \en State of the process. \~ + \details \ru Состояние выполнения процесса сообщает о ходе работы функции, операции и т.п. + \en State of the process reports about progress of work of function, operation, etc. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeProcessState { + mps_Error = -3, ///< \ru Ошибка. \en Error. + mps_Skip = -2, ///< \ru Пропущено. \en Has been skipped. + mps_Stop = -1, ///< \ru Остановлено. \en Has been stopped. + mps_Success = 0, ///< \ru Выполнено. \en Done. + mps_SelfIntersect = 24, ///< \ru Выполнено. Объект самопересекается. \en Done. Self-intersecting object. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Направление. + \en Direction. \~ + \details \ru Направление движения относительно базового объекта. + \en The direction of a movement relative to the base object. \~ + \ingroup Data_Structures +*/ +//--- +enum MbeSenseValue { + orient_BOTH = 0, ///< \ru Оба направления (неориентированный). \en Both directions (nonoriented). + orient_FORWARD, ///< \ru Прямое направление. \en Forward direction. + orient_BACK, ///< \ru Обратное направление. \en Backward direction. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип параметризации сплайновых объектов. + \en The parameterization type of spline objects. \~ + \details \ru Тип параметризации сплайновых объектов. \n + \en The parameterization type of spline objects. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSplineParamType { + spt_Unstated = 0, ///< \ru Неустановленный. \en Unstated. + spt_EquallySpaced = 1, ///< \ru Равномерная. \en Equally spaced. + spt_ChordLength = 2, ///< \ru По длине хорды (расстоянию между точками). \en By the chord length (the distance between the points). + spt_Centripetal = 3, ///< \ru Центростремительная (квадратный корень расстояния между точками). \en Centripetal (square root of the distance between the points). +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Типы форм NURBS-кривой. + \en Types of NURBS-curve forms. \~ + \details \ru Типы форм сплайновой кривой NURBS. \n + \en Types of spline NURBS-curve forms \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeNurbsCurveForm { + ncf_Unspecified = 0, ///< \ru Неопределенная форма. \en Undefined form + ncf_PolylineForm, ///< \ru Ломаная. \en Polyline. + ncf_CircularArc, ///< \ru Дуга окружности. \en Circle arc. + ncf_EllipticArc, ///< \ru Дуга эллипса. \en Ellipse arc. + ncf_ParabolicArc, ///< \ru Дуга параболы. \en Parabola arc. + ncf_HyperbolicArc, ///< \ru Дуга гиперболы. \en Hyperbola arc + ncf_BezierForm, ///< \ru Сплайн Безье. \en Bezier spline. + ncf_HermitForm, ///< \ru Сплайн Эрмита. \en Hermite spline. + ncf_SurfacePoleForm, ///< \ru Сплайн в полюсе поверхности. \en Spline in the pole of surface. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип сопряжения. + \en The conjugation type. \~ + \details \ru Тип сопряжения определяет способ сопряжения краёв сплайна с контактирующими объектами. + \en The conjugation type defines the method of conjugation of spline boundary with contact objects. \~ + \ingroup Data_Structures +*/ +//--- +enum MbeMatingType { + // \ru Не менять номера, тип пишется и читается, новые добавлять в конец \en Do not change the numbers. Type is written and read. Append new types to the end + trt_None = -1, ///< \ru Без сопряжений. \en Without conjugations. + trt_Position = 0, ///< \ru Соединение по позиции (эквивалентно tt_SmoothG0). \en The connection by the position (equivalent to tt_SmoothG0). + trt_Tangent = 1, ///< \ru Соединение по касательной (эквивалентно tt_SmoothG1). \en Tangential connection (equivalent to tt_SmoothG1). + trt_Normal = 2, ///< \ru Соединение перпендикулярно (эквивалентно tt_SmoothG1). \en Perpendicular connection (equivalent to tt_SmoothG1). + trt_SmoothG2 = 3, ///< \ru Гладкое соединение по первой производной касательной (по кривизне). \en The smooth connection by the first derivative of the tangent (the curvature). + trt_SmoothG3 = 4, ///< \ru Гладкое сопряжение по второй производной касательной. \en The smooth conjugation by the second derivative of the tangent. //-V112 +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип сопряжения по ребрам. + \en The type of conjugation by edges. \~ + \details \ru Тип сопряжения по ребрам определяет способ сопряжения поверхности грани с поверхностью смежной по ребру грани. + \en The type of conjugation by edges defines the method of conjugation of face surface with surface of adjacent faces by face edge \~ + \ingroup Data_Structures +*/ +//--- +enum MbeConjugationType { + cjt_NormPlus = 0, ///< \ru По нормали в положительном направлении вектора нормали к грани. \en The type of conjugation by normal in the positive direction of face normal vector. + cjt_NormMinus = 1, ///< \ru По нормали в отрицательном направлении вектора нормали к грани. \en The type of conjugation by normal in the negative direction of face normal vector. + cjt_G1Plus = 2, ///< \ru По касательной к поверхности, слева по направлению касательной к кривой пересечения. \en The type of conjugation by tangent to the surface, to the left in the direction of intersection curve tangent. + cjt_G1Minus = 3, ///< \ru По касательной к поверхности, справа по направлению касательной к кривой пересечения. \en The type of conjugation by tangent to the surface, to the right in the direction of intersection curve tangent. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип сглаживания. + \en The type of blending. \~ + \details \ru Тип сглаживания при перемещении узлов в процессе прямого редактирования. + \en The type of blending while moving nodes in the process of direct editing. \~ + \ingroup Data_Structures +*/ +//--- +enum MbeDirectSmoothType { + dst_None = -1, ///< \ru Без сглаживания. \en Without blending. + dst_Convex = 0, ///< \ru Выпуклый. \en Convex. + dst_Concave = 1, ///< \ru Вогнутый. \en Concave. + dst_Smooth = 2, ///< \ru Плавный переход. \en Smooth transition. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы двумерной сетки. + \en Types of two-dimensional mesh. \~ + \details \ru Типы двумерной сетки. \n + \en Types of two-dimensional mesh. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeItemGridType { + igt_Rectangular = 0, ///< \ru Прямоугольная сетка. \en Rectangular mesh. + igt_Concentric = 1, ///< \ru Концентрическая сетка. \en Concentric mesh. + igt_Hexagonal = 2, ///< \ru Гексагональная сетка. \en Hexagonal mesh. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Направление на поверхности. + \en Direction on the surface. \~ + \details \ru Используемое в итерационном методе направление на поверхности. \n + \en Direction on the surface which is used in the iterative method. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeParamDir { + pd_DirU = 0, ///< \ru U-направление на поверхности. \en U-direction on the surface. + pd_DirV = 1, ///< \ru V-направление на поверхности. \en V-direction on the surface. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы кривой пересечения поверхностей по построению. + \en Types of surfaces intersection curve by construction. \~ + \details \ru Типы кривой пересечения поверхностей как результат итерационного метода. + \en Types of surfaces intersection curve as a result of the iterative method. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeCurveBuildType { + cbt_Boundary = -1, ///< \ru Кривая по которой идет граница оболочки. \en Curve which the boundary of the shell goes through. + cbt_Ordinary = 0, ///< \ru Аналитическая кривая. \en Analytical curve. + cbt_Specific = 1, ///< \ru Кривая построена по отдельным точкам. \en Curve is constructed from single points. + cbt_Tolerant = 2, ///< \ru Аналитическая кривая пересечения, рассчитанная неточно. \en The analytical curve of intersection which is calculated imprecisely. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы поверхности сопряжения. + \en Types of blend surface. \~ + \details \ru Типы поверхности сопряжения (скругления или фаски) по построению. + \en The type of blend surface (fillet or chamfer) by a construction. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSurfaceType { + sst_OrdinarySurface = 0, ///< \ru Аналитическая поверхность. \en Analytic surface. + sst_SpecificSurface = 1, ///< \ru Специальная поверхность сопряжения (скругления или фаски) построена по отдельным точкам. \en Special blend surface (fillet or chamfer) is constructed by separate points. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы кривой пересечения поверхностей по топологии. + \en Curve types of surfaces intersection by topology. \~ + \details \ru Типы кривой пересечения поверхностей по топологии. \n + \en Curve types of surfaces intersection by topology. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeCurveGlueType { + cgt_Unknown = 0, ///< \ru Неустановленное значение типа кривой. \en Undefined type of curve. + cgt_Pole = 1, ///< \ru Полюсная кривая. \en Pole curve. + cgt_Edge = 2, ///< \ru Кривая пересечения разных поверхностей. \en Intersection curve of different surfaces. + cgt_Stitch = 3, ///< \ru Шовное ребро или линия разъема из конвертеров (правило выбора первой параметрической кривой). \en Seam edge or parting line from converters (rule for choice of the first parametric curve). + cgt_Split = 4, ///< \ru Кривая пересечения - линия разъема. \en Intersection curve is a parting line. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способы вычисления приращения параметра по объекту. + \en Methods of calculation of parameter increment by the object. \~ + \details \ru Используются три общих способа вычисления приращения параметра кривой или поверхности: + по стрелке прогиба, по углу отклонения, по длине. + Для визуализации геометрической формы используется первый способ. \n + Для операций построения используется второй способ. \n + Для 3D принтеров используется все три перечисленные способа. \n + Ещё три специализированных способа вычисления приращения параметра используются для конкретных целей: + для привязки объектов к параметрам поверхности, + для определения столкновений элементов модели, + для вычисления инерционных характеристик. + \en Methods of calculation of parameter increment by the object. \n \~ + There are three types of steps: by sag, by deviation angle, by length. + Step by sag is used for visualizations. + Step by deviation angle is used for calculation. + Step by length is used for 3D printer (plus by sag and by deviation angle). \n + There are three special types of steps also. + Special step is used for linking with surface parameters. + Special step is used for collision detection of model elements. + Special step is used for calculation of inertial characteristics. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeStepType { + ist_SpaceStep = 0x01, ///< \ru Шаг по стрелке прогиба. \en Step by sag. + ist_DeviationStep = 0x02, ///< \ru Шаг по углу отклонения. \en Step by the deflection angle. + ist_MetricStep = 0x04, ///< \ru Шаг по длине. \en Step by length. + ist_ParamStep = 0x08, ///< \ru Шаг с привязкой объектов к параметрам поверхности. \en Step with binding of objects to the parameters of surface. + ist_CollisionStep = 0x10, ///< \ru Шаг для определения столкновений элементов модели. \en Step for collision detection of model elements. + ist_MipStep = 0x20, ///< \ru Шаг для расчета инерционных характеристик. \en Step for mass-inertial characteristics. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Рабочие метки. + \en Working label. \~ + \details \ru Рабочие метки для операций, используются в MbTopologyItem::GetLabel и MbTopologyItem::SetOwnLabel. + \en Working label for operations are used in MbTopologyItem::GetLabel and MbTopologyItem::SetOwnLabel. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeLabelState { + ls_None = -1, ///< \ru Объект не будет использоваться. \en The object is not to be used. + ls_Null = 0, ///< \ru Объект не рассматривался. \en Object was not considered. + ls_Used = 1, ///< \ru Объект используется. \en Object is used. + ls_Delete = 2, ///< \ru Объект предназначен для удаления. \en The object is to be deleted. + ls_Rebuild = 3, ///< \ru Объект нуждается в перестроении. \en The object needs to be rebuilt. + ls_FirstPass = 4, ///< \ru Объект затронут первым проходом алгоритма. \en The object is affected by the first pass of the algorithm. + ls_SecondPass = 5, ///< \ru Объект затронут вторым проходом алгоритма. \en The object is affected by the second pass of the algorithm. + ls_Error = 6, ///< \ru Объект нужно удалить и возвести ошибку. \en The object must be removed, and the error must be returned. + ls_Doubtful = 7, ///< \ru Объект сомнительный, рассматривается в последнюю очередь. \en The object is doubtful. + ls_TempMark = 8 ///< \ru Временная метка (для сбора объектов). \en Temporary mark (for collection of objects). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способы построения поверхности сопряжения (скругления или фаски). + \en Methods of construction of a blend surface (fillet or chamfer). \~ + \details \ru Способы построения поверхности сопряжения (скругления или фаски). \n + \en Methods of construction of a blend surface (fillet or chamfer). \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSmoothForm { + st_Span = -1, ///< \ru Скругление с заданной хордой. \en Fillet with a given chord. + st_Fillet = 0, ///< \ru Скругление с заданными радиусами. \en Fillet with given radii. + st_Chamfer = 1, ///< \ru Фаска с заданными катетами. \en Chamfer with given cathetuses. + st_Slant1 = 2, ///< \ru Фаска по катету и углу (катет distance2 рассчитан для прямого угла между гранями и определяет прилегающий к катету distance1 угол). \en Chamfer by cathetus and angle (distance2 cathetus is calculated for right angle between faces and defines angle adjacent to the distance1 cathetus). + st_Slant2 = 3, ///< \ru Фаска по углу и катету (катет distance1 рассчитан для прямого угла между гранями и определяет прилегающий к катету distance2 угол). \en Chamfer by angle and cathetus (distance1 cathetus is calculated for right angle between faces and defines angle adjacent to the distance2 cathetus). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы булевых операций над твердыми телами. + \en Types of boolean operations on solids. \~ + \details \ru Типы булевых операций над твердыми телами. \n + \en Types of boolean operations on solids. \n \~ + \ingroup Data_Structures +*/ +// --- +enum OperationType { + bo_Internal = -4, ///< \ru Пересечение оболочек. \en Shells intersection. + bo_External = -3, ///< \ru Вычитание оболочек. \en Shells subtraction. + bo_Intersect = -2, ///< \ru Пересечение тел. \en Solids intersection. + bo_Difference = -1, ///< \ru Вычитание тел. \en Solids subtraction. + bo_Unknown = 0, ///< \ru Неопределённая операция. \en Undefined operation. + bo_Union = 1, ///< \ru Объединение тел. \en Solids union. + bo_Base = 2, ///< \ru Исходное состояние. \en Initial state. + bo_Variety = 3, ///< \ru Объединение оболочек. \en Shells union. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы булевых операций над двумерными регионами. + \en Types of boolean operations on two-dimensional regions. \~ + \details \ru Типы булевых операций над двумерными регионами. \n + \en Types of boolean operations on two-dimensional regions. \n \~ +\ingroup Data_Structures +*/ +// --- +enum RegionOperationType { + rbo_Intersect = -2, ///< \ru Операция пересечение. \en Intersection operation. + rbo_Difference = -1, ///< \ru Операция разность. \en Subtraction operation. + rbo_Unknown = 0, ///< \ru Неопределенная операция. \en Undefined operation. + rbo_Union = 1, ///< \ru Операция объединение. \en Union operation. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способы сопряжения кривых. + \en Methods of curves conjugation. \~ + \details \ru Способы сопряжения двух кривых третьей кривой. + \en Methods of two curves conjugation by the third curve. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeConnectingType { + ft_Fillet = 0, ///< \ru Скругление круговое на цилиндре. \en Circular fillet on the cylinder. + ft_OnSurface = 1, ///< \ru Скругление пересечением цилиндра и общей поверхности сопрягаемых кривых. \en Fillet by intersection of the cylinder and common surface of the mating curves. + ft_Spline = 2, ///< \ru Сопряжение сплайном. \en Conjugation by spline. + ft_Double = 3, ///< \ru Сопряжение двумя дугами. \en Conjugation by two arcs. + ft_Bridge = 4, ///< \ru Сопряжение кубической кривой. \en Conjugation by a cubic curve. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Cпособы передачи данных при копировании оболочек. + \en Methods of transferring data while copying shells. \~ + \details \ru Cпособы передачи данных при копировании оболочек в операциях над телами. \n + Любая операция, и удачная, и ошибочная, безвозвратно модифицирует вершины, рёбра и грани оболочек операндов. \n + Для сохранения неизменной исходной оболочки операнда применяется полное или частичное копирование данных. \n + Используются четыре способа передачи данных в операцию. \n + Если не требуется сохранить данные, то оболочка не копируется, а используется исходная. \n + Если требуется, чтобы операция не портила исходную оболочку и максимально экономила память, + то в копии оболочки сохраняются базовые поверхности и вершины. + Кроме того, после операции копия и исходная оболочка имеют общие неизменённые операцией грани. \n + Если требуется, чтобы операция не портила исходную оболочку и имела высокую скорость выполнения, + то в копии оболочки сохраняются базовые поверхности и вершины. \n + Если требуется, чтобы результат операции не был связан с исходными объектами, + то вершины, рёбра, поверхности и грани операндов полностью копируются. + Такой подход используется в операциях, трансформирующих тело, например при зеркальном копировании. \n + \en Methods of transferring data while copying shells in operations on solids. \n + Any operation (successful or faulty) modifies vertices, edges and shell faces of operands irreversibly. \n + Used full or partial copying of data to save the initial operand shell. \n + Four methods of transferring data to operation are used. \n + If it is not required to save the data, then the shell isn't copied and the original shell is used. \n + If it is required that the operation should not spoil the original shell and save memory, + then the base surfaces and vertices are saved in a copy of the shell. + In addition after operation a copy and the initial shell have common faces unchanged by operation. \n + If it is required that the operation should not spoil the original shell and had a high speed, + then the base surfaces and vertices are saved in a copy of the shell. \n + If it is required that the operation result should not relate to the original objects, + then the vertices, edges, surfaces and faces of operands are copied. + This approach is used in operations which transform solid, such as mirroring. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeCopyMode { + cm_Same = 0, ///< \ru Оболочка не копируется. \en Shell is not copied. + cm_KeepHistory, ///< \ru Исходная оболочка и её копия имеют общие базовые поверхности, вершины и неизменённые операцией грани. \en Initial shell and its copy have common base surfaces, vertices and faces unchanged by operation. + cm_KeepSurface, ///< \ru Исходная оболочка и её копия имеют общие базовые поверхности. \en Initial shell and its copy have common base surfaces. + cm_Copy, ///< \ru Исходная оболочка и её копия не имеют общих данных. \en Initial shell and its copy don't have common data. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поддерживаемые типы производных на кривой. + \en Supported types of derivatives on the curve. \~ + \details \ru Поддерживаемые типы производных на кривой. Они же индексы производных в общем массиве. \n + \en Supported types of derivatives on the curve. They are the indices of derivatives in the general array. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeCurveDerivativeType { + cdt_CurPoint = 0, ///< \ru Точка (нулевой порядок) \en A point (zero order) + cdt_FirstDer, ///< \ru Первая производная \en First derivative. + cdt_SecondDer, ///< \ru Вторая производная \en Second derivative + cdt_ThirdDer, ///< \ru Третья производная \en Third derivative + // \ru Новые производные вставлять по порядку перед количеством \en New derivatives are to be inserted before the number of derivatives + cdt_CountDer, ///< \ru Количество запоминаемых значений (порядков) \en The number of memorized values (orders) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поддерживаемые типы производных на поверхности. + \en Supported types of derivatives on the surface. \~ + \details \ru Поддерживаемые типы производных на поверхности. Они же индексы производных в общем массиве. \n + \en Supported types of derivatives on the surface. They are the indices of derivatives in the general array. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSurfaceDerivativeType { + sdt_SurPoint = 0, ///< \ru Точка. \en A point. + sdt_DeriveU, ///< \ru Частная производная по U. \en Partial derivative by U. + sdt_DeriveV, ///< \ru Частная производная по V. \en Partial derivative by V. + sdt_DeriveUU, ///< \ru Частная производная по UU. \en Partial derivative by UU. + sdt_DeriveUV, ///< \ru Частная производная по UV. \en Partial derivative by UV. + sdt_DeriveVV, ///< \ru Частная производная по VV. \en Partial derivative by VV. + sdt_DeriveUUU, ///< \ru Частная производная по UUU. \en Partial derivative by UUU. + sdt_DeriveUUV, ///< \ru Частная производная по UUV. \en Partial derivative by UUV. + sdt_DeriveUVV, ///< \ru Частная производная по UVV. \en Partial derivative by UVV. + sdt_DeriveVVV, ///< \ru Частная производная по UVV. \en Partial derivative by UVV. + sdt_Normal, ///< \ru Нормаль. \en Normal. + sdt_NormalU, ///< \ru Частная производная нормали по U. \en Partial derivative of normal by U. + sdt_NormalV, ///< \ru Частная производная нормали по V. \en Partial derivative of normal by V. + sdt_NormalUU, ///< \ru Частная производная нормали по UU. \en Partial derivative of normal by UU. + sdt_NormalUV, ///< \ru Частная производная нормали по UV. \en Partial derivative of normal by UV. + sdt_NormalVV, ///< \ru Частная производная нормали по VV. \en Partial derivative of normal by VV. + // \ru Новые производные вставлять по порядку перед количеством \en New derivatives are to be inserted before the number of derivatives + sdt_CountNor, ///< \ru Количество запоминаемых значений. \en The number of memorized values. + sdt_CountDer = sdt_Normal, ///< \ru Количество запоминаемых значений. \en The number of memorized values. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Перечисление способов захвата граней. + \en Enumeration of faces capturing methods. \~ + \details \ru Перечисление способов захвата граней. \n + \en Enumeration of faces capturing methods. \n \~ + \ingroup Base_Items + \attention \ru Идентификаторы не менять (пишутся в файл)! + \en Do not change identifiers (they are written to file)! \~ +*/ +//--- +enum MbeFacePropagation { + fp_None = 0, ///< \ru Без захвата. \en Without capture. + fp_All = 1, ///< \ru Захват всех граней. \en Capture all faces. + fp_SmoothlyJointedAlong = 2, ///< \ru Прохождение по гладкостыкующимся граням через сонаправленные ребра (прямолинейные). \en Movement on smooth-joint faces through collinear edges (straight). + fp_SmoothlyJointedOrtho = 3, ///< \ru Прохождение по гладкостыкующимся граням через ортогональные ребра (прямолинейные.) \en Movement on smooth-joint faces through orthogonal edges (straight). + fp_SmoothlyJointed = 4, ///< \ru Прохождение по гладкостыкующимся граням через прямолинейные ребра. \en Movement on smooth-joint faces through straight edges. //-V112 +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы точек пересечения. + \en Types of intersection points. \~ + \details \ru Типы точек пересечения. \n + \en Types of intersection points. \n \~ + \ingroup Point_Modeling +*/ +// --- +enum MbeIntersectionType { + ipt_Simple = 0, ///< \ru Обыкновенная точка пересечения. \en Ordinary intersection point. + ipt_Tangent = 1, ///< \ru Касательная точек пересечения. \en Tangent of intersection points. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расположение полюсов. + \en Location of the poles. \~ + \details \ru Расположение полюсов поверхности в параметрической области. \n + \en The location of surface poles in the parametric region. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbePoleLocation { + pln_None = -1, ///< \ru Нет полюса. \en No pole. + pln_MinU = 0, ///< \ru Полюс при u = umin. \en Pole at u = umin. + pln_MaxU = 1, ///< \ru Полюс при u = umax. \en Pole at u = umax. + pln_MinV = 2, ///< \ru Полюс при v = vmin. \en Pole at v = vmin. + pln_MaxV = 3, ///< \ru Полюс при v = vmax. \en Pole at v = vmax. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип границы поверхности. + \en Surface border type. \~ + \details \ru Тип границы поверхности. \n + \en Surface border type. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSurfacePoleType { + spt_Undefined = 0, ///< \ru Тип не определен. \en A type is undefined. + spt_Point, ///< \ru Точка. \en A point. + spt_Curve, ///< \ru Кривая. \en A curve. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы элементарных тел. + \en Types of elementary solids. \~ + \details \ru Типы элементарных тел, которые можно построить по нескольким точкам. \n + \en Types of elementary solids which can be constructed by several points. \n \~ + \ingroup Build_Parameters +*/ +//--- +enum ElementaryShellType { + et_Sphere = 0, ///< \ru Шар (3 точки). \en Sphere (3 points). + et_Torus = 1, ///< \ru Тор (3 точки). \en Torus (3 points). + et_Cylinder = 2, ///< \ru Цилиндр (3 точки). \en Cylinder (3 points). + et_Cone = 3, ///< \ru Конус (3 точки). \en Cone (3 points). + et_Block = 4, ///< \ru Блок (4 точки). \en Block (4 points). + et_Wedge = 5, ///< \ru Клин (4 точки). \en Wedge (4 points). + et_Prism = 6, ///< \ru Призма (n + 1 точек, n > 2). \en Prism (n + 1 points, n > 2). + et_Pyramid = 7, ///< \ru Пирамида (n + 1 точек, n > 2). \en Pyramid (n + 1 points, n > 2). + et_Plate = 8, ///< \ru Плита (4 точки). \en Plate (4 points). + et_Icosahedron = 9, ///< \ru Икосаэдр (3 точки). \en Icosahedron (3 points). + et_Polyhedron = 10, ///< \ru Многогранник (3 точки). \en Polyhedron (3 points). + et_Tetrapipe = 11, ///< \ru Тетратруба (3 точки). \en Tetrapipe (3 points). + et_Octapipe = 12, ///< \ru Октатруба (3 точки). \en Octapipe (3 points). +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы изменения смещения точек эквидистантных кривых и поверхностей. + \en Types of points offset displacement for offset curves and offset surfaces from base objects. \~ + \details \ru Смещение точек эквидистантных кривых и поверхностей может быть константным, или выполняться по линейному закону, или выполняться по кубическому закону. + Смещение является функцией параметров кривых и поверхностей. Кубическая функция смещения на краях имеет нулевые производные. + \en The points displacement of offset curves and offset surfaces can be constant, or can be linear, or can be cubic. + The offset is a function of the parameters of curves and surfaces. The cubic function has zero derivatives at the beginning and at the end. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeOffsetType { + off_Empty = 0, ///< \ru Смещение отсутствует (нулевое). \en The offset is absent (null). + off_Const = 1, ///< \ru Постоянное значение смещения. \en Constant value of offset. + off_Linea = 2, ///< \ru Линейная функция смещения. \en Linear function of offset. + off_Cubic = 3, ///< \ru Кубическая функция смещения. \en Cubic function of offset. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы сообщений индикатора прогресса выполнения. + \en Identifiers of the execution progress indicator messages. \~ + \ingroup Data_Structures +*/ +//--- +enum MbeProgBarId_Common +{ + pbarId_Common_Beg = 0, + + pbarId_Read_Data, ///< \ru Чтение данных. \en Data reading. + pbarId_Prepare_Data, ///< \ru Подготовка данных. \en Data preparing. + pbarId_Process_Data, ///< \ru Обработка данных. \en Data processing. + pbarId_Finish_Data, ///< \ru Завершение обработки данных. \en Completion of data processing. + pbarId_Draw_Data, ///< \ru Отображение данных. \en Data mapping. + pbarId_Write_Data, ///< \ru Запись данных. \en Data writing. + + pbarId_Common_End, +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы сообщений индикатора прогресса выполнения. Поверхность по пласту(сети) точек. + \en Identifiers of the execution progress indicator messages. Surface by points layer(grid). \~ + \ingroup Data_Structures +*/ +//--- +enum MbeProgBarId_PointsSurface +{ + pbarId_PointsSurface_Beg = pbarId_Common_End + 1, + + pbarId_Solve_LinearEquationsSystem, ///< \ru Решение системы линейных уравнений. \en System of linear equations solving. + pbarId_Remove_RedundantPoints, ///< \ru Удаление избыточных точек. \en Removal of redundant points. + pbarId_Build_ShellByPointsMesh, ///< \ru Построение оболочки по сети точек. \en Construction of shell by points grid. + pbarId_Build_PointsCloudMesh, ///< \ru Построение сети точек по пласту точек. \en Construction of points grid by points layer. + pbarId_Build_TriangleFaces, ///< \ru Построение треугольных граней. \en Construction of triangular faces. + pbarId_Find_AdjacentEdges, ///< \ru Поиск смежных ребер. \en Search adjacent edges. + pbarId_Build_TrianglesShell, ///< \ru Построение поверхности из треугольных граней. \en Construction of surface from triangular faces. + pbarId_Prepare_SurfaceData, ///< \ru Подготовка данных для построения поверхности. \en Preparing data for surface construction. + pbarId_Check_Surface, ///< \ru Проверка правильности построения поверхности. \en Check correctness of surface construction. + + pbarId_PointsSurface_End, +}; + + +#endif // __MB_ENUM_H diff --git a/C3d/Include/mb_homogeneous.h b/C3d/Include/mb_homogeneous.h new file mode 100644 index 0000000..54a14c9 --- /dev/null +++ b/C3d/Include/mb_homogeneous.h @@ -0,0 +1,546 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Расширенная точка с однородными координатами в двумерном пространстве. + \en Extended point with homogeneous coordinates in the two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_HOMOGENIUS_H +#define __MB_HOMOGENIUS_H + + +#include + + +class MATH_CLASS MbMatrix; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширенная точка с однородными координатами в двумерном пространстве. + \en Extended point with homogeneous coordinates in the two-dimensional space. \~ + \details \ru Расширенная точка с однородными координатами в двумерном пространстве. \n + Дополнительная координата точки (вес) вводится для удобства работы с неоднородными рациональными сплайнами.\n + Определены операции преобразования точки и вектора в однородные координаты. + Определены различные арифметические операции однородной точки с числом, декартовой точкой и однородной точкой. + \en Extended point with homogeneous coordinates in the two-dimensional space. \n + Additional coordinate of a point (weight) is introduced for the convenience of working with non-uniform rational splines. \n + Operations of transformation of a point and a vector in homogeneous coordinates are defined. + Various arithmetic operations of a homogeneous point with a number, a cartesian point and a homogeneous point are defined. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbHomogeneous { +public : + double x; ///< \ru Первая координата точки. \en A first point coordinate. + double y; ///< \ru Вторая координата точки. \en A second point coordinate. + double w; ///< \ru Вес точки. \en A point weight. + + static const MbHomogeneous zero; ///< \ru Нулевая точка. \en Zero point. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbHomogeneous() : x( 0.0 ), y( 0.0 ), w( 1.0 ) {} + /// \ru Конструктор по точке и весу. \en The constructor by a point and a weight. + MbHomogeneous( const MbVector & v, double ww ) : x( v.x * ww ), y( v.y * ww ), w( ww ) {} + /// \ru Конструктор копирования. \en The copy constructor. + MbHomogeneous( const MbHomogeneous & other ) : x( other.x ), y( other.y ), w( other.w ) {} + /// \ru Конструктор по компонентам точки и весу. \en The constructor by point components and weight. + MbHomogeneous( double initX, double initY, double initW ) : x( initX ), y( initY ), w( initW ) {} + +public: + /// \ru Инициализация по компонентам точки. \en The initialization by point components. + void Init( double initX, double initY ); + /// \ru Инициализация по компонентам точки и весу. \en The initialization by point components and weight. + void Init( double initX, double initY, double initW ); + /// \ru Инициализация по компонентам точки и весу. \en The initialization by point components and weight. + void Init( const MbCartPoint & pnt, double weight ) { x = pnt.x*weight; y = pnt.y*weight; w = weight; } + /// \ru Установить вектор нулевой длины. \en Set a vector with null length. + void SetZero() { x = 0; y = 0; w = 1; } + + /// \ru Преобразование по матрице. \en The transformation by a matrix. + void Transform( const MbMatrix & matr ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move( const MbVector & shift ); + /** + \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Угол определяет вектор вращения, а точка - центр. + \en An angle defines a rotation vector and a point defines a center. \~ + \param[in] pnt - \ru Точка. + \en A point. \~ + \param[in] angle - \ru Угол вращения. + \en A rotation angle. \~ + */ + void Rotate( const MbCartPoint & pnt, double angle ); + + /// \ru Дать вес точки. \en Get a point weight. + double GetWeight() const { return w; }; + /// \ru Вычислить декартовы координаты, как точки. \en Calculate cartesian coordinates as point. + void GetCartPoint( MbCartPoint & pnt ) const; + /// \ru Вычислить декартовы координаты, как вектора. \en Calculate cartesian coordinates as vector. + void GetVector ( MbVector & vect ) const; + + /// \ru Преобразовать точку в однородные координаты. \en Transform a point to homogeneous coordinates. + void Set( const MbCartPoint & pnt ); + /// \ru Преобразовать точку в однородные координаты. \en Transform a point to homogeneous coordinates. + void Set( const MbCartPoint & pnt, double weight ); + /// \ru Преобразовать вектор в однородные координаты. \en Transform a vector to homogeneous coordinates. + void Set( const MbVector & pnt, double weight ); + /** + \brief \ru Установить по точкам. + \en Set by points. \~ + \details \ru Координаты точки равны сумме однородных координат исходных точек, а вес - сумме весов. + \en Coordinates of a point are equal to the sum of homogeneous coordinates of initial points, and weight is equal to the sum of the weights. \~ + \param[in] pnt1, pnt2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] weight1, weight2 - \ru Весы точек. + \en Weights of points. \~ + */ + void Set( const MbCartPoint & pnt1, double weight1, + const MbCartPoint & pnt2, double weight2 ); + /** + \brief \ru Увеличить координаты на указанные значения. + \en Increase coordinates by given values. \~ + \details \ru Увеличить координаты на указанные значения. + \en Increase coordinates by given values. \~ + \param[in] initX - \ru Исходное значение координаты x. + \en The initial value of x. \~ + \param[in] initY - \ru Исходное значение координаты y. + \en The initial value of y. \~ + \param[in] weight - \ru Вес. + \en A weight. \~ + */ + void Add( double initX, double initY, double weight ); + /** + \brief \ru Добавить точки. + \en Add points. \~ + \details \ru Увеличить координаты на значения однородных координат двух исходных точек. + \en Increase coordinates by values of the homogeneous coordinates of two initial points. \~ + \param[in] pnt1, pnt2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] weight1, weight2 - \ru Весы точек. + \en Weights of points. \~ + */ + void Add( const MbCartPoint & pnt1, double weight1, + const MbCartPoint & pnt2, double weight2 ); + /** + \brief \ru Добавить точку. + \en Add a point. \~ + \details \ru Увеличить координаты на значения однородных координат точки. + \en Increase coordinates by values of homogeneous coordinates of a point. \~ + \param[in] pnt - \ru Исходная точка. + \en The initial point. \~ + \param[in] weight - \ru Вес точки. + \en A point weight. \~ + */ + void Add( const MbCartPoint & pnt, double weight ); + + /// \ru Разность p2 - p1 умножить на kk. \en Subtract p2 - p1 multiple by kk. + void Dec( const MbHomogeneous & p1, const MbHomogeneous & p2, double kk ); + /// \ru Приравнять координаты вектора координатам точки v1, умноженных на t1. \en Equate coordinates of vector with coordinates of point v1 multiplied by t1. + void Set( const MbHomogeneous & v1, double t1 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector coordinates with sum of points v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector coordinates with coordinates of sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3, const MbHomogeneous & v4, double t4 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3, v4 и v5, умноженных на t1, t2, t3 t4 и t5 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3, t4, t5 correspondingly. + void Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3, const MbHomogeneous & v4, double t4, const MbHomogeneous & v5, double t5 ); + /// \ru Добавить вектор p, умноженный на kk. \en Add vector p multiplied by kk. + void Add( const MbHomogeneous & p, double kk ); + + /** + \ru \name Перегрузка арифметических операций. + \en \name Overload of arithmetic operations. + \{ */ + /// \ru Сложить две точки. \en Add two points. + MbHomogeneous operator + ( const MbHomogeneous & with ) const; + /// \ru Вычесть из точки точку. \en Subtract a point from the point. + MbHomogeneous operator - ( const MbHomogeneous & with ) const; + /// \ru Умножить координаты точки на число. \en Multiply point coordinates by a number. + MbHomogeneous operator * ( double factor ) const; + /// \ru Разделить координаты точки на число. \en Divide point coordinates by a number. + MbHomogeneous operator / ( double factor ) const; + /// \ru Скалярное умножение двух векторов. \en Scalar product of two vectors. + double operator * ( const MbHomogeneous & vector ) const; + /// \ru Векторное умножение двух векторов. \en Vector product of two vectors. + MbHomogeneous operator | ( const MbHomogeneous & vect2 ) const; + /// \ru Присвоить значение. \en Assign a value. + void operator = ( const MbHomogeneous & other ) { x = other.x; y = other.y; w = other.w; } + /// \ru Умножить координаты точки на число. \en Multiply point coordinates by a number. + void operator *= ( double factor ); + /// \ru Разделить координаты точки на число. \en Divide point coordinates by a number. + void operator /= ( double factor ); + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbHomogeneous & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbHomogeneous & ) const; + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbHomogeneous & other, double accuracy ) const; + /** \} */ +}; // MbHomogeneous + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en The initialization. +// --- +inline void MbHomogeneous::Init( double initX, double initY ) +{ + x = initX; + y = initY; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация \en The initialization. +// --- +inline void MbHomogeneous::Init( double initX, double initY, double initW ) +{ + x = initX; + y = initY; + w = initW; +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление декартовых координат \en Calculation of the cartesian coordinates +// --- +inline void MbHomogeneous::GetCartPoint( MbCartPoint & pnt ) const +{ + pnt.x = x; + pnt.y = y; + if ( w != 0 ) { + double k = 1.0 / w; + pnt.x *= k; + pnt.y *= k; + } +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление декартовых координат как вектора \en Calculation of the cartesian coordinates as vector +// --- +inline void MbHomogeneous::GetVector( MbVector & v ) const +{ + v.x = x; + v.y = y; + if ( w != 0 ) { + double k = 1.0 / w; + v.x *= k; + v.y *= k; + } +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать точку в однородные координаты \en Transform a point to homogeneous coordinates +// --- +inline void MbHomogeneous::Set( const MbCartPoint & pnt ) +{ + Init( pnt.x * w, + pnt.y * w ); +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать точку в однородные координаты \en Transform a point to homogeneous coordinates +// --- +inline void MbHomogeneous::Set( const MbCartPoint & pnt, double weight ) +{ + Init( pnt.x * weight, + pnt.y * weight, + weight ); +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать вектор в однородные координаты \en Transform a vector to homogeneous coordinates +// --- +inline void MbHomogeneous::Set( const MbVector & vect, double weight ) +{ + Init( vect.x * weight, + vect.y * weight, + weight ); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить координаты на указанные значения. \en Increase coordinates by given values. +// --- +inline void MbHomogeneous::Add( double initX, double initY, double weight ) +{ + x += initX; + y += initY; + w += weight; +} + +//------------------------------------------------------------------------------ +// \ru Преобразовать точки в однородные координаты \en Transform points to homogeneous coordinates +// --- +inline void MbHomogeneous::Set( const MbCartPoint & pnt1, double weight1, + const MbCartPoint & pnt2, double weight2 ) +{ + Init( pnt1.x * weight1 + pnt2.x * weight2, + pnt1.y * weight1 + pnt2.y * weight2, + weight1 + weight2 ); +} + + +//------------------------------------------------------------------------------ +// \ru Добавить точку \en Add a point +// --- +inline void MbHomogeneous::Add( const MbCartPoint &pnt, double weight ) +{ + Add( pnt.x * weight, + pnt.y * weight, + weight ); +} + + +//------------------------------------------------------------------------------ +// \ru Добавить точки \en Add points +// --- +inline void MbHomogeneous::Add( const MbCartPoint &pnt1, double weight1, + const MbCartPoint &pnt2, double weight2 ) +{ + Add( pnt1.x * weight1 + pnt2.x * weight2, + pnt1.y * weight1 + pnt2.y * weight2, + weight1 + weight2 ); +} + + +//------------------------------------------------------------------------------ +// \ru Разность p2 - p1 умножить на kk. \en Subtract p2 - p1 multiple by kk. +// --- +inline void MbHomogeneous::Dec( const MbHomogeneous & p1, const MbHomogeneous & p2, double kk ) +{ + Init( (p2.x - p1.x) * kk, + (p2.y - p1.y) * kk, + (p2.w - p1.w) * kk ); +} + + +//------------------------------------------------------------------------------ +// \ru Приравнять вектору вектор p, умноженному на kk. \en Equate vector with vector p multiplied by k. +// --- +inline void MbHomogeneous::Set( const MbHomogeneous & v1, double t1 ) +{ + Init( v1.x * t1, + v1.y * t1, + v1.w * t1 ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous::Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2 ) +{ + Init( v1.x * t1 + v2.x * t2, + v1.y * t1 + v2.y * t2, + v1.w * t1 + v2.w * t2 ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous::Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3 ) +{ + Init( v1.x * t1 + v2.x * t2 + v3.x * t3, + v1.y * t1 + v2.y * t2 + v3.y * t3, + v1.w * t1 + v2.w * t2 + v3.w * t3 ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous::Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3, const MbHomogeneous & v4, double t4 ) +{ + Init( v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4, + v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4, + v1.w * t1 + v2.w * t2 + v3.w * t3 + v4.w * t4 ); +} + + +//------------------------------------------------------------------------------ +// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3, v4 и v5, умноженных на t1, t2, t3 t4, t4 и t5 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3, t4, t5 correspondingly. +// --- +inline void MbHomogeneous::Set( const MbHomogeneous & v1, double t1, const MbHomogeneous & v2, double t2, + const MbHomogeneous & v3, double t3, const MbHomogeneous & v4, double t4, const MbHomogeneous & v5, double t5 ) +{ + Init( v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4 + v5.x * t5, + v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4 + v5.y * t5, + v1.w * t1 + v2.w * t2 + v3.w * t3 + v4.w * t4 + v5.w * t5 ); +} + + +//------------------------------------------------------------------------------ +// \ru Добавить вектор p, умноженный на kk. \en Add vector p multiplied by kk. +// --- +inline void MbHomogeneous::Add( const MbHomogeneous & p, double kk ) +{ + Add( p.x * kk, p.y * kk, p.w * kk ); +} + + +//------------------------------------------------------------------------------ +// \ru Скалярное умножение двух векторов \en Scalar product of two vectors +// --- +inline double MbHomogeneous::operator * ( const MbHomogeneous &vector ) const { + return ( x * vector.x + y * vector.y + w * vector.w ); +} + + +//------------------------------------------------------------------------------ +// \ru Векторное умножение двух векторов \en Vector product of two vectors +// --- +inline MbHomogeneous MbHomogeneous::operator | ( const MbHomogeneous &vect2 ) const { + return MbHomogeneous( y * vect2.w - w * vect2.y, + w * vect2.x - x * vect2.w, + x * vect2.y - y * vect2.x ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на число \en The multiplication by a number +// --- +inline void MbHomogeneous::operator *= ( double factor ) { + x *= factor; + y *= factor; + w *= factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление на число \en The division by a number +// --- +inline void MbHomogeneous::operator /= ( double factor ) { + if ( factor != 0 ) { + double k = 1.0 / factor; + x *= k; + y *= k; + w *= k; + } +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на число \en The multiplication by a number +// --- +inline MbHomogeneous MbHomogeneous::operator * ( double factor ) const { + return MbHomogeneous( x * factor, y * factor, w * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Деление на число \en The division by a number +// --- +inline MbHomogeneous MbHomogeneous::operator / ( double factor ) const { + if ( factor != 0 ) { + double k = 1.0 / factor; + return MbHomogeneous( x * k, y * k , w * k ); + } + else { + return MbHomogeneous( x, y, w ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на равенство. \en Check for equality. +// --- +inline bool MbHomogeneous::operator == ( const MbHomogeneous & with ) const +{ + return IsSame( with, Math::LengthEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на неравенство. \en Check for inequality. +// --- +inline bool MbHomogeneous::operator != ( const MbHomogeneous & with ) const +{ + return !( *this == with ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbHomogeneous::IsSame( const MbHomogeneous & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(w - other.w) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/** \brief \ru Разделение координат и весов. + \en Separation of coordinates and weights. \~ + \details \ru Разделение координат и весов. \n + Дополнительная координата точки (вес) вводится для удобства работы с неоднородными рациональными сплайнами.\n + \en Separation of coordinates and weights. \n + Additional coordinate of a point (weight) is introduced for the convenience of working with non-uniform rational splines. \n \~ + \ingroup Mathematic_Base_2D +*/ +// --- +template< typename ParamContainer, typename PointContainer > +void SplitHomoVector( const SArray & hList, PointContainer & uvList, ParamContainer * tList = NULL ) +{ + const size_t sz = hList.size(); + uvList.clear(); + uvList.reserve( sz ); + if ( tList != NULL ) { + tList->clear(); + tList->reserve( sz ); + for ( size_t n = 0; n < sz; n++ ) { + uvList.push_back( MbCartPoint( hList[n].x, hList[n].y ) ); + tList->push_back( hList[n].w ); + } + } + else { + for ( size_t n = 0; n < sz; n++ ) + uvList.push_back( MbCartPoint( hList[n].x, hList[n].y ) ); + } +} + +//------------------------------------------------------------------------------ +// Выделить только координаты +// --- +inline +void SplitHomoVector( const SArray & hList, SArray & uvList ) { + SplitHomoVector >( hList, uvList ); +} + +} // namespace C3D + + +#endif // __MB_HOMOGENIUS_H diff --git a/C3d/Include/mb_homogeneous3d.h b/C3d/Include/mb_homogeneous3d.h new file mode 100644 index 0000000..06c39c3 --- /dev/null +++ b/C3d/Include/mb_homogeneous3d.h @@ -0,0 +1,484 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Расширенная точка с однородными координатами в трёхмерном пространстве. + \en Extended point with homogeneous coordinates in the three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_HOMOGENIUS3D_H +#define __MB_HOMOGENIUS3D_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширенная точка с однородными координатами в трёхмерном пространстве. + \en Extended point with homogeneous coordinates in the three-dimensional space. \~ + \details \ru Расширенная точка с однородными координатами в трёхмерном пространстве. + Дополнительная координата точки (вес) вводится для удобства работы с неоднородными + рациональными сплайнами.\n + Определены операции преобразования точки и вектора в однородные координаты. + Определены различные арифметические операции однородной точки с числом, декартовой точкой и однородной точкой. + \en Extended point with homogeneous coordinates in the three-dimensional space. + Additional coordinate of a point (weight) is introduced for the convenience of working with non-uniform + rational splines. \n + Operations of transformation of a point and a vector in homogeneous coordinates are defined. + Various arithmetic operations of a homogeneous point with a number, a cartesian point and a homogeneous point are defined. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbHomogeneous3D { + +public : + double x; ///< \ru Первая координата точки. \en A first point coordinate. + double y; ///< \ru Вторая координата точки. \en A second point coordinate. + double z; ///< \ru Третья координата точки. \en A third point coordinate. + double w; ///< \ru Вес точки. \en A point weight. + + static const MbHomogeneous3D zero; ///< \ru Нулевая точка. \en Zero point. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbHomogeneous3D() : x( 0.0 ), y( 0.0 ), z( 0.0 ), w( 1.0 ) {} + /// \ru Конструктор по точке и весу. \en The constructor by a point and a weight. + MbHomogeneous3D( const MbVector3D & v, double ww ) : x( v.x * ww ), y( v.y * ww ), z( v.z * ww ), w( ww ) {} + /// \ru Конструктор копирования. \en Copy constructor. + MbHomogeneous3D( const MbHomogeneous3D & v ) : x( v.x ), y( v.y ), z( v.z ), w( v.w ) {} + /// \ru Конструктор по компонентам точки и весу. \en The constructor by point components and weight. + MbHomogeneous3D( double initX, double initY, double initZ, double initW ) : x( initX ), y( initY ), z( initZ ), w( initW ) {} + +public: + /// \ru Инициализация по компонентам точки и весу. \en The initialization by point components and weight. + void Init( double xx, double yy, double zz, double ww ) { x = xx; y = yy; z = zz; w = ww; } + /// \ru Инициализация по компонентам точки и весу. \en The initialization by point components and weight. + void Init( const MbCartPoint3D & pnt, double weight ) { x = pnt.x*weight; y = pnt.y*weight; z = pnt.z*weight; w = weight; } + /// \ru Установить вектор нулевой длины. \en Set a vector with null length. + void SetZero() { x = y = z = 0.0; w = 1.0; } + + /// \ru Сделать копию элемента. \en Create a copy of the element. + MbHomogeneous3D & Duplicate() const; + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D & matr ); + + /// \ru Дать вес точки. \en Get a point weight. + double GetWeight() const { return w; } + /// \ru Вычислить декартовы координаты, как точки. \en Calculate cartesian coordinates as point. + void GetCartPoint( MbCartPoint3D & pnt ) const; + /// \ru Вычислить декартовы координаты, как вектора. \en Calculate cartesian coordinates as vector. + void GetVector ( MbVector3D & vect ) const; + /// \ru Преобразовать точку в однородные координаты. \en Transform a point to homogeneous coordinates. + void Set( const MbCartPoint3D & pnt ); + /// \ru Преобразовать точку в однородные координаты. \en Transform a point to homogeneous coordinates. + void Set( const MbCartPoint3D & pnt, double weight ); + /// \ru Преобразовать вектор в однородные координаты. \en Transform a vector to homogeneous coordinates. + void Set( const MbVector3D & vect, double weight ); + /** + \brief \ru Установить по точкам. + \en Set by points. \~ + \details \ru Координаты точки равны сумме однородных координат исходных точек, а вес - сумме весов. + \en Coordinates of a point are equal to the sum of homogeneous coordinates of initial points, and weight is equal to the sum of the weights. \~ + \param[in] pnt1, pnt2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] weight1, weight2 - \ru Весы точек. + \en Weights of points. \~ + */ + void Set( const MbCartPoint3D & pnt1, double weight1, + const MbCartPoint3D & pnt2, double weight2 ); + /** + \brief \ru Добавить точку. + \en Add a point. \~ + \details \ru Увеличить координаты на значения однородных координат точки. + \en Increase coordinates by values of homogeneous coordinates of a point. \~ + \param[in] pnt - \ru Исходная точка. + \en The initial point. \~ + \param[in] weight - \ru Вес точки. + \en A point weight. \~ + */ + void Add( const MbCartPoint3D & pnt, double weight ); + /** + \brief \ru Добавить точки. + \en Add points. \~ + \details \ru Увеличить координаты на значения однородных координат двух исходных точек. + \en Increase coordinates by values of the homogeneous coordinates of two initial points. \~ + \param[in] pnt1, pnt2 - \ru Исходные точки. + \en Initial points. \~ + \param[in] weight1, weight2 - \ru Весы точек. + \en Weights of points. \~ + */ + void Add( const MbCartPoint3D & pnt1, double weight1, + const MbCartPoint3D & pnt2, double weight2 ); ///< \ru Добавить точки. \en Add points. + /// \ru Разность p2 - p1 умножить на kk. \en Subtract p2 - p1 multiple by kk. + void Dec( const MbHomogeneous3D & p1, const MbHomogeneous3D & p2, double kk ); + /// \ru Приравнять координаты вектора координатам точки v1, умноженных на t1. \en Equate coordinates of vector with coordinates of point v1 multiplied by t1. + void Set( const MbHomogeneous3D & v1, double t1 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector coordinates with sum of points v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector coordinates with coordinates of sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3, const MbHomogeneous3D & v4, double t4 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3, v4 и v5, умноженных на t1, t2, t3 t4 и t5 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3, t4, t5 correspondingly. + void Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3, const MbHomogeneous3D & v4, double t4, const MbHomogeneous3D & v5, double t5 ); + /// \ru Добавить вектор p, умноженный на kk. \en Add vector p multiplied by kk. + void Add( const MbHomogeneous3D & v, double t ); + + /** + \ru \name Перегрузка арифметических операций. + \en \name Overload of arithmetic operations. + \{ */ + /// \ru Сложить две точки. \en Add two points. + MbHomogeneous3D operator + ( const MbHomogeneous3D & with ) const; + /// \ru Вычесть из точки точку. \en Subtract a point from the point. + MbHomogeneous3D operator - ( const MbHomogeneous3D & with ) const; + /// \ru Разделить координаты точки на число. \en Divide point coordinates by a number. + MbHomogeneous3D operator / ( double factor ) const; + /// \ru Присвоить значение. \en Assign a value. + void operator = ( const MbHomogeneous3D & ); + /// \ru Умножить координаты точки на число. \en Multiply point coordinates by a number. + void operator *= ( double factor ); + /// \ru Разделить координаты точки на число. \en Divide point coordinates by a number. + void operator /= ( double factor ); + /// \ru Прибавить координаты точки. \en Add coordinates of the point. + void operator += ( const MbHomogeneous3D & with ); + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbHomogeneous3D & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbHomogeneous3D & ) const; + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbHomogeneous3D & other, double accuracy ) const; + /** \} */ + + /// \ru Функция чтения по ссылке. \en Reading function by reference. + friend MATH_FUNC (reader &) operator >> ( reader & in, MbHomogeneous3D & ref ); + /// \ru Функция записи по ссылке. \en Writing function by reference. + friend MATH_FUNC (writer &) operator << ( writer & out, const MbHomogeneous3D & ref ); + /// \ru Функция записи по ссылке. \en Writing function by reference. + friend MATH_FUNC (writer &) operator << ( writer & out, MbHomogeneous3D & ref ) { return operator << ( out, (const MbHomogeneous3D &)ref ); } +}; // MbHomogeneous3D + + +//------------------------------------------------------------------------------ +// \ru Вычисление декартовых координат как точки \en Calculation of the cartesian coordinates as point +// --- +inline void MbHomogeneous3D::GetCartPoint( MbCartPoint3D & pnt ) const { + if ( w != 0 ) { //-V550 + double r = 1.0 / w; + pnt.x = x * r; + pnt.y = y * r; + pnt.z = z * r; + } + else { + pnt.x = x; + pnt.y = y; + pnt.z = z; + } +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление декартовых координат как точки \en Calculation of the cartesian coordinates as point +// --- +inline void MbHomogeneous3D::GetVector( MbVector3D & v ) const { + v.x = x; + v.y = y; + v.z = z; + if ( w != 0 ) { //-V550 + double k = 1.0 / w; + v.x *= k; + v.y *= k; + v.z *= k; + } +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать точку в однородные координаты \en Transform a point to homogeneous coordinates +// --- +inline void MbHomogeneous3D::Set( const MbCartPoint3D & pnt ) { + x = pnt.x * w; + y = pnt.y * w; + z = pnt.z * w; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать точку в однородные координаты \en Transform a point to homogeneous coordinates +// --- +inline void MbHomogeneous3D::Set( const MbCartPoint3D & pnt, double weight ) { + x = pnt.x * weight; + y = pnt.y * weight; + z = pnt.z * weight; + w = weight; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать вектор в однородные координаты \en Transform a vector to homogeneous coordinates +// --- +inline void MbHomogeneous3D::Set( const MbVector3D & vect, double weight ) { + x = vect.x * weight; + y = vect.y * weight; + z = vect.z * weight; + w = weight; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать точки в однородные координаты \en Transform points to homogeneous coordinates +// --- +inline void MbHomogeneous3D::Set( const MbCartPoint3D & pnt1, double weight1, + const MbCartPoint3D & pnt2, double weight2 ) { + x = pnt1.x * weight1 + pnt2.x * weight2; + y = pnt1.y * weight1 + pnt2.y * weight2; + z = pnt1.z * weight1 + pnt2.z * weight2; + w = weight1 + weight2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить точку \en Add a point +// --- +inline void MbHomogeneous3D::Add( const MbCartPoint3D & pnt, double weight ) { + x += pnt.x * weight; + y += pnt.y * weight; + z += pnt.z * weight; + w += weight; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить точки \en Add points +// --- +inline void MbHomogeneous3D::Add( const MbCartPoint3D & pnt1, double weight1, + const MbCartPoint3D & pnt2, double weight2 ) { + x += pnt1.x * weight1 + pnt2.x * weight2; + y += pnt1.y * weight1 + pnt2.y * weight2; + z += pnt1.z * weight1 + pnt2.z * weight2; + w += weight1 + weight2; +} + + +//------------------------------------------------------------------------------ +/// \ru Разность p2 - p1 умножить на kk. \en Subtract p2 - p1 multiple by kk. +// --- +inline void MbHomogeneous3D::Dec( const MbHomogeneous3D & p1, const MbHomogeneous3D & p2, + double kk ) { + x = ( p2.x - p1.x ) * kk; + y = ( p2.y - p1.y ) * kk; + z = ( p2.z - p1.z ) * kk; + w = ( p2.w - p1.w ) * kk; +} + + +//------------------------------------------------------------------------------ +/// \ru Приравнять вектору вектор p, умноженному на kk. \en Equate vector with vector p multiplied by k. +// --- +inline void MbHomogeneous3D::Set( const MbHomogeneous3D & v1, double t1 ) +{ + x = v1.x * t1; + y = v1.y * t1; + z = v1.z * t1; + w = v1.w * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous3D::Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2 ) +{ + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; + w = v1.w * t1 + v2.w * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous3D::Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; + z = v1.z * t1 + v2.z * t2 + v3.z * t3; + w = v1.w * t1 + v2.w * t2 + v3.w * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbHomogeneous3D::Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3, const MbHomogeneous3D & v4, double t4 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; + w = v1.w * t1 + v2.w * t2 + v3.w * t3 + v4.w * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3, v4 и v5, умноженных на t1, t2, t3 t4, t4 и t5 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3, t4, t5 correspondingly. +// --- +inline void MbHomogeneous3D::Set( const MbHomogeneous3D & v1, double t1, const MbHomogeneous3D & v2, double t2, + const MbHomogeneous3D & v3, double t3, const MbHomogeneous3D & v4, double t4, const MbHomogeneous3D & v5, double t5 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4 + v5.x * t5; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4 + v5.y * t5; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4 + v5.z * t5; + w = v1.w * t1 + v2.w * t2 + v3.w * t3 + v4.w * t4 + v5.w * t5; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить вектор p, умноженный на kk. \en Add vector p multiplied by kk. +// --- +inline void MbHomogeneous3D::Add( const MbHomogeneous3D & p, double kk ) +{ + x += p.x * kk; + y += p.y * kk; + z += p.z * kk; + w += p.w * kk; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение \en Assignment +// --- +inline void MbHomogeneous3D::operator = ( const MbHomogeneous3D & obj ) { + x = obj.x; + y = obj.y; + z = obj.z; + w = obj.w; +} + +//------------------------------------------------------------------------------ +// \ru Сложение \en Addition +// --- +inline MbHomogeneous3D MbHomogeneous3D::operator + ( const MbHomogeneous3D & with ) const { + return MbHomogeneous3D( x + with.x, y + with.y, z + with.z, w + with.w ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание \en Subtraction +// --- +inline MbHomogeneous3D MbHomogeneous3D::operator - ( const MbHomogeneous3D & with ) const { + return MbHomogeneous3D( x - with.x, y - with.y, z - with.z, w - with.w ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на число \en Multiplication by a number +// --- +inline MbHomogeneous3D operator * ( const MbHomogeneous3D & vector, double factor ) { + return MbHomogeneous3D( vector.x*factor, vector.y*factor, vector.z*factor, vector.w*factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на число \en Multiplication by a number +// --- +inline MbHomogeneous3D operator * ( double factor, const MbHomogeneous3D &vector ) { + return vector * factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление на число \en Division by a number +// --- +inline MbHomogeneous3D MbHomogeneous3D::operator / ( double factor ) const { + if ( factor != 0 ) { //-V550 + double r = 1.0 / factor; + return MbHomogeneous3D( x * r, y * r, z * r, w * r ); + } + else { + return MbHomogeneous3D( x, y, z, w ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на число \en Multiplication by a number +// --- +inline void MbHomogeneous3D::operator *= ( double factor ) { + x *= factor; + y *= factor; + z *= factor; + w *= factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление на число \en Division by a number +// --- +inline void MbHomogeneous3D::operator /= ( double factor ) { + if ( factor != 0 ) { //-V550 + x /= factor; + y /= factor; + z /= factor; + w /= factor; + } +} + + +//------------------------------------------------------------------------------ +// \ru Сложение \en Addition +// --- +inline void MbHomogeneous3D::operator += ( const MbHomogeneous3D & with ) { + x += with.x; + y += with.y; + z += with.z; + w += with.w; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на равенство. \en Check for equality. +// --- +inline bool MbHomogeneous3D::operator == ( const MbHomogeneous3D & with ) const +{ + return IsSame( with, Math::region ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на неравенство. \en Check for inequality. +// --- +inline bool MbHomogeneous3D::operator != ( const MbHomogeneous3D & with ) const +{ + return !( *this == with ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbHomogeneous3D::IsSame( const MbHomogeneous3D & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(z - other.z) < accuracy) && + (::fabs(w - other.w) < accuracy) ); +} + + +#endif // __MB_HOMOGENIUS3D_H diff --git a/C3d/Include/mb_matrix.h b/C3d/Include/mb_matrix.h new file mode 100644 index 0000000..f84773d --- /dev/null +++ b/C3d/Include/mb_matrix.h @@ -0,0 +1,781 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Расширенная матрица преобразования в двумерном пространстве. + \en The extended matrix of transformation in a two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_MATRIX_H +#define __MB_MATRIX_H + + +#include +#include + + +#define MATRIX_DIM_2D 3 + + +class MATH_CLASS MbPlacement; +class MATH_CLASS MbHomogeneous; + + +template +void CheckOrigin ( const Transform & trans, uint8 & flag, bool resetFlag ); +template +void CheckRotation( const Transform & trans, uint8 & flag, bool resetFlag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширенная матрица преобразования в двумерном пространстве. + \en The extended matrix of transformation in a two-dimensional space. \~ + \details \ru Расширенная матрица преобразования в двумерном пространстве. \n + Расширенная матрица имеет размерность (3, 3) и представляет собой обычную матрицу, + окаймлённую снизу вектором сдвига а справа нулевым столбцом. + Трансформация точки p по матрице M имеет вид: r = p * M (строка координат умножается на матрицу слева).\n + Матрица преобразования из локальной системы координат может быть получена следующим образом:\n + первая строка матрицы должна быть заполнена соответствующими компонентами первого вектора локальной системы, + вторая строка матрицы должна быть заполнена соответствующими компонентами второго вектора локальной системы, + последняя строка матрицы должна быть заполнена соответствующими координатами положения начала локальной системы. + Матрица трансформации состоит из четырёх блоков:\n + | R, P | + | V, S | + где R - матрица вращения, тензор размерностью (2, 2), + V - вектор сдвига, тензор (0, 2), + P - вектор перспективы, тензор (2, 0) (всегда ноль), + S - скаляр масштабного преобразования (единица).\n + \en The extended matrix of transformation in a two-dimensional space. \n + The extended matrix has dimension (3, 3) and is a regular matrix + bordered below by a translation vector and by the null column to the right. + The transformation of point "p" by the matrix "M" has the form: r = p * M (the row of coordinates is multiplied by the matrix to the left).\n + The transformation matrix from a local coordinate system can be obtained as follows:\n + the first row must be filled with the corresponding components of the first vector of a local system, + the second row must be filled with the corresponding components of the second vector of a local system, + the last row of the matrix must be filled with the corresponding coordinates of a local system origin. + The matrix of transformation consists of four blocks:\n + | R, P | + | V, S | + where R - is a rotation matrix, the tensor with dimension (2, 2), + V - translation vector, tensor (0, 2), + P - perspective vector, the tensor (2, 0) (always null), + S - scalar of scale transformation (the unit). \ n \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbMatrix { + friend MATH_FUNC (void) MulMatrix( const MbMatrix &, const MbMatrix &, MbMatrix & ); +protected: + double el[MATRIX_DIM_2D][MATRIX_DIM_2D]; ///< \ru Элементы матрицы. \en Elements of matrix. +private: + /** + \brief \ru Состояние матрицы определяется установкой битовых полей. + \en State of the matrix is defined by setting of bit fields. \~ + \details \ru Состояние матрицы определяется установкой битовых полей: \n + MB_TRANSLATION - вектор трансляции не ноль, \n + MB_ROTATION - матрица вращения не единичная, \n + MB_SCALING - масштабный компонент не 1.0, \n + MB_REFLECTION - детерминант матрицы вращения отрицателен, \n + MB_ORTOGONAL - матрица вращения ортогональная, взводится только в случае аффинной системы координат, \n + MB_AFFINE - матрица вращения произвольная аффинная, \n + MB_PERSPECTIVE - присутствует перспективное преобразование (не нулевой вектор перспективы), \n + MB_UNSET - битовые флаги не установлены. \n + При изменении элементов матрицы (el[..][..]) flag должен быть сброшен в неустановленное состояние MB_UNSET, + при котором происходит полный пересчет состояния матрицы по требованию, для оптимизации функционала матрицы + рекомендуется устанавливать его в ручную соответственно тому как изменилось содержание el[..][..]. \n + При модификации извне пользоваться методами Set* которые автоматически сбрасыват флаг в неустановленное состояние + при получении данных матрицы из вне пользоваться методами Get*, + НЕ ПОЛЬЗОВАТСЯ МЕТОДАМИ Get* ДЛЯ ИЗМЕННИЯ ЭЛЕМЕНТОВ МАТРИЦЫ ПЕРЕИМЕНОВЫВАЯ const В НЕ const, + НЕ ДОСТУПАТЬСЯ К ДАННЫМ МАТРИЦЫ НАПРЯМУЮ В ОБХОД Get* и Set*. + \en State of the matrix is defined by setting of bit fields: \n + MB_TRANSLATION - translation vector is not zero \n + MB_ROTATION - rotation matrix is not unit \n + MB_SCALING - scale component is not 1.0, \n + MB_REFLECTION - determinant of the rotation matrix is negative, \n + MB_ORTOGONAL - orthogonal matrix of rotation, it is used only if coordinate system is affine \n + MB_AFFINE - arbitrary affine rotation matrix, \n + MB_PERSPECTIVE - is perspective transformation (non-zero perspective vector), \n + MB_UNSET - bit flags are not set. \n + If matrix elements (el[..][..]) are changed, then 'flag' must be set to unspecified MB_UNSET state, + for which the full recalculation of the matrix state is performed (on request) to optimize the functional of the matrix. + It is recommended to set it manually according to how the content of el [..] [..] is changed. \n + To modify data of a matrix from the outside use "Set..." methods which automatically reset the flag to unspecified state, + use "Get..." methods to get data of matrix from the outside, + DO NOT USE "Get..." METHODS TO MODIFY MATRIX ELEMENTS BY RENAMING const TO non-const, + USE ONLY Get* AND Set* TO ACCESS AND MODIFY OF MATRIX DATA. \~ + */ + mutable uint8 flag; + +public: + static const MbMatrix identity; ///< \ru Единичная матрица, I = diag(1,1,1); \en Identity matrix, I = diag(1,1,1); + +public : + /// \ru Конструктор по умолчанию. \en Default constructor. + MbMatrix() : flag( MB_UNSET ) { Init(); } + /// \ru Конструктор копирования. \en Copy constructor. + MbMatrix( const MbMatrix & init ) : flag( init.flag ) { ::memcpy( &el, init.el, sizeof(el) ); } + /// \ru Конструктор по локальной системе координат. \en The constructor by placement. + explicit MbMatrix( const MbPlacement & place ) : flag( MB_UNSET ) { Set( place ); } +public: + /** + \brief \ru Конструктор по точке и нормализованному вектору. + \en The constructor by a point and a normalized vector \~ + \details \ru Конструктор по точке и нормализованному вектору. + \en The constructor by a point and a normalized vector \~ + \param[in] pnt - \ru Точка. Задает сдвиг относительно нуля. + \en A point. Sets translation relative to zero. \~ + \param[in] dir - \ru Единичный вектор. Задает поворот. + \en Unit vector. Sets a rotation. \~ + */ + MbMatrix( const MbCartPoint & pnt, const MbDirection & dir ) : flag( MB_UNSET ) { Init( pnt, dir ); } + /** + \brief \ru Конструктор матрицы масштабирования по x и y. + \en The constructor of scaling matrix by x and y. \~ + \details \ru Конструктор матрицы масштабирования по x и y. + \en The constructor of scaling matrix by x and y. \~ + \param[in] pnt - \ru Точка. Задает сдвиг относительно нуля. + \en A point. Sets translation relative to zero. \~ + \param[in] sx, sy - \ru Коэффициенты масштабирования по x и y соответственно. + \en Scaling coefficients by x and y, respectively. \~ + */ + MbMatrix( const MbCartPoint & pc, double sx, double sy ) : flag( MB_UNSET ) { Init( pc, sx, sy ); } + /** + \brief \ru Конструктор матрицы поворота. + \en The constructor of rotation matrix. \~ + \details \ru Конструктор матрицы поворота вокруг точки pc на угол angle. + \en The constructor of rotation matrix around the point "pc" on the angle "angle". \~ + \param[in] pc - \ru Точка. + \en A point. \~ + \param[in] angle - \ru Угол поворота. + \en A rotation angle. \~ + */ + MbMatrix( const MbCartPoint & pc, double angle ) : flag( MB_UNSET ) { Init( pc, angle ); } +public: + /// \ru Деструктор. \en Destructor. + ~MbMatrix(); + +public : + /** + \ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + /// \ru Инициализировать матрицу как единичную. \en Initialize a matrix as unit one. + MbMatrix & Init(); + /** + \brief \ru Инициализировать матрицу по точке и нормализованному вектору. + \en Initialize a matrix by a point and normalized vector. \~ + \details \ru Инициализировать матрицу по точке и нормализованному вектору. + \en Initialize a matrix by a point and normalized vector. \~ + \param[in] pnt - \ru Точка. Задает сдвиг относительно нуля. + \en A point. Sets translation relative to zero. \~ + \param[in] dir - \ru Единичный вектор. Задает поворот. + \en Unit vector. Sets a rotation. \~ + */ + MbMatrix & Init( const MbCartPoint & pnt, const MbDirection & dir ); + /** + \brief \ru Инициализировать матрицу масштабирования по x и y. + \en Initialize scaling matrix by x and y. \~ + \details \ru Инициализировать матрицу масштабирования по x и y. + \en Initialize scaling matrix by x and y. \~ + \param[in] pnt - \ru Точка. Задает сдвиг относительно нуля. + \en A point. Sets translation relative to zero. \~ + \param[in] sx, sy - \ru Коэффициенты масштабирования по x и y соответственно. + \en Scaling coefficients by the x and y, respectively. \~ + */ + MbMatrix & Init( const MbCartPoint & pc, double sx, double sy ); + /** + \brief \ru Инициализировать матрицу поворота. + \en Initialize a rotation matrix. \~ + \details \ru Инициализировать матрицу поворота вокруг точки pc на угол angle. + \en Initialize a rotation matrix around the point "pc" on the angle "angle". \~ + \param[in] pc - \ru Точка. + \en A point. \~ + \param[in] angle - \ru Угол поворота. + \en A rotation angle. \~ + */ + MbMatrix & Init( const MbCartPoint & pc, double angle ); + /** + \brief \ru Инициализировать матрицу согласно плейсменту. + \en Initialize a matrix according to a placement. \~ + \details \ru Инициализировать матрицу согласно плейсменту. + \en Initialize a matrix according to a placement. \~ + \param[in] place - \ru Исходный плейсмент. + \en The initial placement. \~ + */ + MbMatrix & Set ( const MbPlacement & place ); + /// \ru Задать нулевую матрицу. \en Set a zero matrix. + MbMatrix & SetZero(); + + /** \} */ +public: + /** + \ru \name Функции проверки свойств матриц. + \en \name Functions for check of matrices properties. + \{ */ + + + /// \ru Выдать признак отрицательности детерминанта матрицы вращения. \en Get an attribute of negativity of the determinant of a rotation matrix. + bool IsInvert() const { return IsLeft(); } + /// \ru Выдать признак отрицательности детерминанта матрицы вращения. \en Get an attribute of negativity of the determinant of a rotation matrix. + bool IsInvertEps( double eps = EXTENT_EPSILON ) const { return (el[0][0] * el[1][1] - el[0][1] * el[1][0]) < -eps; } + /// \ru Выдать признак единичности матрицы. \en Get an attribute of unit matrix. + bool IsSingle() const { return (MB_IDENTITY == CheckFlag()); } + /// \ru Выдать признак единичности матрицы с заданной точностью. \en Get an attribute of the identity matrix with a given tolerance. + bool IsSingleEps( double eps = LENGTH_EPSILON ) const; + + /// \ru Выдать признак не равенства нулю вектора трансляции. \en Get an attribute of inequality to zero of translation vector. + bool IsTranslation() const { return !!( CheckFlag() & MB_TRANSLATION ); } + /// \ru Выдать признак не единичности матрицы вращения. \en Get an attribute of non-identity of a rotation matrix. + bool IsRotation () const { return !!( CheckFlag() & MB_ROTATION ); } + /// \ru Выдать признак лево-определенной матрицы. \en Get an attribute of the left-definite matrix. + bool IsLeft () const { return !!( CheckFlag() & MB_LEFT ); } + /// \ru Выдать признак ортогональности для случая аффинной матрицы. \en Get an attribute of orthogonality for the case if the matrix is affine. + bool IsOrt () const { return !!( CheckFlag() & MB_ORTOGONAL ); } + /// \ru Выдать признак ортогональности для матрицы вращения. \en Get an attribute of orthogonality for the case if the matrix is a rotation matrix. + bool IsOrthogonal () const { CheckFlag(); return ( !(flag & MB_AFFINE) || !!(flag & MB_ORTOGONAL) ); } + /// \ru Выдать признак того, что матрица вращения произвольная аффинная. \en Get an attribute that the rotational matrix is arbitrary and affine. + bool IsAffine () const { return !!( CheckFlag() & MB_AFFINE ); } + + /// \ru Выдать признак не равенства 1.0 масштабного компонента. \en Get an attribute of inequality to 1.0 of a scale component. + bool IsScaling () const { return !!( CheckFlag() & MB_SCALING ); } + ///< \ru Выдать признак не равенства нулю вектора перспективы. \en Get an attribute of inequality to zero of perspective vector. + bool IsPerspective() const { return !!( CheckFlag() & MB_PERSPECTIVE ); } + /// \ru Проверить, что битовые флаги не установлены. \en Check whether bit flags are not set. + bool IsUnSet () const { return !!( flag & MB_UNSET ); } + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbMatrix &, double accuracy ) const; + + /// \ru Выдать признак, что есть только перенос. \en Get an attribute that there is only translation. + bool IsTranslationOnly() const; + /// \ru Совпадают ли оси описываемой матрицей ЛСК с глобальными осями с точностью до поворотов на 90 градусов? \en Are the axis described by the matrix local system coincide with global axes up to a 90-degree rotation? + bool IsSubstitutionOnly( double epsilon = METRIC_EPSILON ) const; + /** + \brief \ru Выдать признак изотропности. + \en Get an attribute of isotropism. \~ + \details \ru Выполняется проверка, является ли матрица ортогональной с равными по длине + осями X, Y (круг остается кругом). + \en Checks whether the matrix is orthogonal with equal lengths of + X and Y axes (circle remains a circle). \~ + \param[out] l - \ru Длина ортов осей X, Y. + \en The length of the X and Y axes orts. \~ + \return \ru true, если матрица изотропна. + \en Returns true if the matrix is isotropic. \~ + */ + bool IsIsotropic( double & l ) const; + + /// \ru Можно ли трансформировать габарит без искажений? \en Is it possible to transform a bounding box without distortion? + bool CanTransformGabarit() const; + + /** \} */ +public: + /** + \ru \name Функции доступа к элементам матрицы. + \en \name Functions of access to matrix elements. + \{ */ + + /// \ru Выдать элемент матрицы. \en Get an element of the matrix. + double El( size_t i, size_t j ) const { return el[i][j]; } + /// \ru Выдать указатель на первый элемент матрицы. \en Get a pointer to the first matrix element. + const double * GetEl() const { return (const double *)el; } + + /// \ru Выдать первую строку (ось X). \en Get the first row (the X-axis). + const MbVector & GetAxisX() const { return (const MbVector &)*el[0]; } + /// \ru Выдать вторую строку (ось Y). \en Get the second row (the Y-axis). + const MbVector & GetAxisY() const { return (const MbVector &)*el[1]; } + /// \ru Выдать третью строку (начало системы координат). \en Get the third row (the origin of coordinates) + const MbCartPoint & GetOrigin() const { return (const MbCartPoint &)*el[2]; } + + /// \ru Выдать i-ый вектор-столбец матрицы. \en Get the i-th column vector of the matrix. + MbVector GetColumn ( size_t i ) const { return MbVector( el[0][i], el[1][i] ); } + /// \ru Выдать i-ую вектор-строку матрицы. \en Get the i-th row-vector of the matrix. + MbVector GetRow ( size_t i ) const { return MbVector( el[i][0], el[i][1] ); } + /// \ru Выдать i-ый вектор-столбец матрицы. \en Get the i-th column vector of the matrix. + MbHomogeneous GetFullColumn( size_t i ) const { return MbHomogeneous( el[0][i], el[1][i], el[2][i] ); } + /// \ru Выдать i-ую вектор-строку матрицы. \en Get the i-th row-vector of the matrix. + MbHomogeneous GetFullRow ( size_t i ) const { return MbHomogeneous( el[i][0], el[i][1], el[i][2] ); } + + /** \} */ +public: + /** + \ru \name Функции модификации элементов матрицы. + \en \name Functions for matrix elements modification. + \{ */ + + /** + \brief \ru Присвоить значение элементу матрицы. + \en Assign a value to the matrix element. \~ + \details \ru Присвоить значение элементу матрицы. + \en Assign a value to the matrix element. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное значение, которое надо присвоить элементу матрицы. + \en Initial value which to be assigned to an element of the matrix. \~ + */ + void El( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] = e; } + /** + \brief \ru Прибавить число к элементу матрицы. + \en Add a number to the matrix element. \~ + \details \ru Прибавить число к элементу матрицы. + \en Add a number to the matrix element. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное число, которое надо прибавить к элементу матрицы. + \en Initial number which to be added to the matrix element. \~ + */ + void AddEl( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] += e; } + /** + \brief \ru Умножить элемент матрицы на число. + \en Multiply the matrix element by a number. \~ + \details \ru Умножить элемент матрицы на число. + \en Multiply the matrix element by a number. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное число, на которое надо умножить элемент матрицы. + \en Initial number by which to multiply the matrix element. \~ + */ + void MulEl( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] *= e; } + /** + \brief \ru Присвоить элементам столбца значения координат точки. + \en Assign point coordinates values to column elements. \~ + \details \ru Присвоить элементам столбца значения координат точки. + \en Assign point coordinates values to column elements. \~ + \param[in] icol - \ru Индекс столбца. + \en A column index. \~ + \param[in] column - \ru Исходная точка. + \en The initial point. \~ + */ + void SetColumn( size_t icol, const MbCartPoint & column ); + /** + \brief \ru Присвоить элементам столбца значения компонент вектора. + \en Assign vector components values to column elements. \~ + \details \ru Присвоить элементам столбца значения компонент вектора. + \en Assign vector components values to column elements. \~ + \param[in] icol - \ru Индекс столбца. + \en A column index. \~ + \param[in] column - \ru Исходный вектор. + \en The initial vector. \~ + */ + void SetColumn( size_t icol, const MbVector & column ); + /** + \brief \ru Присвоить элементам столбца значения координат однородной точки. + \en Assign coordinates of the uniform point to column elements. \~ + \details \ru Присвоить элементам столбца значения координат однородной точки. + \en Assign coordinates of the uniform point to column elements. \~ + \param[in] icol - \ru Индекс столбца. + \en A column index. \~ + \param[in] column - \ru Исходная точка. + \en The initial point. \~ + */ + void SetColumn( size_t icol, const MbHomogeneous & column ); + /** + \brief \ru Присвоить элементам строки значения компонент вектора. + \en Assign vector components values to row elements. \~ + \details \ru Присвоить элементам строки значения компонент вектора. + \en Assign vector components values to row elements. \~ + \param[in] irow - \ru Индекс столбца. + \en A column index. \~ + \param[in] row - \ru Исходный вектор. + \en The initial vector. \~ + */ + void SetRow( size_t irow, const MbVector & row ); + /** + \brief \ru Присвоить элементам строки значения координат точки. + \en Assign point coordinates values to row elements. \~ + \details \ru Присвоить элементам строки значения координат точки. + \en Assign point coordinates values to row elements. \~ + \param[in] irow - \ru Индекс столбца. + \en A column index. \~ + \param[in] row - \ru Исходная точка. + \en The initial point. \~ + */ + void SetRow( size_t irow, const MbCartPoint & row ); + /** + \brief \ru Присвоить элементам строки значения координат однородной точки. + \en Assign coordinates of the uniform point to row elements. \~ + \details \ru Присвоить элементам строки значения координат однородной точки. + \en Assign coordinates of the uniform point to row elements. \~ + \param[in] irow - \ru Индекс столбца. + \en A column index. \~ + \param[in] row - \ru Исходная точка. + \en The initial point. \~ + */ + void SetRow( size_t irow, const MbHomogeneous & row ); + /// \ru Установить компоненты сдвига матрицы. \en Set components of matrix translation. + void SetOrigin( const MbCartPoint & p ); + /** \} */ + +public: + /** + \ru \name Функции умножения матриц. + \en \name Matrices multiplication. + \{ */ + + /// \ru Домножить матрицу слева \en Multiply a matrix on the left + MbMatrix & PreMultiply ( const MbMatrix & ); + /// \ru Домножить матрицу справа \en Multiply a matrix on the right. + MbMatrix & PostMultiply ( const MbMatrix & ); + + /** \} */ +public: + /** + \ru \name Функции масштабирования. + \en \name Scaling functions. + \{ */ + /// \ru Масштабировать по X и Y. \en Scale by X and Y. + MbMatrix & Scale ( double s ); + /// \ru Масштабировать по X. \en Scale by X. + void ScaleX( double s ); + /// \ru Масштабировать по Y. \en Scale by Y. + void ScaleY( double s ); + /// \ru Выдать коэффициент масштабирования по X. \en Get scaling coefficient by X. + double GetScaleX() const; + /// \ru Выдать коэффициент масштабирования по Y. \en Get scaling coefficient by Y. + double GetScaleY() const; + /// \ru Проверить, различаются ли коэффициенты масштабирования по X и Y. \en Check differences of scaling coefficients (X and Y). + bool IsDifferentScale() const; + + /** \} */ +public: + /** + \ru \name Функции преобразований матрицы: сдвиг, поворот и т.д. + \en \name Functions of matrix transformations: translation, rotation, etc. + \{ */ + + /// \ru Сместить по X и Y. \en Shift by X and Y. + void Shift ( double shift ); + /// \ru Сместить по X. \en Shift by X. + void ShiftX( double shift ); + /// \ru Сместить по Y. \en Shift by Y. + void ShiftY( double shift ); + + /// \ru Сдвинуть на вектор (домножение справа на матрицу сдвига). \en Translate by the vector (multiply by translation matrix on the right). + MbMatrix & Move( const MbVector & v ) { return Move( v.x, v.y ); } + /// \ru Сдвинуть на заданные приращения. \en Translate by given increments. + MbMatrix & Move ( double dx, double dy ); + + /** + \brief \ru Повернуть на угол. + \en Rotate by an angle. \~ + \details \ru Поворот совершается вокруг оси Z. + \en Rotation is around the axis Z. \~ + \param[in] angle - \ru Угол вращения. + \en A rotation angle. \~ + */ + MbMatrix & Rotate( double angle ); + /** + \brief \ru Повернуть согласно вектору направления. + \en Rotate according to the direction vector. \~ + \details \ru Поворот совершается вокруг оси Z, т.к. матрица двумерная. Вектор направления + определяет угол поворота. + \en Rotation is around the Z axis, because matrix is two-dimensional. A direction vector + defines a rotation angle. \~ + \param[in] - \ru Вектор направления. + \en A direction vector. \~ + */ + MbMatrix & Rotate( const MbDirection & ); + /** + \brief \ru Повернуть вокруг точки на угол. + \en Rotate at angle around a point. \~ + \details \ru Повернуть вокруг точки на угол. + \en Rotate at angle around a point. \~ + \param[in] - \ru Точка. + \en A point. \~ + \param[in] angle - \ru Вектор направления, задающий угол вращения. + \en A direction vector which defines a rotation angle \~ + */ + MbMatrix & Rotate( const MbCartPoint &, const MbDirection & angle ); + + /** + \brief \ru Преобразовать координаты. + \en Transform coordinates. \~ + \details \ru Координаты преобразуются согласно матрице. + \en Coordinates are transformed according to a matrix. \~ + \param[in] x, y - \ru Старые координаты по x и y. + \en Old coordinates by x and y. \~ + \param[in] xn, yn - \ru Преобразованные координаты. + \en Transformed coordinates. \~ + */ + void TransformCoord ( double x, double y, double & xn, double & yn ) const; + /** + \brief \ru Преобразовать длину по направлению 0X. + \en Transform the length in the direction of 0X. \~ + \details \ru Длина преобразуются согласно матрице. Если матрица имеет разные масштабы по X и Y, + то масштаб по Y проигнорируется. + \en The length is transformed according to a matrix. If the matrix has a different scales for the X and Y, + then the scale by Y is ignored. \~ + \param[in, out] len - \ru Длина по направлению 0X. + \en The length in the direction of 0X. \~ + */ + void TransformScalarX( double & len ) const; + + /** + \brief \ru Задать матрицу преобразования симметрии (отражение). + \en Set the matrix to symmetry transformation (reflection). \~ + \details \ru Находится матрица для преобразования симметрии относительно прямой, заданной точкой и нормалью к прямой. + \en The matrix of symmetry transformation is found relative to a line which is defined by a point and the normal. \~ + \param[in] origin - \ru Точка прямой. + \en A point of a line. \~ + \param[in] normal - \ru Нормаль прямой. + \en The normal of a line. \~ + */ + MbMatrix & Symmetry( const MbCartPoint & origin, const MbVector & normal ); + /// \ru Найти матрицу для преобразования симметрии относительно прямой, заданной точкой и направлением. \en Find a matrix for transformation of symmetry relative to a line given by a point and direction. + MbMatrix & Symmetry( const MbCartPoint & origin, const MbDirection & direction ); + + /** \} */ +public: + /** + \ru \name Расчет алгебраических свойств матрицы. + \en \name Calculation of the algebraic properties of a matrix. + \{ */ + + /// \ru Транспонировать матрицу. \en Transpose a matrix. + void Adj(); + /// \ru Вычислить алгебраическое дополнение. \en Calculate the algebraic adjunct. + double Delta( size_t line, size_t column, size_t dim ) const; + /// \ru Вычислить определитель матрицы. \en Calculate the determinant of a matrix. + double Det ( size_t dim ) const; + /// \ru Вычислить обратную матрицу. \en Calculate inverse matrix. + void Div ( MbMatrix & ) const; + /// \ru Наибольший элемент матрицы по абсолютному значению. \en Maximal element of the matrix in absolute value. + double NormMax() const; + + /** \} */ +public: + /** + \ru \name Перегрузка алгебраических и логических операций. + \en \name Overload of arithmetical and logical operations. + \{ */ + /// \ru Умножить на матрицу справа. \en Multiply by the matrix on the right. + MbMatrix operator * ( const MbMatrix & ) const; + /// \ru Домножить на матрицу справа. \en Multiply by the matrix on the right. + MbMatrix & operator *= ( const MbMatrix & m ) { return PostMultiply( m ); } + /// \ru Присвоить значение. \en Assign a value. + MbMatrix & operator = ( const MbMatrix & m ) { flag = m.flag; ::memcpy( &el, m.el, sizeof(el) ); return *this; } + /// \ru Сравнить с матрицей (точность - LENGTH_EPSILON). \en Compare with a matrix(tolerance- LENGTH_EPSILON). + bool operator == ( const MbMatrix & ) const; + + /// \ru Доступ по ссылке к элементу матрицы. \en Access to a matrix element by a reference. + double & operator() ( size_t i, size_t j ) { C3D_ASSERT( std_max( i, j ) < MATRIX_DIM_2D ); flag = MB_UNSET; return el[i][j]; } + /// \ru Значение элемента матрицы. \en The value of a matrix element. + const double & operator() ( size_t i, size_t j ) const { C3D_ASSERT( std_max( i, j ) < MATRIX_DIM_2D ); return el[i][j]; } + + /** \} */ + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & properties ); + +private: + /// \ru Выставить флаги. \en Set flags. + uint8 ResetFlag() const; + // Оценить флаги, если оценки не было + uint8 CheckFlag() const { return IsUnSet() ? ResetFlag() : flag; } + // Проверить флаг смещения. + void CheckOrigin() const { ::CheckOrigin( *this, flag, true ); } + // \ru Проверить флаг вращения. \en Check rotation flag. + void CheckRotation() const { ::CheckRotation( *this, flag, true ); } + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( MbMatrix ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( MbMatrix ) + DECLARE_NEW_DELETE_CLASS_EX( MbMatrix ) +}; + + +//------------------------------------------------------------------------------- +// \ru Установка флага смещения для матрицы и системы координат. \en Check translation +/** +\attention \ru Только для внутреннего использования. +\en For internal use only. \~ +*/ +// --- +template +void CheckOrigin( const Transform & trans, uint8 & flag, bool resetFlag ) +{ + if ( !(flag & MB_UNSET) ) { + const MbCartPoint & pOrigin = trans.GetOrigin(); + const double lengthEpsilon = LENGTH_EPSILON; + + if ( (::fabs(pOrigin.x) > lengthEpsilon) || + (::fabs(pOrigin.y) > lengthEpsilon) ) + flag |= MB_TRANSLATION; + else if ( resetFlag ) { + flag &= ~MB_TRANSLATION; + } + } +} + + +//------------------------------------------------------------------------------- +// \ru Установка флага вращения для матрицы и системы координат. \en Check rotation. +// ( Использование корректно только для ортонормированных СК) +/** + \attention \ru Только для внутреннего использования. + \en For internal use only. \~ +*/ +// --- +template +void CheckRotation( const Transform & trans, uint8 & flag, bool resetFlag ) +{ + if ( !(flag & MB_UNSET) ) { + const MbVector & axisX = trans.GetAxisX(); + const MbVector & axisY = trans.GetAxisY(); + + // Барьер нулевых элементов матрицы + const double eps = EXTENT_EPSILON; + if ( ::fabs(axisX.y) > eps || + ::fabs(axisY.x) > eps || + ::fabs(axisX.x - 1.0) > eps || + ::fabs(axisY.y - 1.0) > eps ) + { + flag |= MB_ROTATION; + } + else if ( resetFlag ) { + flag &= ~MB_ROTATION; + flag &= ~MB_LEFT; + flag &= ~MB_ORTOGONAL; + flag &= ~MB_AFFINE; + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация матрицы. \en Initialize matrix. +// --- +inline MbMatrix & MbMatrix::Init() +{ + el[0][1] = el[0][2] = 0.0; //-V525 + el[1][0] = el[1][2] = 0.0; + el[2][0] = el[2][1] = 0.0; + el[0][0] = el[1][1] = el[2][2] = 1.0; + flag = MB_IDENTITY; + return *this; +} + +//------------------------------------------------------------------------------ +// \ru Инициализация матрицы по точке и нормализованному вектору направления \en Initialization of a matrix by a point and normalized direction vector +// --- +inline MbMatrix & MbMatrix::Init( const MbCartPoint & pnt, const MbDirection & dir ) +{ + Init(); // \ru Инициализация матрицы как единичной \en Initialization of unit matrix + Rotate( dir ); // \ru Поворот на угол dir \en Rotation by the "dir" angle. + Move( pnt.x, pnt.y ); // \ru Сдвиг в точку pnt \en Translation to "pnt" point + flag = MB_UNSET; + return *this; +} + + +//------------------------------------------------------------------------------- +// \ru Выдать признак, что есть только перенос. \en Get an attribute that there is only translation. +// --- +inline bool MbMatrix::IsTranslationOnly() const +{ + CheckFlag(); + if ( !!(flag & MB_TRANSLATION) && !(flag & MB_ROTATION) && !(flag & MB_LEFT) && !(flag & MB_SCALING) && !(flag & MB_PERSPECTIVE) ) + return true; + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство матриц. \en Check for equality of matrices. +// --- +inline bool MbMatrix::operator == ( const MbMatrix & m ) const +{ + bool bRes = true; + for ( size_t i = 0; (i < MATRIX_DIM_2D) && bRes; i++ ) { + bRes = ( (::fabs(el[i][0] - m.el[i][0]) <= LENGTH_EPSILON) && + (::fabs(el[i][1] - m.el[i][1]) <= LENGTH_EPSILON) && + (::fabs(el[i][2] - m.el[i][2]) <= LENGTH_EPSILON) ); + } + return bRes; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать длину по направлению 0X \en Transform the length in the direction of 0X +// \ru Если вдруг матрица начинена разными масштабами по X и Y, \en If the matrix has a different scales by X and Y, +// \ru То масштаб по Y игнорируется \en Then the scale by Y is ignored +// --- +inline void MbMatrix::TransformScalarX( double & len ) const { + len *= MbVector( el[0][0], el[0][1] ).Length(); +} + + +//------------------------------------------------------------------------------ +// \ru Двумерная матрица - преобразовать координаты \en Two-dimensional matrix - transform coordinates +// --- +inline void MbMatrix::TransformCoord( double x, double y, double & xn, double & yn ) const { + xn = x * el[0][0] + y * el[1][0] + el[2][0]; + yn = x * el[0][1] + y * el[1][1] + el[2][1]; +} + +//------------------------------------------------------------------------------ +// \ru Являются ли объекты равными? \en Determine whether an object is equal? +// --- +inline bool MbMatrix::IsSame( const MbMatrix & m2, double accuracy ) const +{ + const MbMatrix & m1 = *this; + + bool isSame = ( + (::fabs(m1.el[0][0] - m2.el[0][0]) <= accuracy) && + (::fabs(m1.el[0][1] - m2.el[0][1]) <= accuracy) && + (::fabs(m1.el[0][2] - m2.el[0][2]) <= accuracy) && + + (::fabs(m1.el[1][0] - m2.el[1][0]) <= accuracy) && + (::fabs(m1.el[1][1] - m2.el[1][1]) <= accuracy) && + (::fabs(m1.el[1][2] - m2.el[1][2]) <= accuracy) && + + (::fabs(m1.el[2][0] - m2.el[2][0]) <= accuracy) && + (::fabs(m1.el[2][1] - m2.el[2][1]) <= accuracy) && + (::fabs(m1.el[2][2] - m2.el[2][2]) <= accuracy) ); + + return isSame; +} + + +//------------------------------------------------------------------------------ +// \ru чтение матрицы из потока \en Reading of matrix from stream +// --- +inline reader & CALL_DECLARATION operator >> ( reader & in, MbMatrix & obj ) { + in.readBytes( obj.el, sizeof(obj.el) ); + obj.flag = MB_UNSET; + return in; +} + +//------------------------------------------------------------------------------ +// \ru Запись матрицы в поток \en Writing of matrix to the stream +// --- +inline writer & CALL_DECLARATION operator << ( writer & out, const MbMatrix & obj ) { + out.writeBytes( (double *)obj.el, sizeof(obj.el) ); + return out; +} + + +//------------------------------------------------------------------------------ +/** + \brief \ru Перемножить матрицы. + \en Multiply matrices. \~ + \details \ru Умножение матрицы m1 на матрицу m2 (вместо res = m1 * m2). + \en Multiply m1 matrix by m2 matrix (instead of res = m1 * m2). \~ + \param[in] m1, m2 - \ru Исходные матрицы. + \en Initial matrices. \~ + \param[out] res - \ru Результирующая матрица. + \en The required matrix. \~ + \ingroup Mathematic_Base_2D +*/ +MATH_FUNC (void) MulMatrix( const MbMatrix & m1, const MbMatrix & m2, MbMatrix & res ); + + +#endif // __MB_MATRIX_H diff --git a/C3d/Include/mb_matrix3d.h b/C3d/Include/mb_matrix3d.h new file mode 100644 index 0000000..7c0c6ab --- /dev/null +++ b/C3d/Include/mb_matrix3d.h @@ -0,0 +1,866 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Расширенная матрица преобразования в трёхмерном пространстве. + \en The extended matrix of transformation in a three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_MATRIX3D_H +#define __MB_MATRIX3D_H + + +#include +#include +#include + + +#define MATRIX_DIM_3D 4 // \ru Размер матрицы \en A matrix size +#define AXIS_0X 0 // \ru Ось 0X \en 0X-axis +#define AXIS_0Y 1 // \ru Ось 0Y \en 0Y-axis +#define AXIS_0Z 2 // \ru Ось 0Z \en 0Z-axis + + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbHomogeneous3D; +class MATH_CLASS MbVector3D; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbProperties; + + +typedef double GLdouble; + +template +void CheckOrigin3D ( const Transform & trans, uint8 & flag, bool resetFlag ); +template +void CheckRotation3D( const Transform & trans, uint8 & flag, bool resetFlag ); +template +void CheckAffine3D ( const Transform & trans, uint8 & flag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширенная матрица преобразования в трёхмерном пространстве. + \en The extended matrix of transformation in a three-dimensional space. \~ + \details \ru Расширенная матрица преобразования в трёхмерном пространстве. \n + Расширенная матрица имеет размерность (4, 4) и представляет собой обычную матрицу, + окаймлённую снизу вектором сдвига а справа нулевым столбцом. + Трансформация точки p по матрице M имеет вид: r = p * M (строка координат умножается на матрицу слева).\n + Матрица преобразования из локальной системы координат может быть получена следующим образом:\n + первая строка матрицы должна быть заполнена соответствующими компонентами первого вектора локальной системы, + вторая строка матрицы должна быть заполнена соответствующими компонентами второго вектора локальной системы, + третья строка матрицы должна быть заполнена соответствующими компонентами третьего вектора локальной системы, + последняя строка матрицы должна быть заполнена соответствующими координатами положения начала локальной системы. + Матрица трансформации состоит из четырёх блоков:\n + | R, P | \n + | V, S | \n + , где R - матрица вращения, тензор размерностью (3, 3), + V - вектор сдвига, тензор (0, 3), + P - вектор перспективы, тензор (3, 0) (всегда ноль), + S - скаляр масштабного преобразования (единица).\n + Для ускорения вычислений матрица имеет дополнительные данные - флаг состояния.\n + Для получения данных матрицы извне следует пользоваться методами Get...\n + Для модификации данных матрицы извне следует пользоваться методами Set..., которые автоматически сбрасывают флаг системы в неустановленное состояние.\n + \en The extended matrix of transformation in a three-dimensional space. \n + The extended matrix has dimension (4, 4) and is a regular matrix + bordered below by a translation vector and by the null column to the right. + The transformation of point "p" by the matrix "M" has the form: r = p * M (the row of coordinates is multiplied by the matrix to the left).\n + The transformation matrix from a local coordinate system can be obtained as follows:\n + the first row must be filled with the corresponding components of the first vector of a locale system, + the second row must be filled with the corresponding components of the second vector of a local system, + the third row must be filled with the corresponding components of the third vector of a locale system, + the last row of the matrix must be filled with the corresponding coordinates of a local system origin. + The matrix of transformation consists of four blocks:\n + | R, P | \n + | V, S | \n + where R - is a rotation matrix, the tensor with dimension (3, 3), + V - translation vector, tensor (0, 3), + P - perspective vector, tensor (3, 0) (always is null) + S - scalar of scale transformation (the unit). \ n + To speed up the calculation the matrix has additional data - flag of state.\n + Use "Get..." methods to get data of matrix from the outside. \n + To modify data of a matrix from the outside use "Set..." methods which automatically reset the system flag to unspecified state. \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbMatrix3D { +private: + double el[MATRIX_DIM_3D][MATRIX_DIM_3D]; ///< \ru Элементы матрицы. \en Elements of matrix. +private: + /** + \brief \ru Состояние матрицы определяется установкой битовых полей. + \en State of the matrix is defined by setting of bit fields. \~ + \details \ru Состояние матрицы определяется установкой битовых полей: \n + MB_TRANSLATION - вектор трансляции не ноль, \n + MB_ROTATION - матрица вращения не единичная, \n + MB_SCALING - масштабный компонент не 1.0, \n + MB_REFLECTION - детерминант матрицы вращения отрицателен, \n + MB_ORTOGONAL - матрица вращения ортогональная, взводится только в случае аффинной системы координат, \n + MB_AFFINE - матрица вращения произвольная аффинная, \n + MB_PERSPECTIVE - присутствует перспективное преобразование (не нулевой вектор перспективы), \n + MB_UNSET - битовые флаги не установлены. \n + При изменении элементов матрицы (el[..][..]) flag должен быть сброшен в неустановленное состояние MB_UNSET, + при котором происходит полный пересчет состояния матрицы по требованию, для оптимизации функционала матрицы + рекомендуется устанавливать его в ручную соответственно тому как изменилось содержание el[..][..]. \n + При модификации извне пользоваться методами Set* которые автоматически сбрасыват флаг в неустановленное состояние + при получении данных матрицы из вне пользоваться методами Get*, + НЕ ПОЛЬЗОВАТСЯ МЕТОДАМИ Get* ДЛЯ ИЗМЕННИЯ ЭЛЕМЕНТОВ МАТРИЦЫ ПЕРЕИМЕНОВЫВАЯ const В НЕ const, + НЕ ДОСТУПАТЬСЯ К ДАННЫМ МАТРИЦЫ НАПРЯМУЮ В ОБХОД Get* и Set*. + \en State of the matrix is defined by setting of bit fields: \n + MB_TRANSLATION - translation vector is not zero \n + MB_ROTATION - rotation matrix is not unit \n + MB_SCALING - scale component is not 1.0, \n + MB_REFLECTION - determinant of the rotation matrix is negative, \n + MB_ORTOGONAL - orthogonal matrix of rotation, it is used only if coordinate system is affine \n + MB_AFFINE - arbitrary affine rotation matrix, \n + MB_PERSPECTIVE - is perspective transformation (non-zero perspective vector), \n + MB_UNSET - bit flags are not set. \n + If matrix elements (el[..][..]) are changed, then 'flag' must be set to unspecified MB_UNSET state, + for which the full recalculation of the matrix state is performed (on request) to optimize the functional of the matrix. + It is recommended to set it manually according to how the content of el [..] [..] is changed. \n + To modify data of a matrix from the outside use "Set..." methods which automatically reset the flag to unspecified state, + use "Get..." methods to get data of matrix from the outside, + DO NOT USE "Get..." METHODS TO MODIFY MATRIX ELEMENTS BY RENAMING const TO non-const, + USE ONLY Get* AND Set* TO ACCESS AND MODIFY OF MATRIX DATA. \~ + */ + mutable uint8 flag; + +public: + static const MbMatrix3D identity; ///< \ru Единичная матрица, I = diag(1,1,1,1); \en Identity matrix, I = diag(1,1,1,1); + +public: + /// \ru Конструктор по умолчанию, определяет единичную матрицу. \en Default constructor. Defines the identity matrix. + MbMatrix3D() : flag( MB_UNSET ) { Init(); } + /// \ru Конструктор копирования. \en The copy constructor. + MbMatrix3D( const MbMatrix3D & init ) : flag( init.flag ) { ::memcpy( el, init.el, sizeof(el) ); } + /// \ru Конструктор по локальной системе координат. \en The constructor by placement. + explicit MbMatrix3D( const MbPlacement3D & place ) : flag( MB_UNSET ) { Init( place ); } + +public: + /// \ru Конструктор по двумерной матрице. \en The constructor by a two-dimensional matrix. + explicit MbMatrix3D( const MbMatrix & m ) : flag( MB_UNSET ) { Init( m ); } + /** + \brief \ru Конструктор по двум матрицам. + \en The constructor by two matrices. \~ + \details \ru Матрица определяется как произведение двух исходных: C = (B * A). + \en Matrix is defined as the product of two initial matrices: C = (B * A). \~ + \param[in] A, B - \ru Исходные матрицы. + \en Initial matrices. \~ + */ + explicit MbMatrix3D( const MbMatrix3D & A, const MbMatrix3D & B ) : flag( MB_UNSET ) { Init( A, B ); } +public: + /// \ru Деструктор. \en Destructor. + ~MbMatrix3D(); + +public: + /** + \ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + /// \ru Инициализировать матрицу как единичную. \en Initialize a matrix as unit one. + void Init(); + /// \ru Инициализировать элементами другой матрицы. \en Initialize by elements of another matrix. + void Init( const MbMatrix3D & init ) { flag = init.flag; ::memcpy( el, init.el, sizeof(el) ); } + /// \ru Инициализировать двумерной матрицей. \en Initialize by a two-dimensional matrix. + void Init( const MbMatrix & ); + /// \ru Инициализировать плейсментом. \en Initialize by a placement. + void Init( const MbPlacement3D & ); + /** + \brief \ru Инициализировать произведением заданных матриц. + \en Initialize by the product of given matrices. \~ + \details \ru Инициализировать произведением заданных матриц. this = b * a (!= a * b)!!!. + \en Initialize by the product of given matrices. this = b * a (!= a * b)!!!. \~ + \param[in] a, b - \ru Исходные матрицы. + \en Initial matrices. \~ + */ + void Init( const MbMatrix3D & a, const MbMatrix3D & b ); + /** \} */ + +public: + /** + \ru \name Функции проверки свойств матриц. + \en \name Functions for check of matrices properties. + \{ */ + /// \ru Выдать признак отрицательности детерминанта матрицы вращения. \en Get an attribute of negativity of the determinant of a rotation matrix. + bool IsInvert () const { return IsReflection(); } + /// \ru Выдать признак единичности матрицы. \en Get an attribute of unit matrix. + bool IsSingle () const { return (MB_IDENTITY == CheckFlag()); } + /// \ru Выдать признак единичности матрицы с заданной точностью. \en Get an attribute of the identity matrix with a given tolerance. + bool IsSingleEps ( double eps = PARAM_EPSILON ) const; + + /// \ru Выдать признак не равенства нулю вектора трансляции. \en Get an attribute of inequality to zero of translation vector. + bool IsTranslation() const { return !!( CheckFlag() & MB_TRANSLATION ); } + /// \ru Выдать признак не единичности матрицы вращения. \en Get an attribute of non-identity of a rotation matrix. + bool IsRotation () const { return !!( CheckFlag() & MB_ROTATION ); } + /// \ru Выдать признак отрицательности детерминанта матрицы вращения. \en Get an attribute of negativity of the determinant of a rotation matrix. + bool IsReflection () const { return !!( CheckFlag() & MB_REFLECTION ); } + /// \ru Выдать признак ортогональности для случая аффинной матрицы. \en Get an attribute of orthogonality for the case if the matrix is affine. + bool IsOrt () const { return !!( CheckFlag() & MB_ORTOGONAL ); } + /// \ru Выдать признак ортогональности для матрицы вращения. \en Get an attribute of orthogonality for the case if the matrix is a rotation matrix. + bool IsOrthogonal () const { CheckFlag(); return ( !(flag & MB_AFFINE) || !!(flag & MB_ORTOGONAL) ); } + /// \ru Выдать признак того, что матрица вращения произвольная аффинная. \en Get an attribute that the rotational matrix is arbitrary and affine. + bool IsAffine () const { return !!( CheckFlag() & MB_AFFINE ); } + + /// \ru Выдать признак не равенства 1.0 масштабного компонента. \en Get an attribute of inequality to 1.0 of a scale component. + bool IsScaling () const { return !!( CheckFlag() & MB_SCALING ); } + ///< \ru Выдать признак не равенства нулю вектора перспективы. \en Get an attribute of inequality to zero of perspective vector. + bool IsPerspective() const { return !!( CheckFlag() & MB_PERSPECTIVE ); } + /// \ru Проверить, что битовые флаги не установлены. \en Check whether bit flags are not set. + bool IsUnSet () const { return !!( flag & MB_UNSET ); } + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbMatrix3D &, double accuracy ) const; + /// \ru Выдать признак идентичности матриц. \en Get an attribute of unit matrices. + bool IsAbsIdentical( const MbMatrix3D & m ) const; + + /// \ru Выдать признак, что есть только перенос. \en Get an attribute that there is only translation. + bool IsTranslationOnly() const; + /// \ru Совпадают ли оси описываемой матрицей ЛСК с глобальными осями с точностью до поворотов на 90 градусов? \en Are the axis described by the matrix local system coincide with global axes up to a 90-degree rotation? + bool IsSubstitutionOnly( double epsilon = METRIC_EPSILON ) const; + + /** + \brief \ru Выдать признак изотропности. + \en Get an attribute of isotropism. \~ + \details \ru Выполняется проверка, является ли матрица ортогональной с равными по длине + осями X, Y и Z (круг остается кругом). + \en Checks whether the matrix is ??orthogonal with equal lengths of + X, Y and Z axes (circle remains a circle) \~ + \param[out] l - \ru Длина ортов осей X, Y и Z. + \en The length of the X, Y and Z axes orts. \~ + \return \ru true, если матрица изотропна. + \en Returns true if the matrix is isotropic. \~ + */ + bool IsIsotropic( double & l ) const; + + /** \} */ +public: + /** + \ru \name Функции доступа к элементам матрицы. + \en \name Functions of access to matrix elements. + \{ */ + + /// \ru Дать элемент матрицы. \en Get an element of the matrix. + double El( size_t i, size_t j ) const { return el[i][j]; } + /// \ru Дать указатель на первый элемент матрицы. \en Get a pointer to the first matrix element. + const double * GetEl() const { return (const double *)el; } + + /// \ru Дать первую строку (ось X). \en Get the first row (the X-axis). + const MbVector3D & GetAxisX() const { return (const MbVector3D &)*el[0]; } + /// \ru Дать вторую строку (ось Y). \en Get the second row (the Y-axis). + const MbVector3D & GetAxisY() const { return (const MbVector3D &)*el[1]; } + /// \ru Дать третью строку (ось Z). \en Get the third row (the Z-axis). + const MbVector3D & GetAxisZ() const { return (const MbVector3D &)*el[2]; } + /// \ru Дать четвертую строку (начало системы координат). \en Get the fourth row (the origin of coordinates) + const MbCartPoint3D & GetOrigin() const { return (const MbCartPoint3D &)*el[3]; } + + /// \ru Выдать i-ый вектор-столбец матрицы. \en Get the i-th column vector of the matrix. + MbVector3D GetColumn ( size_t i ) const { return MbVector3D( el[0][i], el[1][i], el[2][i] ); } + /// \ru Выдать i-ую вектор-строку матрицы. \en Get the i-th row-vector of the matrix. + MbVector3D GetRow ( size_t i ) const { return MbVector3D( el[i][0], el[i][1], el[i][2] ); } + /// \ru Выдать i-ый вектор-столбец матрицы. \en Get the i-th column vector of the matrix. + MbHomogeneous3D GetFullColumn( size_t i ) const { return MbHomogeneous3D( el[0][i], el[1][i], el[2][i], el[3][i] ); } + /// \ru Выдать i-ую вектор-строку матрицы. \en Get the i-th row-vector of the matrix. + MbHomogeneous3D GetFullRow ( size_t i ) const { return MbHomogeneous3D( el[i][0], el[i][1], el[i][2], el[i][3] ); } + /// \ru Выдать компоненты сдвига матрицы. \en Get components of matrix translation. + void GetOffset ( MbCartPoint3D & p ) const { p = GetOrigin(); } + + /** \} */ +public: + /** + \ru \name Функции модификации элементов матрицы. + \en \name Functions for matrix elements modification. + \{ */ + + /** + \brief \ru Присвоить значение элементам матрицы. + \en Assign a value to matrix elements. \~ + \details \ru Элементы матрицы инициализируются элементами исходного массива. + \en Matrix elements are initialized by elements of initial array. \~ + \param[in] _el - \ru Исходный массив. + \en Initial array. \~ + */ + void SetEl( const double * _el ) { flag = MB_UNSET; ::memcpy( el, _el, sizeof(el) ); } + /** + \brief \ru Дать массив элементов матрицы. + \en Get an array of matrix elements. \~ + \details \ru ТОЛЬКО ДЛЯ OGL !!! + \en ONLY FOR OGL !!! \~ + \return \ru Указатель на начало массива элементов матрицы. + \en The pointer to the array of the matrix elements. \~ + */ + GLdouble * SetEl( ) { flag = MB_UNSET; return (GLdouble *)el; } + /** + \brief \ru Присвоить значение элементу матрицы. + \en Assign a value to the matrix element. \~ + \details \ru Присвоить значение элементу матрицы. + \en Assign a value to the matrix element. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное значение, которое надо присвоить элементу матрицы. + \en Initial value which to be assigned to an element of the matrix. \~ + */ + void El ( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] = e; } + /** + \brief \ru Прибавить число к элементу матрицы. + \en Add a number to the matrix element. \~ + \details \ru Прибавить число к элементу матрицы. + \en Add a number to the matrix element. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное число, которое надо прибавить к элементу матрицы. + \en Initial number which to be added to the matrix element. \~ + */ + void AddEl( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] += e; } + /** + \brief \ru Умножить элемент матрицы на число. + \en Multiply the matrix element by a number. \~ + \details \ru Умножить элемент матрицы на число. + \en Multiply the matrix element by a number. \~ + \param[in] i - \ru Индекс строки. + \en A row index. \~ + \param[in] j - \ru Индекс столбца. + \en A column index. \~ + \param[in] e - \ru Исходное число, на которое надо умножить элемент матрицы. + \en Initial number by which to multiply the matrix element. \~ + */ + void MulEl( size_t i, size_t j, double e ) { flag = MB_UNSET; el[i][j] *= e; } + + /// \ru Дать первую строку (ось X). \en Get the first row (the X-axis). + MbVector3D & SetAxisX () { flag = MB_UNSET; return (MbVector3D &)*el[0]; } + /// \ru Дать вторую строку (ось Y). \en Get the second row (the Y-axis). + MbVector3D & SetAxisY () { flag = MB_UNSET; return (MbVector3D &)*el[1]; } + /// \ru Дать третью строку (ось Z). \en Get the third row (the Z-axis). + MbVector3D & SetAxisZ () { flag = MB_UNSET; return (MbVector3D &)*el[2]; } + /// \ru Дать четвертую строку (начало системы координат). \en Give the fourth row (the origin of coordinates) + MbCartPoint3D & SetOrigin() { flag = MB_UNSET; return (MbCartPoint3D &)*el[3]; } + + /// \ru Установить Z компоненту начала координат. \en Set Z component of the origin. + void SetOriginZ( double or_z ) { el[3][2] = or_z; CheckOrigin(); } + + /// \ru Установить значения в i-ый столбец матрицы. \en Set values in the i-th column of the matrix. + void SetColumn( size_t i, const MbCartPoint3D & ); + /// \ru Установить значения в i-ый столбец матрицы. \en Set values in the i-th column of the matrix. + void SetColumn( size_t i, const MbVector3D & ); + /// \ru Установить значения в i-ый столбец матрицы. \en Set values in the i-th column of the matrix. + void SetColumn( size_t i, const MbHomogeneous3D & ); + /// \ru Установить значения в i-ую строку матрицы. \en Set values in the i-th row of the matrix. + void SetRow ( size_t i, const MbCartPoint3D & ); + /// \ru Установить значения в i-ую строку матрицы. \en Set values in the i-th row of the matrix. + void SetRow ( size_t i, const MbVector3D & ); + /// \ru Установить значения в i-ую строку матрицы. \en Set values in the i-th row of the matrix. + void SetRow ( size_t i, const MbHomogeneous3D & ); + /// \ru Установить компоненты сдвига матрицы. \en Set components of matrix translation. + void SetOffset( const MbCartPoint3D & p ); + /** + \brief \ru Установить флаг состояния. + \en Set the flag of state. \~ + \details \ru Установить флаг состояния. + \en Set the flag of state. \~ + \param[in] bReflection - \ru Флаг отрицательности детерминанта матрицы вращения. + \en Negativity flag of the rotation matrix determinant. \~ + \param[in] bAffine - \ru Флаг аффинности. + \en Affinity flag. \~ + \param[in] bOrt - \ru Флаг ортогональности. + \en Orthogonality flag. \~ + */ + void SetFlag ( bool bReflection, bool bAffine = false, bool bOrt = true ) const; + + /** \} */ +public: + /** + \ru \name Функции умножения матриц. + \en \name Matrices multiplication. + \{ */ + + /// \ru Умножить на матрицу: this = this * b; \en Multiply by a matrix: this = this * b; + void Multiply( const MbMatrix3D & b ); + /// \ru Перемножить матрицы this = a * b. \en Multiply matrices this = a * b. + void Multiply( const MbMatrix3D & a, const MbMatrix3D & b ) { Init( b, a ); } + + /** \} */ +public: + /** + \ru \name Функции масштабирования. + \en \name Scaling functions. + \{ */ + + /** + \brief \ru Масштабировать по X, Y, Z. + \en Scale by X, Y and Z. \~ + \details \ru Масштабировать по X, Y, Z. + \en Scale by X, Y and Z. \~ + \param[in] sx, sy, sz - \ru Коэффициенты масштабирования для каждой из осей. + \en Scaling coefficients for each axis. \~ + */ + void Scale ( double sx, double sy, double sz ) { ScaleX( sx ), ScaleY( sy ), ScaleZ( sz ); } + /// \ru Масштабировать по X, Y, Z. \en Scale by X, Y and Z. + void Scale ( double s ); + /// \ru Масштабировать по X. \en Scale by X. + void ScaleX( double s ); + /// \ru Масштабировать по Y. \en Scale by Y. + void ScaleY( double s ); + /// \ru Масштабировать по Z. \en Scale by Z. + void ScaleZ( double s ); + /// \ru Масштабировать по X и Y и Z без сдвига. \en Scale by X, Y and Z without translation. + void ScaleAxes( double s ); + + /// \ru Выдать коэффициент масштабирования по X. \en Get scaling coefficient by X. + double GetScaleX() const; + /// \ru Выдать коэффициент масштабирования по Y \en Get scaling coefficient by Y + double GetScaleY() const; + /// \ru Выдать коэффициент масштабирования по Z \en Get scaling coefficient by Z + double GetScaleZ() const; + + /** \} */ +public: + /** + \ru \name Функции преобразований матрицы: сдвиг, поворот и т.д. + \en \name Functions of matrix transformations: translation, rotation, etc. + \{ */ + + /// \ru Сдвинуть на заданный вектор. \en Translate by a given vector. + void Move( const MbVector3D & to ) { Move( to.x, to.y, to.z ); } + /// \ru Сдвинуть на заданные приращения. \en Translate by given increments. + void Move( double dx, double dy, double dz ); + /// \ru Сдвинуть в нуль. \en Translate to null. + void MoveZero(); + + /** + \brief \ru Повернуть вокруг оси. + \en Rotate around an axis. \~ + \details \ru Повернуть вокруг оси, проходящей через центр координат в направлении axisDir. + \en Rotate around an axis which passes through the origin in the axisDir direction. \~ + \param[in] axisDir - \ru Вектор, задающий направление поворота. + \en A vector which defines the direction of rotation. \~ + \param[in] angle - \ru Угол поворота. + \en A rotation angle. \~ + \return \ru Матрица возвращает ссылку на себя. + \en Returns the reference to this matrix. \~ + + */ + MbMatrix3D & RotateAbout( const MbVector3D & axisDir, double angle ); + /// \ru Повернуть вокруг заданной оси на заданный угол. \en Rotate around axis by angle. + MbMatrix3D & Rotate( const MbAxis3D & axis, double angle ); + /** + \brief \ru Повернуть вокруг оси. + \en Rotate around an axis. \~ + \details \ru Повернуть вокруг оси X, Y, Z. + \en Rotate around the X, Y, or Z axis. \~ + \param[in] axis - \ru Номер оси, т.е. AXIS_0X, AXIS_0Y или AXIS_0Z. + \en The number of axis, i.e. AXIS_0X, AXIS_0Y or AXIS_0Z. \~ + \param[in] angle - \ru Угол поворота. + \en A rotation angle. \~ + \return \ru Матрица возвращает ссылку на себя. + \en Returns the reference to this matrix. \~ + */ + MbMatrix3D & Rotate( int axis, double angle ); + + /** + \brief \ru Преобразовать длину. + \en Transform the length. \~ + \details \ru Длина преобразуются согласно матрице (*this). + \en The length is transformed according to a matrix (*this). \~ + \param[in, out] len - \ru Длина. + \en A length. \~ + \param[in] axis - \ru Ось, по которой отмеряется длина. + \en An axis on which the length is measured. \~ + */ + void TransformLength( double & len, int axis = 1 ) const; + /** + \brief \ru Преобразовать координаты. + \en Transform coordinates. \~ + \details \ru Координаты преобразуются согласно матрице. Преобразовываются две координаты (z = 0). + \en Coordinates are transformed according to a matrix. Two coordinates are transformed (z=0). \~ + \param[in, out] x, y - \ru Координаты по x и y. + \en Coordinates by x and y. \~ + */ + void TransformCoord2D( double & x, double & y ) const; + + /// \ru Преобразовать согласно заданной матрице. \en Transform according to the given matrix. + MbMatrix3D & Transform( const MbMatrix3D & matr ) { *this = ( *this ) * matr; return *this; } + /// \ru Инвертировать ось. \en Invert the axis. + void Invert( size_t n ); + + /** + \brief \ru Задать матрицу преобразования симметрии (отражение). + \en Set the matrix to symmetry transformation (reflection). \~ + \details \ru Находится матрица для преобразования симметрии относительно плоскости, заданной точкой и нормалью. + \en The matrix of symmetry transformation is found relative to the plane which is defined by a point and normal. \~ + \param[in] origin - \ru Точка плоскости. + \en A point of plane. \~ + \param[in] normal - \ru Нормаль плоскости. + \en The normal of a plane. \~ + \return \ru Матрица возвращает ссылку на себя. + \en Returns the reference to this matrix. \~ + */ + MbMatrix3D & Symmetry( const MbCartPoint3D & origin, const MbVector3D & normal ); + /** + \brief \ru Задать матрицу преобразования симметрии (отражение). + \en Set the matrix to symmetry transformation (reflection). \~ + \details \ru Находится матрица для преобразования симметрии относительно плоскости, + заданной точкой и двумя векторами. + \en The matrix of symmetry transformation is found relative to the plane + which is defined by a point and two vectors. \~ + \param[in] origin - \ru Точка плоскости (начало системы координат). + \en A point of plane (an origin). \~ + \param[in] vx, vy - \ru Векторы, параллельные плоскости. + \en Vectors which parallel for a plane. \~ + \return \ru Матрица возвращает ссылку на себя. + \en Returns the reference to this matrix. \~ + */ + MbMatrix3D & Symmetry( const MbCartPoint3D & origin, const MbVector3D & vx, const MbVector3D & vy ); + + /** \} */ +public: + /** + \ru \name Расчет алгебраических свойств матрицы. + \en \name Calculation of the algebraic properties of a matrix. + \{ */ + + /// \ru Транспонировать матрицу. \en Transpose a matrix. + void Adj(); + /// \ru Вычислить алгебраическое дополнение. \en Calculate the algebraic adjunct. + double Delta( size_t line, size_t column, size_t dim ) const; + /// \ru Вычислить определитель матрицы. \en Calculate the determinant of a matrix. + double Det( size_t dim ) const; + /// \ru Вычислить обратную матрицу. \en Calculate inverse matrix. + void Div( MbMatrix3D & ) const; + + /** \} */ + + /** + \brief \ru Получить матрицу для масштабирования каверны литейной формы. + \en Get the matrix for scale of a mold cavern. \~ + \details \ru Получить матрицу для масштабирования каверны литейной формы. + \en Get the matrix for scale of a mold cavern. \~ + \param[in] fixedPoint - \ru Неподвижная точка. + \en Fixed point. \~ + \param[in] deltaX, deltaY, deltaZ - \ru Относительное приращение размера по направлению соответствующей координаты. + \en Relative increment of size in the direction of corresponding coordinate. \~ + */ + void MouldCavityScale( MbCartPoint3D & fixedPoint, double deltaX, double deltaY, double deltaZ ); + /** + \brief \ru Округлить с точностью до eps. + \en Round with eps tolerance. \~ + \details \ru Округлить с точностью до eps. + \en Round with eps tolerance. \~ + \param[in] total - \ru Если true, то округлять в любом случае. + \en If true, round anyway. \~ + \param[in] eps - \ru Точность округления. + \en A round-off tolerance. \~ + \return \ru true, если округление было выполнено. + \en Returns true if round-off has been done. \~ + */ + bool SetRoundedValue( bool total, double eps ); + /// \ru Нормализовать. \en Normalize. + void Normalize(); + /// \ru Вычислить неподвижную точку преобразования. \en Calculate a fixed point of transformation. + bool CalculateFixedPoint( MbCartPoint3D & fixedPoint ) const; + + /** + \ru \name Перегрузка алгебраических и логических операций. + \en \name Overload of arithmetical and logical operations. + \{ */ + /// \ru Умножить на матрицу: M = this * m. \en Multiply by a matrix: M = this * m. + MbMatrix3D operator * ( const MbMatrix3D & m ) const { return MbMatrix3D( m, *this ); } + /// \ru Умножить на матрицу: this = this * m. \en Multiply by a matrix: this = this * m. + MbMatrix3D & operator *= ( const MbMatrix3D & m ) { Multiply( m ); return *this; } + /// \ru Присвоить значение. \en Assign a value. + MbMatrix3D & operator = ( const MbMatrix3D & m ) { flag = m.flag; ::memcpy( el, m.el, sizeof(el) ); return *this; } + /// \ru Сложить матрицы. \en Add matrices. + void operator += ( const MbMatrix3D & ); + /// \ru Вычесть из матрицы матрицу. \en Subtract a matrix from the matrix. + void operator -= ( const MbMatrix3D & ); + /// \ru Умножить матрицу на число. \en Multiply the matrix by a number. + void operator *= ( double factor ); + /// \ru Разделить матрицу на число. \en Divide the matrix by a number. + void operator /= ( double factor ); + /// \ru Сравнить с матрицей (точность - LENGTH_EPSILON). \en Compare with a matrix (tolerance - LENGTH_EPSILON). + bool operator == ( const MbMatrix3D & ) const; + + /// \ru Доступ по ссылке к элементу матрицы. \en Access to a matrix element by a reference. + double & operator() ( size_t i, size_t j ) { C3D_ASSERT( std_max( i, j ) < MATRIX_DIM_3D ); flag = MB_UNSET; return el[i][j]; } + /// \ru Значение элемента матрицы. \en The value of a matrix element. + const double & operator() ( size_t i, size_t j ) const { C3D_ASSERT( std_max( i, j ) < MATRIX_DIM_3D ); return el[i][j]; } + + /** \} */ + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + +private: + /// \ru Удалить мусор в данных \en Remove trash from data. + void RemoveInaccuracies(); + /// \ru Выставить флаги. \en Set flags. + uint8 ResetFlag() const; + // Оценить флаги, если оценки не было + uint8 CheckFlag() const { return IsUnSet() ? ResetFlag() : flag; } + // Проверить флаг смещения. + void CheckOrigin() const { ::CheckOrigin3D( *this, flag, true ); } + /// \ru Проверить флаг вращения. \en Check rotation flag. + void CheckRotation() const { ::CheckRotation3D( *this, flag, true ); } + + void CheckScale() const; + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbMatrix3D, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( MbMatrix3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbMatrix3D ) +}; + + +//------------------------------------------------------------------------------- +// Установка флага смещения для матрицы и системы координат. +/** + \attention \ru Только для внутреннего использования. + \en For internal use only. \~ +*/ +// --- +template +void CheckOrigin3D( const Transform & trans, uint8 & flag, bool resetFlag ) +{ + if ( !(flag & MB_UNSET) ) { + const MbCartPoint3D & pOrigin = trans.GetOrigin(); + const double eps = LENGTH_EPSILON; + + if ( (::fabs(pOrigin.x) > eps) || + (::fabs(pOrigin.y) > eps) || + (::fabs(pOrigin.z) > eps) ) + { + flag |= MB_TRANSLATION; + } + else if ( resetFlag ) { + flag &= ~MB_TRANSLATION; + } + } +} + + +//------------------------------------------------------------------------------- +// Установка флага вращения для матрицы и системы координат. +// ( Использование корректно только для ортонормированных СК) +/** + \attention \ru Только для внутреннего использования. + \en For internal use only. \~ +*/ +// --- +template +void CheckRotation3D( const Transform & trans, uint8 & flag, bool resetFlag ) +{ + if ( !(flag & MB_UNSET) ) { + const MbVector3D & axisX = trans.GetAxisX(); + const MbVector3D & axisY = trans.GetAxisY(); + const MbVector3D & axisZ = trans.GetAxisZ(); + + // Барьер нулевых элементов матрицы + const double eps = EXTENT_EPSILON; + if ( (::fabs(axisZ.x ) > eps) || + (::fabs(axisZ.y ) > eps) || + (::fabs(axisX.y ) > eps) || + (::fabs(axisX.z ) > eps) || + (::fabs(axisY.x ) > eps) || + (::fabs(axisY.z ) > eps) || + (::fabs(axisZ.z - 1.0) > eps) || + (::fabs(axisX.x - 1.0) > eps) || + (::fabs(axisY.y - 1.0) > eps) ) + { + flag |= MB_ROTATION; + } + else if ( resetFlag ) { + flag &= ~MB_ROTATION; + flag &= ~MB_LEFT; + flag &= ~MB_ORTOGONAL; + flag &= ~MB_AFFINE; + } + } +} + + +//------------------------------------------------------------------------------- +// Установка флага аффинности для матрицы и системы координат. +// (Использование корректно только для ортонормированных СК) +/** + \attention \ru Только для внутреннего использования. + \en For internal use only. \~ +*/ +// --- +template +void CheckAffine3D( const Transform & trans, uint8 & flag ) +{ + if ( !(flag & MB_UNSET) ) { + const MbVector3D & vAxisX = trans.GetAxisX(); + const MbVector3D & vAxisY = trans.GetAxisY(); + const MbVector3D & vAxisZ = trans.GetAxisZ(); + + const double eps = EXTENT_EPSILON; + + double lnX = vAxisX.Length(); + double lnY = vAxisY.Length(); + double epsX = (eps * lnX); + + if ( ::fabs( vAxisX * vAxisY ) > (epsX * lnY) ) + flag |= MB_AFFINE; + else { + double lnZ = vAxisZ.Length(); + if ( ::fabs( vAxisX * vAxisZ ) > (epsX * lnZ) ) + flag |= MB_AFFINE; + else { + if ( ::fabs( vAxisY * vAxisZ ) > (eps * lnY * lnZ) ) + flag |= MB_AFFINE; + else if ( (::fabs(lnX - 1.0) > eps) || + (::fabs(lnY - 1.0) > eps) || + (::fabs(lnZ - 1.0) > eps) ) + { + flag |= MB_ORTOGONAL; // система ортогональна + flag |= MB_AFFINE; + } + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация матрицы. \en Initialization of a matrix. +// --- +inline void MbMatrix3D::Init() +{ + el[0][1] = el[0][2] = el[0][3] = 0.0; + el[1][0] = el[1][2] = el[1][3] = 0.0; + el[2][0] = el[2][1] = el[2][3] = 0.0; + el[3][0] = el[3][1] = el[3][2] = 0.0; + el[0][0] = el[1][1] = el[2][2] = el[3][3] = 1.0; + flag = MB_IDENTITY; +} + + +//------------------------------------------------------------------------------- +// \ru Есть только перенос. \en Only translation. +// --- +inline bool MbMatrix3D::IsTranslationOnly() const +{ + CheckFlag(); + if ( !!(flag & MB_TRANSLATION) && !(flag & MB_ROTATION) && !(flag & MB_LEFT) && !(flag & MB_SCALING) && !(flag & MB_PERSPECTIVE) ) + return true; + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство матриц. \en Check for equality of matrices. +// --- +inline bool MbMatrix3D::operator == ( const MbMatrix3D & m ) const +{ + bool bRes = true; + for ( size_t i = 0; (i < MATRIX_DIM_3D) && bRes; i++ ) { + bRes = ( (::fabs(el[i][0] - m.el[i][0]) <= LENGTH_EPSILON) && + (::fabs(el[i][1] - m.el[i][1]) <= LENGTH_EPSILON) && + (::fabs(el[i][2] - m.el[i][2]) <= LENGTH_EPSILON) && + (::fabs(el[i][3] - m.el[i][3]) <= LENGTH_EPSILON) ); + } + return bRes; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение на матрицу this = this * b; \en Multiplication by a matrix this = this * b; +// --- +inline void MbMatrix3D::Multiply( const MbMatrix3D & b ) +{ + MbMatrix3D staticMatrix; // \ru Для промежуточных вычислений. \en For intermediate calculations + staticMatrix.Init( b, *this ); + flag = staticMatrix.flag; + ::memcpy( el, staticMatrix.el, sizeof(el) ); +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать две координаты (z = 0) \en Transform two coordinates (z=0) +// --- +inline void MbMatrix3D::TransformCoord2D( double & x, double & y ) const +{ + double xx = x * el[0][0] + y * el[1][0] + el[3][0]; + double yy = x * el[0][1] + y * el[1][1] + el[3][1]; + x = xx; + y = yy; +} + + +//------------------------------------------------------------------------------ +// \ru Являются ли объекты равными? \en Determine whether an object is equal? +// --- +inline bool MbMatrix3D::IsSame( const MbMatrix3D & m2, double accuracy ) const +{ + const MbMatrix3D & m1 = *this; + + bool isSame = ( + (::fabs(m1.el[0][0] - m2.el[0][0]) <= accuracy) && + (::fabs(m1.el[0][1] - m2.el[0][1]) <= accuracy) && + (::fabs(m1.el[0][2] - m2.el[0][2]) <= accuracy) && + (::fabs(m1.el[0][3] - m2.el[0][3]) <= accuracy) && + + (::fabs(m1.el[1][0] - m2.el[1][0]) <= accuracy) && + (::fabs(m1.el[1][1] - m2.el[1][1]) <= accuracy) && + (::fabs(m1.el[1][2] - m2.el[1][2]) <= accuracy) && + (::fabs(m1.el[1][3] - m2.el[1][3]) <= accuracy) && + + (::fabs(m1.el[2][0] - m2.el[2][0]) <= accuracy) && + (::fabs(m1.el[2][1] - m2.el[2][1]) <= accuracy) && + (::fabs(m1.el[2][2] - m2.el[2][2]) <= accuracy) && + (::fabs(m1.el[2][3] - m2.el[2][3]) <= accuracy) && + + (::fabs(m1.el[3][0] - m2.el[3][0]) <= accuracy) && + (::fabs(m1.el[3][1] - m2.el[3][1]) <= accuracy) && + (::fabs(m1.el[3][2] - m2.el[3][2]) <= accuracy) && + (::fabs(m1.el[3][3] - m2.el[3][3]) <= accuracy) ); + + return isSame; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Извлечь углы Эйлера из ротационной подматрицы R = Rx*Ry*Rz. + \en Extract the Euler angles from the rotational submatrix R = Rx*Ry*Rz. + \param[in] trans - \ru Матрица преобразования, содержащая подматрицу вращения. + \en The transformaton matrix containig the rotational submatrix. \~ + \param[out] alpha - \ru Угол поворота вокруг оси "X", извлеченный из матрицы вращения. + \en Angle of rotation around the "X" axis extracted from the rotation matrix. \~ + \param[out] betta - \ru Угол поворота вокруг оси "Y", извлеченный из матрицы вращения. + \en Angle of rotation around the "Y" axis extracted from the rotation matrix. \~ + \param[out] gamma - \ru Угол поворота вокруг оси "Z", извлеченный из матрицы вращения. + \en Angle of rotation around the "Z" axis extracted from the rotation matrix. \~ + + \details \ru Функция разлагает подматрицу вращения на элементарные повороты вокруг осей R = Rx*Ry*Rz, + заданные в виде угловых значений, а именно значения в радианах, определяющую присланную матрицу вращения R + в виде комбинации (произведения) из трех элементарных поворотов: R = Rx*Ry*Rz<\b>, где\n + Rx = Rx(alpha) - поворот вокруг оси "X", \n + Ry = Ry(betta) - поворот вокруг оси "Y", \n + Rz = Rz(gamma) - поворот вокруг оси "Z" и \n + R - ротационная подматрица 3x3 из матрицы trans<\b>. + Матрица trans может содержать любые преобразования, вклячая масштабирование и сдвиг. + Метод ExtractEulerAngles извлечет из данной матрицы вращающий компонент и разложит его + на три вращения: Rx(alpha), Ry(betta), Rz(gamma). + + \en The function factorizes the rotation submatrix into elementary rotations about the axes: R = Rx * Ry * Rz, + given in the form of angular values, namely the values in radians, specifing the rotation submatrix R of the given trans<\b> + in the form of a combination (product) of three elementary rotations: R = Rx * Ry * Rz <\b>, where \n + Rx = Rx(alpha) - rotation around X-axis, \n + Ry = Ry(betta) - rotation around Y-axis, \n + Rz = Rz(gamma) - rotation around Z-axis and \n + R is a rotational 3x3 submatrix from the matrix trans<\b>. + The matrix trans can contain any transformations including the scaling and the shear. + The ExtractEulerAngles method extracts from the given matrix a rotating component + and decomposes it into three rotations: Rx( alpha ), Ry( betta ), Rz( gamma ). +*/ +//--- +MATH_FUNC(void) ExtractEulerAngles( const MbMatrix3D & trans, double & alpha, double & betta, double & gamma ); + + +#endif // __MB_MATRIX3D_H diff --git a/C3d/Include/mb_matrixnn.h b/C3d/Include/mb_matrixnn.h new file mode 100644 index 0000000..3c89139 --- /dev/null +++ b/C3d/Include/mb_matrixnn.h @@ -0,0 +1,290 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file \brief \ru Квадратная матрица чисел N x N. + \en Square matrix of numbers N x N. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_MATRIXNN_H +#define __MB_MATRIXNN_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Квадратная матрица чисел N x N. + \en Square matrix of numbers N x N. \~ + \ingroup Base_Items +*/ +// --- +class MATH_CLASS MatrixNN +{ +private : + double ** parr; ///< \ru Указатель на первый элемент матрицы. \en A pointer to the first element of the matrix. + size_t n; ///< \ru Размерность матрицы. \en A dimension of the matrix. + +protected: + /// \ru Конструктор. \en Constructor. + MatrixNN() : parr( NULL ), n( 0 ) {} + /// \ru Конструктор по заданной размерности. \en The constructor by a given dimension. + MatrixNN( size_t dim ) : parr( NULL ), n( 0 ) { SetSize( dim ); } +public: + /// \ru Конструктор ограниченной размерности. \en The constructor of restricted dimension. + MatrixNN ( const uint16 & dim ) : parr( NULL ), n( 0 ) { SetSize( dim ); } + /// \ru Конструктор копирования. \en The copy constructor. + explicit MatrixNN ( const MatrixNN & ); + /// \ru Деструктор. \en Destructor. + ~MatrixNN() { SetSize( 0 ); } + +public: + /// \ru Конструктор по заданной размерности. \en The constructor by a given dimension. + static MatrixNN * Create( size_t m ); + +public: // Общие методы матриц (двумерных массивов) + size_t Lines () const { return n; } ///< \ru Дать количество строк матрицы. \en Give the number of matrix rows. + size_t Columns() const { return n; } ///< \ru Дать количество столбцов матрицы. \en Give the number of matrix columns. + size_t Count () const { return (n*n); } ///< \ru Количество элементов матрицы. \en Give the number of matrix elements. + c3d::IndicesPair GetSize() const { return c3d::IndicesPair( n, n ); } ///< \ru Дать размер матрицы. \en Give the size of the matrix. + bool SetSize( c3d::IndicesPair sz ) { size_t m = std_min( sz.first, sz.second ); return SetSize( m ); } ///< \ru Установить размер. \en Set size. + bool SetSize( size_t lsz, size_t csz, bool save_vals = false ) { size_t m = std_min( lsz, csz ); return SetSize( m, save_vals ); } ///< \ru Установить размер. \en Set size. + bool SetSize( size_t dim, bool save_vals = false ); ///< \ru Установить размер. \en Set size. + + /// \ru Получить элемент матрицы (i,j). \en Get an element of the matrix (i,j). + const double & GetElem( size_t i, size_t j ) const { C3D_ASSERT( !!parr && i < n && j < n ); return parr[i][j]; } + /// \ru Установить элемент матрицы (i,j). \en Set an element of the matrix (i,j). + void SetElem( size_t i, size_t j, double v ) { C3D_ASSERT( !!parr && i < n && j < n ); parr[i][j] = v; } + /// \ru Добавить элемент матрицы (i,j). \en Add an element of the matrix (i,j). + void AddElem( size_t i, size_t j, double v ) { C3D_ASSERT( !!parr && i < n && j < n ); parr[i][j] += v; } + /// \ru Получить элемент матрицы (i,j). \en Get an element of the matrix (i,j). + const double & operator() ( size_t i, size_t j ) const { C3D_ASSERT( !!parr && i < n && j < n ); return parr[i][j]; } + /// \ru Обнулить матрицу. \en Set the matrix to null. + MatrixNN & SetZero(); + /// \ru Инициализировать элементами другой матрицы. \en Initialize by elements of another matrix. + bool Init( const MatrixNN & ); + /// \ru Оператор присваивания. \en The assignment operator. + MatrixNN & operator = ( const MatrixNN & mtr ) { Init( mtr ); return *this; } + /// \ru Поменять местами строки. \en Swap lines. + bool SwapLines( size_t ln1, size_t ln2 ); + +public: + /// \ru Установить элемент матрицы (i,j). \en Set an element of the matrix (i,j). + double & operator() ( size_t i, size_t j ) { C3D_ASSERT( !!parr && i < n && j < n ); return parr[i][j]; } + /// \ru Выдать адрес начала строки матрицы. \en Get an address of the matrix row start . + const double * GetLine( size_t i ) const { C3D_ASSERT( !!parr && i < n ); return parr[i]; } + /// \ru Выдать адрес начала строки матрицы. \en Get an address of the matrix row start . + double * SetLine( size_t i ) { C3D_ASSERT( !!parr && i < n ); return parr[i]; } + /// \ru Инициировать элемент. \en Initiate an element. + void Init( size_t i, size_t j, double v ) { C3D_ASSERT( !!parr && i < n && j < n ); parr[i][j] = v; } + /// \ru Установить строку. \en Set a row. + void SetLine( size_t i, double * p ) { C3D_ASSERT( !!parr && i < n ); parr[i] = p; } + /// \ru Выдать адрес матрицы. \en Get an address of the matrix. + double ** SetParr() { return parr; } + + /// \ru Сделать матрицу единичной. \en Set the matrix to unit. + void SetSingle(); + /// \ru Увеличить размерность, добавив строку и столбец в конец. \en Increase the dimension by adding a row and coloumn to the end. + bool Add(); + /// \ru Удалить строку и столбец. \en Remove a row and column. + void Delete( size_t i ); + +private: + // \ru Инициализировать матрицу и установить размерность. \en Initialize a matrix and set dimension. + void SetParrAndDimension( double ** p, size_t i ) { parr = p; n = i; } +}; // MatrixNN + + +//------------------------------------------------------------------------------ +/** \brief \ru Решение системы линейных уравнений методом исключения Гаусса. + \en System of linear equations is solved by the Gauss method. \~ + \details \ru Решение системы линейных уравнений методом исключения Гаусса. \n + \en System of linear equations is solved by the Gauss method. \n \~ + \param[in] a - \ru Матрица коэффициентов при неизвестных + \en Coefficient matrix \~ + \param[in] b - \ru Массив правых частей, в него же помещается результат решения + \en Array of right parts, on output it contains the result of the solution \~ + \param[in] epsilon - \ru Погрешность решения + \en Tolerance of solution \~ + \param[in] baseProgBar - \ru Индикатор процесса решения + \en Progress indicator of solution \~ + \return \ru Код ошибки: если nr_Success (+1), то система решена, если nr_Special, то нет решений или система вырождена. + \en Error code: if nr_Success (+1), then the system is solved, if nr_Special, there is no solution or the system is degenerate. \~ + \ingroup Base_Items +*/ +// --- +template +MbeNewtonResult TypedGaussEquation ( MatrixNN & a, Type * b, double epsilon, ProgressBarWrapper * baseProgBar = NULL ) +{ + ProgressBarWrapper * progBar = NULL; + if ( baseProgBar != NULL ) { + StrData strData( pbarId_Solve_LinearEquationsSystem ); + progBar = &baseProgBar->CreateChildAddRef( strData ); + } + + ptrdiff_t count = (ptrdiff_t)std_min( a.Lines(), a.Columns() ); + C3D_ASSERT( a.Lines() == a.Columns() ); + + if ( count < 1 ) { + ::FinishProgressBar( progBar ); + ::ReleaseItem( progBar ); + return nr_Special; + } + + ptrdiff_t i, j, k; + double m, tmp; + Type parr; + + ptrdiff_t halfCount = count / 2; + + for ( k = 0; k < count - 1; k++ ) { + // \ru Переставить уравнения так, чтобы a[k][k] != 0 \en Swap equations so that a[k][k] != 0 + ptrdiff_t l = k; + tmp = ::fabs( a(k, k) ); + for ( i = k + 1; i < count; i++ ) { + if ( ::fabs( a(i, k) ) > tmp ) { + l = i; + tmp = ::fabs( a(i, k) ); + } + } + + if ( k == halfCount ) + ::SetProgressBarValue( progBar, 25 ); + if ( ::StopProgressBar( progBar ) ) { // \ru Остановка по запросу \en Stop by request + ::ReleaseItem( progBar ); + return nr_Special; + } + + if ( l != k ) { + // (!) Рекомендуется использовать MatrixNN::SwapLines(k,l) + for ( j = k; j < count; j++ ) + { + tmp = a(k, j); + a.SetElem( k, j, a(l, j) ); + a.SetElem( l, j, tmp ); + } + parr = b[k]; + b[k] = b[l]; + b[l] = parr; + } + + if ( ::StopProgressBar( progBar ) ) { // \ru Остановка по запросу \en Stop by request + ::ReleaseItem( progBar ); + return nr_Special; + } + + if ( ::fabs( a(k, k) ) < epsilon ) { + ::FinishProgressBar( progBar ); + ::ReleaseItem( progBar ); + return nr_Special; // \ru Система не имеет решений \en System doesn't have solutions + } + + tmp = 1 / a(k, k); + + for ( i = k + 1; i < count; i++ ) + { + if ( a(i, k) != 0.0 ) { + m = a(i, k) * tmp; + a.SetElem( i, k, 0.0 ); + for ( j = k + 1; j < count; j++ ) + a.SetElem( i, j, a(i, j) - a(k, j) * m ); + b[i] -= b[k] * m; + } + } + + if ( ::StopProgressBar( progBar ) ) { // \ru Остановка по запросу \en Stop by request + ::ReleaseItem( progBar ); + return nr_Special; + } + } + + ::SetProgressBarValue( progBar, 50 ); + + if ( ::fabs( a(k, k) ) < epsilon ) { + ::FinishProgressBar( progBar ); + ::ReleaseItem( progBar ); + return nr_Special; // \ru Система не имеет решений \en System doesn't have solutions + } + + // \ru Обратная подстановка \en Back-substitution + i = count - 1; + b[i] *= 1 / a(i, i); + + for ( i = count - 2; i >= 0; i-- ) { + j = i + 1; + parr = b[j] * a(i, j); + for ( j = i + 2; j < count; j++ ) + parr += b[j] * a(i, j); + m = 1.0 / a(i, i); + b[i] = ( b[i] - parr ) * m; + + if ( i == halfCount ) + ::SetProgressBarValue( progBar, 75 ); + if ( ::StopProgressBar( progBar ) ) { // \ru Остановка по запросу \en Stop by request + ::ReleaseItem( progBar ); + return nr_Special; + } + } + + ::SetProgressBarValue( progBar, 100 ); + ::FinishProgressBar( progBar ); + ::ReleaseItem( progBar ); + return nr_Success; +} // GaussEquation + + +//------------------------------------------------------------------------------ +/** + \brief \ru Решение системы линейных уравнений с трехдиагональной матрицей методом прогонки. + \en System of linear equations with a tridiagonal matrix is solved by the sweep method. \~ + \details \ru Решение системы линейных уравнений с трехдиагональной матрицей методом прогонки. + Используется для построения NURBS-копии незамкнутого кубического сплайна. + \en System of linear equations with a tridiagonal matrix is solved by the sweep method. + Used to build a NURBS-copy of a non-closed cubic spline. \~ + \param[in] n - \ru число неизвестных + \en The number of unknown variables \~ + \param[in] a - \ru Главная диагональ трехдиагональной матрицы, массив double размерности n + \en Main diagonal of a tridiagonal matrix is an array of doubles of size "n" \~ + \param[in] b - \ru Верхняя диагональ, размерность n-1 + \en Upper diagonal, dimension is n-1 \~ + \param[in] \ru С - нижняя диагональ, размерность n-1 + \en C- lower diagonal, dimension is n-1 \~ + \param[in] r - \ru Вектор правой части, массив точек или векторов размерности n; должна быть определена операция умножения на double справа + \en Vector of the right part is an array of points or vectors of dimension n; the multiplication operation by the double value on the right must be defined \~ + \param[in] solution - \ru Массив решений (точек, векторов), размерности n + \en Array of solutions (points, vectors) of dimension n \~ + \param[in] epsZero - \ru Погрешность нуля + \en Tolerance of zero \~ + \return \ru Код ошибки: если nr_Success (+1), то система решена, если nr_Special, то нет решений или система вырождена. + \en Error code: if nr_Success (+1), then the system is solved, if nr_Special, there is no solution or the system is degenerate. \~ + \ingroup Base_Items +*/ +// --- +template +MbeNewtonResult TypedTridiagonalSolve ( const size_t n, ArrayDouble & a, ArrayDouble & b, ArrayDouble & c, + ArrayType & r, ArrayType & solution, double epsZero ) +{ + if ( ::fabs ( a[0] ) < epsZero ) + return nr_Special; // \ru Прогонка не работает \en Sweep does not work + // \ru Прямой ход прогонки \en Forward step of sweep + b[0] /= - a[0]; + r[0] /= a[0]; + for ( size_t i = 1; i < n; ++i ) { + double dom = a[i] + b[i - 1] * c[i - 1]; + if ( ::fabs ( dom ) < epsZero ) + return nr_Special; // \ru Прогонка не работает \en Sweep does not work + if ( i < n - 1 ) // \ru Размерность b равна n-1, поэтому не можем вычислять b[n-1], да и не нужно оно. \en B dimension is equal to n-1, therefore we can not calculate b [n-1], and it isn't necessary. + b[i] /= - dom; + r[i] = ( r[i] - r[i - 1] * c[i - 1] ) / dom; + } + // \ru Обратный ход \en Backward substitution + solution[n - 1] = r[n - 1]; + for ( ptrdiff_t i = n - 2; i >= 0; --i ) + solution[i] = r[i] + solution[i + 1] * b[i]; + return nr_Success; +} + + +#endif // __MB_MATRIXNN_H diff --git a/C3d/Include/mb_nurbs_function.h b/C3d/Include/mb_nurbs_function.h new file mode 100644 index 0000000..082d9d3 --- /dev/null +++ b/C3d/Include/mb_nurbs_function.h @@ -0,0 +1,2316 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль геометрических построений. + \en The module of geometric constructions. \~ + \details \ru Базовые алгоритмы Nurbs кривых и поверхностей. + \en The base algorithms for NURBS curves and surfaces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_NURBS_FUNCTION_H +#define __MB_NURBS_FUNCTION_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbContour; +class MATH_CLASS MbContour3D; +class MATH_CLASS MbNurbs; +class MATH_CLASS MbNurbs3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Флаг, определяющий построение сплайна, проходящего через точки. + \en Flag defining creation of spline passing through points. \~ + \details \ru Флаг, определяющий построение сплайна, проходящего через точки. Связан с версией. \n + \en Flag defining creation of spline passing through points. Related to the version. \n \~ + \ingroup Data_Structures +*/ +// --- +enum MbeSplineCreateType { + sct_Version0 = 0, ///< \ru Используется в версиях < V13 (центростремительная параметризация). \en Used in versions < V13 (centripetal parameterization). + sct_Version1 = 1, ///< \ru Используется в версии V13 (параметризация по длине хорды). \en Used in version V13 (parameterization by chord length). + sct_Version2 = 2, ///< \ru Используется в версии V13+. \en Used in version V13+. +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Дополнительная информация для преобразования кривой или поверхности в Nurbs. + \en Additional information for transformation of a curve or surface to NURBS. \~ + \details \ru Дополнительная информация для преобразования кривой или поверхности в Nurbs. \n + \en Additional information for transformation of a curve or surface to NURBS. \n \~ + \ingroup Data_Structures +*/ +// --- +class MbCurveIntoNurbsInfo { +private: + double tbeg; ///< \ru Параметр начала участка кривой. \en A parameter of the curve piece start. + double tend; ///< \ru Параметр конца участка кривой. \en A parameter of the curve piece end. + int sense; ///< \ru Направление сплайн-кривой. \en Direction of spline-curve. + bool matchParams; ///< \ru Сохранять ли при преобразовании однозначное соответствие параметрических областей. \en Whether to save correspondence of parametric regions while transforming or not. + bool extendRange; ///< \ru Строится ли преобразование на продолжении для незамкнутой подложки. \en Whether transformation is constructed on the extension for a non-closed substrate. + VERSION version; ///< \ru Версия исполнения. \en The version of execution. +private: + MbCurveIntoNurbsInfo(); +public: + /// \ru Конструктор. \en Constructor. + template + MbCurveIntoNurbsInfo( const Curve & c, bool match, bool ext, VERSION ver = Math::DefaultMathVersion() ) + : tbeg ( c.GetTMin() ) + , tend ( c.GetTMax() ) + , sense ( 1 ) + , matchParams( match ) + , extendRange( ext ) + , version ( ver ) + {} + /// \ru Конструктор. \en Constructor. + MbCurveIntoNurbsInfo( double t1, double t2, int s, bool match, bool ext, VERSION ver = Math::DefaultMathVersion() ) + : tbeg ( t1 ) + , tend ( t2 ) + , sense ( s ) + , matchParams( match ) + , extendRange( ext ) + , version ( ver ) + {} + /// \ru Конструктор. \en Constructor. + MbCurveIntoNurbsInfo( const MbCurveIntoNurbsInfo & other, double t1, double t2, int s ) + : tbeg ( t1 ) + , tend ( t2 ) + , sense ( s ) + , matchParams( other.matchParams ) + , extendRange( other.extendRange ) + , version ( other.version ) + {} + /// \ru Функция присвоения. \en Assignment function. + void Assign( const MbCurveIntoNurbsInfo & other ) + { + tbeg = other.tbeg; + tend = other.tend; + sense = other.sense; + matchParams = other.matchParams; + extendRange = other.extendRange; + version = other.version; + } + /// \ru Функция инициализации. \en The initialization function. + bool Init( double t1, double t2, int s ) + { + tbeg = t1; + tend = t2; + sense = s; + C3D_ASSERT( ((sense == 1) || (sense == -1)) ); + return ((sense == 1) || (sense == -1)); + } + /// \ru Функция инициализации. \en The initialization function. + bool Init( double t1, double t2, int s, bool match, bool ext ) { + matchParams = match; + extendRange = ext; + return Init( t1, t2, s ); + } + +public: + /// \ru Получить параметр начала участка кривой. \en Get the parameter of the start curve region. + double GetTBeg() const { return tbeg; } + /// \ru Получить параметр конца участка кривой. \en Get the parameter of the end curve region. + double GetTEnd() const { return tend; } + /// \ru Получить направление сплайн-кривой. \en Get the direction of spline-curve. + int GetSense() const { return sense; } + /// \ru Сохранять ли при преобразовании однозначное соответствие параметрических областей. \en Whether to save correspondence of parametric regions by transformation or not. + bool MatchParams() const { return matchParams; } + /// \ru Строится ли преобразование на продолжении для незамкнутой подложки. \en Whether transformation is constructed on the extension for a non-closed substrate or not. + bool ExtendRange() const { return extendRange; } + /// \ru Получить версию исполнения. \en Get the version of execution. + VERSION GetMathVersion() const { return version; } + +OBVIOUS_PRIVATE_COPY( MbCurveIntoNurbsInfo ) +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Параметры построения NURBS копии объекта. + \en Parameters for the construction of a NURBS copy of the object. \~ + \details \ru Параметры построения NURBS копии объекта. \n + \en Parameters for the construction of a NURBS copy of the object. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MbNurbsParameters { +public: + size_t degree; ///< \ru Порядок NURBS копии. \en Order of NURBS copy. + size_t pointsCount; ///< \ru Количество контрольных точек (при 0 параметр игнорируется). \en The number of control points (if there is no control points, parameter is ignored). + MbRect1D region; ///< \ru Область объекта, подлежащая копированию: [0 1] соответствует [tMin tMax] объекта. \en Region of the object to be copied: [0, 1] corresponds to [tMin tMax] object. + SArray knots; ///< \ru Узловой вектор. \en Knot vector. + mutable bool useApprox; ///< \ru Не пытаться построить точную поверхность. \en Don't try to create the exact surface. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbNurbsParameters() + : degree ( c3d::NURBS_DEGREE ) + , pointsCount( 0 ) + , region ( 0.0, 1.0 ) + , knots ( 0, 1 ) + , useApprox ( true ) + {} + /// \ru Конструктор по параметрам (без узлов) построения NURBS. \en The constructor of NURBS by parameters (without knots). + MbNurbsParameters( size_t d, size_t c, double zmin, double zmax, bool approx ) + : degree ( d ) + , pointsCount( c ) + , region ( zmin, zmax ) + , knots ( 0, 1 ) + , useApprox ( approx ) + { + C3D_ASSERT( d > 1 && d < SYS_MAX_UINT16 ); + degree = std_max( d, (size_t)2 ); + degree = std_min( d, (size_t)SYS_MAX_UINT16 ); + } + /// \ru Конструктор по полному набору параметров построения NURBS. \en The constructor of NURBS by a complete set of parameters. + MbNurbsParameters( size_t d, size_t c, double zmin, double zmax, bool approx, const SArray & aKnots ) + : degree ( d ) + , pointsCount( c ) + , region ( zmin, zmax ) + , knots ( aKnots ) + , useApprox ( approx ) + { + C3D_ASSERT( d > 1 && d < SYS_MAX_UINT16 ); + degree = std_max( d, (size_t)2 ); + degree = std_min( d, (size_t)SYS_MAX_UINT16 ); + } + /// \ru Конструктор копирования. \en The copy constructor. + MbNurbsParameters( const MbNurbsParameters & other ) + : degree ( other.degree ) + , pointsCount( other.pointsCount ) + , region ( other.region ) + , knots ( other.knots ) + , useApprox ( other.useApprox ) + {} + /// \ru Деструктор. \en Destructor. + ~MbNurbsParameters() {} + + /// \ru Инициализировать по другим параметрам построения NURBS копии объекта. \en Initialize by another parameters. + void Init( const MbNurbsParameters & other ) { + degree = other.degree; + pointsCount = other.pointsCount; + region = other.region; + knots = other.knots; + useApprox = other.useApprox; + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbNurbsParameters & other, double accuracy ) const; + /// \ru Оператор присваивания. \en The assignment operator. + MbNurbsParameters & operator = ( const MbNurbsParameters & other ) { + degree = other.degree; + pointsCount = other.pointsCount; + region = other.region; + knots = other.knots; + useApprox = other.useApprox; + return (*this); + } + +public: + size_t GetDegree() const { return degree; } + size_t GetPointsCount() const { return pointsCount; } + const MbRect1D & GetRegion() const { return region; } + const SArray & GetKnots() const { return knots; } + bool UseApprox() const { return useApprox; } + +KNOWN_OBJECTS_RW_REF_OPERATORS( MbNurbsParameters ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class +}; // MbNurbsParameters + + +//------------------------------------------------------------------------------- +/** \brief \ru Параметры узловой точки сплайновой копии объекта. + \en Parameters of knot point of the object spline copy. \~ + \details \ru Параметры узловой точки сплайновой копии объекта. \n + \en Parameters of knot point of the object spline copy. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MbNurbsPointInfo { +public: + MbCartPoint3D point; ///< \ru Узловая точка сплайновой поверхности. \en A knot point of a spline surface. + bool visible; ///< \ru Флаг видимости точки. \en A point visibility flag. + int8 poleLocation; ///< \ru Расположение полюса в параметрической области. \en The location of a pole in the parametric region. +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbNurbsPointInfo() + : point ( ) + , visible ( true ) + , poleLocation ( (uint8)pln_None ) + {} + /// \ru Конструктор по точке и флагу видимости. \en The constructor by a point and visibility flag. + MbNurbsPointInfo( MbCartPoint3D aPount, bool aVisible, MbePoleLocation aPoleLocation ) + : point ( aPount ) + , visible ( aVisible ) + , poleLocation ( (uint8)aPoleLocation ) + {} + /// \ru Конструктор копирования. \en The copy constructor. + MbNurbsPointInfo( const MbNurbsPointInfo & other ) + : point ( other.point ) + , visible ( other.visible ) + , poleLocation ( (uint8)other.poleLocation ) + {} + /// \ru Деструктор. \en Destructor. + ~MbNurbsPointInfo() {} + + /// \ru Инициализировать по точке и флагу видимости. \en Initialize by a point and visibility flag. + void Init( const MbNurbsPointInfo & other ) + { + point = other.point; + visible = other.visible; + poleLocation = other.poleLocation; + } + /// \ru Оператор присваивания. \en The assignment operator. + MbNurbsPointInfo & operator = ( const MbNurbsPointInfo & other ) + { + point = other.point; + visible = other.visible; + poleLocation = other.poleLocation; + return (*this); + } + /// \ru Определить, является ли точка полюсом. \en Define whether the point is a pole. + MbePoleLocation GetPoleLocation() { return (MbePoleLocation)poleLocation; } + + // \ru Закомментировала строчку ниже, поскольку объект служит только для передачи дополнительной информации об узлах сплайна \en Commented out the line below, because the object is used only to pass additional information about spline knots + // \ru В процессе прямого моделирования. Не пишется и не читается. \en In the direct modeling. Not written and not read. + // \ru KNOWN_OBJECTS_RW_REF_OPERATORS( MbNurbsPointInfo ) // для работы со ссылками и объектами класса \en KNOWN_OBJECTS_RW_REF_OPERATORS( MbNurbsPointInfo ) // for working with references and objects of the class +}; //MbNurbsPointInfo + + +//------------------------------------------------------------------------------ +/** \brief \ru Дать меру расстояния. + \en Get a measure of the distance. \~ + \details \ru Дать меру расстояния. + \en Get a measure of the distance. \~ + \param[in] p1, p2 - \ru Точки между которыми ищется расстояние. + \en Points between which the distance is computed. \~ + \param[in] spType - \ru Тип параметризации сплайновых объектов. + \en The parametrization type of spline objects. \~ + \return \ru Расстояние. + \en Distance. \~ + \ingroup Base_Algorithms +*/ +// --- +template +double GetParamDistance( const Type & p1, const Type & p2, MbeSplineParamType spType ) +{ + switch ( spType ) { + case spt_Unstated : + case spt_EquallySpaced : + return 1.0; + case spt_ChordLength : + return p1.DistanceToPoint( p2 ); + case spt_Centripetal: + return ::sqrt( p1.DistanceToPoint( p2 ) ); + } + + return 1.0; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \details \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] pcnt - \ru Число точек. + \en Number of points. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +inline bool IsValidNurbsParams( ptrdiff_t degree, bool closed, size_t pcnt ) +{ + // \ru 1. Порядок B-сплайна должен быть не менее 2. \en 1. The order of B-spline must be at least 2. + // \ru 2а. Для незамкнутой кривой количество точек не меньше порядка сплайна. \en 2a. The number of open curve points isn't less than the order of spline. + // \ru 2б. Для замкнутой кривой должно быть как минимум 3 различных точки. \en 2b. Closed curve must have at least 3 different points. + + return ( (degree > 1) && (pcnt >= (closed ? 3 : (size_t)degree)) ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \details \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] pcnt - \ru Число точек. + \en Number of points. \~ + \param[in] wcnt - \ru Число весов. + \en Number of weights. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +inline bool IsValidNurbsParams( ptrdiff_t degree, bool closed, size_t pcnt, size_t wcnt ) +{ + // \ru 1. Порядок B-сплайна должен быть не менее 2. \en 1. The order of B-spline must be at least 2. + // \ru 2а. Для незамкнутой кривой количество точек не меньше порядка сплайна. \en 2a. The number of open curve points isn't less than the order of spline. + // \ru 2б. Для замкнутой кривой должно быть как минимум 3 различных точки. \en 2b. Closed curve must have at least 3 different points. + // \ru 3. Количество точек и количество весов должны быть согласованы. \en 3. Number of points and number of weights must be equal. + + bool res = ::IsValidNurbsParams( degree, closed, pcnt ) && (wcnt == pcnt); + return res; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \details \ru Проверить параметры инициализации nurbs-объекта. + \en Check initialization parameters of a nurbs-object. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] pcnt - \ru Число точек. + \en Number of points. \~ + \param[in] wcnt - \ru Число весов. + \en Number of weights. \~ + \param[in] kcnt - \ru Число узлов. + \en Number of knots. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +inline bool IsValidNurbsParams( ptrdiff_t degree, bool closed, size_t pcnt, size_t wcnt, size_t kcnt ) +{ + // \ru 1. Порядок B-сплайна должен быть не менее 2. \en 1. The order of B-spline must be at least 2. + // \ru 2а. Для незамкнутой кривой количество точек не меньше порядка сплайна. \en 2a. The number of open curve points isn't less than the order of spline. + // \ru 2б. Для замкнутой кривой должно быть как минимум 3 различных точки. \en 2b. Closed curve must have at least 3 different points. + // \ru 3. Количество точек и количество весов должны быть согласованы. \en 3. Number of points and number of weights must be equal. + // \ru 4. Количество узлов должно быть согласовано по остальным параметрам. \en 4. Number of knots must be consistent with the other parameters. + + bool res = ::IsValidNurbsParams( degree, closed, pcnt, wcnt ) && + ( kcnt == ((size_t)degree + pcnt + (closed ? ((size_t)degree - 1) : 0)) ); + return res; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры инициализации nurbs-кривой. + \en Check initialization parameters of a nurbs-curve. \~ + \details \ru Проверить параметры инициализации nurbs-кривой. + \en Check initialization parameters of a nurbs-curve. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] pcnt - \ru Число точек. + \en Number of points. \~ + \param[in] knots - \ru Узловой вектор. + \en Knots vector. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool IsValidNurbsParamsExt( ptrdiff_t degree, bool closed, size_t pcnt, + const KnotsVector & knots ) +{ + // \ru 1. Порядок B-сплайна должен быть не менее 2. \en 1. The order of B-spline must be at least 2. + // \ru 2а. Для незамкнутой кривой количество точек не меньше порядка сплайна. \en 2a. The number of open curve points isn't less than the order of spline. + // \ru 2б. Для замкнутой кривой должно быть как минимум 3 различных точки. \en 2b. Closed curve must have at least 3 different points. + // \ru 3. Количество точек и количество весов должны быть согласованы. \en 3. Number of points and number of weights must be equal. + // \ru 4. Количество узлов должно быть согласовано по остальным параметрам. \en 4. Number of knots must be consistent with the other parameters. + + bool res = ::IsValidNurbsParams( degree, closed, pcnt ) && + ( knots.size() == ((size_t)degree + pcnt + (closed ? ((size_t)degree - 1) : 0)) ); + + if ( res ) { + if ( !c3d::IsMonotonic( knots, true, true ) ) + res = false; // SD#7118498 + } + + return res; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры инициализации nurbs-кривой. + \en Check initialization parameters of a nurbs-curve. \~ + \details \ru Проверить параметры инициализации nurbs-кривой. + \en Check initialization parameters of a nurbs-curve. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] pnts - \ru Точки. + \en Points vector. \~ + \param[in] wts - \ru Веса точек. + \en Weights vector. \~ + \param[in] knots - \ru Узловой вектор. + \en Knots vector. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool IsValidNurbsParamsExt( ptrdiff_t degree, bool closed, const PointVector & pnts, + const DoubleVector * wts, + const DoubleVector * knots = NULL ) +{ + // \ru 1. Порядок B-сплайна должен быть не менее 2. \en 1. The order of B-spline must be at least 2. + // \ru 2а. Для незамкнутой кривой количество точек не меньше порядка сплайна. \en 2a. The number of open curve points isn't less than the order of spline. + // \ru 2б. Для замкнутой кривой должно быть как минимум 3 различных точки. \en 2b. Closed curve must have at least 3 different points. + // \ru 3. Количество точек и количество весов должны быть согласованы. \en 3. Number of points and number of weights must be equal. + // \ru 4. Количество узлов должно быть согласовано по остальным параметрам. \en 4. Number of knots must be consistent with the other parameters. + + size_t pcnt = pnts.size(); + + bool res = ::IsValidNurbsParams( degree, closed, pcnt ) && + ( (wts == NULL) || (wts->size() == pcnt) ) && + ( (knots == NULL) || (knots->size() == ((size_t)degree + pcnt + (closed ? ((size_t)degree - 1) : 0))) ); + + if ( res && (knots != NULL) ) { + if ( !c3d::IsMonotonic( *knots, true, true ) ) + res = false; // SD#7118498 + } + + return res; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить узловой вектор nurbs-объекта. + \en Check knots vector of a nurbs-object. \~ + \details \ru Проверить узловой вектор nurbs-объекта. + \en Check knots vector of a nurbs-object. \~ + \param[in] knots - \ru Узловой вектор. + \en Knots vector. \~ + \return \ru true, если параметры согласованы. + \en Returns true if parameters are consistent. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool IsValidNurbsKnots( const KnotsVector & knots, double eps = EXTENT_EPSILON ) +{ + // \ru 1 . Количество узлов должно быть не менее 4 \en 1 . The number of knots must be at least 4 + // \ru 2 . Последовательность узлов должна быть неубывающей \en 2 . Sequence of nodes must be nondecreasing + // \ru 3 . Первый и последний узлы должны быть различны \en 3 . The first and the last nodes must be different + + size_t cnt = knots.size(); + if ( cnt < 4 ) + return false; + + eps = ::fabs(eps); + if ( ::fabs(knots[cnt-1] - knots[0]) < eps ) + return false; + + for ( size_t i = 0; i < (cnt - 1); i++ ) { + if ( knots[i+1] < knots[i] - eps ) + return false; + } + + return true; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение индекса узла left для первой ненулевой функции. + \en Definition of "left" knot index for the first non-zero function. \~ + \details \ru Определение индекса узла left для первой ненулевой функции (knots[mid] <= t < knots[mid + 1]). + \en Definition of "left" knot index for the first non-zero function (knots[mid] <= t < knots[mid + 1]). \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] knots - \ru Множество узлов. + \en Knots. \~ + \param[in, out] t - \ru Значение параметра. + \en A parameter value. \~ + \return \ru Индекс узла. + \en A knot index. \~ + \ingroup Base_Algorithms +*/ +// --- +template +ptrdiff_t KnotIndex( ptrdiff_t degree, const KnotsVector & knots, double & t ) +{ + ptrdiff_t low = ( (ptrdiff_t)degree - 1 ); + ptrdiff_t high = ( (ptrdiff_t)knots.size() - (ptrdiff_t)degree ); + ptrdiff_t mid = low; + + if ( t <= knots[low] ) { + t = knots[low]; + ptrdiff_t countKnt = knots.size(); + ptrdiff_t lowP = low; + lowP++; + // \ru Исправление ошибки BUG_21185 while ( (lowP < countKnt) && (t == knots[lowP]) ) { \en Bugfix BUG_21185 while ( (lowP < countKnt) && (t == knots[lowP]) ) { + while ( (lowP < countKnt - degree) && (t == knots[lowP]) ) { //-V550 + low = lowP; + lowP++; + } + mid = low; + } + else if ( t >= knots[high] ) { + t = knots[high]; + // BUG_82980 while ( (high > 0) && (knots[high] == t) ) { + while ( (high > degree - 1) && (knots[high] == t) ) { + high--; + } + mid = high; + } + else if ( c3d::ArFind( knots, t, mid ) ) { + while ( knots[mid] == t ) { + mid++; + } + mid--; + } + return mid; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить узловой вектор (равномерная параметризация). + \en Define knot vector (uniform parameterization). \~ + \details \ru Определить узловой вектор (равномерная параметризация). + \en Define knot vector (uniform parameterization). \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] uppPointsIndex - \ru Индекс последней точки. + \en Last point index. \~ + \param[in] knots - \ru Узловой вектор. + \en Knots vector. \~ + \ingroup Base_Algorithms +*/ +// --- +template +ptrdiff_t DefineKnotsVector( ptrdiff_t degree, bool closed, ptrdiff_t uppPointsIndex, + KnotsVector & knots ) +{ + if ( (degree < 2) || (uppPointsIndex < 1) ) { + knots.clear(); + return -1; + } + + ptrdiff_t pointsCount = uppPointsIndex + 1; + ptrdiff_t power = degree - 1; + + ptrdiff_t knotsCount = degree + pointsCount + (closed ? power : 0); + knots.clear(); + knots.reserve( knotsCount ); + + ptrdiff_t i = 0; + + if ( closed ) { // замкнутый В-сплайн + double knot = 0.0; + for ( i = 0; i < knotsCount; i++ ) { + knot = (double)(i - power); + knots.push_back( knot ); + } + } + else { + double knot = 0.0; + for ( i = 0; i < degree; i++ ) + knots.push_back( knot ); + + ptrdiff_t cnt = pointsCount - degree; + for ( i = 0; i < cnt; i++ ) { + knot += 1.0; + knots.push_back( knot ); + } + + knot += 1.0; + for ( i = 0; i < degree; i++ ) + knots.push_back( knot ); + } + + return (knotsCount - 1); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить узловой вектор. + \en Define knot vector. \~ + \details \ru Определить узловой вектор. + \en Define knot vector. \~ + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in] count - \ru Количество точек. + \en Number of points. \~ + \param[in] params - \ru Параметры точек (для замкнутого count+1). + \en Points parameters (for closed spline - "count"+1). \~ + \param[out] knots - \ru Узловой вектор. + \en Knots vector. \~ + \return \ru true, если набор параметров сформирован. + \en Returns true if result is success. \~ + \ingroup Base_Algorithms +*/ +// --- +MATH_FUNC (bool) DefineKnotsVector( ptrdiff_t degree, bool closed, size_t count, // \ru Порядок, замкнутость, количество точек \en Order, closedness, number of points + const SArray * params, // \ru Параметры точек (для замкнутого count+1) \en Points parameters (for closed spline - "count"+1) + SArray & knots ); // \ru Формируемый узловой вектор \en Generated knot vector + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить параметрическое распределение точек. + \en Define parametric distribution of points. \~ + \details \ru Определить параметрическое распределение точек. + \en Define parametric distribution of points. \~ + \param[in] points - \ru Массив точек. + \en Points vector. \~ + \param[in] spType - \ru Тип параметризации сплайновых объектов. + \en The parameterization type of spline objects. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[out] params - \ru Параметрическое распределение точек. + \en Parametric distribution of points. \~ + \return \ru true, если набор параметров сформирован. + \en Returns true if result is success. \~ + \ingroup Base_Algorithms +*/ +// --- +template +bool DefineThroughPointsParams( const Points & points, MbeSplineParamType spType, bool closed, + Params & params ) +{ + bool res = false; + + ptrdiff_t count = (ptrdiff_t)points.size(); + + if ( count > (closed ? 2 : 1) ) { + double param = 0.0; + ptrdiff_t extCount = closed ? (count + 1) : count; + params.clear(); + params.resize( extCount, param ); + + double paramSum = 0.0; + for ( ptrdiff_t j = 1; j < extCount; j++ ) { + ptrdiff_t jp = (j - 1 + count) % count; + ptrdiff_t jc = j % count; + param = ::GetParamDistance( points[jp], points[jc], spType ); + params[j] = ( params[j-1] + param ); + paramSum += param; + } + + if ( paramSum > METRIC_PRECISION ) { + for ( ptrdiff_t j = 0; j < extCount; j++ ) { + params[j] /= paramSum; + params[j] *= (double)(extCount-1); + } + res = true; + } + else if ( spType != spt_EquallySpaced ) { + C3D_ASSERT_UNCONDITIONAL( false ); + paramSum = 0.0; + for ( ptrdiff_t j = 1; j < extCount; j++ ) { + ptrdiff_t jp = (j - 1 + count) % count; + ptrdiff_t jc = j % count; + param = ::GetParamDistance( points[jp], points[jc], spt_EquallySpaced ); + params[j] = ( params[j-1] + param ); + paramSum += param; + } + if ( paramSum > METRIC_PRECISION ) { + for ( ptrdiff_t j = 0; j < extCount; j++ ) { + params[j] /= paramSum; + params[j] *= (double)(extCount-1); + } + res = true; + } + } + } + + return res; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление B - базиса (degree - порядок B-сплайна, p = (degree - 1) - степень полинома(B-сплайна)). + \en The calculation of B - basis ("degree" - order of B-spline, p = (degree - 1) - the degree of the polynomial (B-spline)). \~ + \details \ru Вычисление B - базиса (degree - порядок B-сплайна, p = (degree - 1) - степень полинома(B-сплайна)). + Для ускорения используется рабочий вектор lr = { left[p+1], right[p+1] } ). + \en The calculation of B - basis ("degree" - order of B-spline, p = (degree - 1) - the degree of the polynomial (B-spline)). + To speed up vector lr = { left[p+1], right[p+1] } is used. \~ + \param[in] i - \ru Индекс в массиве узлов, получаемый с помощью функции KnotIndex(). + \en Index of knots vector obtained by the function KnotIndex(). \~ + \param[in] t - \ru Параметр. + \en Parameter. \~ + \param[in] p - \ru p = degree - 1, где degree - порядок B-сплайна. + \en p = degree - 1, where degree is B-spline degree. \~ + \param[in] knots - \ru Узловой вектор. + \en Knots vector. \~ + \param[out] nsplines - \ru Массив размерности degree, заполняется значениями сплайна в поля 0..degree-2; nsplines[degree-1] = 0. + \en Array of B-spline values. \~ + \param[in,out] lrVect - \ru Массив размерности 2*(p+1) = 2*degree, содержимое игнорируется и будет перезаписано. Нужен для ускорения работы функции. В результате работы в нем останется мусор.. + \en Temporary working vector with dimension 2*(p+1) = 2*degree. \~ + \ingroup Base_Algorithms +*/ +// --- +template +MATH_FUNC (bool) BasisFuns( ptrdiff_t i, double t, ptrdiff_t p, const Knots & knots, DoubleVector & nsplines, + DoubleVector & lrVect ); + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить базисный сплайн по параметру t и узловому вектору. + \en Calculate basic spline by "t" parameter and knots vector. \~ + \details \ru Вычислить базисный сплайн по параметру t и узловому вектору. + \en Calculate basic spline by "t" parameter and knots vector. \~ + \ingroup Base_Algorithms +*/ +// --- +template +MATH_FUNC (bool) CalcBsplvb( const DoubleVector & knots, double t, ptrdiff_t left, ptrdiff_t degree, + DoubleVector & biatx, DoubleVector & lrVect ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление B - базиса ( с использованием рабочих указателей классов nurbs кривых и поверхностей ). + \en Calculation of B - basis (using working pointers to nurbs curves and surfaces). \~ + \details \ru Вычисление B - базиса ( с использованием рабочих указателей классов nurbs кривых и поверхностей ). + \en Calculation of B - basis (using working pointers to nurbs curves and surfaces). \~ + \ingroup Base_Algorithms +*/ +// --- +void AllBasisFuns( ptrdiff_t i, double t, ptrdiff_t p, const SArray & knots, double ** ndu, + double * left, double * right, bool newPatch = true ); + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление B - базиса ( с использованием рабочих указателей классов nurbs кривых и поверхностей ). + \en Calculation of B - basis (using working pointers to nurbs curves and surfaces). \~ + \details \ru Вычисление B - базиса ( с использованием рабочих указателей классов nurbs кривых и поверхностей ). + \en Calculation of B - basis (using working pointers to nurbs curves and surfaces). \~ + \ingroup Base_Algorithms +*/ +// --- +void AllBasisFuns( ptrdiff_t i, double t, ptrdiff_t p, const SArray & knots, double * ndu, size_t degree, + double * left, double * right, bool newPatch = true ); + +//------------------------------------------------------------------------------ +/// \ru Вычислить значения базисного сплайна и его производных. \en Calculate values and derivatives of basic spline. +/** + \param[in] t - \ru Параметр на кривой. + \en Curve parameter. \~ + \param[in] left - \ru Номер узла первого ненулевого сплайна. + \en Knot number of the first nonzero spline. \~ + \param[in] n - \ru Порядок вычисляемых производных. + \en Order of calculated derivatives. \~ + \param[out] values - \ru Двумерный массив значений. + \en 2D-Array filled by spline values. \~ + \ingroup Base_Algorithms +*/ +//--- +bool CalcDBsplvb( const SArray & knots, ptrdiff_t degree, double t, ptrdiff_t left, ptrdiff_t n, Array2 & values ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить все разностные формы кривой. + \en Calculate all difference forms of curve. \~ + \details \ru Вычислить все (или опционально некоторые) разностные формы кривой (характеристические производные). + \en Calculate all (or some, optionally) difference forms of curve (characteristic derivatives). \~ + \ingroup Base_Algorithms +*/ +// --- +template +void CurveDeriveCpts( ptrdiff_t p, const KnotsVector & U, const Point * P, const double * W, size_t pointCount, + const NurbsVector * PW, ptrdiff_t d, ptrdiff_t r1, ptrdiff_t r2, NurbsVector * PK ) +{ + C3D_ASSERT( (P != NULL && W != NULL) != (PW != NULL) ); + + ptrdiff_t r = ( r2 - r1 ); + ptrdiff_t degree = ( p + 1 ); + ptrdiff_t i, k, icount; + NurbsVector & PK0 = PK[0]; + + if ( PW != NULL ) { + for ( i = 0; i <= r; i++ ) + PK0.Set( i, *PW, (r1 + i) ); + } + else { + if ( !PK0.UseWeights() && ( r1 + r ) < pointCount ) { + for ( i = 0; i <= r; i++ ) { + PK0[i] = P[r1 + i]; + } + } + else { + for ( i = 0; i <= r; i++ ) { + k = ( ( r1 + i ) % pointCount ); + PK0.Init( i, P[k], W[k] ); + } + } + } + + for ( k = 1; k <= d; k++ ) { + NurbsVector & PKMin = PK[k - 1]; + NurbsVector & PKPls = PK[k]; + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = (r - k); i <= icount; i++ ) { + r1i = ( r1 + i ); + C3D_ASSERT( ( ::fabs( U[r1i + degree] - U[r1i + k] ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + PKPls.Dec( i, PKMin, i, PKMin, (i + 1), (tmp / (U[r1i + degree] - U[r1i + k])) ); + } + } +} + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить все разностные формы кривой. + \en Calculate all difference forms of curve. \~ + \details \ru Вычислить все (или опционально некоторые) разностные формы кривой (характеристические производные). + \en Calculate all (or some, optionally) difference forms of curve (characteristic derivatives). \~ + \ingroup Base_Algorithms +*/ +// --- +template +void CurveDeriveCpts( ptrdiff_t p, const KnotsVector & U, const Point * P, const double w, size_t pointCount, + const NurbsVector * PW, ptrdiff_t d, ptrdiff_t r1, ptrdiff_t r2, NurbsVector * PK ) +{ + C3D_ASSERT( (P != NULL) != (PW != NULL) ); + + ptrdiff_t r = ( r2 - r1 ); + ptrdiff_t degree = ( p + 1 ); + ptrdiff_t i, k, icount; + NurbsVector & PK0 = PK[0]; + + if ( PW != NULL ) { + for ( i = 0; i <= r; i++ ) + PK0.Set( i, *PW, (r1 + i) ); + } + else { + if ( !PK0.UseWeights() && ( r1 + r ) < pointCount ) { + for ( i = 0; i <= r; i++ ) { + PK0[i] = P[r1 + i]; + } + } + else { + for ( i = 0; i <= r; i++ ) { + k = ( ( r1 + i ) % pointCount ); + PK0.Init( i, P[k], w ); + } + } + } + + for ( k = 1; k <= d; k++ ) { + NurbsVector & PKMin = PK[k - 1]; + NurbsVector & PKPls = PK[k]; + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = (r - k); i <= icount; i++ ) { + r1i = ( r1 + i ); + C3D_ASSERT( ( ::fabs( U[r1i + degree] - U[r1i + k] ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + PKPls.Dec( i, PKMin, i, PKMin, (i + 1), (tmp / (U[r1i + degree] - U[r1i + k])) ); + } + } +} + +//------------------------------------------------------------------------------ + /** \brief \ru Вычислить все разностные формы кривой. + \en Calculate all difference forms of curve. \~ + \details \ru Вычислить все (или опционально некоторые) разностные формы кривой (характеристические производные). + \en Calculate all (or some, optionally) difference forms of curve (characteristic derivatives). \~ + \ingroup Base_Algorithms +*/ +// --- +template +void CurveDeriveCpts( ptrdiff_t p, const KnotsVector & U, const Point * P, const double * W, size_t pointCount, + const NurbsVector * PW, ptrdiff_t d, ptrdiff_t r1, ptrdiff_t r2, DoubleTriple ** DT, double ** WT ) +{ + C3D_ASSERT( ( P != NULL && W != NULL ) != ( PW != NULL ) ); + + ptrdiff_t r = ( r2 - r1 ); + ptrdiff_t degree = ( p + 1 ); + ptrdiff_t i, k, icount; + DoubleTriple * DT0 = DT[0]; + double * WT0 = WT[0]; + bool useWeight = WT0 != NULL; + + if ( PW != NULL ) { + if ( !useWeight ) { + for ( i = 0; i <= r; i++ ) + DT0[i].Init( (*PW)[r1 + i] ); + } + else { + for ( i = 0; i <= r; i++ ) { + DT0[i].Init( (*PW)[r1 + i] ); + WT0[i] = PW->w( r1 + i ); + } + } + } + else { + if ( !useWeight && ( r1 + r ) < pointCount ) { + for ( i = 0; i <= r; i++ ) { + DT0[i].Init( P[r1 + i].x, P[r1 + i].y, P[r1 + i].z ); + } + } + else { + for ( i = 0; i <= r; i++ ) { + k = ( ( r1 + i ) % pointCount ); + DT0[i].Init( P[k], W[k] ); + if ( useWeight ) + WT0[i] = W[k]; + } + } + } + + double * WTMin = NULL; + double * WTPls = NULL; + for ( k = 1; k <= d; k++ ) { + DoubleTriple * DTMin = DT[k - 1]; + DoubleTriple * DTPls = DT[k]; + if ( useWeight ) { + WTMin = WT[k - 1]; + WTPls = WT[k]; + } + + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = ( r - k ); i <= icount; i++ ) { + r1i = ( r1 + i ); + double tmp2 = U[r1i + degree] - U[r1i + k]; + C3D_ASSERT( ( ::fabs( tmp2 ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + DTPls[i].Dec( DTMin[i], DTMin[i + 1], tmp / (tmp2) ); + if ( useWeight ) + WTPls[i] = ( WTMin[i + 1] - WTMin[i] ) * ( tmp / (tmp2) ); + } + } +} + +//------------------------------------------------------------------------------ + /** \brief \ru Вычислить все разностные формы кривой. + \en Calculate all difference forms of curve. \~ + \details \ru Вычислить все (или опционально некоторые) разностные формы кривой (характеристические производные). + \en Calculate all (or some, optionally) difference forms of curve (characteristic derivatives). \~ + \ingroup Base_Algorithms +*/ +// --- +template +void CurveDeriveCpts( ptrdiff_t p, const KnotsVector & U, const Point * P, const double w, size_t pointCount, + const NurbsVector * PW, ptrdiff_t d, ptrdiff_t r1, ptrdiff_t r2, DoubleTriple ** DT, double ** WT ) +{ + C3D_ASSERT( ( P != NULL ) != ( PW != NULL ) ); + + ptrdiff_t r = ( r2 - r1 ); + ptrdiff_t degree = ( p + 1 ); + ptrdiff_t i, k, icount; + DoubleTriple * DT0 = DT[0]; + double * WT0 = WT[0]; + bool useWeight = WT0 != NULL; + + if ( PW != NULL ) { + if ( !useWeight ) { + for ( i = 0; i <= r; i++ ) + DT0[i].Init( (*PW)[r1 + i] ); + } + else { + for ( i = 0; i <= r; i++ ) { + DT0[i].Init( (*PW)[r1 + i] ); + WT0[i] = PW->w( r1 + i ); + } + + } + } + else { + if ( !useWeight && ( r1 + r ) < pointCount ) { + for ( i = 0; i <= r; i++ ) { + DT0[i].Init( P[r1 + i].x, P[r1 + i].y, P[r1 + i].z ); + } + } + else { + for ( i = 0; i <= r; i++ ) { + k = ( ( r1 + i ) % pointCount ); + DT0[i].Init( P[k], w ); + if( useWeight ) + WT0[i] = w; + } + } + } + + double * WTMin = NULL; + double * WTPls = NULL; + for ( k = 1; k <= d; k++ ) { + DoubleTriple * DTMin = DT[k - 1]; + DoubleTriple * DTPls = DT[k]; + if ( useWeight ) { + WTMin = WT[k - 1]; + WTPls = WT[k]; + } + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = ( r - k ); i <= icount; i++ ) { + r1i = ( r1 + i ); + double tmp2 = U[r1i + degree] - U[r1i + k]; + C3D_ASSERT( ( ::fabs( tmp2 ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + DTPls[i].Dec( DTMin[i], DTMin[i + 1], tmp / (tmp2) ); + if ( useWeight ) + WTPls[i] = ( WTMin[i + 1] - WTMin[i] ) * ( tmp / ( tmp2 ) ); + } + } +} + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить все разностные формы кривой. + \en Calculate all difference forms of curve. \~ + \details \ru Вычислить все (или опционально некоторые) разностные формы кривой (характеристические производные). + \en Calculate all (or some, optionally) difference forms of curve (characteristic derivatives). \~ + \ingroup Base_Algorithms +*/ +// --- +template +void CurveDeriveCpts( ptrdiff_t p, const double * U, const Point * P, const double * W, size_t pointCount, + ptrdiff_t r1, ptrdiff_t r2, + Homogeneous * H0, Homogeneous * H1, Homogeneous * H2, Homogeneous * H3 ) +{ + ptrdiff_t r = ( r2 - r1 ); + ptrdiff_t degree = ( p + 1 ); + ptrdiff_t i, k, icount; + + for ( i = 0; i <= r; i++ ) { + k = ( (r1 + i) % pointCount ); + if ( W != NULL ) + H0[i].Init( P[k], W[k] ); + else + H0[i].Init( P[k], 1.0 ); + } + k = 1; + { + Homogeneous * PKMin = H0; + Homogeneous * PKPls = H1; + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = (r - k); i <= icount; i++ ) { + r1i = ( r1 + i ); + C3D_ASSERT( ( ::fabs( U[r1i + degree] - U[r1i + k] ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + PKPls[i].Dec( PKMin[i], PKMin[i + 1], (tmp / (U[r1i + degree] - U[r1i + k])) ); + } + } + k = 2; + { + Homogeneous * PKMin = H1; + Homogeneous * PKPls = H2; + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = (r - k); i <= icount; i++ ) { + r1i = ( r1 + i ); + C3D_ASSERT( ( ::fabs( U[r1i + degree] - U[r1i + k] ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + PKPls[i].Dec( PKMin[i], PKMin[i + 1], (tmp / (U[r1i + degree] - U[r1i + k])) ); + } + } + k = 3; + { + Homogeneous * PKMin = H2; + Homogeneous * PKPls = H3; + double tmp = (double)( degree - k ); + ptrdiff_t r1i = r1; + for ( i = 0, icount = (r - k); i <= icount; i++ ) { + r1i = ( r1 + i ); + C3D_ASSERT( ( ::fabs( U[r1i + degree] - U[r1i + k] ) > DOUBLE_EPSILON ) ); // \ru Проверка на сбой \en Check of failure + PKPls[i].Dec( PKMin[i], PKMin[i + 1], (tmp / (U[r1i + degree] - U[r1i + k])) ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Cвертка по Энш. \en Einstein's convolution product. +// --- +void EiSum( const double * pk, double ** nd, size_t jcount, double & sum ); + + +//------------------------------------------------------------------------------ +// \ru Cвертка по Энш. \en Einstein's convolution product. +// --- +void EiSum( const MbHomogeneous * pk, double * nd, size_t degree, size_t jcount, MbHomogeneous & sum ); + + +//------------------------------------------------------------------------------ +// \ru Cвертка по Энш. \en Einstein's convolution product. +// --- +void EiSum( const MbHomogeneous3D * pk, double * nd, size_t degree, size_t jcount, MbHomogeneous3D & sum ); + + +//------------------------------------------------------------------------------ +/// \ru Загнать параметр t в параметрическую область кривой. \en Reduce "t" to parameter in the parametric domain of the curve. +/** + \param[in] tMin, tMax - \ru Параметры, задающие параметрическую область кривой. + \en Parameters which define the parametric region of the curve. \~ + \param[in] closed - \ru Признак замкнутости кривой. + \en An attribute of curve closedness. \~ + \param[in, out] t - \ru Исходный параметр. + \en Initial parameter. \~ + \ingroup Base_Algorithms +*/ +// --- +inline void CheckParam( const double & tMin, const double & tMax, bool closed, double & t ) +{ + if ( (t < tMin) || (t > tMax) ) { + if ( closed ) { // \ru Сплайн кривая замкнута \en Spline curve is closed + double period = tMax - tMin; + t -= ::floor( (t - tMin) / period ) * period; + } + else if ( t < tMin ) + t = tMin; + else if ( t > tMax ) + t = tMax; + } +} + + +//------------------------------------------------------------------------------ +/// \ru Рассчитать ненулевые сплайны при данном параметре. \en Calculate non-zero splines with a given parameter. +/** + \param[in] degree - \ru Порядок B-сплайна. + \en B-spline degree. \~ + \param[in] knots - \ru Множество узлов. + \en Knots. \~ + \param[in] closed - \ru Признак замкнутости. + \en A closedness attribute. \~ + \param[in, out] t - \ru Параметр + \en A parameter \~ + \param[out] nsplines - \ru Множество размерности degree, заполняется значениями сплайна. + \en Array (dimension is "degree") is filled by spline values. \~ + \param[out] lrVect - \ru Вспомогательный массив (содержит мусор). + \en An assisting array (contains garbage). \~ + \return \ru Номер первого ненулевого B-сплайна. + \en The number of the first non-zero B-spline. \~ + \ingroup Base_Algorithms +*/ +// --- +template +ptrdiff_t CalculateSplines( ptrdiff_t degree, + const KnotsVector & knots, + bool closed, + double & t, + DoubleVector1 & nsplines, + DoubleVector2 & lrVect ) +{ + ptrdiff_t begInd = -1; // \ru Возвращаемое значение = номер первого ненулевого B-сплайна \en The return value = the number of the first non-zero B-spline. + + if ( (degree > 1) && ((ptrdiff_t)knots.size() > (ptrdiff_t)degree) ) { + ptrdiff_t power = degree-1; + ptrdiff_t lastKnotInd = (ptrdiff_t)knots.size() - 1; + + // \ru Загнать параметр t в параметрическую область кривой \en Reduce "t" to a parameter in the parametric domain of the curve + ::CheckParam( knots[power], knots[lastKnotInd - (ptrdiff_t)power], closed, t ); + + ptrdiff_t tspan = ::KnotIndex( degree, knots, t ); + begInd = tspan - (ptrdiff_t)power; + if ( begInd >= 0 && begInd <= lastKnotInd - (ptrdiff_t)power ) + ::BasisFuns( tspan, t, power, knots, nsplines, lrVect ); + else { + begInd = SYS_MAX_T; // \ru Ошибка \en Error + for ( size_t i = 0; i < (size_t)degree; i++ ) + nsplines[i] = 0.0; + } + + C3D_ASSERT( (size_t)begInd != SYS_MAX_T ); + } + + return begInd; +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление характеристических точек pointList для прохождения NURBS-кривой через points[i] при params[i] \en Calculation of characteristic points "pointList" of NURBS-curve passing through points[i] with params[i] +// --- +template +MbeNewtonResult CalculatePointList( const DoubleVector & params, const PointVector & points, + ptrdiff_t degree, bool closed, const DoubleVector & knots, + PointVector & pointList ) +{ + MbeNewtonResult res = nr_Failure; + + ptrdiff_t pointsCount = (ptrdiff_t)points.size(); + C3D_ASSERT( points.size() > 1 ); + + if ( pointsCount > 1 && degree > 1 && knots.size() > 1 ) { + // \ru Инициализация опорных точек \en Initialization of support points + if ( &pointList != &points ) { + pointList.clear(); + pointList = points; + } + ptrdiff_t uppIndex = (ptrdiff_t)pointList.size() - 1; // \ru Количество точек \en The count of points + if ( closed && (uppIndex > 1) && + c3d::EqualPoints( pointList[0], pointList[uppIndex], METRIC_REGION ) ) { + pointList.erase( pointList.begin() + uppIndex ); + pointsCount = (ptrdiff_t)pointList.size(); + } + + DPtr matrixPtr( MatrixNN::Create( pointsCount ) ); // \ru Матрица системы уравнений для прохождения NURBS при params[i] через points[i] \en Matrix of equation system for constructing the NURBS-curve passing through the points[i] with params[i] + + if ( matrixPtr != NULL && ::IsValidNurbsParamsExt( degree, closed, pointList.size(), knots ) ) { + MatrixNN & matrix = *matrixPtr; + + std::vector bSplines; // \ru Ненулевые B-сплайны \en Non-zero B-splines + bSplines.resize( degree ); + + std::vector lrVect; + + for ( ptrdiff_t i = 0; i < pointsCount; i++ ) { // \ru Заполняем строки матрицы \en Fills matrix rows + double t = params[i]; + ptrdiff_t k = 0; + ptrdiff_t ind = ::CalculateSplines( degree, knots, closed, t, bSplines, lrVect ); + // \ru Заполняем i-ю строку \en Fill the i-th row + for ( k = 0; k < ind; k++ ) + matrix( i, k ) = 0.0; + for ( k = ind; k < ind + (ptrdiff_t)degree; k++ ) + matrix( i, k%pointsCount ) = bSplines[k - ind]; // \ru Ненулевые элементы строки \en Non-zero elements of row + for ( k = ind + (size_t)degree; k < pointsCount; k++ ) + matrix( i, k ) = 0.0; + } + + double epsilon = PARAM_EPSILON; + // \ru Решаем систему уравнений относительно характеристических точек pointList \en Solve the system of equations for the characteristic points "pointList" + // \ru Правая часть системы = адрес начала массива опорных точек pointList.begin(). \en The right system part = address of beginning of support point array pointList.begin(). + res = ::TypedGaussEquation( matrix, &pointList[0], epsilon ); + } + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление характеристических точек pointList для прохождения NURBS-кривой через points[i] при params[i] \en Calculation of characteristic points "pointList" of NURBS-curve passing through points[i] with params[i] +// --- +template +MATH_FUNC (MbeNewtonResult) CalculatePointListWithBandMatrix( const DoubleVector & params, const PointsVector & points, + ptrdiff_t degree, bool closed, const DoubleVector & knots, + PointsVector & pointList ); + + +//------------------------------------------------------------------------------ +// \ru Установить касательность сплайна к вектору \en Set tangency of spline to vector +//--- +template +bool AttachNurbsG1( TypedNurbs & nurbs, // \ru Модифицируемый сплайн \en Modifiable spline + const TypedVector & tang, // \ru Касательный вектор \en Tangent vector + bool begin, // \ru Сопряжение выставлено в начале \en Conjugation is defined for the start + bool modify, // \ru Можно ли менять существующие полюса \en Whether it is possible to modify the existing pole + bool isC1 ) // \ru Нужно сохранить длину касательного вектора \en Need to save the length of the tangent vector +{ + bool res = false; + + if ( !nurbs.IsClosed() && nurbs.GetPointListCount() > 2 && nurbs.GetDegree() > 2 ) { + bool needRebuild = false; + + TypedVector normTang( tang ); + double tangLen = tang.Length(); + if ( tangLen > LENGTH_EPSILON ) + normTang /= tangLen; + + SArray points ( 0, 1 ); + SArray weights( 0, 1 ); + SArray knots ( 0, 1 ); + nurbs.GetPointList( points ); + nurbs.GetWeights( weights ); + nurbs.GetKnots( knots ); + ptrdiff_t degree = nurbs.GetDegree(); + bool closed = false; + + // \ru Дополнительная точка, которая обеспечивает визуальную касательность \en Additional point which provides a visual tangency + TypedPoint point, add( points[begin ? 0 : points.MaxIndex()] ); + TypedVector curTang, curVect; + double dist = 0.0; + //double dKnots = 0.0; + + double part = modify ? 1.0 : 0.5; // \ru Параметрическая доля \en Parametric part + double pointKnot = 0.0; // \ru Узел точки, обеспечивающий сопряжение \en Point knot which provides a conjugation + double pointWeight = 1.0; // \ru Вес точки \en A point weight + + if ( begin ) { // \ru Стыковка производится в начале \en Connection is performed in the beginning + nurbs._Tangent( nurbs.GetTMin(), curTang ); + if ( !curTang.Colinear(tang) || + curTang * tang < -ANGLE_EPSILON ) // BUG_55564 + { // \ru Если еще не установлено сопряжение \en If conjugation is not set + curVect.Set( points[1], 1.0, points[0], -1.0 ); + + if ( isC1 || !modify || tang.Orthogonal( curTang, Math::metricNear ) ) { + // BUG_53978 if ( !modify || tang.Orthogonal( curTang, Math::metricNear ) ) { + pointKnot = modify ? knots[(size_t)degree] : + knots[(size_t)degree] * part + knots[0] * ( 1.0 - part ); + + pointWeight = modify ? weights[1] : weights[0]; + + dist = points[0].DistanceToPoint( points[1] ) * part; // \ru Длина производной \en Derivative length + + if ( isC1 ) + add.Add( tang, (pointKnot - knots[0]) / (double)(degree - 1) * weights[0] / pointWeight ); + else + add.Add( normTang, dist / (double)(degree - 1) * weights[0] / pointWeight ); + + if ( modify ) + points[1] = add; + else { + points.AddAt( add, 1 ); + weights.AddAt( pointWeight, 1 ); + knots.AddAt( pointKnot, (size_t)degree ); + } + } + else { + // \ru BUG_50080 dist = (normTang * curVect); // МСГ К12 решено не учитывать знак производной \en BUG_50080 dist = (normTang * curVect); // МСГ К12 ignore the sign of the derivative + dist = ::fabs(normTang * curVect); + points[1] = points[0] + normTang * dist; + } + needRebuild = true; + } + + res = true; + } + else { // \ru Стыковка производится в конце \en Connection is performed at the end + nurbs._Tangent( nurbs.GetTMax(), curTang ); + if ( !curTang.Colinear(tang) || + curTang * tang < -ANGLE_EPSILON ) // BUG_55564) + { // \ru Если еще не установлено сопряжение \en If conjugation is not set + ptrdiff_t shear = points.MaxIndex(); + curVect.Set( points[shear], 1.0, points[shear - 1], -1.0 ); + + if ( isC1 || !modify || tang.Orthogonal( curTang, Math::metricNear ) ) { + // BUG_53978 if ( !modify || tang.Orthogonal( curTang, Math::metricNear ) ) { + pointKnot = modify ? knots[shear] : + knots[shear] * ( 1.0 - part ) + knots[shear + (size_t)degree] * part; + + pointWeight = modify ? weights[shear - 1] : weights[shear]; + + dist = points[shear].DistanceToPoint( points[shear - 1] ) * part; // \ru Длина производной \en Derivative length + + if ( isC1 ) + add.Add( tang, -(knots[shear + degree] - pointKnot) / (double)(degree - 1) * weights[shear] / pointWeight ); + else { + // BUG_49940 add.Add( tang, -dist / (degree - 1) * weights[shear] / pointWeight ); + add.Add( normTang, -dist / (double)(degree - 1) * weights[shear] / pointWeight ); + } + + if ( modify ) + points[shear - 1] = add; + else { + points.AddAt( add, shear ); + weights.AddAt( pointWeight, shear ); + knots.AddAt( pointKnot, shear + 1 ); + } + } + else { + // \ru BUG_50080 dist = (normTang * curVect); // МСГ К12 решено не учитывать знак производной \en BUG_50080 dist = (normTang * curVect); // МСГ К12 ignore the sign of the derivative + dist = ::fabs(normTang * curVect); + points[shear - 1] = points[shear] - normTang * dist; + } + needRebuild = true; + } + + res = true; + } + + if ( res && needRebuild ) + nurbs.Init( degree, closed, points, weights, knots, ncf_Unspecified ); +/*#if defined(C3D_DEBUG) + if ( res ){ // \ru Отладка \en Debugging + TypedVector vect; + if ( begin ) nurbs._FirstDer( nurbs.GetTMin(), vect ); + else nurbs._FirstDer( nurbs.GetTMax(), vect ); + double vectLen = vect.Length(); + C3D_ASSERT( tang.Colinear( vect ) && tang * vect > ANGLE_EPSILON ); + C3D_ASSERT( !isC1 || ::fabs(tangLen - vectLen) < METRIC_EPSILON ); + } +#endif +*/ + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Установить касательные на краях \en Set tangents at the ends +// --- +template +bool SetLimitFirstDerivatives( const Curve & curve, bool setBeg, bool setEnd, Nurbs & nurbs, bool setLen ) +{ // BUG_59596 + bool changed = false; + + if ( setBeg ) { + Vector fd; + curve._FirstDer( curve.GetTMin(), fd ); + if ( ::AttachNurbsG1( nurbs, fd, true, false, setLen ) ) + changed = true; + } + if ( setEnd ) { + Vector fd; + curve._FirstDer( curve.GetTMax(), fd ); + if ( ::AttachNurbsG1( nurbs, fd, false, false, setLen ) ) + changed = true; + } + + return changed; +} + + +//------------------------------------------------------------------------------ +// \ru Установить точки так, чтобы совпала касательная и главная нормаль \en Set points such that tangent and principal normal are coincident +//--- +template +bool AttachNurbsG2( TypedNurbs & nurbs, // \ru Модифицируемый сплайн \en Modifiable spline + const TypedVector & tang, // \ru Касательный вектор \en Tangent vector + const TypedVector & tangDiff, // \ru Производная касательного вектора \en The derivative of a tangent vector + bool begin, // \ru Сопряжение выставлено в начале \en Conjugation is defined for the start + bool modify, // \ru Можно ли менять существующие полюса \en Whether it is possible to modify the existing poles + double * wDiff1, + double * wDiff2 ) +{ + bool res = false; + + if ( !nurbs.IsClosed() && nurbs.GetPointListCount() > 3 && nurbs.GetDegree() > 3 && + ::AttachNurbsG1( nurbs, tang, begin, modify, false ) ) // \ru Стыкуем сначала по касательной \en Join by a tangent at first + { + bool needRebuild = false; // \ru Нужно ли перестраивать кривую \en Whether to rebuild the curve + + TypedVector normTang( tang ); + double tangLen = tang.Length(); + if ( tangLen > LENGTH_EPSILON ) + normTang /= tangLen; + + SArray points ( 0, 1 ); + SArray weights( 0, 1 ); + SArray knots ( 0, 1 ); + nurbs.GetPointList( points ); + nurbs.GetWeights( weights ); + nurbs.GetKnots( knots ); + ptrdiff_t degree = nurbs.GetDegree(); + bool closed = nurbs.IsClosed(); + + double eps = Math::metricEpsilon; + + //double dKnots = 0.0; + ptrdiff_t degm = degree - 1; + double curCurv = 0.0; + double curvature = tangDiff.Length(); + + TypedVector curNormal; // \ru Текущая нормаль в стыке \en Current normal at the joint + TypedVector firstDer; // \ru Первая производная сплайна в точке \en The first spline derivative at the point + TypedVector secndDer; // \ru Старая производная сплайна в точке \en The old spline derivative at the point + TypedVector secDer( tangDiff ); // \ru Вторая производная, с которой фактически устанавливается равенство \en The second derivative which the equality is set with + + TypedPoint add; // \ru Точка, обеспечивающая равенство вторых производных \en Point which provides the equality of second derivatives + TypedPoint wp0, wp1; // \ru Взвешенные точки \en Weighted points + + double part = modify ? 1.0 : 0.5; // \ru Параметрическая доля \en Parametric part + double pointKnot = 0.0; // \ru Узел точки, обеспечивающий сопряжение \en Point knot which provides a conjugation + double pointWeight = 1.0; // \ru Вес точки \en A point weight + + double weightDiff1 = 0.0, weightDiff2 = 0.0; // \ru Первая и вторая производная весов \en The first and the second derivative of weights + if ( begin ) { // \ru Стыковка производится в начале \en Connection is performed at the start + nurbs._Normal( nurbs.GetTMin(), curNormal ); + curCurv = nurbs.Curvature( nurbs.GetTMin() ); + + pointKnot = modify ? knots[(size_t)degree + 1] : + knots[(size_t)degree + 1] * part + knots[degree] *( 1.0 - part ); + pointWeight = modify ? weights[2] : weights[0] ; + weightDiff1 = (double)degm * ( weights[1] - weights[0] ) / ( knots[degree] - knots[1] ); + weightDiff2 = ( (double)degm - 1 ) * (double)degm / ( knots[degree] - knots[2] ) * + ( (pointWeight - weights[1]) / (pointKnot - knots[2]) - + (weights[1] - weights[0]) / (knots[degree] - knots[1]) ); + + if ( !(curNormal.Colinear(tangDiff) && + ::fabs(curCurv - curvature) < eps) ) // \ru Еще нет необходимой гладкости стыка \en The required smoothness of a joint is not provided yet + { + nurbs._FirstDer( nurbs.GetTMin(), firstDer ); + secDer *= firstDer * firstDer; + nurbs._SecondDer( nurbs.GetTMin(), secndDer ); + secDer += normTang * ( part * normTang * secndDer ); // \ru Сохранение старой проекции \en Saving of the old projection + + wp0 += points[0] * weights[0]; + wp1 += points[1] * weights[1]; + + // \ru Обрабатываем вторую производную \en Process the second derivative + secDer *= weights[0]; + secDer.Add( points[0], weightDiff2, firstDer, 2.0 * weightDiff1 ); + + double dK = pointKnot - knots[2]; + double dK1 = 1.0 / dK + 1.0 / ( knots[(size_t)degree] - knots[1] ); + + add.Set( wp0, 1.0, wp1 - wp0, dK1 * dK ); + add.Add( secDer, (knots[(size_t)degree] - knots[2]) * dK / ((double)degm * (double)(degm - 1)) ); + add /= pointWeight; + + if ( modify ) + points[2] = add; + else { + knots.AddAt( pointKnot, (size_t)degree + 1 ); + points.AddAt( add, 2 ); + weights.AddAt( pointWeight, 2 ); + } + needRebuild = true; + } + + res = true; + } + else { // \ru Стыковка производится в конце \en Connection is performed at the end + nurbs._Normal( nurbs.GetTMax(), curNormal ); + curCurv = nurbs.Curvature( nurbs.GetTMax() ); + + ptrdiff_t shear = points.MaxIndex(); + + pointKnot = modify ? knots[shear - 1] : + knots[shear] * ( 1.0 - part ) + knots[shear - 1] * part ; + + pointWeight = modify ? weights[shear - 2] : weights[shear]; + + weightDiff1 = (double)degm * ( weights[shear] - weights[shear - 1] ) / + ( knots[shear + (size_t)degree] - knots[shear] ); + weightDiff2 = (double)(degm - 1) * (double)degm / ( knots[shear + (size_t)degm] - knots[shear] ) * + ( (weights[shear] - weights[shear - 1]) / (knots[shear + (size_t)degree] - knots[shear]) - + (weights[shear - 1] - pointWeight ) / (knots[shear + (size_t)degree - 1] - pointKnot ) ); + + if ( !(curNormal.Colinear(tangDiff) && + ::fabs(curCurv - curvature) < eps) ) // \ru Еще нет необходимой гладкости стыка \en The required smoothness of a joint is not provided yet + { + nurbs. _FirstDer( nurbs.GetTMax(), firstDer ); + secDer *= firstDer * firstDer; + nurbs._SecondDer( nurbs.GetTMax(), secndDer ); + secDer += normTang * ( part * normTang * secndDer ); // \ru Сохранение старой проекции \en Saving of the old projection + + wp0 += points[shear] * weights[shear]; + wp1 += points[shear - 1] * weights[shear - 1]; + + // \ru Обрабатываем вторую производную \en Process the second derivative + secDer *= weights[shear]; + secDer.Add( points[shear], weightDiff2, firstDer, 2.0 * weightDiff1 ); + + double dK = knots[shear + (size_t)degm] - pointKnot; + double dK1 = 1.0 / ( knots[shear + (size_t)degm] - knots[shear] ) + + 1.0 / ( knots[shear + (size_t)degm] - pointKnot ); + + add.Set( wp0, 1.0, wp1 - wp0, dK1 * dK ); + add.Add( secDer, (knots[shear + (size_t)degm] - knots[shear]) * dK / ((double)degm * (double)(degm - 1)) ); + add /= pointWeight; + + if ( modify ) + points[shear - 2] = add; + else { + knots.AddAt( pointKnot, shear ); + points.AddAt( add, shear - 1 ); + weights.AddAt( pointWeight, shear - 1 ); + } + needRebuild = true; + } + + res = true; + } + + // \ru Сохраняем вычисленные производные \en Save the calculated derivatives + if ( res ) { + if ( wDiff1 != NULL ) + *wDiff1 = weightDiff1; + if ( wDiff2 != NULL && res ) + *wDiff2 = weightDiff2; + } + + if ( res && needRebuild ) + nurbs.Init( degree, closed, points, weights, knots, ncf_Unspecified ); + } + +/*#if defined(C3D_DEBUG) + if ( res ) { // \ru Отладка \en Debugging + double t = begin ? nurbs.GetTMin() : nurbs.GetTMax(); + + MbVector3D vect; + nurbs._Tangent( t, vect ); + C3D_ASSERT( vect.Colinear( tang ) ); + + MbVector3D normal; + nurbs._Normal( t, normal ); + C3D_ASSERT( normal.Colinear(tangDiff) ); + + double curvature = tangDiff.Length(); + double curCurvature = nurbs.Curvature( t ); + C3D_ASSERT( ::fabs(curCurvature - curvature) < Math::metricAccuracy ); + } +#endif +*/ + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Создать замкнутый NURBS, проходящий через точки с заданными параметрами. \en Calculate closed NURBS by points which it passes through and points parameters. +//--- +template +bool CreateClosedNURBS4( Nurbs & nurbs, const SArray & initPoints, const SArray & initParams ) +{ + bool bRes = ( (initParams.Count() > 3) && (initParams.Count() == initPoints.Count() + 1) ); + + if ( bRes ) { + nurbs.Refresh(); // должен стоять первым, т.к. освобождается выделенная память + + const ptrdiff_t degree = 4; // степень В-сплайна //-V112 + const bool closed = true; // признак замкнутости + const MbeNurbsCurveForm form = ncf_Unspecified; // форма B - сплайна + + // скопировать массив характеристических точек + SArray points( initPoints ); + + // установить единичные веса + SArray weights( points.Count(), 1 ); + { + const double weight0 = 1.0; + weights.Fill( points.Count(), weight0 ); + } + + const ptrdiff_t degm = degree - 1; + + // заполнить массив параметров (на концах используем условие "отсутствия узла"), обеспечивающий замыкание + SArray knots ( (initParams.MaxIndex() + 2 * degree - 1), 1 ); + { + ptrdiff_t uppKnotsIndex = (ptrdiff_t)initParams.Count() - 1; + ptrdiff_t i = 0; // индекс + + // вставляем начальные узлы 0.. degree - 2 + for ( i = 0; i < degm; i++ ) { + ptrdiff_t startIndex = uppKnotsIndex - degm; + knots.Add( initParams[0] - initParams[uppKnotsIndex] + initParams[startIndex + i] ); + } + + knots += initParams; + + // вставляем конечные узлы + const double tmax = initParams[initParams.MaxIndex()]; + ptrdiff_t i0 = degm; + for ( i = i0; i < i0 + degm; i++ ) + knots.Add( tmax + knots[i + 1] - knots[i0] ); + + uppKnotsIndex = knots.MaxIndex(); + } + + points.Adjust(); + weights.Adjust(); + knots.Adjust(); + + const ptrdiff_t pointsCnt = initPoints.Count(); + const ptrdiff_t uppIndex = pointsCnt - 1; + // для приведения матрицы к матрице с диагональным преобладанием необходимо + // последнее уравнение исключать первым + // далее решаем систему уравнений методом Гаусса без выбора ведущего элемента + SArray biatx( degree, 1 ); // не нулевые B - сплайны + SArray d ( pointsCnt ); // массив диагоналей + SArray ar ( pointsCnt ); // массив правых частей + SArray n ( pointsCnt ); // последний столбец в результирующей матрице + + SArray lrVect; + lrVect.resize( 2*degree ); + + ar.Add( initPoints[initPoints.MaxIndex()] ); + ar += initPoints; + ar.RemoveInd( ar.MaxIndex() ); + + ptrdiff_t lastIndex = initParams.MaxIndex() - 1; + ptrdiff_t lastKnot = knots.Count() - degree - 1; + + // первое уравнение + ::CalcBsplvb( knots, initParams[lastIndex], lastKnot, degree, biatx, lrVect ); + + double norm = 1 / biatx[1]; + double normLast = 1.0; + + ar[0] *= norm; + + d.Add( biatx[2] * norm ); + n.Add( biatx[0] * norm ); + + // последнее уравнение + ::CalcBsplvb( knots, initParams[lastIndex - 1], lastKnot - 1, degree, biatx, lrVect ); + norm = 1.0 / biatx[2]; + // в последнем уравнении, соответственно, внедиагональный и диагональный элемент + double a = biatx[0] * norm; + double b = biatx[1] * norm; + + ar[lastIndex] *= norm; + Point & sn = ar[lastIndex]; + + // прямой ход + ptrdiff_t crLeft = degm; + ptrdiff_t i = 1, im = 0, ip = 1; + for ( ; i < lastIndex - 1; i++, im++, crLeft++ ) { + ::CalcBsplvb( knots, initParams[i - 1], crLeft, degree, biatx, lrVect ); + + norm = 1 / ( biatx[1] - d[im] * biatx[0] ); + + ar[i] = ( ar[i] - ar[im] * biatx[0] ) * norm; + d [i] = biatx[2] * norm; + // исключаем из последнего уравнения ведущую 1 и меняем последний столбец + normLast = -1.0 / d[im]; + + a *= normLast; + b = ( b - n[im] ) * normLast; + + sn = ( sn - ar[im] ) * normLast; + + n.Add( -norm * biatx[0] * n[im] ); + } + + // исключаем из 2-х последних уравнений 3-е с конца + ::CalcBsplvb( knots, initParams[i - 1], crLeft, degree, biatx, lrVect ); + + norm = 1.0 / ( biatx[1] - d[im] * biatx[0] ); + d [lastIndex - 1] = ( biatx[2] - n[im] * biatx[0] ) * norm; + ar[lastIndex - 1] = ( ar[lastIndex - 1] - ar[im] * biatx[0] ) * norm; + + normLast = 1.0 / ( a - d[im] ); + b = ( b - n[im] ) * normLast; + a = 1.0; + sn = ( sn - ar[im] ) * normLast; + + // исключаем из последнего предпоследнее + im++; + points[uppIndex] = ( sn - ar[im] ) / ( b - d[im] ); + + ptrdiff_t prevLast = uppIndex - 1; + points[prevLast] = ar[lastIndex - 1] - points[uppIndex] * d[prevLast]; + + // обратный ход + for ( i = prevLast - 1, ip = prevLast; i >= 0; i--, ip-- ) { + points[i] = ar[i] - points[ip] * d[i] + - points[uppIndex] * n[i]; + } + + bRes = nurbs.Init( degree, closed, points, weights, knots, form ); + C3D_ASSERT( bRes ); + } + + return bRes; +} + + +//------------------------------------------------------------------------------ +// \ru Получить массив параметров по точкам \en Get an array of parameters given the points +// --- +template +bool CreateSplineParameters( const PointsVector & points, MbeSplineParamType spType, bool cls, + DoubleVector & params ) +{ + bool isDone = false; + params.clear(); + isDone = ::DefineThroughPointsParams( points, spType, cls, params ); + + // \ru Нормализация \en Normalization + if ( isDone ) + c3d::SetLimitParam( params, 0.0, (double)((ptrdiff_t)points.size() - 1 + (cls ? 1 : 0)) ); + + return isDone; + +} + + +//------------------------------------------------------------------------------ +// \ru Выбрать точки на кривой для аппроксимации замкнутой nurbs \en Select points on the curve for approximation of closed nurbs +// --- +template +size_t DefineApproxPointsClosed( const Curve & curve, size_t pCount, double pmin, double pmax, ptrdiff_t degree, SArray & points, const KnotsVector & aKnots, const SArray & pCounts ) +{ + size_t pCountActual = pCount; + if ( pCount < 1 ) + return 0; + + points.clear(); + size_t stepCount = 0; + double factor = 1.0 / ( (double)pCount ); + const double epsilon = curve.GetTRegion( METRIC_REGION ); + const double angle = Math::deviateSag; + + size_t segmCount = curve.GetSegmentsCount(); + + SArray segmPointsCnt( segmCount, 2 ); + SArray tList, restList; + + double tmin, tmax; + ptrdiff_t first_Segm = curve.FindSegment( pmin, tmin ); + ptrdiff_t last_Segm = curve.FindSegment( pmax, tmax ); + ptrdiff_t i = 0; + + size_t freePntsCount = pCount; + + // \ru Найдем количество точек для каждого сегмента. \en Find the number of points for each segment. + size_t totalCount = 0; + for ( i = 0; i < pCounts.size(); ++i ) + totalCount += pCounts[i]; + if ( totalCount < 1 ) + totalCount = 1; + + for ( i = 0; i < pCounts.size(); i++ ){ + double part = ((double)pCounts[i]) / ((double)totalCount); + size_t segmPCnt = (size_t)(pCount * part); //-V113 + if ( i == last_Segm ) + segmPCnt = freePntsCount; + else { + segmPCnt = std_max( segmPCnt, (size_t)1); + segmPCnt = std_min( segmPCnt, freePntsCount ); + } + segmPointsCnt.push_back( segmPCnt ); + freePntsCount -= segmPCnt; + } + + Point p; + double plusT = 0.0; + for ( i = first_Segm; i <= last_Segm; i++ ) { + tList.clear(); + double smin, smax; + smin = curve.GetSegment(i)->GetTMin(); + smax = curve.GetSegment(i)->GetTMax(); + + if ( first_Segm == last_Segm ) { + plusT = pmin + smin - tmin; + smin = tmin; + smax = tmax; + } + else if ( i == first_Segm ){ + plusT = pmin + smin - tmin; + smin = tmin; + } + else if ( i == last_Segm ) { + smax = tmax; + } + double t = smin; + size_t tempCount = segmPointsCnt[i - first_Segm]; + factor = 1.0 / ( (double)tempCount ); + stepCount = 0; + while ( t < (smax - epsilon) ) { + double step = curve.GetSegment(i)->DeviationStep( t, angle ); + if ( (t + step) >= (smax - epsilon) ) + step = smax - t; + + for ( size_t k = 0; k < tempCount; k++ ) + tList.push_back( plusT + t + (step * factor * (double)k) ); + t += step; + stepCount++; + } + tList.push_back(plusT + smax); + plusT += smax; + + for ( size_t j = 0; j < tempCount; j++ ) { + t = tList[j * stepCount]; + curve._PointOn( t, p ); + points.push_back( p ); + restList.push_back( t ); + } + } + + restList.push_back( pmax ); + + // \ru Если задан узловой вектор, надо проверить, что между любыми 2 узлами есть хотя бы одна точка. \en If the knot vector is given, then it is necessary to check that there is at least one point between any two knots. + // \ru Если нет, то добавим точек, сохранив все уже набранные \en If not, then add the points and save old points + if ( aKnots.size() > 0 ) { + SArray pParams( 0, 1 ); + ::CreateSplineParameters( points, spt_ChordLength, true, pParams ); + c3d::SetLimitParam( pParams, aKnots[degree - 1], aKnots[aKnots.size() - degree] ); + double t1, t2; + bool bRes = false; + while ( !bRes ) { + bRes = true; + for ( i = degree - 1; i < aKnots.MaxIndex() - degree + 1 && bRes; i++ ) { + t1 = aKnots[i]; + t2 = aKnots[i + 1]; + if ( ::fabs(t2 - t1) > NULL_EPSILON ) { + size_t il = 0, ir = pParams.MaxIndex(); + size_t itemp = 0; + size_t ires1 = 0; + size_t ires2 = 0; + // \ru Левая граница \en The left boundary + bool goOn = true; + while ( goOn ) { + if ( ::fabs(pParams[il] - t1) < NULL_EPSILON ){ + ires1 = il; + goOn = false; + break; + } + else if ( ::fabs(pParams[ir] - t1) < NULL_EPSILON ) { + ires1 = ir; + goOn = false; + break; + } + else { + itemp = ( il + ir ) / 2; + if ( ::fabs(pParams[itemp] - t1) < NULL_EPSILON ) { + ires1 = itemp; + goOn = false; + break; + } + if ( pParams[itemp] < t1 ) + il = itemp; + else if ( pParams[itemp] > t1 ) + ir = itemp; + if ( ir - il < 2) { + ires1 = il; + goOn = false; + break; + } + } + } + // \ru Правая граница \en The right boundary + il = ires1; + ir = pParams.MaxIndex(); + goOn = true; + while ( goOn ) { + if ( ::fabs(pParams[il] - t2) < NULL_EPSILON ){ + ires2 = il; + goOn = false; + break; + } + else if ( ::fabs(pParams[ir] - t2) < NULL_EPSILON ) { + ires2 = ir; + goOn = false; + break; + } + else { + itemp = ( il + ir ) / 2; + if ( ::fabs(pParams[itemp] - t2) < NULL_EPSILON ) { + ires2 = itemp; + goOn = false; + break; + } + if ( pParams[itemp] < t2 ) + il = itemp; + else if ( pParams[itemp] > t2 ) + ir = itemp; + if ( ir - il < 2) { + ires2 = ir; + goOn = false; + break; + } + } + } + if ( ires2 - ires1 < 2 ) { + bRes = false; + // \ru Вставим среднюю точку между ires1 и ires2 и пересчитаем параметры \en Insert mid-point between ires1 and ires2 and recalculate parameters + double t = 0.5 * (restList[ ires1 ] + restList[ ires2 ]); + restList.AddAt( t, ires1 + 1 ); + + curve._PointOn( t, p ); + points.AddAt( p, ires1 + 1); + + pParams.clear(); + ::CreateSplineParameters( points, spt_ChordLength, false, pParams ); + c3d::SetLimitParam( pParams, aKnots[degree - 1], aKnots[aKnots.size() - degree] ); + pCountActual++; + } + } + } + } + } + + return pCountActual; +} + + +//------------------------------------------------------------------------------ +// \ru Выбрать точки на кривой для аппроксимации незамкнутой nurbs \en Select points on the curve for approximation of non-closed nurbs +// --- +template +size_t DefineApproxPointsOpen( const Curve & curve, size_t pCount, double pmin, double pmax, SArray & points, const KnotsVector & aKnots, const SArray & pCounts ) +{ + size_t pCountActual = pCount; + if ( pCount < 1 ) + return 0; + + points.clear(); + size_t stepCount = 0; + double factor = 1.0 / ( (double)(pCount - 1) ); + const double epsilon = curve.GetTRegion( METRIC_REGION ); + const double angle = Math::deviateSag; + + size_t segmCount = curve.GetSegmentsCount(); + if ( pCounts.size() != segmCount ) + return 0; + + SArray tList, restList; + SArray segmPointsCnt( segmCount, 2 ); + + double tpmin = pmin; + double tpmax = pmax; + + double tmin, tmax; + ptrdiff_t first_Segm = curve.FindSegment( tpmin, tmin ); + ptrdiff_t last_Segm = curve.FindSegment( tpmax, tmax ); + ptrdiff_t i; + + size_t freePntsCount = pCount - 1; + + // \ru Найдем количество точек для каждого сегмента. \en Find the number of points for each segment. + size_t totalCount = 0; + for ( i = 0; i < pCounts.size(); ++i ) + totalCount += pCounts[i]; + if ( totalCount == 0 ) + totalCount = 1; + + for ( i = 0; i < pCounts.size(); i++ ){ + double part = ((double)pCounts[i]) / ((double)totalCount); + size_t segmPCnt = (size_t)(pCount * part); //-V113 + if ( i == last_Segm ) + segmPCnt = freePntsCount; + else { + segmPCnt = std_max( segmPCnt, (size_t)1); + segmPCnt = std_min( segmPCnt, freePntsCount ); + } + segmPointsCnt.push_back( segmPCnt ); + freePntsCount -= segmPCnt; + } + + Point p; + double plusT = 0.0; + for ( i = first_Segm; i <= last_Segm; i++ ) { + tList.clear(); + + double smin = curve.GetSegment(i)->GetTMin(); + double smax = curve.GetSegment(i)->GetTMax(); + + if ( first_Segm == last_Segm ) { + plusT = tpmin + smin - tmin; + smin = tmin; + if (pmin < tpmin - PARAM_EPSILON ) + smin += pmin - tpmin; + smax = tmax; + if (pmax > tpmax + PARAM_EPSILON ) + smax += pmax - tpmax; + } + else if ( i == first_Segm ){ + plusT = tpmin + smin - tmin; + smin = tmin; + if (pmin < tpmin - PARAM_EPSILON ) + smin += pmin - tpmin; + } + else if ( i == last_Segm ) { + smax = tmax; + if (pmax > tpmax + PARAM_EPSILON ) + smax += pmax - tpmax; + } + double t = smin; + size_t tempCount = segmPointsCnt[i - first_Segm]; + factor = 1.0 / ( (double)tempCount ); + stepCount = 0; + while ( t < (smax - epsilon) ) { + double step = curve.GetSegment(i)->DeviationStep( t, angle ); + if ( (t + step) >= (smax - epsilon) ) + step = smax - t; + + for ( size_t j = 0; j < tempCount; j++ ) + tList.push_back( plusT + t + (step * factor * (double)j) ); + t += step; + stepCount++; + } + tList.push_back(plusT + smax); + plusT += smax; + + for ( size_t k = 0; k < tempCount; k++ ) { + t = tList[k * stepCount]; + curve._PointOn ( t, p ); + points.push_back( p ); + restList.push_back( t ); + } + } + + double t = pmax; + curve._PointOn ( t, p ); + points.push_back( p ); + restList.push_back( t ); + + // \ru Если задан узловой вектор, надо проверить, что между любыми 2 узлами есть хотя бы одна точка. \en If the knot vector is given, then it is necessary to check that there is at least one point between any two knots. + // \ru Если нет, то добавим точек, сохранив все уже набранные \en If not, then add the points and save old points + if ( aKnots.size() > 0 ) { + SArray pParams( 0, 1 ); + ::CreateSplineParameters( points, spt_ChordLength, false, pParams ); + c3d::SetLimitParam( pParams, aKnots.front(), aKnots.back() ); + + double t1, t2; + bool bRes = false; + while ( !bRes ) { + bRes = true; + for ( i = 0; i < aKnots.MaxIndex() && bRes; i++ ) { + t1 = aKnots[i]; + t2 = aKnots[i + 1]; + if ( ::fabs(t2 - t1) > NULL_EPSILON ) { + size_t il = 0, ir = pParams.MaxIndex(); + size_t itemp = 0; + size_t ires1 = 0; + size_t ires2 = 0; + // \ru Левая граница \en The left boundary + bool goOn = true; + while ( goOn ) { + if ( ::fabs(pParams[il] - t1) < NULL_EPSILON ){ + ires1 = il; + goOn = false; + break; + } + else if ( ::fabs(pParams[ir] - t1) < NULL_EPSILON ) { + ires1 = ir; + goOn = false; + break; + } + else { + itemp = ( il + ir ) / 2; + if ( ::fabs(pParams[itemp] - t1) < NULL_EPSILON ) { + ires1 = itemp; + goOn = false; + break; + } + if ( pParams[itemp] < t1 ) + il = itemp; + else if ( pParams[itemp] > t1 ) + ir = itemp; + if ( ir - il < 2) { + ires1 = il; + goOn = false; + break; + } + } + } + // \ru Правая граница \en The right boundary + il = ires1; + ir = pParams.MaxIndex(); + goOn = true; + while ( goOn ) { + if ( ::fabs(pParams[il] - t2) < NULL_EPSILON ){ + ires2 = il; + goOn = false; + break; + } + else if ( ::fabs(pParams[ir] - t2) < NULL_EPSILON ) { + ires2 = ir; + goOn = false; + break; + } + else { + itemp = ( il + ir ) / 2; + if ( ::fabs(pParams[itemp] - t2) < NULL_EPSILON ) { + ires2 = itemp; + goOn = false; + break; + } + if ( pParams[itemp] < t2 ) + il = itemp; + else if ( pParams[itemp] > t2 ) + ir = itemp; + if ( ir - il < 2) { + ires2 = ir; + goOn = false; + break; + } + } + } + if ( ires2 - ires1 < 2 ) { + bRes = false; + // \ru Вставим среднюю точку между ires1 и ires2 и пересчитаем параметры \en Insert mid-point between ires1 and ires2 and recalculate parameters + t = 0.5 * (restList[ ires1 ] + restList[ ires2 ]); + restList.AddAt( t, ires1 + 1 ); + + curve._PointOn( t, p ); + points.AddAt( p, ires1 + 1 ); + + pParams.clear(); + ::CreateSplineParameters( points, spt_ChordLength, false, pParams ); + c3d::SetLimitParam( pParams, aKnots.front(), aKnots.back() ); + pCountActual++; + } + } + } + } + } + return pCountActual; +} + + +//------------------------------------------------------------------------------ +// \ru Построение незамкнутого сплайна, аппроксимирующего набор точек, с помощью метода наименьших квадратов \en Construction of non-closed spline which approximates a set of points by the method of least squares +/*\ru aDegree - порядок сплайна, + pCount - количество узлов, + aPoints - набор точек для аппроксимации, + aKnots - предустановленный узловой вектор + \en ADegree - spline order, + pCount - count of knots, + aPoints - point set for approximation, + aKnots - predefined knots vector \~ +*/ +//--- +template +MATH_FUNC (bool) CreateNurbsLSMClosed( SPtr & nurbs, // \ru Модифицируемый сплайн \en Modifiable spline + const ptrdiff_t degree, + const ptrdiff_t pCount, + const PointsVector & aPoints, + const DoubleVector & aKnots, + const DoubleVector * aParams = NULL ); + +//------------------------------------------------------------------------------ +// \ru Построение незамкнутого сплайна, аппроксимирующего набор точек, с помощью метода наименьших квадратов \en Construction of non-closed spline which approximates a set of points by the method of least squares +// \ru Для построения замкнутого сплайна, надо затем использовать Unclamped( true ) \en Use Unclamped (true) for the construction of a closed spline +/*\ru aDegree - порядок сплайна, + pCount - количество узлов, + aPoints - набор точек для аппроксимации, + aKnots - предустановленный узловой вектор + \en ADegree - spline degree, + pCount - count of knots, + aPoints - point set for approximation, + aKnots - predefined knot vector \~ +*/ +//--- +template +MATH_FUNC (bool) CreateNurbsLSM( SPtr & nurbs, // \ru Модифицируемый сплайн \en Modifiable spline + const ptrdiff_t degree, + const ptrdiff_t pCount, + const PointsVector & aPoints, + const DoubleVector & aKnots, + const DoubleVector * aParams = NULL ); + +//------------------------------------------------------------------------------- +// +// --- +template +Nurbs * CreateLineOutRgn( const Curve & curve, double tn1, double tn2, double t1, double t2, + const MbCurveIntoNurbsInfo & nci ) +{ + Nurbs * nurbs = NULL; + + if ( !curve.IsClosed() && nci.ExtendRange() && ((tn2 - tn1) > Math::paramEpsilon) ) { + SArray points ( 2, 1 ); + SArray weights( 2, 1 ); + SArray knots ( 4, 1 ); //-V112 + + curve._PointOn( t1, *(points.Add()) ); + curve._PointOn( t2, *(points.Add()) ); + + weights.Add( 1.0 ); + weights.Add( 1.0 ); + + knots.Add( tn1 ); + knots.Add( tn1 ); + knots.Add( tn2 ); + knots.Add( tn2 ); + + nurbs = Nurbs::Create( 2, false, points, weights, knots, ncf_Unspecified ); + } + + return nurbs; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать контур в нурбс \en Transform contour to NURBS +// --- +MbNurbs * ContourToNurbs( const MbContour & cntr, double t1, double t2, int sense, const MbCurveIntoNurbsInfo & nci, bool reparamByLength ); + +//------------------------------------------------------------------------------ +// \ru Преобразовать контур в нурбс \en Transform contour to NURBS +// --- +MbNurbs3D * ContourToNurbs( const MbContour3D & cntr, double t1, double t2, int sense, const MbCurveIntoNurbsInfo & nci, bool reparamByLength ); + + +#endif // __MB_NURBS_FUNCTION_H diff --git a/C3d/Include/mb_operation_result.h b/C3d/Include/mb_operation_result.h new file mode 100644 index 0000000..c7d946b --- /dev/null +++ b/C3d/Include/mb_operation_result.h @@ -0,0 +1,251 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Результат операции. + \en Operation result. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_OPERATION_RESULT_H +#define __MB_OPERATION_RESULT_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Код результата операции. + \en Operation result code. \~ + \details \ru Код результата операции. \n + \en Operation result code. \n \~ + \ingroup Base_Items +*/ +// \ru ДОБАВЛЯТЬ ТОЛЬКО В КОНЕЦ (ИДЕНТИФИКАТОРЫ СООБЩЕНИЙ СОХРАНЯЮТСЯ В ФАЙЛ) \en TO ADD ONLY TO THE END (IDENTIFIERS OF MESSAGES ARE SAVED TO FILE) +// --- +enum MbResultType { + rt_Success = 0, ///< \ru Нормальная работа. \en Normal work. + + // \ru Типы ошибок образующих контуров \en Generating contours error types + rt_Empty, ///< \ru Пустой результат. \en Empty result. + rt_ToManyAxis, ///< \ru Слишком много осей. \en Too many axes. + rt_ToFewAxis, ///< \ru Не хватает осей. \en Too few axes. + rt_ToManyContours, ///< \ru Слишком много контуров. \en Too many contours. + rt_Stars, ///< \ru Есть "звезда". \en Has "star". + rt_SelfIntersection, ///< \ru Самопересечение контура. \en Contour is self-intersecting. + rt_SelfIntWhenExtended, ///< \ru Самопересечение в продолжении контура. \en Contour extension is self-intersecting. + rt_Intersection, ///< \ru Пересечение контуров. \en Contours intersection. + rt_NoIntersectSolid, ///< \ru Образующий контур не пересекает тела. \en Generating contour does not intersect solids. + rt_NoIntersectSection, ///< \ru Образующий контур не пересекает сечения (для операции построения тела по сечениям). \en Generating contour does not intersect sections (for loft solid construction operation). + rt_LibNotFound, ///< \ru Фрагмент не найден в библиотеке. \en Fragment is not found in library. + rt_MustBeClosed, ///< \ru Должен быть замкнут. \en Must be closed. + rt_MustBeOpen, ///< \ru Должен быть разомкнут. \en Must be opened. + rt_AxisIntersection, ///< \ru Пересечение с осью. \en Intersection with axis. + rt_DegenerateAxis, ///< \ru Вырожденная ось. \en Degenerate axis. + + // \ru Tипы ошибок тела \en Solid error types + rt_MultiSolid, ///< \ru Тело состоит из отдельных частей. \en Solid consists of separate parts. + rt_CurveError, ///< \ru Ошибочная кривая. \en Wrong curve. + rt_ContourError, ///< \ru Ошибочный контур. \en Wrong contour. + rt_SurfaceError, ///< \ru Ошибочная поверхность. \en Wrong surface. + rt_SolidError, ///< \ru Ошибочное тело. \en Wrong solid. + rt_ParameterError, ///< \ru Ошибочный параметр. \en Wrong parameter. + rt_ThicknessError, ///< \ru Неправильно задана толщина. \en Wrong thickness. + rt_NoSequenceCurveAndSections, ///< \ru Не последовательное расположение сечений вдоль кривой (для операции построения тела по сечениям). \en Non-sequential arrangement of sections along the curve (for loft solid construction operation). + rt_SelfIntersect, ///< \ru Объект самопересекается. \en Self-intersecting object. + rt_NoIntersect, ///< \ru Объекты не пересекаются. \en Objects are not crossed. + rt_OffsetIntersectError, ///< \ru Невозможно построить эквидистанту с данными параметрами. \en Cannot create offset with the given parameters. + rt_BooleanError, ///< \ru Ошибка в булевой операции. \en Boolean operation error. + rt_NoEdges, ///< \ru Ребра не найдены. \en Edges not found. + rt_PrepareError, ///< \ru Ошибка при подготовке операции. \en Operation preparation error. + rt_ChamferError, ///< \ru Ошибка при создании фаски ребра. \en Error at creating chamfer of edge. + rt_FilletError, ///< \ru Ошибка при создании скругления ребра. \en Error at creating fillet of edge. + rt_PartlyChamfer, ///< \ru Созданы фаски не на всех ребрах. \en Chamfers are created not for all the edges. + rt_PartlyFillet, ///< \ru Скруглены не все ребра. \en Fillets are created not for all the edges. + rt_ChamferSurfaceError, ///< \ru Ошибка при создании поверхности фаски ребра. \en Error of a chamfer surface creation for an edge. + rt_FilletSurfaceError, ///< \ru Ошибка при создании поверхности скругления ребра. \en Error of a fillet surface creation for an edge. + rt_TooLargeChamfer, ///< \ru Слишком большие катеты фаски. \en Too big cathetuses of chamfer. + rt_TooLargeFillet, ///< \ru Слишком большой радиус скругления. \en Too big radius of chamfer. + rt_SemiChamfer, ///< \ru Фаски построены не для всех ребер. \en Chamfers are created not for all the edges. + rt_SemiFillet, ///< \ru Скруглены не все ребра. \en Fillets are created not for all the edges. + rt_CuttingError, ///< \ru Ошибка резки поверхностью. \en Error cutting by surface. + rt_ThinError, ///< \ru Ошибка при создании тонкостенного тела. \en Error of a thin-walled solid creation. + rt_OffsetError, ///< \ru Слишком большая толщина стенки при создании тонкостенного тела. \en Too big wall thickness while creating thin-walled solid. + rt_FaceError, ///< \ru Ошибочная грань. \en Wrong face. + rt_RibError, ///< \ru Неизвестная ошибка постановки ребра жесткости. \en Unknown error at rib statement. + rt_DraftError, ///< \ru Неизвестная ошибка уклона граней тела. \en Unknown error of inclining of solid faces. + rt_NoObjectForDirection, ///< \ru В выбранном направлении отсутствует поверхность. \en No surface in the choosen direction. + rt_AbsorptionSolid, ///< \ru Локальное тело поглощает результат. \en Local solid absorbs result. + rt_Error, ///< \ru Неизвестная ошибка. \en Unknown error. + rt_None, ///< \ru Нет сообщений. \en No messages. + rt_Intersect, ///< \ru Объекты пересекаются. \en Objects are crossed. + rt_InvalidType, ///< \ru Ненадлежащий тип кривой. \en Wrong type of curve. + rt_NoConvertTextToNurbs, ///< \ru Преобразование текста выполнить невозможно. \en Unable to convert text. + rt_SplitWireNotSplitFace, ///< \ru Контур не разбивает ни одну из граней или совпадает с кромкой грани. \en The contour does not split any face or coincides with a face boundary. + rt_SplitWireNotIntersectFace, ///< \ru Контур не пересекает выбранное множество граней или совпадает с кромкой грани. \en The contour does not intersect selected set of faces or coincides with a face boundary. + rt_MustBeOnlyOnePoint, ///< \ru Для данной операции в эскизе должна быть только одна точка. \en There must be only one point in sketch for current operation. + rt_InvalidPoleUsage, ///< \ru Эскиз с одной точкой может использоваться только для крайнего сечения. \en Sketch with one point can be used only for the last section. + rt_ThinWithPole, ///< \ru Построение тонкой стенки невозможно, если одно из сечений представляет собой точку. \en Creation of a thin wall is impossible if one of sections represents a point. + rt_TopologyError, ///< \ru Ошибочная топология. \en Wrong topology. + + // \ru Начало "нездорового" диапазона ошибок, НИКОГДА НЕ ВЗВОДИТЬ ЭТУ ОШИБКУ \en Beginning of "unhealthy" range of errors, NEVER TO RAISE THIS ERROR + rt_BeginOfInvalidRange, + + // \ru K8+из 3Д, там хранить нельзя так как они записываются и потом читаются \en K8+from 3D, it is forbidden to store there since they register and then are read + rt_ErBodyCloosed = rt_TopologyError + 2, ///< \ru Тело детали не определено. \en Solid of part is undefined. + rt_OneEdge = rt_ErBodyCloosed + 2, ///< \ru У выбранного угла нет общего ребра. \en The selected corner has no common edge. + rt_SomeEdge = rt_OneEdge + 1, ///< \ru У одного из выбранных углов нет общего ребра. \en One of chosen corners has no common edge. + rt_NoSuitedSketch = rt_OneEdge, ///< \ru Неподходящий эскиз для операции. \en Improper sketch for operation. + // \ru K12 rt_SketchNoSheet = rt_OneEdge, // Эскиз должен располагаться только на внешней или внутренней плоской грани листового тела \en K12 rt_SketchNoSheet = rt_OneEdge, // Sketch should be located only on inner or outer flat face of a sheet solid + rt_SketchNoProj = rt_OneEdge + 1, ///< \ru Эскиз не проецируется на базовую грань. \en Sketch cannot be projected on a basic face. + rt_NoSheetFace = rt_OneEdge, ///< + rt_ErHeight = rt_OneEdge, ///< \ru Полный размер высоты должен быть больше толщины листового материала. \en Full size of height has to be greater than thickness of a sheet material. + rt_ErSketch = rt_ErHeight + 1, ///< \ru Эскиз должен располагаться только на внешней или внутренней плоской грани листового тела. \en Sketch should be located only on inner or outer flat face of a sheet solid. + rt_UpdatePlaceWrong = rt_TopologyError + 2, + rt_ErDegree = rt_TopologyError + 2, + + // \ru Окончание "нездорового" диапазона ошибок, НИКОГДА НЕ ВЗВОДИТЬ ЭТУ ОШИБКУ \en Ending of "unhealthy" range of errors, NEVER TO RAISE THIS ERROR + rt_EndOfInvalidRange = rt_BeginOfInvalidRange + 20, + + rt_NoObjectInDirNormal, ///< \ru Нет объекта в прямом направлении. \en No object in forward direction. + rt_NoObjectInDirReverse, ///< \ru Нет объекта в обратном направлении. \en No object in reverse direction. + rt_SolidAffectedByBoolean, ///< \ru Тела изменены булевой операцией. \en Solids changed by boolean operation. + rt_HaveDegenerateSegment, ///< \ru Кривая содержит сегменты нулевой длины. \en Curve has segments with zero length. + rt_NotAllSourcesFound, ///< \ru Не найдены одна или несколько исходных операций. \en One or several source operations are not found. + rt_InvalidEmptyContour, ///< \ru Контур состоит из 2 отрезков, проходящих друг по другу. \en Contour consists of two segments passing through each other. + + rt_UnnecessaryVariables, ///< \ru Избыточное количество переменных. \en Excessive variables. + rt_DomainMismatch, ///< \ru Область определения не соответствует заданным значениям. \en Domain doesn't match to given values. + rt_UnknownTranslatorError, ///< \ru Неизвестная ошибка при работе транслятора. \en Unknown translator error. + rt_UnknownParserError, ///< \ru Неизвестная ошибка при работе синтаксического анализатора. \en Unknown parser error. + rt_UnknownSymbol, ///< \ru В строке присутствует неизвестный символ. \en String contains unknown symbol. + rt_NoClosingBracket, ///< \ru Не хватает закрывающей скобки. \en Missed closing bracket. + rt_NoOpeningBracket, ///< \ru Не хватает открывающей скобки. \en Missed opening bracket. + rt_ImpossibleOperation, ///< \ru Невозможная операция. \en Impossible operation. + rt_LostObject, ///< \ru Операция потеряла опорные объекты. \en Operation lost support object. + rt_NotAllBendsProcessed, ///< \ru Не все сгибы согнуты/разогнуты. \en Not all bends are bent/unbent. + rt_ValueScalingError, ///< \ru Масштабирование с заданным коэффициентом невозможно. \en Scaling with the given factor is impossible. + rt_RatioScalingError, ///< \ru Масштабирование с заданным соотношением коэффициентов невозможно. \en Scaling with given factors ratio is impossible. + rt_MultiSolidDeflected, ///< \ru Данная операция не применима к телам из частей. \en Current operation cannot be applied to solids consisting of parts. + rt_MultiSolidDefused, ///< \ru Результатом данной операции не может быть тело из частей. \en Result of current operation cannot be a solid consisting of parts. + rt_TransitionError, ///< \ru Перестало выполняться граничное условие сопряжения. \en The boundary condition of conjugation is not satisfied. + rt_MeshCrossingError, ///< \ru Точки пересечения кривых не образуют регулярной сетки. \en Points of curves intersection don't form a regular mesh. + rt_ClosedError, ///< \ru Нельзя выполнить замыкание. \en Impossible to carry out closure. + rt_TooGreatCurve, ///< \ru Кривая, через которую происходит сопряжение, больше, чем сама поверхность. \en Curve to conjugate through is bigger than surface. + rt_ClosedOrUnClosedError, ///< \ru Все кривые должны быть либо замкнуты, либо разомкнуты. \en All the curves must be closed or open simultaneously. + rt_SketchNoSheet, ///< \ru Эскиз должен располагаться только на внешней или внутренней плоской грани листового тела. \en Sketch should be located only on inner or outer flat face of a sheet solid. + rt_BadSketch, ///< \ru Эскиз не удовлетворяет требованиям операции. \en Sketch doesn't meet the operation requirements. + rt_ConnectionError, ///< \ru Нарушена связность объектов. \en Broken connectivity of objects. + rt_MeshSmoothError, ///< \ru В точках пересечения кривые из противоположных семейств касаются. \en Intersection points are tangent points of curves from opposite families. + rt_NoIntersectContour, ///< \ru Нет контуров пересечения. \en No intersection contours. + rt_ErShMtHeight, ///< \ru Полный размер высоты должен быть больше толщины листового материала. \en Full size of height has to be greater than thickness of a sheet material. + rt_DegenerateSurface, ///< \ru Поверхность вырождена. \en Degenerate surface. + rt_SurfaceEdgesIntersect, ///< \ru Невозможно создать поверхность: нарушен порядок внутренних ребер разбиения. \en Cannot create surface: broken order of internal edges of splitting. + rt_TooLargeExtension, ///< \ru Величина удлинения слишком велика. \en Too large extension. + rt_TooSmallExtension, ///< \ru Величина удлинения слишком мала. \en Too small extension. + rt_VertexExtensionError, ///< \ru Не удалось продлить поверхность до данной вершины. \en Cannot extend the surface up to a given vertex. + rt_SurfaceExtensionError, ///< \ru Не удалось продлить поверхность до данной поверхности. \en Cannot extend surface to a given surface. + rt_NoEdgesConection, ///< \ru Ребра не образуют связную цепочку. \en Edges are not connected. + rt_TooManyPoints, ///< \ru Большое количество точек. Уменьшите количество. \en Too many points. Reduce them. + rt_TooManyPoints_1, ///< \ru Слишком большое количество точек. \en Too many points. + rt_DirectionExtensionError, ///< \ru Не удалось продлить поверхность в данном направлении. \en Cannot extend surface in the given direction. + rt_ExtensionPoleError, ///< \ru Грань содержит полюс: укажите другую кромку или выберите другой тип продления. \en Face contains a pole: specify another boundary or select another extension type. + rt_MustBeOpenOrClosed, ///< \ru Контуры должны быть либо все замкнуты, либо все разомкнуты. \en All the contours must be closed or open simultaneously. + rt_TooComplicatedItemsSet, ///< \ru Слишком сложный набор элементов для обработки. \en Too complicated set of elemnts to process. + rt_NoAxesIntersection, ///< \ru Оси не пересекаются. \en Axes are not crossed. + rt_TooFarItems, ///< \ru Объекты слишком далеко. \en Objects too far. + rt_ProcessIsStopped, ///< \ru Процесс остановлен. \en Process is stopped. + rt_ContourSweptError, ///< \ru Контур невозможно использовать для заданного перемещения. \en Contour cannot be used for given movement. + rt_SomeContourError, ///< \ru Один из контуров невозможно использовать для заданного построения. \en Contour cannot be used for given construction. + rt_SplitWireNotAllFaces, ///< \ru Линии разъема созданы не на всех выбранных гранях. \en Parting lines created not on all selected faces. + rt_GeneratrixColinearGuide, ///< \ru В некоторых точках образующая параллельна направляющей. \en Generatrix parallel to the giude at some points. + rt_NotEnoughMemory, ///< \ru Недостаточно памяти. \en Not enough memory. + rt_BorderColinearCurve, ///< \ru Направление боковой границы параллельно касательной на конце образующей кривой. \en Direction of lateral border is parallel to a tangent at the end of a guide curve. + rt_ObjectNotFound, ///< \ru Объект не найден. \en Object not found. + rt_PoleBrokenError, ///< \ru В сплайновой поверхности часть точек из полюса передвинута, часть осталась совпадающей. \en Some points of spline surface moved from pole, some remained coincident. + rt_ApproxError, ///< \ru Аппроксимация не выполнена. \en No approximation performed. + rt_AccuracyError, ///< \ru Не выполнены условия по точности построения. \en The construction accuracy conditions are not satisfied. + rt_BadVariable, ///< \ru Ошибочное значение переменной. \en Wrong value of variable. + rt_BadEdgesForChamfer, ///< \ru Невозможно построить фаску на указанных ребрах. \en Cannot create chamfer on specified edges. + rt_RevokeStopFillet, ///< \ru Остановка скругления невозможна, скругление выполнено без остановки. \en Can't stop fillet, the fillet without stopping was done. + rt_AdjacentTransitionError, ///< \ru Не согласованы сопряжения на смежных границах. \en The boundary condition of conjugation is not satisfied along adjacent boundaries. + rt_ObjectAccessDenied, ///< \ru Доступ к объекту запрещен. \en Access to the object is denied. + rt_TooManySegments, ///< \ru Количество сегментов слишком велико. \en The number of segments is too large. + rt_GapShiftError, ///< \ru Недопустимое положение зазора обечайки. \en Wrong gapShift parameter value. + rt_CutBySilhouetteError, ///< \ru Силуэтная грани линия не разрезает грань. \en Silhouette curve of face do not cut the face. + rt_DegeneratedProjection, ///< \ru Вырожденная проекция опорного объекта. \en The projection is degenerated for the reference object. + rt_NotAllContoursUsed, ///< \ru Использованы не все контура (кривые). \en Not all contours (curves) were used. + rt_ChangedParameter, ///< \ru Параметр операции был изменен. \en Parameter was changed. + rt_NotAllObjectsUsed, ///< \ru Использованы не все объекты. \en Not all objects were used. + rt_ZeroJumperError, ///< \ru Ошибка из-за образования перемычки нулевой толщины. \en Zero jumper error. + rt_FullFilletError, ///< \ru Ошибка при создании скругления грани. \en Error at creating full fillet. + + // \ru Ошибки построения плавных сплайнов. \en Build failure of fair splines. + rt_IncorrectSettings, ///< 0 \ru Некорректные объект / параметры. \en Incorrect object / parameters. + rt_IncorrectData, ///< 1 \ru Некорректные данные. \en Incorrect data. + rt_IncorrectPolylines, ///< 2 \ru Некорректные формы ломаных / направления касательных. \en Incorrect polylines / tangent directions. + rt_Incorrectstructure, ///< 3 \ru Некорректная структура ломаной с прямолинейными участками. \en Incorrect structure of 3d poly with straight sites. + rt_TooFewPoints, ///< 4 \ru Слишком мало точек. \en Too few points. + rt_CoincidencePoints, ///< 5 \ru Совпадение точек. \en Coincidence of points. + rt_TooAcuteAngle, ///< 6 \ru Слишком острый угол между сегментами ломаной. \en Too acute angle between segments of polyline. + rt_ReturnMotion, ///< 7 \ru Обратный ход сегмента. \en Return motion of segment. + rt_SharpTorsion, ///< 8 \ru Резкое кручение ломаной. \en Sharp torsion of spatial polyline. + rt_IncorrectFirstDirection, ///< 9 \ru Некорректное направление касательной в начальной точке. \en Incorrect direction of first tangent vector. + rt_IncorrectLastDirection, ///< 10 \ru Некорректное направление касательной в конечной точке. \en Incorrect direction of last tangent vector. + rt_FirstTangentVector, ///< 11 \ru Первая касательная задана к прямолинейному участку. \en First tangent vector is set to a rectilinear site of a polyline. + rt_LastTangentVector, ///< 12 \ru Последняя касательная задана к прямолинейному участку. \en Last tangent vector is set to a rectilinear site of a polyline. + rt_TangentVectorsSuitable, ///< 13 \ru Касательные векторы не корректны для локально-выпуклого участка. \en Tangent vectors are not suitable to convex shape of curve. + rt_IncorrectStructure, ///< 14 \ru Некорректная структура исходной кривой Безье. \en Incorrect structure of the initial Bezier curve. + rt_NoIntersection, ///< 15 \ru Нет пересечения касательных. Некорректная структура ломаной. \en No intersection of tangents. Incorrect structure of polyline. + rt_CriticalConfiguration, ///< 16 \ru Критическая конфигурация для B-сплайновой аппроксимации. \en Critical configuration for B-Spline approximation. + rt_IncorrectInitialData, ///< 17 \ru Некорректные исходные данные. \en Incorrect initial data. + rt_CommandNotImplemented, ///< 18 \ru Данная команда не реализована. \en This command is not implemented. + rt_InsufficientMemory, ///< 19 \ru Недостаточно памятию \en Insufficient memory. + rt_IncorrectFirstTangent, ///< 20 \ru Некорректное направление первой касательной. \en Incorrect direction of first tangent. + rt_IncorrectLastTangent, ///< 21 \ru Некорректное направление последней касательной. \en Incorrect direction of last tangent. + rt_StraightenLastSite, ///< 22 \ru Конечный прямолинейный участок. Касательный вектор не нужен. \en Straighten last site. Last tangent Ignored. + rt_IncorrectPolylineStructure, ///< 23 \ru Некорректная структура ломаной с прямолинейными участками. \en Incorrect structure of polyline with straight sites. + rt_ncorrectDataStructure, ///< 24 \ru Некорректная структура данных в модели. \en Incorrect data structure in the model. + rt_ObjectIsNotPolyline, ///< 25 \ru Объект - не пространственная ломаная. \en Object is not a 3D polyline. + rt_MissingKnots, ///< 26 \ru Отсутствует вектор узлов. \en Missing knots vector. + rt_ClosedSpline, ///< 27 \ru Замкнутый сплайн во внешнем файле. \en Closed spline in an external file. + rt_ObjectNotSelected, ///< 28 \ru Не выбран нужный объект. \en Object is not selected. + rt_InputFile, ///< 29 \ru Входной файл. \en Input file. + rt_ExternalMemory, ///< 30 \ru Внешняя память. \en External memory. + rt_TooFewStartPoints, ///< 31 \ru Слишком мало точек на выпуклом участке начального участка. \en Too few points on convex start site of curve. + rt_BanClosedConfiguration, ///< 32 \ru Запрет на замкнутую конфигурацию при количестве точек < 5. \en A ban on a closed configuration when the number of points < 5. + rt_IncorrectDeterminant, ///< 33 \ru Некорректная структура исходного геометрического определителя. \en Incorrect structure of the initial geometric determinant. + rt_DimensionsPointsArrays, ///< 34 \ru Размеры массивов точек. \en Dimensions of points arrays. + rt_TangentsNotIntersect, ///< 35 \ru Касательные не пересекаются. \en Tangents do not intersect. + rt_PointsCoincide, ///< 36 \ru Точки совпадают. \en Points coincide. + rt_FewPointsForClosed, ///< 37 \ru Мало точек для замкнутой ломаной. \en Few points for a closed polyline. + rt_TooFewPointsOnSite, ///< 38 \ru Слишком мало точек на выпуклом участке. \en Too few points on convex end site of curve. + rt_PointsOnLine, ///< 39 \ru Точки на прямой. \en Points on the straight line. + rt_TooManyApexes, ///< 40 \ru Слишком много точек. \en Too many points. + rt_SiteNotConvex, ///< 41 \ru Трехсегментный участок не выпуклый. \en Three-linked site is not convex. + rt_CurvatuteRange, ///< 42 \ru Кривизна за пределами допустимого диапазона. \en Curvatute out of range. + rt_ObjectIsNotHermiteGD, ///< 43 \ru Объект не ГО Эрмита. \en The object is not Hermite GD. + rt_ObjectIsNotNURBS, ///< 44 \ru Объект не NURBzS. \en The object is not NURBzS. + rt_DerivativeContinuityErr, ///< 45 \ru Ошибка обеспечения непрерывности производной. \en Error ensuring derivative continuity. + + // \ru !!! СТРОКИ ВСТАВЛЯТЬ СТРОГО ПЕРЕД ЭТОЙ СТРОКОЙ !!!! \en !!! INSERT LINES STRICTLY BEFORE THIS LINE !!!! + rt_ErrorTotal // \ru НИЖЕ НЕ ДОБАВЛЯТЬ! \en DON'T ADD BELOW! +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Результат операции "Сшивка". + \en The "stitching" operation result. \~ + \ingroup Data_Structures +*/ +// --- +enum MbeStitchResType { + stch_Success = 0, ///< \ru Нет ошибок. \en No errors. + stch_PrepareError, ///< \ru Ошибка при подготовке операции сшивки. \en "Stitching" operation preparation error. + stch_CoorientFaceError, ///< \ru Невозможно выставить согласованную ориентацию граней. \en Unable to set the matched orientation of faces. + stch_SomeEdgesUnstitched, ///< \ru Некоторые рёбра остались несшитыми. \en Some edges are still unstitched. + stch_OutwardOrientError, ///< \ru Не удалось установить нормали граней наружу тела. \en Can't set the normals of faces oriented outside the solid. + stch_NoEdgeWasStitched, ///< \ru Не было сшито ни одного ребра. \en No edge was stitched. + stch_SeparatePartsResult, ///< \ru После сшивки остались несвязанные между собой куски. \en There are separate parts after stitching. + stch_EdgeStitchError ///< \ru Ошибка сшивки ребра. \en Edge stitching error. +}; + + +#endif // __MB_OPERATION_RESULT_H diff --git a/C3d/Include/mb_placement.h b/C3d/Include/mb_placement.h new file mode 100644 index 0000000..8ae54a8 --- /dev/null +++ b/C3d/Include/mb_placement.h @@ -0,0 +1,488 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** \file + \brief \ru Локальная система координат в двумерном пространстве. + \en Local coordinate system in two dimensional space. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_PLACEMENT_H +#define __MB_PLACEMENT_H + +#include +#include + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Типы локальных систем координат в двумерном пространстве. + \en Types of local coordinate systems in two dimensional space. \~ + \details \ru Типы локальных систем координат в двумерном пространстве. + \en Types of local coordinate systems in two dimensional space. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +enum MbeLocalSystemType { + ls_CartesSystem, ///< \ru Декартова система координат. \en Cartesian coordinate system. + ls_PolarSystem, ///< \ru Полярная система координат. \en Polar coordinate system. +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Локальная система координат в двумерном пространстве. + \en Local coordinate system in two dimensional space. \~ + \details \ru Локальная система координат в двумерном пространстве. \n + В большинстве случаев система координат (СК) является правой, а векторы системы ортонормированы. + С помощью преобразований система координат может стать левой и не ортонормированнной. + Локальная система координат является декартовой, + Точка в декартовой системе координат определяется двумя координатами x, y. + \en Local coordinate system in two dimensional space. \n + Local coordinate system is described by the initial point and two non-parallel vectors. + In most cases the system of coordinates is right, and vectors of system are orthonormalized. + A coordinate system can become left and not orthonormalized via transformations. + Local coordinate system is Cartesian, + Point in the Cartesian coordinate system is defined by two coordinates x, y. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbPlacement { +private: + MbCartPoint origin; ///< \ru Положение начала локальной системы координат. \en Origin of coordinate system. + MbVector axisX; ///< \ru Направление первой оси. \en Direction of first axis. + MbVector axisY; ///< \ru Направление второй оси. \en Direction of second axis. +private: + /** + \brief \ru Состояние локальной системы координат. + \en State of local coordinate system. \~ + \details \ru Состояние локальной системы координат определяется установкой битовых полей: \n + MB_TRANSLATION - начало координат не ноль \n + MB_ROTATION - система координат не единичная \n + MB_LEFT - признак левой системы координат \n + MB_ORTOGONAL - ортогональная система координат, взводится только в случае аффинной системы координат \n + MB_AFFINE - система координат произвольная аффинная \n + MB_UNSET - битовые флаги не установлены \n + При изменении системы координат flag должен быть сброшен в неустановленное состояние MB_UNSET. \n + Если flag == MB_UNSET, то при использовании системы координат происходит определение её состояния.\n + \en State of local coordinate system is defined by setting-up of bit fields: \n + MB_TRANSLATION - origin of coordinate system is not zero \n + MB_ROTATION - coordinate system is not unit \n + MB_LEFT - attribute of left coordinate system \n + MB_ORTOGONAL - orthogonal coordinate system, it is set-up only if coordinate system is affine \n + MB_AFFINE - any affine coordinate system \n + MB_UNSET - bit flags not set \n + 'flag' has to be reset to unspecified MB_UNSET state while changing the coordinate system. \n + if 'flag' == MB_UNSET then the state of coordinate system is specified while it is being used.\n \~ + */ + mutable uint8 flag; + +public : + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPlacement(); + /// \ru Конструктор по точке и нормализованному вектору направления. \en Constructor by point and normalized direction vector. + MbPlacement( const MbCartPoint &, const MbDirection &, bool l = false ); + /// \ru Конструктор по точке и двум векторам. \en Constructor by point and two vectors. + MbPlacement( const MbCartPoint &, const MbVector &, const MbVector & ); + /// \ru Конструктор по точке и знакам направления осей X и Y. \en Constructor by point and signs of X-axis and Y-axis directions. + MbPlacement( const MbCartPoint &, bool, bool ); + /// \ru Конструктор по точке и углу. \en Constructor by point and angle. + MbPlacement( const MbCartPoint &, double angle, bool l = false ); + /// \ru Конструктор по координатам начала ЛСК и углу. \en Constructor by angle and coordinates of local coordinate system origin. + MbPlacement( double x, double y, double angle ); + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbPlacement( const MbCartPoint & p1, const MbCartPoint & p2 ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPlacement( const MbPlacement & ); + /// \ru Конструктор по матрице. \en Constructor by matrix. + MbPlacement( const MbMatrix & matr ); + /// \ru Деструктор. \en The destructor. + ~MbPlacement(); + +public: // \ru Функции инициализации \en Initialization functions. + + /// \ru Сделать совпадающей с мировой СК. \en Make coincident with global coordinate system. + void Init(); + /// \ru Инициализировать по заданной ЛСК. \en Initialize by given local coordinate system. + void Init( const MbPlacement & init ); + /// \ru Инициализировать по точке и вектору направления. \en Initialize by a point and direction vector. + void Init( const MbCartPoint & initOrigin, const MbDirection & initDir, bool l = false ); + /// \ru Инициализировать по точке и углу. \en Initialize by a point and an angle. + void Init( const MbCartPoint & initOrigin, double angle, bool l = false ); + /// \ru Инициализировать по точке и двум векторам. \en Initialize by a point and two vectors. + void Init( const MbCartPoint &, const MbVector &, const MbVector & ); + +public: // \ru Функции доступа к данным. \en Getters and Setters. + + /// \ru Дать начало ЛСК. \en Get the origin of local coordinate system. + const MbCartPoint & GetOrigin() const { return origin; } + /// \ru Дать ось X. \en Get the X-axis. + const MbVector & GetAxisX() const { return axisX; } + /// \ru Дать ось Y. \en Get the Y-axis. + const MbVector & GetAxisY() const { return axisY; } + /// \ru Дать начало ЛСК. \en Get the origin of local coordinate system. + void GetOrigin( MbCartPoint & pc ) const { pc = origin; } + /// \ru Перевести точку и первые три производные из локальной в глобальную систему координат. \en Transform a point and the first three derivatives from a local coordinate system to the global coordinate system. + void GetPointAndDerivesFrom( MbCartPoint & point, MbVector & firstDer, + MbVector & secondDer, MbVector & thirdDer, + MbeLocalSystemType type = ls_CartesSystem ) const; + + // \ru Установить новое значение \en Set the new value + /// \ru Дать начало ЛСК. \en Get the origin of local coordinate system. + MbCartPoint & SetOrigin() { flag = MB_UNSET; return origin; } + /// \ru Дать ось X. \en Get the X-axis. + MbVector & SetAxisX() { flag = MB_UNSET; return axisX; } + /// \ru Дать ось Y. \en Get the Y-axis. + MbVector & SetAxisY() { flag = MB_UNSET; return axisY; } + /// \ru Задать начало ЛСК. \en Set the origin of local coordinate system. + void SetOrigin( const MbCartPoint & p ); + /// \ru Задать ось X. \en Set the X-axis. + void SetAxisX ( const MbDirection & v ); + /// \ru Задать ось Y. \en Set the Y-axis. + void SetAxisY ( const MbDirection & v ); + /// \ru Задать ось X. \en Set the X-axis. + void SetAxisX ( const MbVector & v ); + /// \ru Задать ось Y. \en Set the Y-axis. + void SetAxisY ( const MbVector & v ); + /// \ru Дать матрицу преобразования в локальную СК: r=R*into (обратная матрица). \en Get the matrix of transformation to the local coordinate system: r=R*into (inverse matrix). + void GetMatrixInto( MbMatrix & m ) const; + /// \ru Дать матрицу преобразования из локальной СК: R=r*from (прямая матрица). \en Get the matrix of transformation from the local coordinate system: R=r*from (direct matrix). + void GetMatrixFrom( MbMatrix & m ) const; + +public: // \ru Функции доступа к данным. \en Getters and Setters. + + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move( const MbVector & ); + /// \ru Сдвинуть на заданные приращения. \en Translate by given increments. + void Move( double dx, double dy ); + /// \ru Повернуть вокруг точки на угол. \en Rotate at angle around a point. + void Rotate( const MbCartPoint & pnt, double angle ); + /// \ru Повернуть вокруг точки на угол, заданный вектором направления. \en Rotate around a point at the angle given by direction vector. + void Rotate( const MbCartPoint & pnt, const MbDirection & angle ); + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Transform( const MbMatrix & matr ); + /// \ru Рассчитать СК по начальной и конечной точкам. \en Calculate the coordinate system by the start point and the end point. + void Calculate( const MbCartPoint & from, const MbCartPoint & to ); + /// \ru Пересчитать СК по измененным внутренним данным. \en Recalculate the coordinate system by changed internal data. + void Reset(); + ///< \ru Масштабировать ЛСК. \en Scale the local coordinate system. + void Scale( double sx, double sy, double &lx, double &ly ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbPlacement & other, double accuracy ) const; + /// \ru Инвертировать ось 0X. \en Invert the 0X-axis. + void InvertAxisX(); + /// \ru Инвертировать ось 0Y. \en Invert the 0Y-axis. + void InvertAxisY(); + + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbPlacement & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbPlacement & ) const; + /// \ru Присвоить другую систему координат. \en Assign another coordinate system. + void operator = ( const MbPlacement & ); + /// \ru Умножить на локальную систему (как перемножение матриц): P = this * p. \en Multiply by a local coordinate system: P = this * p (as of matrix multiplication). + MbPlacement operator * ( const MbPlacement & p ) const; + + /// \ru Перевести точку из глобальной в локальную систему координат. \en Transform point from the global coordinate system to a local coordinate system. + void TransformInto( MbCartPoint & ) const; + /// \ru Перевести точку из локальной в глобальную систему координат. \en Transform point from a local coordinate system to the global coordinate system. + void TransformFrom( MbCartPoint & ) const; + /// \ru Перевести вектор из глобальной в локальную систему координат. \en Transform a vector from the global coordinate system to a local coordinate system. + void TransformInto( MbVector & ) const; + /// \ru Перевести вектор из локальной в глобальную систему координат. \en Transform a vector from a local coordinate system to the global coordinate system. + void TransformFrom( MbVector & ) const; + /// \ru Нормализовать. \en Normalize. + void Normalize() { Reset(); } + +public: // \ru Функции получения свойств. \en Properties. + + /// \ru Свойство совпадения с мировой системой координат. \en Property of coincidence with global coordinate system. + bool IsSingle () const { return (MB_IDENTITY == CheckFlag()); } + /// \ru Проверить, присутствует ли сдвиг системы координат относительно глобальной. \en Check if a coordinate system is translated relative to the global coordinate system. + bool IsTranslation() const { return !!(CheckFlag() & MB_TRANSLATION); } + /// \ru Проверить, присутствует ли поворот системы координат относительно глобальной. \en Check if the coordinate system is rotated relative to the global coordinate system. + bool IsRotation () const { return !!(CheckFlag() & MB_ROTATION); } + /// \ru Выдать признак лево-ориентированного плейсмента. \en Get attribute of left placement. + bool IsLeft () const { return !!(CheckFlag() & MB_LEFT); } + /// \ru Проверить, является ли СК ортогональной, но ненормированной. \en Check if a coordinate system is orthogonal, but not normalized. + bool IsOrt () const { return !!(CheckFlag() & MB_ORTOGONAL); } + /// \ru Проверить признак ортогональности СК. \en Check orthogonality of a coordinate system. + bool IsOrthogonal () const { CheckFlag(); return ( !(flag & MB_AFFINE) || !!(flag & MB_ORTOGONAL) ); } + /// \ru Проверить, является ли СК аффинной (если нет - то она ортонормированная). \en Check if a coordinate system is affine (otherwise it is orthonormalized). + bool IsAffine () const { return !!(CheckFlag() & MB_AFFINE); } + /// \ru Проверить признак ортонормированности СК. \en Check if a coordinate system is orthonormalized. + bool IsNormal () const { return !IsAffine(); } + /// \ru Проверить, что битовые флаги не установлены. \en Check whether bit flags are not set. + bool IsUnSet () const { return !!( flag & MB_UNSET ); } + + /// \ru Вычислить и вернуть признак лево-ориентированного плейсмента. \en Calculate and return attribute of left placement. + bool CheckLeft(); + + /// \ru Проверить ортогональность. \en Check orthogonality. + bool IsCardinalPoint( double eps = Math::AngleEps ) const; + /// \ru Проверить параллелен оси 0X или 0Y. \en Check if parallel to 0X-axis or 0Y-axis + bool IsCardinalStrict( double eps ) const; + /// \ru Являются ли оси СК совпадающими со стандартной (правой ортонормированной СК). \en Check if axes of coordinate system are coincident to a standard one (right orthonormalized coordinate system). + bool IsTranslationStandard() const; + + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsCircular() const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsCircular( double & lxy ) const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsIsotropic() const { return IsCircular(); } + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsIsotropic( double & lxy ) const { return IsCircular( lxy ); } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & properties ); + +private: + /// \ru Выставить флаги. \en Set flags. + uint8 ResetFlag() const; + // Оценить флаги, если оценки не было + uint8 CheckFlag() const { return IsUnSet() ? ResetFlag() : flag; } + // Проверить флаг смещения. + void CheckOrigin() const { ::CheckOrigin( *this, flag, true ); } + // \ru Проверить флаг вращения. \en Check rotation flag. + void CheckRotation() const { ::CheckRotation( *this, flag, true ); } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbPlacement, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbPlacement ) + DECLARE_NEW_DELETE_CLASS_EX( MbPlacement ) +}; + + +//---------------------------------------------------------------------------------------- +// \ru Конструктор по умолчанию. \en Constructor. +// --- +inline MbPlacement::MbPlacement() + : origin( 0.0, 0.0 ) + , axisX ( 1.0, 0.0 ) + , axisY ( 0.0, 1.0 ) + , flag ( MB_IDENTITY ) +{ +} + + +//---------------------------------------------------------------------------------------- +// \ru Конструктор копирования. \en Copy constructor. +// --- +inline MbPlacement::MbPlacement( const MbPlacement & other ) + : origin( other.origin ) // начало координат + , axisX ( other.axisX ) // направление оси 0X + , axisY ( other.axisY ) // направление оси 0Y + , flag ( other.flag ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbPlacement::MbPlacement( const MbMatrix & matr ) + : origin( matr.GetOrigin() ) + , axisX ( matr.GetAxisX() ) + , axisY ( matr.GetAxisY() ) + , flag( MB_UNSET ) +{ + if ( !matr.IsAffine() ) { + flag = MB_IDENTITY; + if ( matr.IsTranslation() ) + flag |= MB_TRANSLATION; + if ( matr.IsRotation() ) + flag |= MB_ROTATION; + if ( matr.IsLeft() ) + flag |= MB_LEFT; + if ( matr.IsOrt() ) + flag |= MB_ORTOGONAL; + } +} + + +//---------------------------------------------------------------------------------------- +// \ru Инициализация единичной матрицы (мировая СК). \en Initialize. +// --- +inline void MbPlacement::Init() +{ + origin.SetZero(); + axisX.Init( 1.0, 0.0 ); + axisY.Init( 0.0, 1.0 ); + flag = MB_IDENTITY; +} + + +//---------------------------------------------------------------------------------------- +// \ru Инициализация по плейсменту. \en Initialize by placement. +// --- +inline void MbPlacement::Init( const MbPlacement & init ) { + *this = init; +} + + +//---------------------------------------------------------------------------------------- +// \ru Сдвиг по вектору. \en Move by vector. +// --- +inline void MbPlacement::Move( const MbVector & to ) { + origin.Move( to ); + CheckOrigin(); +} + + +//---------------------------------------------------------------------------------------- +// \ru Сдвиг по вектору. \en Move by vector. +// --- +inline void MbPlacement::Move( double dx, double dy ) { + origin.Move( dx, dy ); + CheckOrigin(); +} + + +//---------------------------------------------------------------------------------------- +// \ru Трансформация по матрице. \en Transform by matrix. +// --- +inline void MbPlacement::Transform( const MbMatrix & matr ) +{ + origin.Transform( matr ); + axisX.Transform( matr ); + axisY.Transform( matr ); + ResetFlag(); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установить новое начало плейсмента. \en Set new origin. +// --- +inline void MbPlacement::SetOrigin( const MbCartPoint & pc ) +{ + origin = pc; + CheckOrigin(); +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbPlacement::operator == ( const MbPlacement & with ) const +{ + return ( origin == with.origin ) && + ( axisX == with.axisX ) && + ( axisY == with.axisY ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbPlacement::operator != ( const MbPlacement & with ) const { + return !( *this == with ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Присвоение другой системы координат \en Assignment of another coordinate system +// --- +inline void MbPlacement::operator = ( const MbPlacement & other ) +{ + origin = other.origin; // \ru Начало координат \en The origin + axisX = other.axisX; // \ru Направление оси 0X \en Direction of 0X-axis + axisY = other.axisY; // \ru Направление оси 0Y \en Direction of 0Y-axis + flag = other.flag; +} + + +//---------------------------------------------------------------------------------------- +// \ru Поворот \en Rotation +// --- +inline void MbPlacement::Rotate( const MbCartPoint & pnt, double angle ) +{ + MbDirection d( angle ); + Rotate( pnt, d ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Вычислить и вернуть признак лево-ориентированного плейсмента \en Calculate and return attribute of left placement +// --- +inline bool MbPlacement::CheckLeft() +{ + if ( !(flag & MB_UNSET) ) { + if ( (axisX | axisY) < 0.0 ) + flag |= MB_LEFT; + else + flag &= ~MB_LEFT; + } + else { + ResetFlag(); + } + + return !!( flag & MB_LEFT ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка параллелен оси 0X или 0Y \en Check if parallel to 0X-axis or 0Y-axis +// --- +inline bool MbPlacement::IsCardinalPoint( double eps ) const +{ + return ( ((::fabs( axisX.y ) < eps) && (::fabs( axisY.x ) < eps)) || + ((::fabs( axisX.x ) < eps) && (::fabs( axisY.y ) < eps)) ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка параллелен оси 0X или 0Y \en Check if parallel to 0X-axis or 0Y-axis +// --- +inline bool MbPlacement::IsCardinalStrict( double eps ) const { + return ( (::fabs( axisX.y ) < eps) && (::fabs( axisY.x ) < eps) ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Являются ли оси с.к. совпадающими со стандартной (правой ортонормированной с.к.) \en Check if the axes of a coordinate system are coincident to a standard one (right orthonormalized coordinate system) +// --- +inline bool MbPlacement::IsTranslationStandard() const +{ + if ( !IsLeft() && IsNormal() ) { + if ( axisX.Colinear( MbVector::xAxis, ANGLE_EPSILON ) && axisY.Colinear( MbVector::yAxis, ANGLE_EPSILON ) ) + return true; + } + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Является ли с.к. ортогональной с равными по длине осями X,Y (круг остается кругом) \en Whether a coordinate system is orthogonal with the axes X and Y of equal length (circle moves to circle) +// --- +inline bool MbPlacement::IsCircular() const +{ + if ( IsNormal() ) + return true; + else if ( IsOrthogonal() && c3d::EqualLengths( axisX.Length(), axisY.Length() ) ) + return true; + + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Является ли с.к. ортогональной с равными по длине осями X,Y (круг остается кругом) \en Whether a coordinate system is orthogonal with the axes X and Y of equal length (circle moves to circle) +// --- +inline bool MbPlacement::IsCircular( double & lxy ) const +{ + lxy = 1.0; + + if ( IsNormal() ) + return true; + else if ( IsOrthogonal() ) { + double lx = axisX.Length(); + double ly = axisY.Length(); + if ( c3d::EqualLengths( lx, ly ) ) { + lxy = 0.5 * (lx + ly); + return true; + } + } + + return false; +} + + +#endif // __MB_PLACEMENT_H diff --git a/C3d/Include/mb_placement3d.h b/C3d/Include/mb_placement3d.h new file mode 100644 index 0000000..9798737 --- /dev/null +++ b/C3d/Include/mb_placement3d.h @@ -0,0 +1,980 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Локальная система координат. + \en A local coordinate system. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_PLACEMENT3D_H +#define __MB_PLACEMENT3D_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbDirection; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbCube; +class MATH_CLASS MbLine3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы локальных систем координат в трёхмерном пространстве. + \en Types of local coordinate systems in three dimensional space. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +enum MbeLocalSystemType3D +{ + ls_CartesianSystem, ///< \ru Декартова система координат. \en Cartesian coordinate system. + ls_CylindricalSystem, ///< \ru Цилиндрическая система координат. \en Cylindrical coordinate system. + ls_SphericalSystem, ///< \ru Сферическая система координат. \en Spherical coordinate system. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Локальная система координат в трёхмерном пространстве. + \en Local coordinate system in three dimensional space. \~ + \details \ru Локальная система координат в трёхмерном пространстве. \n + В большинстве случаев система координат является правой, а векторы системы ортонормированы. + С помощью преобразований система координат (СК) может стать левой и не ортонормированной. + Локальная система координат является декартовой. + Точка в декартовой системе координат определяется тремя координатами x, y, z.\n + Локальная система может выступать в роли цилиндрической или сферической системы координат.\n + Точка в цилиндрической системе координат определяется тремя координатами r, f, z: \n + r, f - полярные координаты проекции точки на основную плоскость;\n + r - длина проекции радиус-вектора; \n + f - полярный угол проекции радиус-вектора; \n + z - аппликата (расстояние от точки до основной плоскости). \n + При использовании локальной системы координат в роли цилиндрической системы считаем, что: \n + начало координат цилиндрической системы совпадает с началом координат декартовой системы; \n + ось Oz цилиндрической системы координат совпадает с осью Oz декартовой системы; \n + основная плоскость цилиндрической системы координат совпадает с плоскостью Oxy декартовой системы; \n + полярная ось координат цилиндрической системы совпадает с осью Ox декартовой системы; \n + полярный угол f цилиндрической системы отсчитываем от оси Ox к положительному направлению оси Oy. \n + Точка в сферической системе координат определяется тремя координатами r, f, w: \n + r - расстояние от начала координат до точки (длина радиус-вектора);\n + f - угол между проекцией радиус-вектора на плоскость и лучом принадлежащим плоскости (долгота);\n + w - угол между радиус-вектором и нормалью к плоскости сферической системы (полярное расстояние).\n + При использовании локальной системы координат в роли сферической системы считаем, что: \n + начало сферической системы совпадает с началом декартовой системы координат; \n + луч перпендикулярный плоскости сферической системы координат совпадает с осью Oz декартовой системы; \n + плоскость сферической системы координат совпадает с плоскостью Oxy декартовой системы; \n + угол f сферической системы определяется отсчитываем от оси Ox к положительному направлению оси Oy.\n + Для ускорения преобразования координат локальная система имеет дополнительные данные - флаг состояния.\n + Для получения данных системы координат извне следует пользоваться методами Get...\n + Для модификации данных системы координат извне следует пользоваться методами Set..., которые автоматически сбрасывают флаг системы в неустановленное состояние.\n + \en Local coordinate system in three dimensional space. \n + Local coordinate system is described by the initial point and three non-parallel vectors. + In most cases the system of coordinates is right, and vectors of system are orthonormalized. + A coordinate system can become left and not orthonormalized via transformations. + Local coordinate system is Cartesian. + A point is defined by three coordinates x, y, z in the Cartesian coordinate system.\n + A local coordinate system may act both as a cylindrical or a sphricial coordinate system.\n + A point in a cylindrical coordinate system is defined by three coordinates r, f, z: \n + r, f - polar coordinates of point projection to the main plane;\n + r - length of radius-vector projection; \n + f - polar angle of radius-vector projection; \n + z - z-axis (the distance from point to the main plane). \n + When a local coordinate system is used as a cylindrical coordinate system, it is considered that: \n + the origin of a cylindrical coordinate system is coincident to the origin of Cartesian coordinate system; \n + Oz-axis of a cylindrical coordinate system is coincident to Oz-axis of the Cartesian coordinate system; \n + the main plane of a cylindrical coordinate system is coincident to Oxy-plane of the Cartesian coordinate system; \n + the polar axis of a cylindrical coordinate system is coincident to Ox-axis of the Cartesian coordinate system; \n + the polar angle f of a cylindrical coordinate system is counted from Ox-axis to the positive direction of Oy-axis. \n + A point in a spherical coordinate system is defined by three coordinates r, f, w: \n + r - distance from the origin to a point (length of radius-vector);\n + f - the angle between radius-vector projection to the plane and a ray on the plane (longitude);\n + w - the angle between radius-vector and the normal of spherical coordinate system plane (polar distance).\n + When a local coordinate system is used as a spherical coordinate system, it is considered that: \n + the origin of a spherical coordinate system is coincident to the origin of the Cartesian coordinate system; \n + the ray perpendicular to the plane of a spherical coordinate system is coincident to Oz-axis of the Cartesian coordinate system; \n + the plane of a spherical coordinate system is coincident to Oxy-plane of the Cartesian coordinate system; \n + the angle f of a spherical coordinate system is counted from Ox-axis to the positive direction of Oy-axis.\n + To speed up transformation of coordinates the local coordinate system has additional data - flag of state.\n + Use Get... methods to obtain data of a coordinate system from the outside. \n + To modify data of a coordinate system from the outside use Set... methods that automatically reset the flag of the system to the unspecified state. \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbPlacement3D { +private: + MbCartPoint3D origin; ///< \ru Положение начала локальной системы координат. \en Position of a coordinate system origin. + MbVector3D axisX; ///< \ru Направление первой оси. \en Direction of the first axis. + MbVector3D axisY; ///< \ru Направление второй оси. \en Direction of the second axis. + MbVector3D axisZ; ///< \ru Направление третьей оси. \en Direction of the third axis. + /** + \brief \ru Состояние локальной системы координат. + \en State of a local coordinate system. \~ + \details \ru Состояние локальной системы координат определяется установкой битовых полей: \n + MB_TRANSLATION - начало координат не ноль \n + MB_ROTATION - система координат не единичная \n + MB_LEFT - признак левой системы координат \n + MB_ORTOGONAL - ортогональная система координат, взводится только в случае аффинной системы координат \n + MB_AFFINE - система координат произвольная аффинная \n + MB_UNSET - битовые флаги не установлены \n + При изменении системы координат flag должен быть сброшен в неустановленное состояние MB_UNSET. \n + Если flag == MB_UNSET, то при использовании системы координат происходит определение её состояния.\n + \en State of a local coordinate system is defined by setting-up of bit fields: \n + MB_TRANSLATION - the origin of a coordinate system is not zero \n + MB_ROTATION - a coordinate system is not unit \n + MB_LEFT - attribute of a left coordinate system \n + MB_ORTOGONAL - orthogonal coordinate system, it is set-up only if a coordinate system is affine \n + MB_AFFINE - any affine coordinate system \n + MB_UNSET - bit flags not set \n + 'flag' has to be reset to unspecified MB_UNSET state while changing the coordinate system. \n + if 'flag' == MB_UNSET, then the state of coordinate system is specified while it is being used.\n \~ + */ + mutable uint8 flag; + +public: + ///< \ru Константа глобальной системы координат. \en A constant of the global coordinate system. + static const MbPlacement3D global; + +public: /** \ru \name Конструкторы. + \en \name The constructors. + \{ */ + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPlacement3D(); + /// \ru Конструктор по точке. \en Constructor by point. + explicit MbPlacement3D( const MbCartPoint3D & org ); + /// \ru Конструктор двум векторам и точке. \en Constructor by point and two vectors. + explicit MbPlacement3D( const MbVector3D & axisX, const MbVector3D & axisY, const MbCartPoint3D & org ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPlacement3D( const MbPlacement3D & place ); + /// \ru Конструктор по матрице. \en Constructor by matrix. + MbPlacement3D( const MbMatrix3D & matr ); + /// \ru Конструктор по точке и двум векторам. \en Constructor by point and two vectors. + explicit MbPlacement3D( const MbCartPoint3D & org, const MbVector3D & axisZ, const MbVector3D & axisX, bool l = false ); + /// \ru Конструктор по трем точкам. \en Constructor by three points. + explicit MbPlacement3D( const MbCartPoint3D & org, const MbCartPoint3D & px, const MbCartPoint3D & py, bool l = false ); + /// \ru Конструктор по точке и вектору (ось Z) с произвольной осью X. \en Constructor by point and vector (Z-axis) with arbitrary X-axis. + MbPlacement3D( const MbCartPoint3D & org, const MbVector3D & axisZ, bool l = false ); + +public: /** \} + \ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + + /// \ru Инициализировать единичную матрицу прямого преобразования (мировая СК). \en Initialize identity matrix of a direct transformation (the global coordinate system). + MbPlacement3D & Init(); + /// \ru Инициализировать по плейсменту. \en Initialize by a placement. + MbPlacement3D & Init( const MbPlacement3D & ); + /// \ru Инициализировать по матрице. \en Constructor by a matrix. + MbPlacement3D & Init( const MbMatrix3D & matr ); + + /// \ru Инициализировать по началу и векторам осей X, Z. \en Initialize by the origin and vectors of X and Z axes. + MbPlacement3D & Init( const MbCartPoint3D & p, const MbVector3D & axisZ, const MbVector3D & axisX, + bool left = false ); + + /// \ru Инициализировать по началу и точкам осей X, Y. \en Initialize by the origin and points of X and Y axes. + MbPlacement3D & Init( const MbCartPoint3D & p, const MbCartPoint3D & axisX, const MbCartPoint3D & axisY, + bool left = false ); + /// \ru Инициализировать осью Z с произвольной осью X. \en Initialize by Z-axis and arbitrary X-axis. + MbPlacement3D & Init ( const MbCartPoint3D & p, const MbVector3D & axisZ, + bool left ); + /// \ru Инициализировать по плейсменту со смещением. \en Initialize by placement with a shift. + MbPlacement3D & Init( const MbPlacement3D & pl, double distance ); + /// \ru Инициализировать по началу и ориентирующему плейсменту. \en Initialize by origin and orienting placement. + MbPlacement3D & Init( const MbCartPoint3D & p, const MbPlacement3D & pl ); + /// \ru Инициализировать по началу. \en Initialize by origin. + MbPlacement3D & Init( const MbCartPoint3D & org ); + // \ru Методы инициализации по началу и двум векторам осям \en Methods for initialization by origin and two vectors of axes + /// \ru Инициализировать по точке и двум векторам (оси X, Y). \en Initialize by a point and two vectors (X and Y axes). + MbPlacement3D & InitXY( const MbCartPoint3D & p, const MbVector3D & axisX, const MbVector3D & axisY, bool reset ); + /// \ru Инициализировать по точке и двум векторам (оси X, Z). \en Initialize by a point and two vectors (X and Z axes). + MbPlacement3D & InitXZ( const MbCartPoint3D & p, const MbVector3D & axisX, const MbVector3D & axisZ ); + /// \ru Инициализировать по точке и двум векторам (оси Y, Z). \en Initialize by a point and two vectors (Y and Z axes). + MbPlacement3D & InitYZ( const MbCartPoint3D & p, const MbVector3D & axisY, const MbVector3D & axisZ ); + + /// \ru Инициализировать по кривой и углу к плоскости. \en Initialize by curve and angle to plane. + bool Init ( const MbPlacement3D & pl, double ang, const MbCurve3D & c, double t ); + /// \ru Инициализировать по точке и кривой. \en Initialize by point and curve. + bool Init ( const MbCartPoint3D & p, const MbCurve3D & c, double t ); + /// \ru Инициализировать по точке перпендикулярно кривой. \en Initialize by point, perpendicularly to curve. + bool Init ( const MbCurve3D &, const MbCartPoint3D &, bool checkPlanar ); + /// \ru Инициализировать по прямой и точке. \en Initialize by a line and a point. + bool Init ( const MbLine3D &, const MbCartPoint3D & ); + /// \ru Инициализировать по прямой и вектору. \en Initialize by a line and a vector. + bool Init ( const MbLine3D &, const MbVector3D & ); + /// \ru Инициализировать по двум прямым. \en Initialize by two lines. + bool Init ( const MbLine3D & l1, const MbLine3D & l2 ); + /// \ru Инициализировать перпендикулярно кривой по параметру на кривой. \en Initialize perpendicularly to a curve by a parameter on the curve. + bool Init ( const MbCurve3D &, double t, bool checkPlanar ); + + // \ru Методы инициализации для привязки \en Methods for initialization for binding + /// \ru Привязать плейсмент к другим координатам. \en Bind placement to another coordinates. + void Update( const MbPlacement3D &, VERSION version, bool fuzzy_null = true ); + /// \ru Привязать плейсмент к другим координатам. \en Bind placement to another coordinates. + void Update( const MbPlacement3D &, const MbPlacement3D & ); + + /// \ru Привязать плейсмент к локальному нулю. \en Bind placement to the local zero. + void UpdateFromNull( VERSION version, bool fuzzy_null = true ) { Update( MbPlacement3D(), version, fuzzy_null ); } + +public: /** \} + \ru \name Булевские свойства. + \en \name The boolean properties. + \{ */ + + /// \ru Проверить, свойство совпадения с мировой СК (т.е. прямая матрица СК - единичная). \en Check coincidence with the global coordinate system (i.e. the direct matrix of a coordinate system is unit). + bool IsSingle() const { return (MB_IDENTITY == CheckFlag()); } + /// \ru Проверить, присутствует ли сдвиг системы координат относительно глобальной. \en Check if a coordinate system is translated relative to the global coordinate system. + bool IsTranslation() const { return !!(CheckFlag() & MB_TRANSLATION); } + /// \ru Проверить, присутствует ли поворот системы координат относительно глобальной. \en Check if the coordinate system is rotated relative to the global coordinate system. + bool IsRotation() const { return !!(CheckFlag() & MB_ROTATION); } + /// \ru Проверить, является ли СК левой. \en Check if a coordinate system is left. + bool IsLeft() const { return !!(CheckFlag() & MB_LEFT); } + ///< \ru Проверить, является ли СК правой. \en Check if a coordinate system is right. + bool IsRight() const { return !(CheckFlag() & MB_LEFT ); } + /// \ru Проверить, является ли СК ортогональной, но ненормированной. \en Check if a coordinate system is orthogonal, but not normalized. + bool IsOrt() const { return !!(CheckFlag() & MB_ORTOGONAL); } + /// \ru Выдать признак ортогональности СК. \en Get orthogonality property of coordinate system. + bool IsOrthogonal() const { CheckFlag(); return ( !(flag & MB_AFFINE) || !!(flag & MB_ORTOGONAL) ); } + /// \ru Проверить, является ли СК афинной (если нет - то она ортонормированная). \en Check if a coordinate system is affine (otherwise it is orthonormalized). + bool IsAffine() const { return !!(CheckFlag() & MB_AFFINE ); } + /// \ru Проверить, что СК ортонормированная. \en Check if coordinate system is orthonormalized. + bool IsNormal() const { return ( !IsAffine() ); } + /// \ru Проверить, что битовые флаги не установлены. \en Check whether bit flags are not set. + bool IsUnSet() const { return !!( flag & MB_UNSET ); } + /// \ru Выдать признак единичного плейсмента. \en Get attribute of the unit placement. + bool IsUnit( double eps = Math::lengthEpsilon ) const; + /// \ru Выдать признак единичного плейсмента и квадраты ортов. \en Get attribute of unit placement and squares of orts. + bool IsUnit( double & sqX, double & sqY, double & sqZ, double eps = Math::lengthEpsilon ) const; + /// \ru Проверить, являются ли оси СК совпадающими со стандартной (правой ортонормированной СК). \en Check if the axes of a coordinate system are coincident to the standard one (right orthonormalized coordinate system). + bool IsTranslationStandard() const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsCircular () const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y (круг остается кругом). \en Check if a coordinate system is orthogonal with axes X and Y of equal length (circle moves to circle). + bool IsCircular ( double & lxy ) const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y,Z. \en Check if a coordinate system is orthogonal with axes X and Y of equal length. + bool IsIsotropic() const; + /// \ru Проверить, является ли СК ортогональной с равными по длине осями X,Y,Z. \en Check if a coordinate system is orthogonal with axes X and Y of equal length. + bool IsIsotropic( double & l ) const; + +public: /** \} + \ru \name Функции доступа к полям. + \en \name Functions for access to fields. + \{ */ + + /// \ru Получить начало СК. \en Get the origin of a coordinate system. + const MbCartPoint3D & GetOrigin() const { return origin; } + /// \ru Получить ось Z. \en Get the Z-axis. + const MbVector3D & GetAxisZ () const { return axisZ; } + /// \ru Получить ось X. \en Get the X-axis. + const MbVector3D & GetAxisX () const { return axisX; } + /// \ru Получить ось Y. \en Get the Y-axis. + const MbVector3D & GetAxisY () const { return axisY; } + /// \ru Дать начало ЛСК. \en Get the origin of a local coordinate system. + MbCartPoint3D & SetOrigin() { flag = MB_UNSET; return origin; } + /// \ru Дать ось Z. \en Get the Z-axis. + MbVector3D & SetAxisZ () { flag = MB_UNSET; return axisZ; } + /// \ru Дать ось X. \en Get the X-axis. + MbVector3D & SetAxisX () { flag = MB_UNSET; return axisX; } + /// \ru Дать ось Y. \en Get the Y-axis. + MbVector3D & SetAxisY () { flag = MB_UNSET; return axisY; } + /// \ru Задать начало ЛСК. \en Set the origin of a local coordinate system. + void SetOrigin( const MbCartPoint3D & o ) { origin = o; CheckOrigin(); } + /// \ru Задать ось Z. \en Set the Z-axis. + void SetAxisZ ( const MbVector3D & a ) { flag = MB_UNSET; axisZ = a; } + /// \ru Задать ось X. \en Set the X-axis. + void SetAxisX ( const MbVector3D & a ) { flag = MB_UNSET; axisX = a; } + /// \ru Задать ось Y. \en Set the Y-axis. + void SetAxisY ( const MbVector3D & a ) { flag = MB_UNSET; axisY = a; } + /// \ru Инвертировать ось Z. \en Invert the Z-axis. + void AxisZInvert() { flag ^= MB_LEFT; axisZ.Invert(); CheckRotation(); } + /// \ru Инвертировать ось X. \en Invert the X-axis. + void AxisXInvert() { flag ^= MB_LEFT; axisX.Invert(); CheckRotation(); } + /// \ru Инвертировать ось Y. \en Invert the Y-axis. + void AxisYInvert() { flag ^= MB_LEFT; axisY.Invert(); CheckRotation(); } + /// \ru Установить флаг состояния. \en Set the flag of state. + void SetFlag( bool bLeft, bool bAffine = false, bool bOrt = true ) const; + ///< \ru Установить СК как правую. \en Set the coordinate system as right. + void SetRight(); + +public: /** \} + \ru \name Общие функции математического объекта. + \en \name The common functions of the mathematical object. + \{ */ + + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + MbPlacement3D & Transform( const MbMatrix3D & ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + MbPlacement3D & Move( const MbVector3D & ); + /// \ru Повернуть вокруг оси на заданный угол. \en Rotate at a given angle around an axis. + MbPlacement3D & Rotate( const MbAxis3D & axis, double angle ); + /// \ru Масштабировать. \en Scale. + MbPlacement3D & Scale( double sx, double sy, double sz ); + /// \ru Масштабировать. \en Scale. + MbPlacement3D & Scale( double s ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbPlacement3D & other, double accuracy ) const; + + /// \ru Дать матрицу преобразования в ЛСК: r=R*into (обратная матрица). \en Get the matrix of transformation to the local coordinate system: r=R*into (inverse matrix). + void GetMatrixInto( MbMatrix3D & ) const; + /// \ru Дать матрицу преобразования в ЛСК: r=R*into (обратная матрица). \en Get the matrix of transformation to the local coordinate system: r=R*into (inverse matrix). + MbMatrix3D GetMatrixInto() const; + /// \ru Дать матрицу преобразования из ЛСК: R=r*from (прямая матрица). \en Get the matrix of transformation from the local coordinate system: R=r*from (direct matrix). + void GetMatrixFrom( MbMatrix3D & ) const; + /// \ru Дать матрицу преобразования из ЛСК: R=r*from (прямая матрица). \en Get the matrix of transformation from the local coordinate system: R=r*from (direct matrix). + MbMatrix3D GetMatrixFrom() const; + /// \ru Дать матрицу симметрии относительно плоскости XY. \en Get the matrix of symmetry with respect to the XY-plane. + void Symmetry ( MbMatrix3D & ) const; + + /// \ru Дать матрицу преобразования в place. \en Get the matrix of transformation to place. + bool GetMatrixToPlace( const MbPlacement3D & p, MbMatrix & matr, double eps = Math::angleRegion ) const; + /// \ru Дать матрицу преобразования в place. \en Get the matrix of transformation to place. + void GetMatrixToPlace( const MbPlacement3D & p, MbMatrix3D & matr ) const; + + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + double DistanceToPoint ( const MbCartPoint3D & to ) const; + /// \ru Найти проекцию точки на плоскость XY. \en Find point projection to XY-plane. + void PointProjection ( const MbCartPoint3D & p, MbCartPoint3D & pOn ) const; + /// \ru Найти вектор проекции на плоскость XY. \en Find the vector of projection to XY-plane. + void VectorProjection( const MbVector3D & v, double & x, double & y ) const; + /// \ru Найти проекцию точки на плоскость XY. \en Find the point projection to XY-plane. + void PointProjection ( const MbCartPoint3D & p, double & x, double & y ) const; + /// \ru Найти проекцию точки на плоскость XY вдоль вектора в любом из двух направлений. \en Find the point projection to XY-plane along a vector in either of two directions. + bool DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & v, double & x, double & y ) const; + /// \ru Найти проекцию точки на плоскость XY в направлении вектора. \en Find the point projection to XY-plane in direction of the vector. + bool NearDirectPointProjection( const MbCartPoint3D & p, const MbVector3D & v, double & x, double & y, bool onlyPositiveDirection ) const; + /// \ru Дать координаты точки на плоскости XY. \en Get the projection of a point on XY-plane. + void PointOn ( double x, double y, MbCartPoint3D & p ) const { p.Set( origin, axisX, x, axisY, y ); } + /// \ru Дать пространственную точку по точке на плоскости XY. \en Get the space point by a point on XY-plane. + void PointOn ( const MbCartPoint & r, MbCartPoint3D & p ) const { p.Set( origin, axisX, r.x, axisY, r.y ); } + /// \ru Дать пространственный вектор по вектору на плоскости XY. \en Get the space vector by a vector on XY-plane. + void VectorOn( const MbVector & r, MbVector3D & p ) const { p.Set( axisX, r.x, axisY, r.y ); } + /// \ru Дать пространственный вектор по вектору на плоскости XY. \en Get the space vector by a vector on XY-plane. + void VectorOn( const MbDirection & r, MbVector3D & p ) const { p.Set( axisX, r.ax, axisY, r.ay ); } + + /// \ru Дать нормаль плоскости XY локальной системы координат, направление оси Z при этом не учитывается. \en Get the normal of the plane XY of a local coordinate system, the Z axis is not taken into account here. + void Normal( MbVector3D & n ) const; + /// \ru Дать нормаль плоскости XY локальной системы координат, направление оси Z при этом не учитывается. \en Get the normal of the plane XY of a local coordinate system, the Z axis is not taken into account here. + MbVector3D Normal() const; + + // \ru C какой стороны от плоскости находится точка. \en Point location relative to the plane. + // \ru iloc_OnItem = 0 - на плоскости \en Iloc_OnItem = 0 - on plane + // \ru iloc_InItem = 1 - над плоскостью \en Iloc_InItem = 1 - above plane + // \ru iloc_OutOfItem = -1 - под плоскостью \en Iloc_OutOfItem = -1 - below plane + /// \ru Определить, с какой стороны от плоскости находится точка. \en Get point location relative to the plane. + MbeItemLocation PointRelative( const MbCartPoint3D & pnt, double eps = ANGLE_REGION ) const; + // \ru C какой стороны от плоскости находится габарит. \en Bounding box location relative to the plane. + // \ru iloc_OnItem = 0 - на плоскости \en Iloc_OnItem = 0 - on plane + // \ru iloc_InItem = 1 - над плоскостью \en Iloc_InItem = 1 - above plane + // \ru iloc_OutOfItem = -1 - под плоскостью \en Iloc_OutOfItem = -1 - below plane + /// \ru Определить, с какой стороны от плоскости находится габарит. \en Get bounding box location relative to the plane. + MbeItemLocation CubeRelative( const MbCube & cube, double eps = ANGLE_REGION ) const; + + // \ru Проверки расположения. \en Location checks. + /// \ru Проверить коллинеарность. \en Check collinearity + bool Colinear ( const MbPlacement3D & with, double eps = Math::angleRegion ) const; + /// \ru Проверить коллинеарность нормалей. \en Check collinearity of normals. + bool NormalColinear( const MbPlacement3D & with, double eps = Math::angleRegion ) const; + /// \ru Проверить компланарность. \en Check complanarity. + bool Complanar ( const MbPlacement3D & with, double eps = Math::angleRegion ) const; + /// \ru Проверить ортогональность. \en Check orthogonality. + bool Orthogonal ( const MbAxis3D &, double & x, double & y, double eps = Math::angleRegion ) const; + + /// \ru Совместить с place путем вращения до параллельности и перемещения вдоль нормали place. \en Match with the place by rotation till the parallelism and translation along place normal. + void AdaptToPlace ( const MbPlacement3D & ); + /// \ru Угол с осью Z. \en Angle to Z-axis. + double Angle( const MbVector3D & v ) const { return v.Angle(axisZ); } + /// \ru Угол между осями Z плейсментов. \en Angle between Z-axes of the placements. + double Angle( const MbPlacement3D & ) const; + /// \ru Дать синус угла вектора с плоскостью. \en Get the sine of angle between a vector and the plane. + double GetNormalAngle( const MbVector3D & ) const; + + /// \ru Пересчитать СК по измененным внутренним данным. \en Recalculate the coordinate system for changed internal data. + void Reset (); + /// \ru Инвертировать. \en Invert. + void Invert( MbMatrix * = NULL ); + + /// \ru Найти ближайшую точку пересечения с линией. \en Find the nearest point of intersection with line. + bool LineIntersectionPoint( const MbCartPoint3D & pc, const MbVector3D & axis, MbCartPoint3D & p, double & d ) const; + /// \ru Получить точку и направление линии пересечения плоскостей. \en Get the point and direction of planes intersection line. + bool PlanesIntersection ( const MbPlacement3D & place, MbCartPoint3D & p, MbVector3D & axis ) const; + /// \ru Преобразовать 2D-точки в другую 2D-точку. \en Transform 2D-point to another 2D-point. + void TransformPoint ( const MbMatrix3D &, MbCartPoint & ) const; + + /// \ru Дать минимально различимую величину параметра U. \en Give the minimum distinguishable value of U parameter. + double GetXEpsilon() const; + ///< \ru Дать минимально различимую величину параметра V. \en Get the minimum distinguishable value of V parameter. + double GetYEpsilon() const; + /// \ru Округлить. \en Round. + bool SetRoundedValue( bool total, double eps ); + + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbPlacement3D & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbPlacement3D & ) const; + /// \ru Присвоить другую СК. \en Assign another coordinate system. + void operator = ( const MbPlacement3D & ); + /// \ru Умножить на локальную систему (как перемножение матриц): P = this * p. \en Multiply by a local coordinate system: P = this * p (as of matrix multiplication). + MbPlacement3D operator * ( const MbPlacement3D & p ) const; + + /// \ru Ортогонализовать и нормализовать оси ЛСК. \en Orthogonalize and normalize axes of a local coordinate system. + void Normalize(); + /// \ru Проверить,является ли объект смещением. \en Check if the object is a translation. + bool IsShift ( const MbPlacement3D &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + /// \ru Проверить на вырожденность. \en Check for degeneracy. + bool IsDegenerate( double lenEps = Math::metricRegion, double angEps = Math::angleRegion ) const; + +public: /** \} + \ru \name Функции для перевода точек и векторов + \en \name Functions for points and vectors transformation + \{ */ + /// \ru Дать точку в глобальной СК по локальным координатам. \en Get the point in the global coordinate system by local coordinates. + void GetPointFrom ( double x0, double y0, double z0, MbCartPoint3D & p, + MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Дать вектор в глобальной СК по локальным координатам. \en Get the vector in the global coordinate system by local coordinates. + void GetVectorFrom( double x1, double y1, double z1, MbVector3D & v, + MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести точку из локальной в глобальную СК. \en Transform a point from a local coordinate system to the global coordinate system. + void GetPointFrom ( MbCartPoint3D & p, MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести вектор из локальной в глобальную СК. \en Transform a vector from a local coordinate system to the global coordinate system. + void GetVectorFrom( MbVector3D & v, MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести точку из глобальной в локальную СК. \en Transform a point from the global coordinate system to a local coordinate system. + void GetPointInto ( MbCartPoint3D & p, MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести вектор из глобальной в локальную СК. \en Transform a vector from the global coordinate system to a local coordinate system. + void GetVectorInto( MbVector3D & v, MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести точку и первые три производные из локальной в глобальную СК. \en Transform a point and the first three derivatives from a local coordinate system to the global coordinate system. + void GetPointAndDerivesFrom( MbCartPoint3D & point, MbVector3D & firstDer, + MbVector3D & secondDer, MbVector3D & thirdDer, + MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /// \ru Перевести точку и первые три производные из глобальной в локальную СК. \en Transform a point and the first three derivatives from the global coordinate system to a local coordinate system. + void GetPointAndDerivesInto( MbCartPoint3D & point, MbVector3D & firstDer, + MbVector3D & secondDer, MbVector3D & thirdDer, + MbeLocalSystemType3D type = ls_CartesianSystem ) const; + /** \} */ + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + +private : + // \ru Выставить флаги. \en Set flags. + uint8 ResetFlag() const; + // Оценить флаги, если оценки не было + uint8 CheckFlag() const { return IsUnSet() ? ResetFlag() : flag; } + // Проверить флаг смещения. + void CheckOrigin() const { ::CheckOrigin3D( *this, flag, true ); } + // \ru Проверить флаг вращения. \en Check rotation flag. + void CheckRotation() const { ::CheckRotation3D( *this, flag, true ); } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbPlacement3D, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbPlacement3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbPlacement3D ) +}; + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbPlacement3D::MbPlacement3D() + : origin( 0.0, 0.0, 0.0 ) + , axisX ( 1.0, 0.0, 0.0 ) + , axisY ( 0.0, 1.0, 0.0 ) + , axisZ ( 0.0, 0.0, 1.0 ) + , flag ( MB_IDENTITY ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbPlacement3D::MbPlacement3D( const MbCartPoint3D & org ) + : origin( org ) + , axisX ( 1.0, 0.0, 0.0 ) + , axisY ( 0.0, 1.0, 0.0 ) + , axisZ ( 0.0, 0.0, 1.0 ) + , flag ( MB_IDENTITY ) +{ + CheckOrigin(); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbPlacement3D::MbPlacement3D( const MbVector3D & axisX, const MbVector3D & axisY, const MbCartPoint3D & org ) + : origin( 0.0, 0.0, 0.0 ) + , axisX ( 1.0, 0.0, 0.0 ) + , axisY ( 0.0, 1.0, 0.0 ) + , axisZ ( 0.0, 0.0, 1.0 ) + , flag( MB_UNSET ) +{ + InitXY( org, axisX, axisY, true/*normalize*/); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbPlacement3D::MbPlacement3D( const MbPlacement3D & place ) + : origin( 0.0, 0.0, 0.0 ) + , axisX ( 1.0, 0.0, 0.0 ) + , axisY ( 0.0, 1.0, 0.0 ) + , axisZ ( 0.0, 0.0, 1.0 ) + , flag( MB_UNSET ) +{ + Init( place ); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbPlacement3D::MbPlacement3D( const MbMatrix3D & matr ) + : origin( 0.0, 0.0, 0.0 ) + , axisX ( 1.0, 0.0, 0.0 ) + , axisY ( 0.0, 1.0, 0.0 ) + , axisZ ( 0.0, 0.0, 1.0 ) + , flag( MB_UNSET ) +{ + Init( matr ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация единичной матрицы (мировая СК). \en Initialize. +// --- +inline MbPlacement3D & MbPlacement3D::Init() +{ + origin.SetZero(); + axisX.Init( 1.0, 0.0, 0.0 ); + axisY.Init( 0.0, 1.0, 0.0 ); + axisZ.Init( 0.0, 0.0, 1.0 ); + flag = MB_IDENTITY; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по плейсменту. \en Initialize by placement. +// --- +inline MbPlacement3D & MbPlacement3D::Init( const MbPlacement3D & place ) +{ + origin = place.origin; + axisZ = place.axisZ; + axisX = place.axisX; + axisY = place.axisY; + flag = place.flag; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по плейсменту и расстоянию. \en Initialize by placement and distance. +// --- +inline MbPlacement3D & MbPlacement3D::Init( const MbPlacement3D & init, double distance ) +{ + Init( init ); + return Move( Normal() * distance ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по точке и плейсменту. \en Initialize by point and placement. +// --- +inline MbPlacement3D & MbPlacement3D::Init( const MbCartPoint3D & p, const MbPlacement3D & init ) +{ + return Init( p, init.axisZ, init.axisX ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по точке. \en Initialize by point. +// --- +inline MbPlacement3D & MbPlacement3D::Init( const MbCartPoint3D & p ) +{ + return Init( p, axisZ, axisX ); +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг по вектору. \en Move by vector. +// --- +inline MbPlacement3D & MbPlacement3D::Move( const MbVector3D & to ) +{ + origin.Move( to ); + CheckOrigin(); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Трансформация по матрице. \en Transform by matrix. +// --- +inline MbPlacement3D & MbPlacement3D::Transform( const MbMatrix3D & matr ) +{ + origin.Transform( matr ); + + if ( matr.IsRotation() ) { + axisZ.Transform( matr ); + axisX.Transform( matr ); + axisY.Transform( matr ); + flag = MB_UNSET; + } + ResetFlag(); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Расстояние до точки. \en Get distance to point. +// --- +inline double MbPlacement3D::DistanceToPoint( const MbCartPoint3D & to ) const +{ + MbCartPoint3D pOn; + PointProjection( to, pOn ); + return pOn.DistanceToPoint( to ); +} + + +//------------------------------------------------------------------------------ +// \ru Спроецировать точку на плоскость XY. \en Get point projection onto XY-plane. +// --- +inline void MbPlacement3D::PointProjection( const MbCartPoint3D & p, MbCartPoint3D & pOn ) const +{ + double x, y; + PointProjection( p, x, y ); + PointOn( x, y, pOn ); +} + + +//------------------------------------------------------------------------------ +// \ru Спроецировать точку на плоскость XY. \en Get point projection onto XY-plane. +// --- +inline void MbPlacement3D::PointProjection( const MbCartPoint3D & p, double & x, double & y ) const +{ + MbVector3D vect( origin, p ); + VectorProjection( vect, x, y ); +} + + +//------------------------------------------------------------------------------ +// \ru Дать матрицу для преобразования симметрии относительно плоскости. \en Get symmetry matrix relative to XY-plane. +// --- +inline void MbPlacement3D::Symmetry( MbMatrix3D & sym ) const { + sym.Symmetry( origin, axisX, axisY ); +} + + +//------------------------------------------------------------------------------ +// \ru Дать матрицу преобразования в place. \en Get transformation matrix from this to place. +// --- +inline void MbPlacement3D::GetMatrixToPlace( const MbPlacement3D & place, MbMatrix3D & matr ) const { + matr = ( GetMatrixFrom() * place.GetMatrixInto() ); +} + + +//------------------------------------------------------------------------------- +// \ru Сделать с.к. правой \en Make the coordinate system right +// --- +inline void MbPlacement3D::SetRight() +{ + if ( IsLeft() ) { + axisZ.Invert(); + flag &= ~MB_LEFT; + } +} + + +//------------------------------------------------------------------------------ +// \ru Являются ли оси с.к. совпадающими со стандартной (правой ортонормированной с.к.) \en Check if the axes of a coordinate system are coincident to a standard one (right orthonormalized coordinate system) +// --- +inline bool MbPlacement3D::IsTranslationStandard() const +{ + if ( !IsNormal() && IsRight() ) { + const double eps = ANGLE_EPSILON; + if ( axisX.Colinear( MbVector3D::xAxis, eps ) && axisY.Colinear( MbVector3D::yAxis, eps ) && axisZ.Colinear( MbVector3D::zAxis, eps ) ) + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Является ли с.к. ортогональной с равными по длине осями X,Y (круг остается кругом) \en Whether a coordinate system is orthogonal with the axes X and Y of equal length (circle moves to circle) +// --- +inline bool MbPlacement3D::IsCircular() const +{ + if ( IsNormal() ) + return true; + else { + bool isOrthogonal = IsOrthogonal(); + + if ( !isOrthogonal ) { // BUG_55499 + if ( axisX.Orthogonal( axisY, EXTENT_EPSILON ) ) + isOrthogonal = true; + } + if ( isOrthogonal ) { + if ( c3d::EqualLengths( axisX.Length(), axisY.Length() ) ) + return true; + } + } + + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Является ли с.к. ортогональной с равными по длине осями X,Y (круг остается кругом) \en Whether a coordinate system is orthogonal with the axes X and Y of equal length (circle moves to circle) +// --- +inline bool MbPlacement3D::IsCircular( double & lxy ) const +{ + lxy = 1.0; + + if ( IsNormal() ) + return true; + else { + bool isOrthogonal = IsOrthogonal(); + + if ( !isOrthogonal ) { // BUG_55499 + if ( axisX.Orthogonal( axisY, EXTENT_EPSILON ) ) + isOrthogonal = true; + } + if ( isOrthogonal ) { + double lx = axisX.Length(); + double ly = axisY.Length(); + if ( c3d::EqualLengths( lx, ly ) ) { + lxy = 0.5 * (lx + ly); + return true; + } + } + } + + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Является ли с.к. ортогональной и изотропной по осям \en Whether a coordinate system is orthogonal and isotropic by axes +// --- +inline bool MbPlacement3D::IsIsotropic() const +{ + if ( IsNormal() ) + return true; + else if ( IsOrthogonal() ) { + double lx = axisX.Length(); + double ly = axisY.Length(); + if ( c3d::EqualLengths( lx, ly ) ) { + double lz = axisZ.Length(); + if ( c3d::EqualLengths( lz, lx ) && c3d::EqualLengths( lz, ly ) ) + return true; + } + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Является ли с.к. ортогональной и изотропной по осям \en If coordinate system is orthogonal and isotropic by axes +// --- +inline bool MbPlacement3D::IsIsotropic( double & l ) const +{ + l = 1.0; + + if ( IsNormal() ) + return true; + else if ( IsOrthogonal() ) { + double lx = axisX.Length(); + double ly = axisY.Length(); + if ( c3d::EqualLengths( lx, ly ) ) { + double lz = axisZ.Length(); + if ( c3d::EqualLengths( lz, lx ) && c3d::EqualLengths( lz, ly ) ) { + l = (lx + ly + lz) * c3d::ONE_THIRD; + if ( ::fabs(l - 1.0) < EPSILON ) + l = 1.0; + return true; + } + } + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Дать нормаль \en Give the normal +// --- +inline void MbPlacement3D::Normal( MbVector3D & n ) const +{ + // This disabled code is faster, but it breaks some models that have not good fillets. Difference is in 1e-16. + //if ( IsNormal() ) { + // n.Init( axisZ ); + // if ( IsLeft() ) + // n.Invert(); + //} + //else + if ( IsOrt() ) { + n.Init( axisZ ); + if ( IsLeft() ) + n.Invert(); + if ( IsAffine() ) + n.Normalize(); + } + else { + ::SetVecM( n, axisX, axisY ); + n.Normalize(); + } +} + + +//------------------------------------------------------------------------------ +// \ru Дать нормаль \en Give the normal +// --- +inline MbVector3D MbPlacement3D::Normal() const +{ + MbVector3D n; + Normal( n ); + return n; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbPlacement3D::operator == ( const MbPlacement3D & with ) const +{ + return ( ( origin == with.origin ) && + ( axisZ == with.axisZ ) && + ( axisY == with.axisY ) && + ( axisX == with.axisX ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbPlacement3D::operator != ( const MbPlacement3D & with ) const { + return !( *this == with ); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор присвоения \en Assignment operator +// --- +inline void MbPlacement3D::operator = ( const MbPlacement3D & pl ) +{ + origin = pl.origin; + axisZ = pl.axisZ; + axisY = pl.axisY; + axisX = pl.axisX; + flag = pl.flag; +} + + +//------------------------------------------------------------------------------ +// \ru Преобразование 2D-точки в другую 2D-точку \en Transformation of 2D-point to another 2D-point +// --- +inline void MbPlacement3D::TransformPoint( const MbMatrix3D & matr, MbCartPoint & p2d ) const +{ + MbCartPoint3D p3d( origin ); + p3d.Add( axisX, p2d.x, axisY, p2d.y ); + p3d.Transform( matr ); + p2d.Init( p3d.x, p3d.y ); +} + + +//------------------------------------------------------------------------------- +// \ru Является ли объект смещением данного \en Check if the object is a shift of the current one +// --- +inline bool MbPlacement3D::IsShift( const MbPlacement3D & other, MbVector3D & vect, bool & isSame, double accuracy ) const +{ + if ( axisZ.IsSame(other.axisZ, accuracy) && + axisY.IsSame(other.axisY, accuracy) && + axisX.IsSame(other.axisX, accuracy) ) { + vect.Init( origin, other.origin ); + isSame = ( vect.MaxFactor() < accuracy ); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из декартовой системы в цилиндрическую + \en Function for transforming coordinates from the Cartesian coordinate system to a cylindrical coordinate system \~ + \details \ru Функция перевода координат из декартовой системы в цилиндрическую + \en Function for transforming coordinates from Cartesian coordinate system to a cylindrical coordinate system \~ + \param[in, out] x, y, z - \ru Исходный координаты. + \en Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) CartesianToCylindrical( double & x, double & y, double & z ); + + +//------------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из цилиндрической системы в декартову + \en Function for transforming coordinates from a cylindrical coordinate system to a Cartesian coordinate system \~ + \details \ru Функция перевода координат из цилиндрической системы в декартову + \en Function for transforming coordinates from a cylindrical coordinate system to a Cartesian coordinate system \~ + \param[in, out] \ru x, y, z - Исходный координаты. + out] \en x, y, z - Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) CylindricalToCartesian( double & x, double & y, double & z ); + + +//------------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из цилиндрической системы в сферическую + \en Function for transforming coordinates from a cylindrical coordinate system to a spherical coordinate system \~ + \details \ru Функция перевода координат из цилиндрической системы в сферическую + \en Function for transforming coordinates from a cylindrical coordinate system to a spherical coordinate system \~ + \param[in, out] \ru x, y, z - Исходный координаты. + out] \en x, y, z - Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) CylindricalToSpherical( double & x, double & y, double & z ); + + +//------------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из декартовой системы в сферическую + \en Function for transforming coordinates from a Cartesian coordinate system to a spherical coordinate system \~ + \details \ru Функция перевода координат из декартовой системы в сферическую + \en Function for transforming coordinates from a Cartesian coordinate system to a spherical coordinate system \~ + \param[in, out] \ru x, y, z - Исходный координаты. + out] \en x, y, z - Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) CartesianToSpherical ( double & x, double & y, double & z ); + + +//------------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из сферической системы в декартову + \en Function for transforming coordinates from a spherical coordinate system to a Cartesian coordinate system \~ + \details \ru Функция перевода координат из сферической системы в декартову + \en Function for transforming coordinates from a spherical coordinate system to a Cartesian coordinate system \~ + \param[in, out] \ru x, y, z - Исходный координаты. + out] \en x, y, z - Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) SphericalToCartesian ( double & x, double & y, double & z ); + + +//------------------------------------------------------------------------------------- +/** \brief \ru Функция перевода координат из сферической системы в цилиндрическую + \en Function for transforming coordinates from a spherical coordinate system to a cylindrical coordinate system \~ + \details \ru Функция перевода координат из сферической системы в цилиндрическую + \en Function for transforming coordinates from a spherical coordinate system to a cylindrical coordinate system \~ + \param[in, out] \ru x, y, z - Исходный координаты. + out] \en x, y, z - Source coordinates. \~ + \ingroup Mathematic_Base_3D +*/ +//--- +MATH_FUNC (void) SphericalToCylindrical( double & x, double & y, double & z ); + + +#endif // __MB_PLACEMENT3D_H diff --git a/C3d/Include/mb_point_mating.h b/C3d/Include/mb_point_mating.h new file mode 100644 index 0000000..e5181cb --- /dev/null +++ b/C3d/Include/mb_point_mating.h @@ -0,0 +1,719 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Модуль геометрических построений. Сопряжение в точке + \en Geometric constructions module. Conjugation at point. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_POINT_MATING_H +#define __MB_POINT_MATING_H + + +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/// \ru Параметры сопряжения в точке \en Parameters of conjugation at point +//--- +template +class MbPntMatingData { +private: // \ru данные \en data +//OV_x64 The structure's size can be decreased via changing the fields' order. The size can be reduced from 56 to 40 bytes. +//OV_x64 MbeMatingType type; ///< \ru тип сопряжения \en conjugation type +//OV_x64 Vector * tangent; ///< \ru направляющий касательный вектор \en guide tangent vector +//OV_x64 Vector * tangentDer1; ///< \ru первая производная касательного вектора \en first derivative of tangent vector +//OV_x64 Vector * tangentDer2; ///< \ru вторая производная касательного вектора \en second derivative of tangent vector +//OV_x64 bool movePnts; ///< \ru двигать исходные точки или добавлять \en move or add source points +//OV_x64 SArray * changedPnts; ///< \ru индексы измененных точек \en indices of changed points +//OV_x64 bool attach; ///< \ru данные служат для стыковки сплайна с кривой \en data for spline and curve connection + + Vector * tangent; ///< \ru Направляющий касательный вектор. \en Guide tangent vector. + Vector * tangentDer1; ///< \ru Первая производная касательного вектора. \en First derivative of tangent vector. + Vector * tangentDer2; ///< \ru Вторая производная касательного вектора. \en Second derivative of tangent vector. + SArray * changedPnts; ///< \ru Индексы измененных точек. \en Indices of changed points. + MbeMatingType type; ///< \ru Тип сопряжения. \en Conjugation type. + bool movePnts; ///< \ru Двигать исходные точки или добавлять. \en Move or add source points. + bool attach; ///< \ru Данные служат для стыковки сплайна с кривой. \en Data for a spline and a curve connection. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPntMatingData(); + /// \ru Конструктор по всем параметрам сопряжения в точке. \en Constructor by all parameters of conjugation at point. + MbPntMatingData( const MbeMatingType type, const Vector * tang, + const Vector * tangDer1, const Vector * tangDer2, + SArray *& changedPnts, + bool movePnts, bool isAttach ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPntMatingData( const MbPntMatingData & ); + /// \ru Деструктор. \en Destructor. + ~MbPntMatingData(); + +public: + /// \ru Инициализировать по всем параметрам сопряжения в точке. \en Initialize by all parameters of conjugation at point. + void Init( const MbeMatingType type, const Vector * tang, + const Vector * tangDer1, const Vector * tangDer2, + SArray *& changedPnts, + bool movePnts, bool isAttach ); + + /// \ru Инициализировать по другому объекту параметров сопряжения в точке. \en Initialize by another parameters object of conjugation at point. + bool Init( const MbPntMatingData & ); + +public: + // \ru доступ к данным \en access to data + /// \ru Дать тип сопряжения. \en Get conjugation type. + MbeMatingType GetType() const { return type; } + /// \ru Дать направляющий касательный вектор. \en Get guide tangent vector. + const Vector * GetTangent() const { return tangent; } + /// \ru Дать первую производную касательного вектора. \en Get the first derivative of tangent vector. + const Vector * GetTangentDer1() const { return tangentDer1; } + /// \ru Дать вторую производную касательного вектора. \en Get the second derivative of tangent vector. + const Vector * GetTangentDer2() const { return tangentDer2; } + /// \ru Выдать признак совпадения направлений касательных в точке сопряжения. \en Get attribute of tangent directions coincidence at conjugation point. + bool IsAttach() const { return attach; } + /// \ru Выдать признак возможности передвижения исходных точек. \en Get attribute of source points movability. + bool CanMovePoints() const { return movePnts; } + /// \ru Вернуть массив изменных точек. \en Get array of changed points. + const SArray * GetChangedPoints() const { return changedPnts; } + /// \ru Вернуть массив изменных точек. \en Get array of changed points. + SArray *& SetChangedPoints() { return changedPnts; } + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbPntMatingData &, double accuracy ) const; + /// \ru Сделать первичную проверку корректности параметров. \en Initial check of parameters correctness. + bool IsValid() const; + /// \ru Уcтановить параметры сопряжения. \en Set conjugation parameters. + void SetVector( ptrdiff_t i, const Vector & vect ); + /// \ru Нормализовать касательную в случае стыковки. \en Normalize tangent in case of connection. + void NormalizeAttachTangent(); + /// \ru Дать фактическую степень гладкости визуального перехода. \en Get the actual smoothness degree of visual transition. + ptrdiff_t GetSmoothDegree() const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + +private: // \ru не реализовано \en not implemented + void operator = ( const MbPntMatingData & ); +}; + + +//------------------------------------------------------------------------------ +// \ru конструктор \en constructor +//--- +template +MbPntMatingData::MbPntMatingData() + : tangent ( NULL ) + , tangentDer1 ( NULL ) + , tangentDer2 ( NULL ) + , changedPnts ( NULL ) + , type ( trt_Position ) + , movePnts ( false ) + , attach ( false ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru конструктор \en constructor +//--- +template +MbPntMatingData::MbPntMatingData( const MbeMatingType nType, + const Vector * nTang, + const Vector * nTangDer1, + const Vector * nTangDer2, + SArray *& nChangedPnts, + bool nMovePnts, + bool nAttach ) + : type ( nType ) + , tangent ( (nTang != NULL) ? new Vector( *nTang ) : NULL ) + , tangentDer1 ( (nTangDer1 != NULL) ? new Vector( *nTangDer1 ) : NULL ) + , tangentDer2 ( (nTangDer2 != NULL) ? new Vector( *nTangDer2 ) : NULL ) + , movePnts ( nMovePnts ) + , changedPnts ( nChangedPnts ) + , attach ( nAttach ) +{ + if ( type <= trt_Position ) { // BUG_52162 + ::DeleteMatItem( tangent ); + ::DeleteMatItem( tangentDer1 ); + ::DeleteMatItem( tangentDer2 ); + } +} + + +//------------------------------------------------------------------------------ +// \ru конструктор копирования \en copy constructor +//--- +template +MbPntMatingData::MbPntMatingData( const MbPntMatingData & d ) + : type ( d.type ) + , tangent ( (d.tangent != NULL) ? new Vector( *d.tangent ) : NULL ) + , tangentDer1 ( (d.tangentDer1 != NULL) ? new Vector( *d.tangentDer1 ) : NULL ) + , tangentDer2 ( (d.tangentDer2 != NULL) ? new Vector( *d.tangentDer2 ) : NULL ) + , movePnts ( d.movePnts ) + , changedPnts ( d.changedPnts ) + , attach ( d.attach ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru деструктор \en destructor +//--- +template +MbPntMatingData ::~MbPntMatingData() +{ + ::DeleteMatItem( tangent ); + ::DeleteMatItem( tangentDer1 ); + ::DeleteMatItem( tangentDer2 ); +} + + +//------------------------------------------------------------------------------ +// \ru инициализация данных \en data initialization +//--- +template +void MbPntMatingData::Init( const MbeMatingType nType, + const Vector * nTang, + const Vector * nTangDer1, + const Vector * nTangDer2, + SArray *& nChangedPnts, + bool nMovePnts, + bool nAttach ) +{ + type = nType; + + if ( tangent != NULL && nTang != NULL ) // \ru касательный вектор \en tangent vector + tangent->Init( *nTang ); + else if ( nTang != NULL ) + tangent = new Vector( *nTang ); + else if ( tangent != NULL ) + ::DeleteMatItem( tangent ); + + if ( tangentDer1 != NULL && nTangDer1 != NULL ) // \ru первая производная касательного вектора \en first derivative of tangent vector + tangentDer1->Init( *nTangDer1 ); + else if ( nTangDer1 != NULL ) + tangentDer1 = new Vector( *nTangDer1 ); + else if ( tangentDer1 != NULL ) + ::DeleteMatItem( tangentDer1 ); + + if ( tangentDer2 != NULL && nTangDer2 != NULL ) // \ru вторая производная касательного вектора \en second derivative of tangent vector + tangentDer2->Init( *nTangDer2 ); + else if ( nTangDer2 != NULL ) + tangentDer2 = new Vector( *nTangDer2 ); + else if ( tangentDer2 != NULL ) + ::DeleteMatItem( tangentDer2 ); + + if ( type <= trt_Position ) { // BUG_52162 + ::DeleteMatItem( tangent ); + ::DeleteMatItem( tangentDer1 ); + ::DeleteMatItem( tangentDer2 ); + } + + if ( changedPnts != NULL ) + changedPnts->Flush(); + + movePnts = nMovePnts; + changedPnts = nChangedPnts; + attach = nAttach; +} + + +//------------------------------------------------------------------------------ +// \ru инициализация данных \en data initialization +//--- +template +bool MbPntMatingData::Init( const MbPntMatingData & d ) +{ + C3D_ASSERT( changedPnts == NULL ); + + if ( this != &d ) { + SArray * dummyInds = NULL; + Init( d.type, d.tangent, d.tangentDer1, d.tangentDer2, dummyInds, d.movePnts, d.attach ); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Являются ли объекты равными? \en Determine whether an object is equal? +//--- +template +bool MbPntMatingData::IsSame( const MbPntMatingData & other, double accuracy ) const +{ + bool isSame = false; + + if ( c3d::EqualVectors( *tangent, *other.tangent, accuracy ) && + c3d::EqualVectors( *tangentDer1, *other.tangentDer1, accuracy ) && + c3d::EqualVectors( *tangentDer2, *other.tangentDer2, accuracy ) && + *changedPnts == *other.changedPnts && + type == other.type && + movePnts == other.movePnts && + attach == other.attach ) + isSame = true; + + return isSame; +} + + +//------------------------------------------------------------------------------ +// \ru первичная проверка корректности параметров \en initial check of parameters correctness +//--- +template +bool MbPntMatingData::IsValid() const +{ + bool isValid = true; + + if ( type >= trt_Position ) { + double lenEps = LENGTH_EPSILON; + bool isTang = (tangent != NULL); + bool isTangDer1 = (tangentDer1 != NULL); + bool isTangDer2 = (tangentDer2 != NULL); + bool isTangLen = (isTang && tangent->Length() > lenEps); + + switch( type ) { + case trt_Tangent: + isValid = isTangLen; + break; + case trt_Normal: + // \ru под нормалью понимается как касательное сопряжение с тем, что названо нормалью, \en normal is considered to be either a tangent conjugation with what is called normal + // \ru так и управление только главной нормалью \en or only principal normal management + isValid = !attach && (isTangLen || (isTangDer1 && tangentDer1->Length() > lenEps)); + break; + case trt_SmoothG2 : + isValid = isTangLen && (isTangDer1 && tangent->Orthogonal( *tangentDer1 )); + break; + case trt_SmoothG3: + isValid = isTangLen && (isTangDer1 && tangent->Orthogonal( *tangentDer1 )) && isTangDer2; + break; + default: break; + } + } + + return isValid; +} + + +//------------------------------------------------------------------------------ +// \ru фактическая степень гладкости визуального перехода \en actual smoothness degree of visual transition +//--- +template +ptrdiff_t MbPntMatingData::GetSmoothDegree() const +{ + ptrdiff_t res = 0; + switch ( type ) { + case trt_Tangent : + res = 1; + break; + case trt_Normal : + if ( tangentDer1 != NULL ) res = 2; + else if ( tangent != NULL ) res = 1; + break; + case trt_SmoothG2: + res = 2; + break; + case trt_SmoothG3: + res = 3; + break; + default: break; + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru уcтановка параметров сопряжения \en set conjugation parameters +//--- +template +void MbPntMatingData::SetVector( ptrdiff_t i, const Vector & vect ) +{ + switch ( i ) { + case 0 : { + if ( tangent != NULL ) tangent->Init( vect ); + else tangent = new Vector( vect ); + break; + } + case 1 : { + if ( tangentDer1 != NULL ) tangentDer1->Init( vect ); + else tangentDer1 = new Vector( vect ); + break; + } + case 2 : { + if ( tangentDer2 != NULL ) tangentDer2->Init( vect ); + else tangentDer2 = new Vector( vect ); + break; + } + } +} + + +//------------------------------------------------------------------------------ +// \ru нормализовать касательную в случае стыковки \en normalize tangent in case of connection +//--- +template +void MbPntMatingData::NormalizeAttachTangent() +{ + if ( attach && tangent != NULL ) { + double tangLen = tangent->Length(); + if ( tangLen > LENGTH_EPSILON ) + (*tangent) /= tangLen; + } +} + + +//------------------------------------------------------------------------------ +// \ru выдать свойства объекта \en get properties of object +// --- +template +void MbPntMatingData::GetProperties( MbProperties & properties ) +{ +/* + properties.SetName( IDS_PROP_0900 ); + + TCHAR * typeName = new TCHAR[256]; + + switch ( type ) { + case trt_None : _sntprintf( typeName, IDS_PROP_0902 ); break; + case trt_Position : _sntprintf( typeName, IDS_PROP_0903 ); break; + case trt_Tangent : _sntprintf( typeName, IDS_PROP_0904 ); break; + case trt_Normal : _sntprintf( typeName, IDS_PROP_0905 ); break; + case trt_SmoothG2 : _sntprintf( typeName, IDS_PROP_0906 ); break; + case trt_SmoothG3 : _sntprintf( typeName, IDS_PROP_0907 ); break; + default : _sntprintf( typeName, IDS_ITEM_0902 ); break; + } + + properties.Add( new StringProperty( IDS_PROP_0901, typeName, false ) ); +*/ + if ( tangent != NULL ) + properties.Add( new MathItemProperty( IDS_PROP_0908, tangent, true ) ); + if ( tangentDer1 != NULL ) + properties.Add( new MathItemProperty( IDS_PROP_0909, tangentDer1, true ) ); + if ( tangentDer2 != NULL ) + properties.Add( new MathItemProperty( IDS_PROP_0910, tangentDer2, true ) ); + + properties.Add( new BoolProperty( IDS_PROP_0911, movePnts, false ) ); + properties.Add( new BoolProperty( IDS_PROP_0912, attach, false ) ); +} + + +//------------------------------------------------------------------------------ +// \ru выдать свойства объекта \en get properties of object +// --- +template +void MbPntMatingData::SetProperties( const MbProperties & /*properties*/ ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru определено ли сопряжение \en whether conjugation is defined +//--- +template +bool IsMatingDefined( const MbPntMatingData * data ) +{ + bool isDefined = false; + + if ( data != NULL && data->IsValid() ) { + if ( data->GetType() > trt_Position ) // \ru по позиции и так выполнится, поэтому считаем не заданным \en would be held at position, so assumed as undefined + isDefined = true; + } + + return isDefined; +} + + +//------------------------------------------------------------------------------ +// \ru определены ли сопряжение \en whether conjugation is defined +//--- +template +bool IsAnyMatingDefined( const RPArray< MbPntMatingData > & data ) +{ + bool isDefined = false; + + if ( data.Count() > 0 ) { + for ( size_t k = 0, cnt = data.Count(); k < cnt; k++ ) { + if ( ::IsMatingDefined( data[k] ) ) { + isDefined = true; + break; + } + } + } + + return isDefined; +} + + +//------------------------------------------------------------------------------ +// \ru копировать сопряжения \en copy conjugations +//--- +template +bool CopyMating( const RPArray< MbPntMatingData > & src, RPArray< MbPntMatingData > & dst ) +{ + bool isDone = false; + + if ( src.Count() > 0 && dst.Count() < 1 ) { + isDone = true; + for ( size_t k = 0, cnt = src.Count(); k < cnt && isDone; k++ ) { + MbPntMatingData * copyItem = NULL; + if ( src[k] != NULL ) { + copyItem = new MbPntMatingData(); + isDone = copyItem->Init( *src[k] ); + } + dst.Add( copyItem ); + } + if ( !isDone ) + ::DeleteMatItems( dst ); + } + + return isDone; +} + + +//------------------------------------------------------------------------------ +// \ru Являются ли объекты равными? \en Determine whether an object is equal? +//--- +template +bool IsSame( const RPArray< MbPntMatingData > & data, const RPArray< MbPntMatingData > & other, double accuracy ) +{ + bool isSame = false; + + if ( data.Count() == other.Count() ) { + isSame = true; + for ( size_t k = 0, cnt = data.Count(); k < cnt; k++ ) + if ( !data[k]->IsSame( *other[k], accuracy ) ) { + isSame = false; + break; + } + } + + return isSame; +} + + +//------------------------------------------------------------------------------ +// \ru трансформировать сопряжения \en transform conjugations +//--- +template +void TransformMating( const RPArray< MbPntMatingData > & data, const Matrix & matr ) +{ + Vector vect; + for ( size_t k = 0, kcnt = data.Count(); k < kcnt; k++ ) { + MbPntMatingData * dataItem = data[k]; + + if ( dataItem != NULL ) { + if ( dataItem->GetTangent() != NULL ) { + vect = *dataItem->GetTangent(); + vect.Transform( matr ); + dataItem->SetVector( 0, vect ); + } + if ( dataItem->GetTangentDer1() != NULL ) { + vect = *dataItem->GetTangentDer1(); + vect.Transform( matr ); + dataItem->SetVector( 1, vect ); + } + if ( dataItem->GetTangentDer2() != NULL ) { + vect = *dataItem->GetTangentDer2(); + vect.Transform( matr ); + dataItem->SetVector( 2, vect ); + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru вращать сопряжения \en rotate conjugations +//--- +template +void RotateMating( const RPArray< MbPntMatingData > & data, const Axis & axis, double angle ) +{ + Vector vect; + for ( size_t i = 0; i < data.Count(); i++ ) { + MbPntMatingData * dataItem = data[i]; + + if ( dataItem->GetTangent() != NULL ){ + vect = *dataItem->GetTangent(); + vect.Rotate( axis, angle ); + dataItem->SetVector( 0, vect ); + } + if ( dataItem->GetTangentDer1() != NULL ){ + vect = *dataItem->GetTangentDer1(); + vect.Rotate( axis, angle ); + dataItem->SetVector( 1, vect ); + } + if ( dataItem->GetTangentDer2() != NULL ){ + vect = *dataItem->GetTangentDer2(); + vect.Rotate( axis, angle ); + dataItem->SetVector( 2, vect ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru запись массива данных сопряжений \en conjugation data array writing +//--- +template +void WriteMating( writer & out, const RPArray< MbPntMatingData > & data ) +{ + if ( out.good() ) { + size_t cnt = data.Count(); + WriteCOUNT( out, cnt ); + for ( size_t k = 0; k < cnt && out.good(); k++ ) { + const MbPntMatingData * item = data[k]; + // \ru наличие сопряжения \en presence of conjugation + bool isItem = (item != NULL); + out << isItem; + + if ( isItem && item->GetChangedPoints() != NULL ) { + C3D_ASSERT_UNCONDITIONAL( false ); // \ru KYA массив индексов должен быть пуст, т.к. он общий для всех сопряжений, им владеет заказчик операции \en KYA array of indices should be empy because it is shared between all of conjugations and owned by user of operation + out.setState( io::cantWriteObject ); + } + + if ( isItem && out.good() ) { + // \ru тип сопряжения \en conjugation type + uint32 type = (uint32)item->GetType(); + out << type; + // \ru касательный вектор \en tangent vector + isItem = (item->GetTangent() != NULL); + out << isItem; + if ( isItem ) + out << (*item->GetTangent()); + // \ru первая производная касательного вектора \en first derivative of tangent vector + isItem = (item->GetTangentDer1() != NULL); + out << isItem; + if ( isItem ) + out << (*item->GetTangentDer1()); + // \ru вторая производная касательного вектора \en second derivative of tangent vector + isItem = (item->GetTangentDer2() != NULL); + out << isItem; + if ( isItem ) + out << (*item->GetTangentDer2()); + + out << (bool)item->CanMovePoints(); + out << (bool)item->IsAttach(); + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива данных сопряжений \en conjugation data array reading +//--- +template +void ReadMating( reader & in, RPArray< MbPntMatingData > & data ) +{ + if ( in.good() ) { + ::DeleteMatItems( data ); + size_t cnt = ReadCOUNT( in ); + + if ( cnt > 0 ) { + data.Reserve( cnt ); + SArray * dummyInds = NULL; + + for ( size_t k = 0; k < cnt && in.good(); k++ ) { + // \ru наличие сопряжения \en presence of conjugation + bool isItem = false; + in >> isItem; + + if ( isItem ) { + // \ru тип сопряжения \en conjugation type + uint32 type = trt_None; + in >> type; + + MbVector3D * v1 = NULL; + MbVector3D * v2 = NULL; + MbVector3D * v3 = NULL; + + // \ru касательный вектор \en tangent vector + in >> isItem; + if ( isItem ) { + v1 = new Vector; + in >> *v1; + } + // \ru первая производная касательного вектора \en first derivative of tangent vector + in >> isItem; + if ( isItem ) { + v2 = new Vector; + in >> *v2; + } + // \ru вторая производная касательного вектора \en second derivative of tangent vector + in >> isItem; + if ( isItem ) { + v3 = new Vector; + in >> *v3; + } + + bool movePnts = false; + in >> movePnts; + bool attach = false; + in >> attach; + + MbPntMatingData * item = new MbPntMatingData(); + item->Init( (MbeMatingType)type, v1, v2, v3, dummyInds, movePnts, attach ); + data.Add( item ); + + ::DeleteMatItem( v1 ); + ::DeleteMatItem( v2 ); + ::DeleteMatItem( v3 ); + } + else { + data.Add( NULL ); + } + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Функция копирования. \en Copy function. +//--- +template +void CopyPntMatingData( const MbPntMatingData & srcData, MbPntMatingData & dstData ) +{ + MbeMatingType type = srcData.GetType(); + bool movePnts = srcData.CanMovePoints(); + bool attach = srcData.IsAttach(); + SArray * changedPnts = const_cast *>( srcData.GetChangedPoints() ); + + size_t dim = std_min( SrcVector::GetDimension(), DstVector::GetDimension() ); + + DstVector * tangent = NULL; + DstVector * tangentDer1 = NULL; + DstVector * tangentDer2 = NULL; + + if ( srcData.GetTangent() != NULL ) { + tangent = new DstVector; + for ( size_t k = 0; k < dim; k++ ) + (*tangent)[k] = (*srcData.GetTangent())[k]; + } + if ( srcData.GetTangentDer1() != NULL ) { + tangentDer1 = new DstVector; + for ( size_t k = 0; k < dim; k++ ) + (*tangentDer1)[k] = (*srcData.GetTangentDer1())[k]; + } + if ( srcData.GetTangentDer2() != NULL ) { + tangentDer2 = new DstVector; + for ( size_t k = 0; k < dim; k++ ) + (*tangentDer2)[k] = (*srcData.GetTangentDer2())[k]; + } + + dstData.Init( type, tangent, tangentDer1, tangentDer2, changedPnts, movePnts, attach ); + + ::DeleteMatItem( tangent ); + ::DeleteMatItem( tangentDer1 ); + ::DeleteMatItem( tangentDer2 ); +} + + +#endif diff --git a/C3d/Include/mb_property.h b/C3d/Include/mb_property.h new file mode 100644 index 0000000..7889f83 --- /dev/null +++ b/C3d/Include/mb_property.h @@ -0,0 +1,881 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Свойства математических объектов. + \en Properties of mathematical objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_PROPERTY_H +#define __MB_PROPERTY_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define GET_PROPERTY_VALUE( v ) _GetPropertyValue( &(v), sizeof(v) ) + + +class MbAttribute; +class MbCurve; +class MbCurve3D; +class MbMultiline; +class MbMatrix3D; +class MbFloatPoint; +class MbFloatPoint3D; +class MbFloatVector3D; +class MbTriangle; +class MbQuadrangle; +class MbElement; +class MbApex3D; +class MbPolygon3D; +class MbGrid; +class MbNamedAttributeContainer; +class MbPlacement3D; +class MbMarker; +class MbSurface; +class MbPoint3D; +class MbPointFrame; +class MbWireFrame; +class MbSolid; +class MbInstance; +class MbAssembly; +class MbConstraintSystem; +class MbMesh; +class MbItem; +class MbSpaceInstance; +class MbPlaneInstance; +class MbAssistingItem; +class MbCollection; +class MbModel; +class MbRegion; +class MbDirection; +class MbPlacement; +class MbMatrix; +class MbMultiline; +class MbRegion; +class MbSymbol; +class MbThread; +class MbFunction; +class MbVertex; +class MbEdge; +class MbCurveEdge; +class MbOrientedEdge; +class MbLoop; +class MbFace; +class MbFaceShell; +class MbName; +class MbCreator; +class MbAttributeContainer; +class MbAttributeAction; +class MbTransactions; +template +class MbPntMatingData; +class MbProperties; + + +//---------------------------------------------------------------------------------------- + /** \brief \ru Типы свойств. + \en Types of properties. \~ + \details \ru Типы свойств. \n + Свойства дают доступ к внутренним данным объектов. + \en Types of properties. \n + Properties give access to internal data of objects. \~ + \ingroup Geometric_Items + */ +// --- +enum PrePropType +{ + pt_UndefinedProp, ///< \ru Свойство неизвестного типа данных. \en Property of unknown datatype. \n + + // \ru Атомарные свойства. \en Atomic properties. + pt_BoolProp, ///< \ru Логическое значение. \en Logical value. + pt_IntProp, ///< \ru Целое значение. \en Integer value. + pt_UIntProp, ///< \ru Беззнаковое целое значение. \en Unsigned integer value. + pt_DoubleProp, ///< \ru Действительное значение. \en Real value. + pt_StringProp, ///< \ru Строковое значение. \en String value. + pt_CharProp, ///< \ru Строковое значение. \en String value. + pt_VersionProp, ///< \ru Свойство-версия. \en Version property. \n + + // \ru Комплексные свойства плоских объектов . \en Complex properties of planar objects. + pt_CartPointProp, ///< \ru Cвойство точки. \en Property of point. + pt_VectorProp, ///< \ru Cвойство вектора. \en Property of vector. + pt_DirectionProp, ///< \ru Cвойство вектора. \en Property of vector. + pt_PlacementProp, ///< \ru Cвойство системы координат. \en Property of coordinate system. + pt_MatrixProp, ///< \ru Cвойство матрицы. \en Property of matrix. + pt_CurveProp, ///< \ru Cвойство кривой. \en Property of curve. + pt_MultilineProp, ///< \ru Свойство мультилинии. \en Property of multiline. + pt_RegionProp, ///< \ru Свойство региона. \en Property of region. + pt_PntMatingProp, ///< \ru Свойство сопряжения в точке. \en Property of conjugation at a point. \n + + // \ru Комплексные свойства пространственных объектов. \en Complex properties of spatial objects. + pt_CartPoint3DProp, ///< \ru Cвойство точки. \en Property of point. + pt_Vector3DProp, ///< \ru Cвойство вектора. \en Property of vector. + pt_Placement3DProp, ///< \ru Cвойство системы. \en Property of coordinate system. + pt_Matrix3DProp, ///< \ru Cвойство матрицы. \en Property of matrix. + pt_FloatPointProp, ///< \ru Cвойство параметра. \en Property of parameter. + pt_FloatPoint3DProp, ///< \ru Cвойство точки. \en Property of point. + pt_FloatVector3DProp, ///< \ru Cвойство вектора. \en Property of vector. + pt_TriangleProp, ///< \ru Cвойство треугольника. \en Property of triangle. + pt_QuadrangleProp, ///< \ru Cвойство четырехугольника. \en Property of quadrangle. + pt_ElementProp, ///< \ru Cвойство элемента. \en Property of element. + pt_Apex3DProp, ///< \ru Cвойство аперса. \en Property of apex. + pt_Polygon3DProp, ///< \ru Cвойство полигона. \en Property of polygon. + pt_GridProp, ///< \ru Cвойство триангуляции. \en Property of triangulation. \n + + // \ru Комплексные свойства геометрических объектов. \en Complex properties of geometric objects. + pt_FunctionProp, ///< \ru Cвойство функции. \en Property of function. + pt_Curve3DProp, ///< \ru Cвойство кривой. \en Property of curve. + pt_SurfaceProp, ///< \ru Cвойство поверхности. \en Property of surface. + pt_Point3DProp, ///< \ru Cвойство точки. \en Property of point. + pt_MarkerProp, ///< \ru Cвойство маркера ("точка присоединения"). \en Property of marker ("point of joint"). + pt_SymbolProp, ///< \ru Cвойство условного обозначения. \en Property of conventional notation. + pt_ThreadProp, ///< \ru Cвойство резьбы. \en Property of thread. + pt_Pnt3DMatingProp, ///< \ru Cвойство сопряжения в точке. \en Property of conjugation at a point. \n + + // \ru Комплексные свойства тел и топологических объектов. \en Complex properties of solids and topological objects. + pt_CreatorProp, ///< \ru Cвойство строителя тела. \en Property of solid creator. + pt_VertexProp, ///< \ru Cвойство вершины. \en Property of vertex. + pt_EdgeProp, ///< \ru Cвойство ребра-кривой. \en Property of edge curve. + pt_CurveEdgeProp, ///< \ru Cвойство ребра грани. \en Property of face edge. + pt_OrientedEdgeProp, ///< \ru Cвойство ориентированного ребра. \en Property of oriented edge. + pt_LoopProp, ///< \ru Cвойство цикла. \en Property of loop. + pt_FaceProp, ///< \ru Cвойство грани. \en Property of face. + pt_FaceShellProp, ///< \ru Cвойство оболочки. \en Property of shell. + pt_NameProp, ///< \ru Cвойство имени. \en Property of name. \n + + // \ru Комплексные свойства объектов модели. \en Complex properties of model objects. + pt_AssistingItemProp, ///< \ru Cвойство вспомогательного объекта. \en Property of assisting item. + pt_CollectionProp, ///< \ru Cвойство коллекции 3D элементов. \en Property of the collection of 3D elements. \n + pt_PointFrameProp, ///< \ru Cвойство точечного каркаса. \en Property of point frame. + pt_WireFrameProp, ///< \ru Cвойство проволочного каркаса. \en Property of wire frame. + pt_SolidProp, ///< \ru Cвойство тела. \en Property of solid. + pt_InstanceProp, ///< \ru Cвойство вставки объекта. \en Property of object instance. + pt_AssemblyProp, ///< \ru Cвойство сборочной единицы. \en Property of assembly unit. + pt_ConstraintSystem, ///< \ru Cвойство системы ограничений. \en Property of constraint system. + pt_MeshProp, ///< \ru Cвойство сетки. \en Property of mesh. + pt_SpaceInstanceProp, ///< \ru Cвойство объекта. \en Property of object. + pt_PlaneInstanceProp, ///< \ru Cвойство плоского объекта. \en Property of flat object. + pt_ConstraintModelProp, ///< \ru Cвойство схемы сопряжений. \en Property of conjugation scheme. + pt_ItemProp, ///< \ru Cвойство объекта. \en Property of object. + pt_ModelProp, ///< \ru Cвойство объектной модели. \en Property of object model. + pt_TransactionsProp, ///< \ru Cвойство журнала построения. \en Property of build log. + pt_AttributeContainerProp, ///< \ru Cвойство контейнера атрибутов. \en Property of attribute container. + pt_AttributeProp, ///< \ru Cвойство атрибута. \en Property of attribute. + pt_NamedAttributeContainerProp, ///< \ru Cвойство именованного контейнера атрибутов. \en Property of named attribute container. + pt_AttributeActionProp, ///< \ru Cвойство атрибута. \en Property of attribute. \n + + pt_LastPropType, ///< \ru Последний тип свойства, все остальные добавлять перед ним. \en Last type of property, any other ones must be added before. +}; + + +//----------------------------------------------------------------------------- +/// \ru Структура соответствия типа объекта и типа свойства. \en Object type and property type correspondence structure. +//--- +template +struct PropType { static const PrePropType propId = pt_UndefinedProp; }; + + +//----------------------------------------------------------------------------- +// \ru Специализация шаблона PropType - организует таблицу соответствий \en PropType template specialization - organizes lookup table +//--- +template<> struct PropType { static const PrePropType propId = pt_CartPointProp; }; +template<> struct PropType { static const PrePropType propId = pt_VectorProp; }; +template<> struct PropType { static const PrePropType propId = pt_DirectionProp; }; +template<> struct PropType { static const PrePropType propId = pt_PlacementProp; }; +template<> struct PropType { static const PrePropType propId = pt_MatrixProp; }; +template<> struct PropType { static const PrePropType propId = pt_CurveProp; }; +template<> struct PropType { static const PrePropType propId = pt_MultilineProp; }; +template<> struct PropType { static const PrePropType propId = pt_RegionProp; }; +template<> struct PropType { static const PrePropType propId = pt_SymbolProp; }; +template<> struct PropType { static const PrePropType propId = pt_ThreadProp; }; +template<> struct PropType { static const PrePropType propId = pt_CartPoint3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_Vector3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_Placement3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_Matrix3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_FloatPointProp; }; +template<> struct PropType { static const PrePropType propId = pt_FloatPoint3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_FloatVector3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_TriangleProp; }; +template<> struct PropType { static const PrePropType propId = pt_QuadrangleProp; }; +template<> struct PropType { static const PrePropType propId = pt_ElementProp; }; +template<> struct PropType { static const PrePropType propId = pt_Apex3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_Polygon3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_GridProp; }; +template<> struct PropType { static const PrePropType propId = pt_MarkerProp; }; +template<> struct PropType { static const PrePropType propId = pt_Curve3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_SurfaceProp; }; +template<> struct PropType { static const PrePropType propId = pt_Point3DProp; }; +template<> struct PropType { static const PrePropType propId = pt_PointFrameProp; }; +template<> struct PropType { static const PrePropType propId = pt_WireFrameProp; }; +template<> struct PropType { static const PrePropType propId = pt_SolidProp; }; +template<> struct PropType { static const PrePropType propId = pt_InstanceProp; }; +template<> struct PropType { static const PrePropType propId = pt_AssemblyProp; }; +template<> struct PropType { static const PrePropType propId = pt_ConstraintSystem; }; +template<> struct PropType { static const PrePropType propId = pt_MeshProp; }; +template<> struct PropType { static const PrePropType propId = pt_ItemProp; }; +template<> struct PropType { static const PrePropType propId = pt_SpaceInstanceProp; }; +template<> struct PropType { static const PrePropType propId = pt_PlaneInstanceProp; }; +template<> struct PropType { static const PrePropType propId = pt_AssistingItemProp; }; +template<> struct PropType { static const PrePropType propId = pt_CollectionProp; }; +template<> struct PropType { static const PrePropType propId = pt_ModelProp; }; +template<> struct PropType { static const PrePropType propId = pt_FunctionProp; }; +template<> struct PropType { static const PrePropType propId = pt_VertexProp; }; +template<> struct PropType { static const PrePropType propId = pt_EdgeProp; }; +template<> struct PropType { static const PrePropType propId = pt_CurveEdgeProp; }; +template<> struct PropType { static const PrePropType propId = pt_OrientedEdgeProp; }; +template<> struct PropType { static const PrePropType propId = pt_LoopProp; }; +template<> struct PropType { static const PrePropType propId = pt_FaceProp; }; +template<> struct PropType { static const PrePropType propId = pt_FaceShellProp; }; +template<> struct PropType { static const PrePropType propId = pt_NameProp; }; +template<> struct PropType { static const PrePropType propId = pt_CreatorProp; }; +template<> struct PropType { static const PrePropType propId = pt_AttributeContainerProp; }; +template<> struct PropType { static const PrePropType propId = pt_AttributeProp; }; +template<> struct PropType { static const PrePropType propId = pt_AttributeActionProp; }; +template<> struct PropType { static const PrePropType propId = pt_TransactionsProp; }; +template<> struct PropType { static const PrePropType propId = pt_NamedAttributeContainerProp; }; +template<> struct PropType > { static const PrePropType propId = pt_PntMatingProp; }; +template<> struct PropType > { static const PrePropType propId = pt_Pnt3DMatingProp; }; + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойство. + \en Property. \~ + \details \ru Свойство является базовым классом для доступа к внутренним данным объектов. + Наследники свойства содержать внутренние данные объектов или их копии. + Свойства предназначены для просмотра и модификации внутренних данных объектов. + \en Property is the base class for access to internal data of objects. + Inheritors of property may contain internal data of objects or its copies. + Properties are intended for reading and changing internal data of objects. \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS MbProperty +{ +private: + MbePrompt prompt; ///< \ru Номер подсказки. \en Number of hint string. + bool changeable; ///< \ru Признак редактируемости. \en Attribute of editability. + +public: + /// \ru Конструктор. \en Constructor. + MbProperty( MbePrompt name, bool change = true ) : prompt( name ), changeable( change ) {} + /// \ru Деструктор. \en Destructor. + virtual ~MbProperty(); + + /// \ru Выдать тип свойства. \en Get type of property. + virtual PrePropType IsA() const = 0; + /// \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void GetCharValue( TCHAR * v ) const = 0; + /// \ru Выдать значение свойства. \en Get value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const = 0; + /// \ru Установить новое значение свойства. \en Set the new value of the property. + virtual void SetPropertyValue( TCHAR * v ) = 0; + /// \ru Выдать кортеж свойств составного свойства (не атомарный объект). \en Get tuple of the complex property (non-atomic object). + virtual void GetProperties( MbProperties & ) {} + /// \ru Задать кортеж свойств составного свойства (не атомарный объект). \en Set tuple of the complex property (non-atomic object). + virtual void SetProperties( const MbProperties & ) {} + /// \ru Выдать подсказку. \en Get a hint. + virtual size_t GetPrompt() const { return prompt; } + /// \ru Выдать подсказку. \en Get a hint. + MbePrompt & SetPrompt() { return prompt; } + /// \ru Можно ли изменять данные. \en Is it possible to change data. + bool IsChangeable() const { return changeable; } + +OBVIOUS_PRIVATE_COPY( MbProperty ) +}; // MbProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru bool свойство. + \en Bool property. \~ + \details \ru bool свойство предназначено для просмотра и модификации данных типа bool.\n + \en Bool property is intended for reading and changing data of boolean type.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS BoolProperty : public MbProperty { +public : + bool value; ///< \ru Значение. \en Value. + + /// \ru Конструктор. \en Constructor. + BoolProperty( MbePrompt name, bool initValue, bool change = true ) + : MbProperty( name, change ) + , value( initValue ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~BoolProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( BoolProperty ) +}; // BoolProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru int свойство. + \en Int property. \~ + \details \ru int свойство предназначено для просмотра и модификации данных типа int.\n + \en Int property is intended for reading and changing data of integer type.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS IntProperty : public MbProperty { +public : + int64 value; ///< \ru Значение. \en Value. + + /// \ru Конструктор. \en Constructor. + IntProperty( MbePrompt name, int64 initValue, bool change = true ) + : MbProperty( name, change ) + , value( (int64)initValue ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~IntProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( IntProperty ) +}; // IntProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru uint свойство. + \en Uint property. \~ + \details \ru uint свойство предназначено для просмотра и модификации данных типа uint64.\n + \en Uint property is intended for reading and changing data of uint64 type.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS UIntProperty : public MbProperty { +public : + uint64 value; ///< \ru Значение. \en Value. + + /// \ru Конструктор. \en Constructor. + UIntProperty( MbePrompt name, size_t initValue, bool change = true ) + : MbProperty( name, change ) + , value( (uint64)initValue ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~UIntProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( UIntProperty ) +}; // UIntProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru double свойство. + \en Double property. \~ + \details \ru double свойство предназначено для просмотра и модификации данных типа double.\n + \en Double property is intended for reading and changing data of double type.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS DoubleProperty : public MbProperty { +public : + double value; ///< \ru Значение. \en Value. + + /// \ru Конструктор. \en Constructor. + DoubleProperty( MbePrompt name, double initValue, bool change = true ) + : MbProperty( name, change ) + , value( initValue ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~DoubleProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( DoubleProperty ) +}; // DoubleProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru double свойство с номером. + \en Double property with number. \~ + \details \ru double свойство с номером предназначено для просмотра и модификации данных типа double, имеющих порядковый номер.\n + \en Double property with number is intended for reading and changing data of double type which have number.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS NDoubleProperty : public MbProperty { +public : + double value; ///< \ru Значение. \en Value. + uint32 number; ///< \ru Номер. \en Number. + + /// \ru Конструктор. \en Constructor. + NDoubleProperty( MbePrompt name, double initValue, bool change = true, uint32 n = 0 ) + : MbProperty( name, change ) + , value( initValue ) + , number( n ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~NDoubleProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( NDoubleProperty ) +}; // NDoubleProperty + + +//---------------------------------------------------------------------------------------- +/** \brief \ru string свойство. + \en String property. \~ + \details \ru string свойство предназначено для просмотра и модификации данных типа TCHAR *.\n + \en String property is intended for reading and changing TCHAR * like data.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS StringProperty : public MbProperty +{ + TCHAR * value; ///< \ru Значение. \en Value. + +public: + /// \ru Конструктор. \en Constructor. + StringProperty( MbePrompt name, const TCHAR * initValue, bool change = true ); + /// \ru Деструктор. \en Destructor. + virtual ~StringProperty(); + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + const TCHAR * CharValue() const { return value; } + +OBVIOUS_PRIVATE_COPY(StringProperty) +}; // StringProperty + + +typedef StringProperty CharProperty; + + +//------------------------------------------------------------------------------ +/** \brief \ru Version свойство. + \en Version property. \~ + \details \ru Version свойство предназначено для просмотра и модификации данных типа VERSION.\n + \en Version property is intended for reading and changing VERSION like data.\n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS VersionProperty : public MbProperty { +public : + VERSION value; ///< \ru Значение. \en Value. + + /// \ru Конструктор. \en Constructor. + VersionProperty( MbePrompt name, VERSION initValue, bool change = true ) + : MbProperty( name, change ) + , value( initValue ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~VersionProperty() {} + + virtual PrePropType IsA() const; // \ru Выдать тип свойства. \en Get type of property. + virtual void GetCharValue( TCHAR * v ) const; // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void _GetPropertyValue( void * v, size_t size ) const; // \ru Выдать значение свойства. \en Get value of the property. + virtual void SetPropertyValue( TCHAR * v ); // \ru Установить новое значение свойства. \en Set the new value of the property. + +OBVIOUS_PRIVATE_COPY( VersionProperty ) +}; // IntProperty + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать строковое значение данного свойства для данного его поля. + \en Get string value of given property for its given field. \~ + \details \ru Функция определена для случая "по умолчанию", для конкретных типов FieldType, + следует перегрузить для статического сопоставления типов компилятором.\n + \en In "default" case function is defined for explicit types FieldType, + it should be overloaded for static mapping of types by compiler.\n \~ + \ingroup Model_Properties +*/ +//--- +template +inline void GetCharValue( const PropType *, const FieldType *, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( v != NULL ); + if ( v != NULL ) { + if ( n == 0 ) { + v[0] = _T(' '); + v[1] = _T('\0'); + } + else + _sntprintf( v, 64, _T("%d\t"), n ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства двумерной точки. + \en Get properties of two-dimensional point. \~ + \details \ru Выдать свойства двумерной точки MbCartPoint.\n + \en Get properties of two-dimensional point MbCartPoint.\n \~ + \ingroup Model_Properties +*/ +//--- +template +inline void GetCharValue( const PropType *, const MbCartPoint * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( value != NULL && v != NULL ); + if ( value != NULL && v != NULL ) { + if ( n == 0 ) + _sntprintf( v, 64, _T("%.3f\t%.3f"), value->x, value->y ); + else + _sntprintf( v, 64, _T("%d %.3f\t%.3f"), n, value->x, value->y ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства двумерного вектора. + \en Get properties of two-dimensional vector. \~ + \details \ru Выдать свойства двумерного вектора MbVector.\n + \en Get properties of two-dimensional vector MbVector.\n \~ + \ingroup Model_Properties +*/ +// --- +template +inline void GetCharValue( const PropType *, const MbVector * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( value != NULL && v != NULL ); + if ( value != NULL && v != NULL ) { + if ( n == 0 ) + _sntprintf( v, 64, _T("%.3f\t%.3f"), value->x, value->y ); + else + _sntprintf( v, 64, _T("%d %.3f\t%.3f"), n, value->x, value->y ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства двумерного нормированного вектора. + \en Get properties of two-dimensional normalized vector. \~ + \details \ru Выдать свойства двумерного нормированного вектора MbDirection.\n + \en Get properties of two-dimensional normalized vector MbDirection.\n \~ + \ingroup Model_Properties +*/ +// --- +template +inline void GetCharValue( const PropType *, const MbDirection * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( value != NULL && v != NULL ); + if ( value != NULL && v != NULL ) { + double angle(0.0); + if ( value->ax==0 && value->ay==0 ) + angle = 0.0; + else + angle = 180 / M_PI * atan2( value->ay, value->ax ); + if ( n == 0 ) + _sntprintf( v, 64, _T("%.3f\t"), angle ); + else + _sntprintf( v, 64, _T("%d %.3f\t"), n, angle ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства трёхмерной точки. + \en Get properties of three-dimensional point. \~ + \details \ru Выдать свойства трёхмерной точки MbCartPoint3D.\n + \en Get properties of three-dimensional point MbCartPoint3D.\n \~ + \ingroup Model_Properties +*/ +// --- +template +inline void GetCharValue( const PropType *, const MbCartPoint3D * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( value != NULL && v != NULL ); + if ( value != NULL && v != NULL ) { + if ( n == 0 ) + _sntprintf( v, 64, _T("%.3f\t%.3f\t%.3f"), value->x, value->y, value->z ); + else + _sntprintf( v, 64, _T("%d %.3f\t%.3f\t%.3f"), n, value->x, value->y, value->z ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства трёхмерного вектора. + \en Get properties of three-dimensional vector. \~ + \details \ru Выдать свойства трёхмерного вектора MbVector3D.\n + \en Get properties of three-dimensional vector MbVector3D.\n \~ + \ingroup Model_Properties +*/ +// --- +template +inline void GetCharValue( const PropType *, const MbVector3D * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( value != NULL && v != NULL ); + if ( value != NULL && v != NULL ) { + if ( n == 0 ) + _sntprintf( v, 64, _T("%.3f\t%.3f\t%.3f"), value->x, value->y, value->z ); + else + _sntprintf( v, 64, _T("%d %.3f\t%.3f\t%.3f"), n, value->x, value->y, value->z ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать свойства имени объекта. + \en Get properties of object name. \~ + \details \ru Выдать свойства имени объекта MbName.\n + \en Get properties of object name MbName.\n \~ + \ingroup Model_Properties +*/ +// --- +template +inline void GetCharValue( const PropType *, const MbName * value, uint32 n, TCHAR * v ) +{ + C3D_ASSERT( v != NULL ); + if ( v != NULL ) { + if ( value != NULL ) { + c3d::string_t str; + value->ToString( str ); + + if ( n !=0 ) { + _sntprintf( v, 64, _T("%d "), n ); + _tcscat( v, str.c_str() ); + } + else { + _tcscpy( v, str.c_str() ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойство объекта. + \en The property of the object. \~ + \details \ru Обертка, реализующая свойство объекта с настройкой владения ним.\n + \en Wrapper that implements property of an object with its ownership setting.\n \~ + \ingroup Model_Properties +*/ +// --- +template +class MathItemProperty : public MbProperty { +public : + Type * value; ///< \ru Объект. \en Object. + uint32 number; ///< \ru Номер. \en Number. + +public : + /// \ru Конструктор. \en Constructor. + MathItemProperty( MbePrompt name, Type * initValue, bool change, uint32 n = 0 ) + : MbProperty( name, change ) + , value( initValue ) + , number( n ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~MathItemProperty() {} + +public : + // \ru Выдать тип свойства. \en Get type of property. + virtual PrePropType IsA() const { return PropType::propId; } + // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void GetCharValue( TCHAR * v ) const { ::GetCharValue( this, value, number, v ); } + // \ru Выдать свойства неатомарного объекта. \en Get properties of the non-atomic object. + virtual void GetProperties( MbProperties & ); + // \ru Задать свойства неатомарного объекта объекта. \en Set properties of the non-atomic object. + virtual void SetProperties( const MbProperties & ); + // \ru Выдать значение свойства. \en Get value of the property. + virtual void _GetPropertyValue( void * v, size_t /*size*/ ) const { *(Type**)v = value; } + // \ru Установить новое значение свойства. \en Set the new value of the property. + virtual void SetPropertyValue( TCHAR * ) {} + +OBVIOUS_PRIVATE_COPY( MathItemProperty ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойство объекта. +\en The property of the object. \~ +\details \ru Обертка, реализующая свойство объекта с настройкой владения ним.\n +\en Wrapper that implements property of an object with its ownership setting.\n \~ +\ingroup Model_Properties +*/ +// --- +template +class MathItemCopyProperty : public MbProperty { +public: + Type value; ///< \ru Объект. \en Object. + uint32 number; ///< \ru Номер. \en Number. + +public: + /// \ru Конструктор. \en Constructor. + MathItemCopyProperty( MbePrompt name, const Type & initValue, bool change, uint32 n = 0 ) + : MbProperty( name, change ) + , value( initValue ) + , number( n ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~MathItemCopyProperty() {} + +public: + // \ru Выдать тип свойства. \en Get type of property. + virtual PrePropType IsA() const { return PropType::propId; } + // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void GetCharValue( TCHAR * v ) const { ::GetCharValue( this, &value, number, v ); } + // \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. + virtual void GetProperties( MbProperties & ); + // \ru Выдать значение свойства. \en Get value of the property. + virtual void _GetPropertyValue( void * v, size_t /*size*/ ) const { *(Type**)v = const_cast(&value); } + // \ru Установить новое значение свойства. \en Set the new value of the property. + virtual void SetPropertyValue( TCHAR * ) {} + +OBVIOUS_PRIVATE_COPY( MathItemCopyProperty ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Cвойство объекта. + \en The property of the object. \~ + \details \ru Обертка, реализующая свойство объекта со счетчиком ссылок.\n + \en Wrapper that implements property of an object with reference counter.\n \~ + \ingroup Model_Properties +*/ +// --- +template +class RefItemProperty : public MbProperty { +public : + SPtr value; ///< \ru Объект. \en Object. + uint32 number; ///< \ru Номер. \en Number. + +public : + /// \ru Конструктор. \en Constructor. + RefItemProperty( MbePrompt name, Type * initValue, bool change, uint32 n = 0 ) + : MbProperty( name, change ) + , value ( initValue ) + , number( n ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~RefItemProperty() {} + + // \ru Выдать тип свойства. \en Get type of property. + virtual PrePropType IsA() const { return PropType::propId; } + // \ru Выдать строковое значение свойства. \en Get string value of the property. + virtual void GetCharValue( TCHAR * v ) const { ::GetCharValue( this, value.get(), number, v ); } + // \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. + virtual void GetProperties( MbProperties & ); + // \ru Задать свойства неатомарного объекта объекта. \en Set properties of the non-atomic object. + virtual void SetProperties( const MbProperties & ); + // \ru Выдать значение свойства. \en Get value of the property. + virtual void _GetPropertyValue( void * v, size_t /*size*/ ) const { *(Type**)v = value.get(); } + // \ru Установить новое значение свойства. \en Set the new value of the property. + virtual void SetPropertyValue( TCHAR * ) {} + +OBVIOUS_PRIVATE_COPY( RefItemProperty ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество свойств объекта. + \en Set of object properties. \~ + \details \ru Множество свойств объекта представляет собой контейнер, вызывающий деструктор своих элементов. \n + \en Set of object properties is container that calls destructor of its elements. \n \~ + \ingroup Model_Properties +*/ +// --- +class MATH_CLASS MbProperties : public PArray +{ + MbePrompt name; ///< \ru Имя объекта. \en A name of an object. + +public: + /// \ru Конструктор. \en Constructor. + MbProperties() + : PArray() + , name( IDS_ITEM_0000 ) {} + +public: + /// \ru Выдать имя объекта. \en Get name of object. + MbePrompt & SetName() { return name; } + /// \ru Выдать имя объекта. \en Get name of object. + size_t GetName() const { return (size_t)name; } + /// \ru Выдать имя объекта. \en Get name of object. + MbePrompt Name() const { return name; } + /// \ru Установить имя объекта. \en Set name of the object. + void SetName( MbePrompt s ) { name = s; } + /// \ru Установить имя объекта. \en Set name of the object. + void SetName( size_t s ) { name = (MbePrompt)s; } + /// \ru Найти свойство по имени и типу. \en Find property by name and type. + MbProperty * FindByPrompt( MbePrompt, uint type ) const; + /// \ru Найти индекс свойства в массиве по имени и типу. \en Find index of property in array by name and type. + size_t FindByPrompt( uint type, MbePrompt ) const; + +OBVIOUS_PRIVATE_COPY( MbProperties ) +}; // MbProperties + +//---------------------------------------------------------------------------------------- +// \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. +//--- +template +void MathItemProperty::GetProperties( MbProperties & props ) +{ + if ( value ) + value->GetProperties( props ); +} + +//---------------------------------------------------------------------------------------- +// \ru Задать свойства неатомарного объекта объекта. \en Set properties of the non-atomic object. +//--- +template +void MathItemProperty::SetProperties( const MbProperties & props ) +{ + if ( value ) + value->SetProperties( props ); +} + +//---------------------------------------------------------------------------------------- +// \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. +//--- +template +void MathItemCopyProperty::GetProperties( MbProperties & props ) +{ + value.GetProperties( props ); +} + +//---------------------------------------------------------------------------------------- +// \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. +//--- +template +void RefItemProperty::GetProperties( MbProperties & props ) +{ + if ( value ) + value->GetProperties( props ); +} + +//---------------------------------------------------------------------------------------- +// \ru Выдать свойства неатомарного объекта объекта. \en Get properties of the non-atomic object. +//--- +template +void RefItemProperty::SetProperties( const MbProperties & props ) +{ + if ( value ) + value->SetProperties( props ); +} + + +#endif // __PROPERTY_H diff --git a/C3d/Include/mb_property_title.h b/C3d/Include/mb_property_title.h new file mode 100644 index 0000000..2973de4 --- /dev/null +++ b/C3d/Include/mb_property_title.h @@ -0,0 +1,1173 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Свойства математических объектов. + \en Properties of mathematical objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_PROPERTY_TITLE_H +#define __MB_PROPERTY_TITLE_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Свойства математических объектов. + \en Properties of mathematical objects. \~ + \attention \ru Целочисленные значения данного перечислительного типа могут быть изменены! + \en Integer values of the enum can be changed! + \ingroup Base_Items +*/ +// --- +enum MbePrompt +{ + IDS_ITEM_0000 = 0, ///< \ru Неопределенный объект. + +// \ru Базовые объекты двумерной математики. \en Base 2D objects. + + IDS_ITEM_0001, ///< \ru Двумерная точка. \en A two-dimensional point. + IDS_ITEM_0002, ///< \ru Двумерный вектор. \en Two-dimensional vector. + IDS_ITEM_0003, ///< \ru Двумерная матрица преобразования. \en Two-dimensional matrix of transformation. + IDS_ITEM_0004, ///< \ru Двумерная локальная система. \en Two-dimensional local system. + IDS_ITEM_0005, ///< \ru Двумерный единичный вектор. \en Two-dimensional unit vector + +// \ru Типы двумерных кривых. \en Types of two-dimensional curves. + + IDS_ITEM_0011, ///< \ru Двумерная кривая. \en Two-dimensional curve + + IDS_ITEM_0013, ///< \ru Двумерная прямая. \en Two-dimensional line. + IDS_ITEM_0014, ///< \ru Двумерный отрезок. \en Two-dimensional segment. + IDS_ITEM_0015, ///< \ru Двумерный отрезок прямой. \en Two-dimensional line segment. + IDS_ITEM_0016, ///< \ru Двумерная дуга окружности. \en Two-dimensional circular arc. + IDS_ITEM_0017, ///< \ru Двумерная усеченная кривая. \en Two-dimensional truncated curve. + IDS_ITEM_0018, ///< \ru Двумерная эквидистантная кривая. \en Two-dimensional offset curve. + IDS_ITEM_0019, ///< \ru Двумерная эквидистанта. \en Two-dimensional equidistant. + IDS_ITEM_0020, ///< \ru Двумерная окружность. \en Two-dimensional circle. + IDS_ITEM_0021, ///< \ru Двумерный эллипс. \en Two-dimensional ellipse. + IDS_ITEM_0022, ///< \ru Двумерная парабола. \en Two-dimensional parabola. + IDS_ITEM_0023, ///< \ru Двумерная дуга эллипса. \en Two-dimensional elliptical arc. + IDS_ITEM_0024, ///< \ru Двумерная ломаная. \en Two-dimensional polyline. + IDS_ITEM_0025, ///< \ru Двумерная NURBS кривая. \en Two-dimensional NURBS curve. + IDS_ITEM_0026, ///< \ru Двумерный сплайн Эрмита. \en Two-dimensional Hermite spline. + IDS_ITEM_0027, ///< \ru Двумерный сплайн Безье. \en Two-dimensional Bezier spline. + IDS_ITEM_0028, ///< \ru Двумерный кубический сплайн. \en Two-dimensional cubic spline. + IDS_ITEM_0029, ///< \ru Двумерная репараметризованная кривая. \en Two-dimensional reparametrized curve. + IDS_ITEM_0030, ///< \ru Двумерный контур. \en Two-dimensional contour. + IDS_ITEM_0031, ///< \ru Двумерная косинусоида. \en Two-dimensional cosine curve. + IDS_ITEM_0032, ///< \ru Двумерная точечная кривая. \en Two-dimensional point curve. + IDS_ITEM_0040, ///< \ru Двумерная область. \en Two-dimensional region. + IDS_ITEM_0050, ///< \ru Двумерный объект. \en Two-dimensional object. + IDS_ITEM_0051, ///< \ru Двумерная мультилиния. \en Two-dimensional multiline. + IDS_ITEM_0052, ///< \ru Двумерная кривая на конусе, соответствующая кривой на коническом изгибе плоскости. \en Two-dimensional curve on cone corresponding to a curve on conic bend of a plane. + IDS_ITEM_0053, ///< \ru Двумерная кривая на плоскости, соответствующая кривой на изгибе конуса. \en Two-dimensional curve on plane corresponding to a curve on a bend of cone + IDS_ITEM_0054, ///< \ru Двумерная кривая, координатные функции которой заданы в символьном виде. \en Functionally defined two-dimensional curve. + IDS_ITEM_0055, ///< \ru Образ трехмерной кривой на поверхности при движении по направляющей. \en Image of a three-dimensional curve on surface while moving along the guide curve. + +// \ru Типы полигональных объектов. \en Types of simplified forms of an object. + + IDS_ITEM_0060, ///< \ru Параметр. \en Parameter. + IDS_ITEM_0061, ///< \ru Вершина. \en Vertex. + IDS_ITEM_0062, ///< \ru Нормаль. \en Normal. + IDS_ITEM_0063, ///< \ru Треугольник. \en Triangle. + IDS_ITEM_0064, ///< \ru Четырехугольник. \en Quadrangle. + IDS_ITEM_0071, ///< \ru Полигональный объект на числах double. \en Polygonal object on double data. + IDS_ITEM_0072, ///< \ru Апекс на числах double. \en Apex on double data. + IDS_ITEM_0073, ///< \ru Полигон на числах double. \en Polygon on double data. + IDS_ITEM_0074, ///< \ru Триангуляция на числах double. \en Triangulation on double data. + IDS_ITEM_0075, ///< \ru Полигональный объект на числах float. \en Polygonal object on float data. + IDS_ITEM_0076, ///< \ru Апекс на числах float. \en Apex on float data. + IDS_ITEM_0077, ///< \ru Полигон на числах float. \en Polygon on float data. + IDS_ITEM_0078, ///< \ru Триангуляция на числах float. \en Triangulation on float data. + +// \ru Базовые объекты трехмерной математики. \en Base objects of three-dimensional mathematics. + + IDS_ITEM_0101, ///< \ru Точка. \en Point. + IDS_ITEM_0102, ///< \ru Вектор. \en Vector. + IDS_ITEM_0103, ///< \ru Матрица преобразования. \en Transformation matrix. + IDS_ITEM_0104, ///< \ru Локальная система координат. \en Local coordinate system. + +// \ru Типы функций \en Types of functions + + IDS_ITEM_0111, ///< \ru Kонстантная функция. \en Constant function. + IDS_ITEM_0112, ///< \ru Линейная функция. \en Linear function. + IDS_ITEM_0113, ///< \ru Kубическая функция. \en Cubic function. + IDS_ITEM_0114, ///< \ru Kубическай сплайн-функция. \en Cubic spline function. + IDS_ITEM_0115, ///< \ru Символьная функция. \en Symbolic function. + IDS_ITEM_0116, ///< \ru Степенная функция. \en Power function. + IDS_ITEM_0117, ///< \ru Синус функция. \en Sinus function. + +// \ru Типы трехмерных кривы.х \en Types of three-dimensional curves. + + IDS_ITEM_0201, ///< \ru Кривая. \en Curve. + IDS_ITEM_0202, ///< \ru B-сплайн. \en B-spline. + IDS_ITEM_0213, ///< \ru Прямая линия. \en Straight line. + IDS_ITEM_0214, ///< \ru Отрезок. \en Segment. + IDS_ITEM_0215, ///< \ru Дуга эллипса. \en Elliptic arc. + IDS_ITEM_0216, ///< \ru Дуга окружности. \en Circular arc. + IDS_ITEM_0217, ///< \ru Усеченная кривая. \en Truncated curve. + IDS_ITEM_0218, ///< \ru Эквидистантная кривая. \en Offset curve. + IDS_ITEM_0219, ///< \ru Коническая спираль. \en Conical spiral. + IDS_ITEM_0220, ///< \ru Oкружность. \en Circle. + IDS_ITEM_0221, ///< \ru Эллипс. \en Ellipse. + IDS_ITEM_0222, ///< \ru Парабола. \en Parabola. + IDS_ITEM_0223, ///< \ru Гипербола. \en Hyperbola. + IDS_ITEM_0224, ///< \ru Ломаная линия. \en Polyline. + IDS_ITEM_0225, ///< \ru NURBS кривая. \en NURBS curve. + IDS_ITEM_0226, ///< \ru Сплайн Эрмита. \en Hermite spline. + IDS_ITEM_0227, ///< \ru Сплайн Безье. \en Bezier spline. + IDS_ITEM_0228, ///< \ru Кубический сплайн. \en Cubic spline. + IDS_ITEM_0229, ///< \ru Репараметризованная кривая. \en Reparametrized curve. + IDS_ITEM_0231, ///< \ru Плоская кривая. \en Plane curve. + IDS_ITEM_0232, ///< \ru Спираль с переменым радиусом. \en Spiral with variable radius. + IDS_ITEM_0233, ///< \ru Спираль с криволинейной осью. \en Spiral with a curved axis. + IDS_ITEM_0234, ///< \ru Кривая-мостик. \en Bridge curve. + IDS_ITEM_0235, ///< \ru Символьная кривая. \en Functionally defined curve. + IDS_ITEM_0236, ///< \ru Кривая на поверхности. \en Curve on a surface. + IDS_ITEM_0237, ///< \ru Линия пересечения поверхностей. \en Intersection curve of surfaces. + IDS_ITEM_0238, ///< \ru Контур на поверхности. \en Contour on a surface. + IDS_ITEM_0239, ///< \ru Контур на плоскости. \en Contour on a plane. + IDS_ITEM_0240, ///< \ru Контур. \en Contour. + IDS_ITEM_0241, ///< \ru Проекционная кривая. \en Projection curve. + IDS_ITEM_0242, ///< \ru Силуэтная кривая. \en Silhouette curve. + IDS_ITEM_0243, ///< \ru Кривая сопряжения кривых. \en Curve of curves conjugation. + IDS_ITEM_0244, ///< \ru Кривая производных поверхности Кунса. \en Curve of Coons surface derivetives. + IDS_ITEM_0249, ///< \ru Направляющая кривая. \en Guide curve. + IDS_ITEM_0250, ///< \ru Кривая пересечения. \en Intersection curve. + +// \ru Типы параметрических поверхностей. \en Types of parametric surfaces. + + IDS_ITEM_0301, ///< \ru Поверхность. \en Surface. + IDS_ITEM_0302, ///< \ru Поверхность заметания. \en Sweep surface. + IDS_ITEM_0303, ///< \ru Поверхность сдвига. \en Motion surface. + IDS_ITEM_0304, ///< \ru Поверхность выдавливания. \en Extrusion surface. + IDS_ITEM_0305, ///< \ru Поверхность вращения. \en Revolution surface. + IDS_ITEM_0306, ///< \ru Линейчатая поверхность. \en Ruled surface. + IDS_ITEM_0307, ///< \ru Поверхность по кривой и точке. \en Surface defined by a curve and a point. + IDS_ITEM_0308, ///< \ru Четырехугольная поверхность. \en Quadrangular surface. + IDS_ITEM_0309, ///< \ru Треугольная поверхность. \en Triangular surface. + IDS_ITEM_0310, ///< \ru Поверхность движения с доворотом. \en Sweep with guide curve surface with rotating ends. + IDS_ITEM_0311, ///< \ru Поверхность на семействе кривых и напрвляющей. \en Loft surface with guide curve. + IDS_ITEM_0312, ///< \ru Спиральная поверхность. \en Spiral surface. + IDS_ITEM_0313, ///< \ru Цилиндрически согнутая поверхность. \en Cylindrically bent surface. + IDS_ITEM_0314, ///< \ru Цилиндрически разогнутая поверхность. \en Cylindrically unbent surface. + IDS_ITEM_0315, ///< \ru Конически согнутая поверхность. \en Conically bent surface. + IDS_ITEM_0316, ///< \ru Конически разогнутая поверхность. \en Conically unbent surface. + IDS_ITEM_0317, ///< \ru Поверхность заметания с изменением образующей. \en Sweep surface with changin generatin. + IDS_ITEM_0319, ///< \ru Плоскость. \en Plane. + IDS_ITEM_0320, ///< \ru Сферическая поверхность. \en Spherical surface. + IDS_ITEM_0321, ///< \ru Тороидальная поверхность. \en Toroidal surface. + IDS_ITEM_0322, ///< \ru Цилиндрическая поверхность. \en Cylindrical surface. + IDS_ITEM_0323, ///< \ru Коническая поверхность. \en Conical surface. + IDS_ITEM_0325, ///< \ru NURBS поверхность. \en NURBS surface. + IDS_ITEM_0326, ///< \ru Треугольная NURBS поверхность. \en Triangular NURBS surface. + IDS_ITEM_0327, ///< \ru Поверхность Безье. \en Bezier surface. + IDS_ITEM_0328, ///< \ru Эквидистантная поверхность. \en Offset surface. + IDS_ITEM_0329, ///< \ru Деформированная поверхность. \en Deformed surface. + IDS_ITEM_0330, ///< \ru Поверхность Грегори. \en Gregory Surface. + IDS_ITEM_0331, ///< \ru Поверхность соединения. \en Joint surface. + IDS_ITEM_0332, ///< \ru Поверхность объединения. \en Join surface. + IDS_ITEM_0333, ///< \ru Поверхность на трех кривых. \en Surface based on three curves. + IDS_ITEM_0334, ///< \ru Поверхность на четырех кривых. \en Surface based on four curves. + IDS_ITEM_0335, ///< \ru Поверхность-фаска. \en Chamfer surface. + IDS_ITEM_0336, ///< \ru Поверхность скругления. \en Fillet surface. + IDS_ITEM_0337, ///< \ru Переменная поверхность скругления. \en Variable fillet surface. + IDS_ITEM_0338, ///< \ru Поверхность на семействе кривых. \en Lofted surface. + IDS_ITEM_0339, ///< \ru Поверхность на сетке кривых. \en Surface defined on a mesh of curves. + IDS_ITEM_0340, ///< \ru Поверхность скругления по кромке. \en Surface of fillet by border. + IDS_ITEM_0341, ///< \ru Поверхность по замкнутому контуру. \en Surface on closed contour. + IDS_ITEM_0342, ///< \ru Плазовая поверхность. \en Spiling surface. + IDS_ITEM_0343, ///< \ru Поверхность Кунса. \en Coons surface. + IDS_ITEM_0345, ///< \ru Поверхность на сетке точек. \en Surface based on a point grid. + IDS_ITEM_0346, ///< \ru Треугольная поверхность Безье. \en Triangular Bezier surface. + IDS_ITEM_0349, ///< \ru Усеченная контурами поверхность. \en Curve bounded surface. + IDS_ITEM_0350, ///< \ru Поверхность-копия. \en Copy surface. + IDS_ITEM_0351, ///< \ru Поверхность соединения. \en Joint surface. + IDS_ITEM_0352, ///< \ru Поверхность полного скругления. \en Full fillet surface. + IDS_ITEM_0353, ///< \ru Поверхность заметания с масштабированием. \en Swept surface with scaling. + +// \ru Типы тел \en Types of solids + + IDS_ITEM_0401, ///< \ru Тело. \en Solid. + IDS_ITEM_0402, ///< \ru Оболочка. \en Shell. + IDS_ITEM_0403, ///< \ru Проволочный каркас. \en Wireframe. + IDS_ITEM_0404, ///< \ru Точечный каркас. \en Point frame. + IDS_ITEM_0405, ///< \ru Коллекция элементов. \en Collection of elements. + +// \ru Типы строителей. \en Types of creators. + + IDS_ITEM_0501, ///< \ru Журнал построения. \en Build log. + IDS_ITEM_0502, ///< \ru Шар. \en Sphere. + IDS_ITEM_0503, ///< \ru Тор. \en Torus. + IDS_ITEM_0504, ///< \ru Цилиндр. \en Cylinder. + IDS_ITEM_0505, ///< \ru Конус. \en Cone. + IDS_ITEM_0506, ///< \ru Блок. \en Block. + IDS_ITEM_0507, ///< \ru Клин. \en Wedge. + IDS_ITEM_0508, ///< \ru Призма. \en Prism. + IDS_ITEM_0509, ///< \ru Пирамида. \en Pyramid. + IDS_ITEM_0510, ///< \ru Твёрдое тело. \en Solid. + + IDS_ITEM_0515, ///< \ru Объединение оболочек. \en Shells union. + IDS_ITEM_0516, ///< \ru Пересечение оболочек. \en Shells intersection. + IDS_ITEM_0517, ///< \ru Разность оболочек. \en Shells subtraction. + + IDS_ITEM_0520, ///< \ru Отверстие. \en Hole. + IDS_ITEM_0521, ///< \ru Карман/Бобышка. \en Pocket/Boss. + IDS_ITEM_0522, ///< \ru Паз. \en Groove. + IDS_ITEM_0523, ///< \ru Заплатка. \en Patch. + IDS_ITEM_0524, ///< \ru Тонкая оболочка. \en Thin shell. + + IDS_ITEM_0526, ///< \ru Оболочка на семействе кривых. \en Shell defined by a set of curves. + IDS_ITEM_0527, ///< \ru Продолженная оболочка. \en Extended shell. + IDS_ITEM_0528, ///< \ru Эквидистантная оболочка. \en Offset shell. + IDS_ITEM_0529, ///< \ru Срединная оболочка. \en Median shell. + + IDS_ITEM_0531, ///< \ru Булево объединение тел. \en Boolean union of solids. + IDS_ITEM_0532, ///< \ru Булево пересечение тел. \en Boolean intersection of solids. + IDS_ITEM_0533, ///< \ru Булевa разность тел. \en Boolean subtraction of solids. + IDS_ITEM_0534, ///< \ru Разрезанное тело. \en Cut solid. + IDS_ITEM_0535, ///< \ru Фаски ребер. \en Edges chamfers. + IDS_ITEM_0536, ///< \ru Скругление ребер. \en Edges fillets. + IDS_ITEM_0537, ///< \ru Симметричное тело. \en Symmetric solid. + IDS_ITEM_0538, ///< \ru Оболочечное тело. \en Thin shell solid. + IDS_ITEM_0539, ///< \ru Тело приданием толщины. \en Solid of thickening. + IDS_ITEM_0540, ///< \ru Оболочка с удалёнными гранями. \en Shell with removed faces. + IDS_ITEM_0541, ///< \ru Коробчатое тело. \en Box-like solid. + IDS_ITEM_0542, ///< \ru Кинематическое тело. \en Sweeping solid. + IDS_ITEM_0543, ///< \ru Тело заметания. \en Swept solid. + IDS_ITEM_0544, ///< \ru Тело выдавливания. \en Extrusion solid. + IDS_ITEM_0545, ///< \ru Тело вращения. \en Revolution solid. + IDS_ITEM_0546, ///< \ru Тело по сечениям. \en Loft solid. + IDS_ITEM_0547, ///< \ru Простое тело. \en Simple solid. + IDS_ITEM_0548, ///< \ru Ребро жесткости тела. \en Rib of a solid. + IDS_ITEM_0549, ///< \ru Набор тел. \en Set of solids. + IDS_ITEM_0550, ///< \ru Часть набора тел. \en Set of solids part. + IDS_ITEM_0551, ///< \ru Клон граней тела. \en Solid's faces drafting. + IDS_ITEM_0552, ///< \ru Разбивка граней тела. \en Splitting of solid's faces. + IDS_ITEM_0553, ///< \ru Сшитое из оболочек тело. \en Stitched solid. + IDS_ITEM_0554, ///< \ru Сшитая из оболочек оболочка. \en Shell stitched from shells. + IDS_ITEM_0555, ///< \ru Оболочка из NURBS-поверхностей. \en Shell from NURBS-surfaces. + IDS_ITEM_0556, ///< \ru Трансформированное тело. \en Transformed solid. + IDS_ITEM_0557, ///< \ru Модифицированное тело. \en Modified solid. + IDS_ITEM_0558, ///< \ru Оболочка из линейчатых поверхностей. \en Shell from ruled surfaces. + IDS_ITEM_0559, ///< \ru Усеченная оболочка. \en Truncated shell. + IDS_ITEM_0560, ///< \ru Оболочка соединения. \en Joint shell. + IDS_ITEM_0561, ///< \ru Тело с восстановленными боковыми рёбрами. \en Solid with restored lateral edges. + IDS_ITEM_0562, ///< \ru Объединение с кинематическим телом. \en Union with a sweeping solid. + IDS_ITEM_0563, ///< \ru Модифицированное тело NURBS-поверхностями. \en Solid modified with NURBS-surfaces. + IDS_ITEM_0564, ///< \ru Объединение с телом выдавливания. \en Union with an extrusion solid. + IDS_ITEM_0565, ///< \ru Объединение с телом вращения. \en Union with a revolution solid. + IDS_ITEM_0566, ///< \ru Объединение с телом по сечениям. \en Union with a lofted solid. + IDS_ITEM_0567, ///< \ru Объединение с простым телом. \en Union with an elementary solid. + IDS_ITEM_0568, ///< \ru Модифицированная NURBS-поверхность грани. \en Modified NURBS-surface of the face. + IDS_ITEM_0569, ///< \ru Объединение с набором тел. \en Union with a solid set. + IDS_ITEM_0570, ///< \ru Оболочка грани соединения. \en Joint face shell. + IDS_ITEM_0571, ///< \ru Скругление граней. \en Faces fillet. + IDS_ITEM_0572, ///< \ru Разность с кинематическим телом. \en Subtraction with a sweeping solid. + IDS_ITEM_0573, ///< \ru Удаление результата операции. \en Delete the result of the operation. + IDS_ITEM_0574, ///< \ru Разность с телом выдавливания. \en Subtraction with an extrusion solid. + IDS_ITEM_0575, ///< \ru Разность с телом вращения. \en Subtraction with a revolution solid. + IDS_ITEM_0576, ///< \ru Разность с телом по сечениям. \en Subtraction with a lofted solid. + IDS_ITEM_0577, ///< \ru Разность с простым телом. \en Subtraction with an elementary solid. + IDS_ITEM_0578, ///< \ru Упрощение развёртки. \en The flat pattern simplification. + IDS_ITEM_0579, ///< \ru Разность с набором тел. \en Subtraction with a set of solids. + IDS_ITEM_0780, ///< \ru Вывернутое тело. \en Reversed solid. + IDS_ITEM_0581, ///< \ru Сгиб нелистового тела. \en Bend of a non-sheet solid. + IDS_ITEM_0582, ///< \ru Пересечение с кинематическим телом. \en Intersection with a sweeping solid. + IDS_ITEM_0583, ///< \ru Сферическая штамповка. \en Spherical stamping. + IDS_ITEM_0584, ///< \ru Пересечение с телом выдавливания. \en Intersection with an extrusion solid. + IDS_ITEM_0585, ///< \ru Пересечение с телом вращения. \en Intersection with a revolution solid. + IDS_ITEM_0586, ///< \ru Пересечение с телом по сечениям. \en Intersection with a lofted solid. + IDS_ITEM_0587, ///< \ru Пересечение с простым телом. \en Intersection with an elementary solid. + IDS_ITEM_0588, ///< \ru Обечайка. \en Ruled shell. + IDS_ITEM_0589, ///< \ru Пересечение с набором тел. \en Intersection with a set of solids. + IDS_ITEM_0590, ///< \ru Оболочка по сети кривых. \en Shell defined by a mesh of curves. + IDS_ITEM_0591, ///< \ru Комбинированный сгиб. \en Combined bend. + IDS_ITEM_0592, ///< \ru Кинематическая оболочка. \en Sweep with guide curve shell. + IDS_ITEM_0593, ///< \ru Жалюзи. \en Jalousie. + IDS_ITEM_0594, ///< \ru Оболочка выдавливания. \en Extrusion shell. + IDS_ITEM_0595, ///< \ru Оболочка вращения. \en Revolution shell. + IDS_ITEM_0596, ///< \ru Оболочка по сечениям. \en Loft shell. + IDS_ITEM_0597, ///< \ru Тонкая оболочка. \en Thin shell. + IDS_ITEM_0598, ///< \ru Разрезанная оболочка. \en Cut shell. + IDS_ITEM_0599, ///< \ru Буртик. \en Bead. + IDS_ITEM_0600, ///< \ru Сгиб/разгиб листового тела. \en Bend/unbend of a sheet solid. + IDS_ITEM_0601, ///< \ru Сгиб листового тела по отрезку. \en Bend of a sheet solid by a segment. + IDS_ITEM_0602, ///< \ru Сгиб листового тела по рёбрам. \en Bend of a sheet solid along edges. + IDS_ITEM_0603, ///< \ru Замыкание угла листового тела. \en Closure of a sheet solid corner. + IDS_ITEM_0604, ///< \ru Листовое тело. \en Sheet solid. + IDS_ITEM_0605, ///< \ru Пластина листового тела. \en Sheet solid plate. + IDS_ITEM_0606, ///< \ru Вырез листового тела. \en Cut of a sheet solid. + IDS_ITEM_0607, ///< \ru Пересечение листового тела. \en Sheet solid intersection. + IDS_ITEM_0608, ///< \ru Подсечка листового тела. \en Jog of a sheet solid. + IDS_ITEM_0609, ///< \ru Штамповка. \en Stamping. + +// \ru Способы построения оболочек. \en Shells construction methods. + + IDS_ITEM_0610, ///< \ru Оболочка. \en Shell. + IDS_ITEM_0611, ///< \ru Оболочка на базе поверхности. \en Shell based on a surface. + + IDS_ITEM_0614, ///< \ru Оболочка тела. \en Shell. + IDS_ITEM_0615, ///< \ru Журнал построения. \en Build log. + IDS_ITEM_0616, ///< \ru Атрибуты объекта. \en Object Attributes. + + IDS_ITEM_0620, ///< \ru Оболочка тела. \en Shell. + IDS_ITEM_0621, ///< \ru Ориентированное ребро цикла. \en Oriented edge of a loop. + IDS_ITEM_0622, ///< \ru Цикл грани. \en Face loop. + IDS_ITEM_0623, ///< \ru Грань оболочки. \en Face of a shell. + IDS_ITEM_0624, ///< \ru Вершина. \en Vertex. + IDS_ITEM_0625, ///< \ru Ребро оболочки. \en Edge of a shell. + IDS_ITEM_0626, ///< \ru Ребро каркаса. \en Edge of a frame. + + IDS_ITEM_0627, ///< \ru Вершина. \en Vertex. + + IDS_ITEM_0628, ///< \ru Разделенная оболочка. \en Divided shell. + +// \ru Способы построения проекций тела\оболочки. \en Solid/shell projections creation methods. + + IDS_ITEM_0650, ///< \ru Проекция тела. \en Solid projection. + IDS_ITEM_0651, ///< \ru Разрез тела. \en Solid cutting. + IDS_ITEM_0652, ///< \ru Сечение тела. \en Solid section. + + IDS_ITEM_0653, ///< \ru Размножение тела. \en Duplication of solids. + +// \ru Вспомогательный объект. \en The helper object. + + IDS_ITEM_0669, ///< \ru Вспомогательный объект. \en The helper object. + +// \ru Резьба. \en A thread. + + IDS_ITEM_0670, ///< \ru Резьба. \en Thread. + +// \ru Обозначение \en Notation + + IDS_ITEM_0671, ///< \ru Условное обозначение. \en Symbolic notation. + +// \ru Объекты. \en Objects. + + IDS_ITEM_0700, ///< \ru Геометрический объект. \en Geometric object. + IDS_ITEM_0701, ///< \ru Переменная уравнения. \en Equation variable. + IDS_ITEM_0702, ///< \ru Объект на плоскости. \en Object on a plane. + IDS_ITEM_0703, ///< \ru Объект в пространстве. \en Object in space. + IDS_ITEM_0704, ///< \ru Объект модели. \en Model object. + IDS_ITEM_0705, ///< \ru Сборочная единица. \en Assembly unit. + IDS_ITEM_0706, ///< \ru Вспомогательный объект. \en Auxiliary object. + IDS_ITEM_0707, ///< \ru Вставка объекта. \en Object instance. + IDS_ITEM_0708, ///< \ru Количество элементов. \en Number of elements. + IDS_ITEM_0709, ///< \ru Геометрическая модель. \en Geometric model. + +// \ru Атрибуты \en Attributes + + IDS_ITEM_0729, ///< \ru Атрибуты модели. \en Model attributes. + IDS_ITEM_0730, ///< \ru Поставщик атрибутов. \en Attributes provider. + IDS_ITEM_0731, ///< \ru Атрибуты объекта. \en Object attributes. + IDS_ITEM_0732, ///< \ru Атрибут. \en Attribute. + IDS_ITEM_0733, ///< \ru Имя примитива. \en Primitive name. + IDS_ITEM_0734, ///< \ru Поведение атрибутов. \en Attributes behavior. + + IDS_ITEM_0751, ///< \ru Механические характеристики. \en Mechanical properties. + IDS_ITEM_0754, ///< \ru Деформации. \en Strains. + + IDS_ITEM_0761, ///< \ru Исполнение (вариант реализации модели). \en Embodiment (variant of model implementation). + IDS_ITEM_0762, ///< \ru Количество u-линий и v-линий отрисовочной сетки. \en The number of u-mesh and v-mesh lines. + IDS_ITEM_0763, ///< \ru Плотность. \en Density. + IDS_ITEM_0764, ///< \ru Цвет. \en Color. + IDS_ITEM_0765, ///< \ru Толщина. \en Thickness. + IDS_ITEM_0766, ///< \ru Стиль. \en Style. + IDS_ITEM_0767, ///< \ru Визуальные свойства. \en Visual properties. + IDS_ITEM_0768, ///< \ru Идентификатор. \en Identifier. + IDS_ITEM_0769, ///< \ru Селектированность. \en Selectivity. + IDS_ITEM_0770, ///< \ru Видимость. \en Visibility. + IDS_ITEM_0771, ///< \ru Измененность. \en Modification. + IDS_ITEM_0772, ///< \ru Топологическое имя. \en Topological name. + IDS_ITEM_0773, ///< \ru Якорь. \en Anchor. + IDS_ITEM_0774, ///< \ru Геометрический атрибут. \en Geometric attribute. + IDS_ITEM_0775, ///< \ru Метка времени обновления. \en Label of update time. + IDS_ITEM_0776, ///< \ru Уникальность ключей. \en Keys uniqueness. + IDS_ITEM_0777, ///< \ru Имя объекта в модели. \en Name of object in the model. + IDS_ITEM_0778, ///< \ru Данные об изделии. \en Product data. + IDS_ITEM_0779, ///< \ru Атрибут ребра жесткости листового тела. \en Attribute of stamp rib of sheet solid. + + IDS_ITEM_0782, ///< \ru Атрибут пользовательский. \en Custom attribute. + IDS_ITEM_0783, ///< \ru Атрибут обобщенный. \en Generalized attribute. + IDS_ITEM_0784, ///< \ru Атрибут булев. \en Boolean attribute. + IDS_ITEM_0785, ///< \ru Атрибут целочисленный (32-битный). \en (32 bit ) Integer attribute. + IDS_ITEM_0786, ///< \ru Атрибут действительный. \en Real attribute. + IDS_ITEM_0787, ///< \ru Атрибут строковый. \en String attribute. + IDS_ITEM_0788, ///< \ru Атрибут элементарный. \en Elementary attribute. + IDS_ITEM_0789, ///< \ru Пояснение. \en Prompt. + IDS_ITEM_0790, ///< \ru Атрибут int64. \en Int64 attribute. + IDS_ITEM_0791, ///< \ru Атрибут бинарный. \en Binary attribute. + +// \ru Сообщения. \en Messages. + + IDS_ITEM_0900, ///< \ru ! Ошибка !. \en ! Error ! + IDS_ITEM_0901, ///< \ru Остановлено. \en Stopped. + IDS_ITEM_0902, ///< \ru Пропущено. \en Missed. + +// \ru Состав объектов \en Structure of objects + + IDS_PROP_0000, ///< \ru Пусто. \en Empty. + + IDS_PROP_0001, ///< \ru Кривая на плоскости. \en Curve on a plane. + IDS_PROP_0002, ///< \ru Параметр кривой. \en Parameter of a curve. + IDS_PROP_0003, ///< \ru Кривая 1 на плоскости. \en Curve 1 on the plane. + IDS_PROP_0004, ///< \ru Кривая 2 на плоскости. \en Curve 2 on the plane. + IDS_PROP_0005, ///< \ru Параметр кривой 1. \en Parameter of curve 1. + IDS_PROP_0006, ///< \ru Параметр кривой 2. \en Parameter of curve 2. + IDS_PROP_0007, ///< \ru Начальная точка. \en Start point. + IDS_PROP_0008, ///< \ru Направление. \en Direction. + IDS_PROP_0009, ///< \ru Конечная точка. \en End point. + IDS_PROP_0014, ///< \ru Начальный параметр усечения. \en Start parameter of truncation. + IDS_PROP_0015, ///< \ru Конечный параметр усечения. \en End parameter of truncation. + IDS_PROP_0016, ///< \ru Совпадение направления. \en Coincidence of direction. + IDS_PROP_0017, ///< \ru Циклическая частота. \en Cyclic frequency. + IDS_PROP_0018, ///< \ru Начальная фаза (град). \en Initial phase (degrees). + IDS_PROP_0019, ///< \ru Амплитуда. \en Amplitude. + IDS_PROP_0020, ///< \ru Перевернуть направление. \en Reverse the direction. + IDS_PROP_0021, ///< \ru Неподвижная точка. \en Fixed point. + IDS_PROP_0022, ///< \ru Использовать точку. \en Use a point. + IDS_PROP_0023, ///< \ru Равномерное преобразование. \en Uniform transformation. + IDS_PROP_0024, ///< \ru Точность. \en Tolerance. + IDS_PROP_0025, ///< \ru Начальное значение. \en Start value. + IDS_PROP_0026, ///< \ru Коэффициент усиления. \en Scale gain. + IDS_PROP_0027, ///< \ru Амплитуда. \en Amplitude. + IDS_PROP_0028, ///< \ru Сдвиг параметра. \en Parameter shift. + IDS_PROP_0029, ///< \ru Степень возведения. \en Exponent parameter. + IDS_PROP_0030, ///< \ru Циклическая частота. \en Frequency. + IDS_PROP_0031, ///< \ru Эквидистантное смещение. \en The offset range. + IDS_PROP_0032, ///< \ru Тип кривой. \en Type of curve. + + IDS_PROP_0101, ///< \ru Координата X. \en Coordinate X. + IDS_PROP_0102, ///< \ru Координата Y. \en Coordinate Y. + IDS_PROP_0103, ///< \ru Координата Z. \en Coordinate Z. + IDS_PROP_0104, ///< \ru Матрица. \en Matrix. + IDS_PROP_0107, ///< \ru Угол с осью X. \en Angle with axis X. + IDS_PROP_0108, ///< \ru Угол с осью Y. \en Angle with axis Y. + IDS_PROP_0109, ///< \ru Угол с осью Z. \en Angle with axis Z. + IDS_PROP_0110, ///< \ru Точка. \en Point. + IDS_PROP_0111, ///< \ru Компонента 1.X. \en Component 1.X. + IDS_PROP_0112, ///< \ru Компонента 1.Y. \en Component 1.Y. + IDS_PROP_0113, ///< \ru Компонента 1.Z. \en Component 1.Z. + IDS_PROP_0114, ///< \ru Компонента 2.X. \en Component 2.X. + IDS_PROP_0115, ///< \ru Компонента 2.Y. \en Component 2.Y. + IDS_PROP_0116, ///< \ru Компонента 2.Z. \en Component 2.Z. + IDS_PROP_0117, ///< \ru Компонента 3.X. \en Component 3.X. + IDS_PROP_0118, ///< \ru Компонента 3.Y. \en Component 3.Y. + IDS_PROP_0119, ///< \ru Компонента 3.Z. \en Component 3.Z. + IDS_PROP_0120, ///< \ru Вектор. \en Vector. + IDS_PROP_0121, ///< \ru Сдвиг по X. \en Shift by X. + IDS_PROP_0122, ///< \ru Сдвиг по Y. \en Shift by Y. + IDS_PROP_0123, ///< \ru Сдвиг по Z. \en Shift by Z. + IDS_PROP_0124, ///< \ru Ось X. \en Axis X. + IDS_PROP_0125, ///< \ru Ось Y. \en Axis Y. + IDS_PROP_0126, ///< \ru Ось Z. \en Axis Z. + IDS_PROP_0127, ///< \ru Длина оси X. \en Length of axis X. + IDS_PROP_0128, ///< \ru Длина оси Y. \en Length of axis Y. + IDS_PROP_0129, ///< \ru Длина оси Z. \en Length of axis Z. + IDS_PROP_0130, ///< \ru Центр. \en Center. + IDS_PROP_0131, ///< \ru Левая система. \en Left system. + IDS_PROP_0132, ///< \ru Прямоугольная. \en Rectangular. + IDS_PROP_0133, ///< \ru Базовая точка. \en Base point. + IDS_PROP_0134, ///< \ru Строка. \en String. + IDS_PROP_0135, ///< \ru Шрифт. \en Font. + IDS_PROP_0136, ///< \ru Позиция начала. \en Start position. + IDS_PROP_0137, ///< \ru Высота. \en Height. + IDS_PROP_0138, ///< \ru Сужение. \en Taper. + IDS_PROP_0139, ///< \ru Угол наклона. \en Slope angle. + IDS_PROP_0140, ///< \ru Радиус. \en Radius. + IDS_PROP_0141, ///< \ru Масштаб по X. \en Scale by X. + IDS_PROP_0142, ///< \ru Масштаб по Y. \en Scale by Y. + IDS_PROP_0143, ///< \ru Масштаб по Z. \en Scale by Z. + IDS_PROP_0144, ///< \ru Функция масштабирования. \en The function of scaling. + IDS_PROP_0145, ///< \ru Функция вращения. \en The function of rotation. + + IDS_PROP_0150, ///< \ru Угол. \en Angle. + IDS_PROP_0151, ///< \ru Шаг. \en Step. + IDS_PROP_0152, ///< \ru Смещение зазора. \en Gap displacement. + IDS_PROP_0153, ///< \ru Перемещение. \en Translation. + IDS_PROP_0154, ///< \ru Вращение. \en Rotation. + IDS_PROP_0155, ///< \ru Общий масштаб. \en Common scale. + IDS_PROP_0156, ///< \ru Зеркальность. \en Specularity. + IDS_PROP_0157, ///< \ru Только ортогональность. \en Orthogonality only. + IDS_PROP_0158, ///< \ru Объект общего вида. \en General object. + IDS_PROP_0159, ///< \ru Перспектива. \en Perspective. + IDS_PROP_0160, ///< \ru Локальная система координат. \en Local coordinate system. + IDS_PROP_0161, ///< \ru Начальное значение. \en Start value. + IDS_PROP_0162, ///< \ru Конечное значение. \en End value. + IDS_PROP_0163, ///< \ru Значение. \en Value. + IDS_PROP_0164, ///< \ru Функция изменения радиусов. \en Radius function. + IDS_PROP_0165, ///< \ru Функция изменения веса. \en Weight function. + IDS_PROP_0166, ///< \ru Функция. \en Function. + IDS_PROP_0167, ///< \ru Минимум. \en Minimum. + IDS_PROP_0168, ///< \ru Максимум. \en Maximum + + IDS_PROP_0169, ///< \ru Продлевать вверх?. \en Extend upwards?. + IDS_PROP_0170, ///< \ru Поворот оси вокруг нормали. \en Rotation of axis about the normal. + IDS_PROP_0171, ///< \ru Угол между осью и нормалью. \en Angle between the axis and the normal. + IDS_PROP_0172, ///< \ru Диаметр головки. \en Cap diameter. + IDS_PROP_0173, ///< \ru Глубина под головку. \en Depth for a cap. + IDS_PROP_0174, ///< \ru Угол фаски под головку. \en Chamfer angle for a cap. + IDS_PROP_0175, ///< \ru Диаметр отверстия под резьбу. \en Diameter of hole for a cap. + IDS_PROP_0176, ///< \ru Глубина отверстия под резьбу. \en Depth of hole for a cap. + IDS_PROP_0177, ///< \ru Угол конусности отверстия. \en Taper angle of hole. + IDS_PROP_0178, ///< \ru Угол раствора конца отверстия. \en Apical angle of hole end. + IDS_PROP_0179, ///< \ru Тип отверстия. \en Hole type. + IDS_PROP_0180, ///< \ru Способ модификации. \en Method of modification. + + IDS_PROP_0181, ///< \ru Тип(true-бобышка, false- карман). \en Type(true-boss, false- pocket). + IDS_PROP_0182, ///< \ru Тип. \en Type. + IDS_PROP_0183, ///< \ru Ширина. \en Width. + IDS_PROP_0184, ///< \ru Ширина. \en Width. + IDS_PROP_0185, ///< \ru Способ. \en Method. + IDS_PROP_0186, ///< \ru Новая грань. \en New face. + + IDS_PROP_0188, ///< \ru Направление (вниз/вверх). \en Direction (down/up). + IDS_PROP_0189, ///< \ru Радиус дуги. \en Arc radius. + +// \ru Параметры. \en Parameters. + + IDS_PROP_0201, ///< \ru Объект на числах double. \en Object on double data. + IDS_PROP_0202, ///< \ru Объект на числах float. \en Object on float data. + IDS_PROP_0203, ///< \ru Кривая 1. \en Curve 1. + IDS_PROP_0204, ///< \ru Кривая 2. \en Curve 2. + IDS_PROP_0205, ///< \ru Кривая 3. \en Curve 3. + IDS_PROP_0206, ///< \ru Кривая 4. \en Curve 4 + IDS_PROP_0207, ///< \ru Начальная точка. \en Start point. + IDS_PROP_0208, ///< \ru Направляющий вектор. \en Direction vector. + IDS_PROP_0209, ///< \ru Конечная точка. \en End point. + IDS_PROP_0210, ///< \ru Нормаль к плоскости.\en Normal to surface. + IDS_PROP_0211, ///< \ru Первая полуось. \en First semiaxis. + IDS_PROP_0212, ///< \ru Вторая полуось. \en Second semiaxis. + IDS_PROP_0213, ///< \ru Фокусное расстояние. \en Focal distance. + IDS_PROP_0214, ///< \ru Параметр min. \en Parameter min. + IDS_PROP_0215, ///< \ru Параметр max. \en Parameter max. + IDS_PROP_0216, ///< \ru Действительная полуось. \en Real semiaxis. + IDS_PROP_0217, ///< \ru Мнимая полуось. \en Imaginary semiaxis. + IDS_PROP_0218, ///< \ru Приращение начального параметра. \en Increment of start parameter. + IDS_PROP_0219, ///< \ru Приращение конечного параметра. \en Increment of end parameter. + IDS_PROP_0220, ///< \ru Замкнутость. \en Closedness. + IDS_PROP_0221, ///< \ru Порядок. \en Order. + IDS_PROP_0222, ///< \ru Количество точек. \en Number of points. + IDS_PROP_0223, ///< \ru Точка. \en Point. + IDS_PROP_0224, ///< \ru Начальный параметр. \en Start parameter. + IDS_PROP_0225, ///< \ru Производная параметра. \en Derivative of parameter. + IDS_PROP_0226, ///< \ru Параметрическая длина. \en Parametric length. + IDS_PROP_0227, ///< \ru Положительное направление. \en Positive direction. + IDS_PROP_0228, ///< \ru Вес. \en Weight. + // IDS_PROP_0229, ///< \ru Касание. \en Tangency. (МА 2019 Лишнее?) + IDS_PROP_0230, ///< \ru Расстояние. \en Distance. + IDS_PROP_0232, ///< \ru Число кривых контура. \en Number of curves of contour. + IDS_PROP_0233, ///< \ru Кривая. \en Curve. + IDS_PROP_0234, ///< \ru Начальный параметр кривой. \en Start parameter of a curve. + IDS_PROP_0235, ///< \ru Конечный параметр кривой. \en End parameter of a curve. + IDS_PROP_0236, ///< \ru Число узлов. \en Number of knots. + IDS_PROP_0237, ///< \ru Значение узла. \en Knot value. + IDS_PROP_0238, ///< \ru Вторая производная в точке. \en Second derivative at a point. + IDS_PROP_0239, ///< \ru Производная. \en Derivative. + IDS_PROP_0240, ///< \ru Кривая. \en Curve. + IDS_PROP_0241, ///< \ru Зависимость по X. \en Dependency by X. + IDS_PROP_0242, ///< \ru Зависимость по Y. \en Dependency by Y. + IDS_PROP_0243, ///< \ru Зависимость по Z. \en Dependency by Z. + IDS_PROP_0244, ///< \ru Расширение minPar. \en Extension minPar. + IDS_PROP_0245, ///< \ru Расширение maxPar. \en Extension maxPar. + IDS_PROP_0246, ///< \ru Количество сплайнов. \en Number of splines. + IDS_PROP_0250, ///< \ru Базовая кривая. \en Base curve. + IDS_PROP_0260, ///< \ru Двумерная кривая. \en Two-dimensional curve. + IDS_PROP_0263, ///< \ru Угол между OX плоскости и прямой касания ее с конусом. \en Angle of OX axis of a plane and the line of its tangency with a cone. + IDS_PROP_0264, ///< \ru Расстояние от листовой грани до нейтрального слоя. \en Distance from a sheet face to the neutral layer. + IDS_PROP_0265, ///< \ru Угол образующей конуса, касательной к плоскости при разгибе. \en Angle of a cone generatrix tangent to the plane while unbending. + IDS_PROP_0266, ///< \ru Количество образующих кривых. \en Number of generating lines. + IDS_PROP_0267, ///< \ru Объект модифицирован. \en Object is modified. + IDS_PROP_0268, ///< \ru Количество нормалей. \en Number of normals. + IDS_PROP_0269, ///< \ru Нормаль. \en Normal. + IDS_PROP_0270, ///< \ru Аппроксимационная кривая. \en Approximation curve. + + IDS_PROP_0271, ///< \ru Удаление выбранных граней. \en Remove selected faces. + IDS_PROP_0272, ///< \ru Создание тела из выбранных граней. \en Solid creation by selected faces. + IDS_PROP_0273, ///< \ru Перемещение выбранных граней. \en Move selected faces. + IDS_PROP_0274, ///< \ru Смещение выбранных граней по нормали. \en Offset selected faces. + IDS_PROP_0275, ///< \ru Изменение радиусов выбранных скруглений. \en Change selected fillets. + IDS_PROP_0276, ///< \ru Замена выбранных граней деформируемыми. \en Replace selected faces by deformed. + IDS_PROP_0277, ///< \ru Удаление выбранных скруглений. \en Remove selected features. + IDS_PROP_0278, ///< \ru Слияние вершин выбранных ребер. \en Merging vertices of selected edges. + + IDS_PROP_0282, ///< \ru Вектор модификации. \en The vector of modification. + IDS_PROP_0283, ///< \ru Количество модифицированных граней. \en Number of modified faces. + IDS_PROP_0284, ///< \ru Положение срединной оболочки тела. \en Position of median shell. + IDS_PROP_0285, ///< \ru Минимальное расстояние между гранями. \en Minimal equidistation value. + IDS_PROP_0286, ///< \ru Максимальное расстояние между гранями. \en Maximal equidistant value. + + IDS_PROP_0301, ///< \ru Начальный параметр U. \en Start parameter U. + IDS_PROP_0302, ///< \ru Начальный параметр V. \en Start parameter V. + IDS_PROP_0303, ///< \ru Положительное направление U. \en Positive direction by U. + IDS_PROP_0304, ///< \ru Положительное направление V. \en Positive direction by V. + IDS_PROP_0305, ///< \ru Параметрическая длина U. \en Parametric length by U. + IDS_PROP_0306, ///< \ru Параметрическая длина V. \en Parametric length by V. + IDS_PROP_0307, ///< \ru Положительное направление 1. \en Positive direction 1. + IDS_PROP_0308, ///< \ru Положительное направление 2. \en Positive direction 2. + IDS_PROP_0309, ///< \ru Тип сопряжения. \en Conjugation type. + IDS_PROP_0310, ///< \ru Точка. \en Point. + IDS_PROP_0311, ///< \ru Замкнутость по U. \en Closedness by U. + IDS_PROP_0312, ///< \ru Замкнутость по V. \en Closedness by V. + IDS_PROP_0313, ///< \ru Число порций по U. \en Number of portions by U. + IDS_PROP_0314, ///< \ru Число порций по V. \en Number of portions by V. + IDS_PROP_0315, ///< \ru Порядок по U. \en Order by U. + IDS_PROP_0316, ///< \ru Порядок по V. \en Order by V. + IDS_PROP_0317, ///< \ru Число точек по U. \en Number of points by U. + IDS_PROP_0318, ///< \ru Число точек по V. \en Number of points by V. + IDS_PROP_0320, ///< \ru Локальная система. \en Local system. + IDS_PROP_0321, ///< \ru Радиус основания. \en Radius of base. + IDS_PROP_0322, ///< \ru Высота. \en Height. + IDS_PROP_0323, ///< \ru Половина угла. \en Half-angle. + IDS_PROP_0324, ///< \ru Большой радиус. \en Major radius. + IDS_PROP_0325, ///< \ru Малый радиус. \en Minor radius. + IDS_PROP_0326, ///< \ru Длина. \en Length. + IDS_PROP_0327, ///< \ru Смещение. \en Shift. + IDS_PROP_0328, ///< \ru Форма. \en Shape. + IDS_PROP_0329, ///< \ru Закрепление границы поверхности. \en Surface boundary fixation. + IDS_PROP_0330, ///< \ru Отличается от базовой поверхности. \en Differs from the base surface. + IDS_PROP_0331, ///< \ru Видимая длина Xmin. \en Visible length Xmin. + IDS_PROP_0332, ///< \ru Видимая длина Ymin. \en Visible length Ymin. + IDS_PROP_0333, ///< \ru Видимая длина Xmax. \en Visible length Xmax. + IDS_PROP_0334, ///< \ru Видимая длина Ymax. \en Visible length Ymax. + IDS_PROP_0336, ///< \ru Число узлов по U. \en Number of knots by U. + IDS_PROP_0337, ///< \ru Значение U узла. \en Value of U knot. + IDS_PROP_0338, ///< \ru Число узлов по V. \en Number of knots by V. + IDS_PROP_0339, ///< \ru Значение V узла. \en Value of V knot. + IDS_PROP_0340, ///< \ru Поверхность. \en Surface. + IDS_PROP_0341, ///< \ru Направляющая кривая. \en Guide curve . + IDS_PROP_0342, ///< \ru Образующая кривая. \en Generating curve. + IDS_PROP_0343, ///< \ru Вектор смещения. \en Translation vector. + IDS_PROP_0344, ///< \ru Вектор направления. \en Direction vector. + IDS_PROP_0345, ///< \ru Точка оси вращения. \en Point of the rotation axis. + IDS_PROP_0346, ///< \ru Направление оси. \en Axis direction. + IDS_PROP_0347, ///< \ru Угол вращения. \en Rotation angle. + IDS_PROP_0348, ///< \ru Вершина. \en Vertex. + IDS_PROP_0350, ///< \ru Базовая поверхность. \en Base surface. + IDS_PROP_0351, ///< \ru Поверхность 1. \en Surface 1. + IDS_PROP_0352, ///< \ru Поверхность 2. \en Surface 2. + IDS_PROP_0353, ///< \ru Контур. \en Contour. + IDS_PROP_0354, ///< \ru Число контуров. \en Number of contours. + IDS_PROP_0355, ///< \ru Двумерный контур. \en Two-dimensional contour. + IDS_PROP_0356, ///< \ru Двумерная кривая. \en Two-dimensional curve. + IDS_PROP_0357, ///< \ru Контур 1. \en Contour 1. + IDS_PROP_0358, ///< \ru Контур 2. \en Contour 2. + IDS_PROP_0360, ///< \ru Плоскость. \en Plane. + IDS_PROP_0361, ///< \ru Вес поверхности 1. \en Weight of surface 1. + IDS_PROP_0362, ///< \ru Вес поверхности 2. \en Weight of surface 2. + IDS_PROP_0363, ///< \ru Производная в начале. \en Derivative at the beginning. + IDS_PROP_0364, ///< \ru Производная в конце. \en Derivative at the end. + IDS_PROP_0370, ///< \ru Кривая на поверхности 0. \en Curve on surface 0. + IDS_PROP_0371, ///< \ru Кривая на поверхности 1. \en Curve on surface 1. + IDS_PROP_0372, ///< \ru Кривая на поверхности 2. \en Curve on surface 2. + IDS_PROP_0373, ///< \ru Кривая вершин. \en Curve of vertices. + IDS_PROP_0374, ///< \ru Параметр Umin. \en Parameter Umin. + IDS_PROP_0375, ///< \ru Параметр Umax. \en Parameter Umax. + IDS_PROP_0376, ///< \ru Параметр Vmin. \en Parameter Vmin. + IDS_PROP_0377, ///< \ru Параметр Vmax. \en Parameter Vmax. + IDS_PROP_0378, ///< \ru Производная dU. \en Derivative dU. + IDS_PROP_0379, ///< \ru Производная dV. \en Derivative dV. + IDS_PROP_0380, ///< \ru Кромка проходит по Vmin. \en Boundary passes through Vmin. + IDS_PROP_0384, ///< \ru Расширение minUPar. \en Extension minUPar. + IDS_PROP_0385, ///< \ru Расширение maxUPar. \en Extension maxUPar. + IDS_PROP_0386, ///< \ru Расширение minVPar. \en Extension minVPar. + IDS_PROP_0387, ///< \ru Расширение maxVPar. \en Extension maxVPar. + IDS_PROP_0390, ///< \ru Число кривых. \en Number of curves. + IDS_PROP_0391, ///< \ru Кривая по U. \en Curve by U + IDS_PROP_0392, ///< \ru Кривая по V. \en Curve by V. + IDS_PROP_0393, ///< \ru Число кривых по U. \en Number of curves by U. + IDS_PROP_0394, ///< \ru Число кривых по V. \en Number of curves by V. + IDS_PROP_0395, ///< \ru Тип поверхности. \en Type of surface. + IDS_PROP_0397, ///< \ru Нейтральная плоскость. \en Neutral plane. + IDS_PROP_0398, ///< \ru Плоскость контура. \en Plane of the contour. + IDS_PROP_0399, ///< \ru Через элементы. \en Through elements. + IDS_PROP_0400, ///< \ru Сопряжение на границе. \en Conjugation on the boundary. + IDS_PROP_0401, ///< \ru Натяжение на границе. \en Tension on the boundary. + IDS_PROP_0402, ///< \ru Параметр определения длины производных. \en Parameter of derivatives length definition. + IDS_PROP_0403, ///< \ru Не сохранять длину производной. \en Do not keep the derivative length. + IDS_PROP_0404, ///< \ru Тип сопряжения (0-4). \en Conjugation type (0-4). + IDS_PROP_0405, ///< \ru Использовать готовый узловой вектор. \en Use prepared knot vector. + IDS_PROP_0406, ///< \ru Количество узлов. \en Number of knots. + IDS_PROP_0407, ///< \ru Проверка самопересечений. \en Check for self-intersections. + IDS_PROP_0408, ///< \ru Используется общий вес точек. \en The common weight of points is used. + IDS_PROP_0409, ///< \ru Построена по пласту точек. \en Build from a cloud of points. + IDS_PROP_0410, ///< \ru Построена по сети точек. \en Build from a mesh of points. + IDS_PROP_0411, ///< \ru В виде набора треугольников. \en As a set of triangles. + IDS_PROP_0412, ///< \ru Использовать проекционную кривую. \en Use projection curve. + IDS_PROP_0413, ///< \ru Усекать границами. \en Truncate by bounds. + IDS_PROP_0414, ///< \ru Привязка к началу. \en Binding to the beginning. + IDS_PROP_0415, ///< \ru Соединять скруглениями.\en Join by fillets. + IDS_PROP_0416, ///< \ru Сохранять радиус. \en Keep the radius. + IDS_PROP_0417, ///< \ru Притуплять острый угол. \en Blunt a sharp angle. + IDS_PROP_0418, ///< \ru Проверка пересечений. \en Check for intersections. + IDS_PROP_0419, ///< \ru Слияние подобных граней. \en Merging of similar faces. + IDS_PROP_0420, ///< \ru Слияние подобных ребер. \en Merging of similar edges. + + IDS_PROP_0421, ///< \ru Номер соседнего объекта. \en The number of neighbour object. + + IDS_PROP_0450, ///< \ru Начальный радиус (поверхность). \en Start radius (surface). + IDS_PROP_0451, ///< \ru Конечный радиус (резьба). \en End radius (thread). + IDS_PROP_0452, ///< \ru Длина резьбы. \en Thread length. + IDS_PROP_0453, ///< \ru Угол коничности резьбы. \en Taper angle of the thread. + + IDS_PROP_0461, ///< \ru Триангуляция. \en Triangulation. + IDS_PROP_0462, ///< \ru Количество точек триангуляции. \en Number of points of triangulation. + IDS_PROP_0463, ///< \ru Количество двумерных точек. \en Number of two-dimension points. + IDS_PROP_0464, ///< \ru Количество точек полигонов. \en Number of points of polygons. + + IDS_PROP_0501, ///< \ru Число вершин. \en Number of vertices. + IDS_PROP_0502, ///< \ru Число ребер. \en Number of edges. + IDS_PROP_0503, ///< \ru Число граней. \en Number of faces. + IDS_PROP_0504, ///< \ru Ориентация вершины. \en Vertex orientation. + IDS_PROP_0505, ///< \ru Ориентация ребра. \en Edge orientation. + IDS_PROP_0506, ///< \ru Ориентация грани. \en Face orientation. + IDS_PROP_0508, ///< \ru Ребро. \en Edge. + IDS_PROP_0509, ///< \ru Грань. \en Face. + IDS_PROP_0510, ///< \ru Число циклов. \en Number of loops. + IDS_PROP_0511, ///< \ru Цикл. \en Loop. + IDS_PROP_0512, ///< \ru Автоопределение. \en Automatic identification. + IDS_PROP_0513, ///< \ru Автоматическое. \en Automatic. + + IDS_PROP_0514, ///< \ru Тип размножения. \en Type of duplication. + IDS_PROP_0515, ///< \ru Кол-во шагов. \en Number of steps. + IDS_PROP_0516, ///< \ru Шаг. \en Step. + IDS_PROP_0517, ///< \ru Количество угловых шагов. \en Number of angular step. + IDS_PROP_0518, ///< \ru Элемент. \en Element. + IDS_PROP_0519, ///< \ru Сегмент полигональной сетки. \en Segment of polygonal mesh. + + IDS_PROP_0521, ///< \ru Длина Lx. \en Length Lx. + IDS_PROP_0522, ///< \ru Ширина Ly. \en Width Ly. + IDS_PROP_0523, ///< \ru Высота Lz. \en Height Lz. + IDS_PROP_0524, ///< \ru Малая длина lx. \en Minor length lx. + IDS_PROP_0525, ///< \ru Толщина. \en Thickness. + IDS_PROP_0526, ///< \ru Толщина стенки. \en Wall thickness. + IDS_PROP_0527, ///< \ru Число вскрытых граней. \en Number of opened faces. + IDS_PROP_0528, ///< \ru Форма. \en Shape. + IDS_PROP_0529, ///< \ru Сохранять кромку\поверхность\автоопределение. \en Keep the boundary\surface\auto. + IDS_PROP_0530, ///< \ru Продолжить далее. \en Continue. + IDS_PROP_0531, ///< \ru Катет 1. \en Cathetus 1. + IDS_PROP_0532, ///< \ru Катет 2. \en Cathetus 2. + IDS_PROP_0533, ///< \ru Число фасок. \en Number of chamfers. + IDS_PROP_0534, ///< \ru Число скруглений. \en Number of fillets. + IDS_PROP_0535, ///< \ru Радиус скругления. \en Fillet radius. + IDS_PROP_0536, ///< \ru Номер грани. \en Face number. + IDS_PROP_0537, ///< \ru Параметр U. \en Parameter U. + IDS_PROP_0538, ///< \ru Параметр V. \en Parameter V. + IDS_PROP_0539, ///< \ru Число модифицированных граней. \en Number of modified faces. + IDS_PROP_0540, ///< \ru Тело. \en Solid. + IDS_PROP_0541, ///< \ru Строитель тела. \en Construct solid. + IDS_PROP_0542, ///< \ru Количество четырёхугольников. \en Number of quadrangles. + IDS_PROP_0543, ///< \ru Остановка от начала. \en Termination from the start. + IDS_PROP_0544, ///< \ru Остановка до конца. \en Termination to the end. + IDS_PROP_0545, ///< \ru Радиус скругления 1. \en Fillet radius 1. + IDS_PROP_0546, ///< \ru Радиус скругления 2. \en Fillet radius 2. + IDS_PROP_0547, ///< \ru Коэффициент полноты. \en Coefficient of completeness. + IDS_PROP_0548, ///< \ru Способ обработки углов стыковки рёбер. \en Method of processing corners of edges connection. + IDS_PROP_0549, ///< \ru Четырехугольник. \en Quadrangle. + + IDS_PROP_0550, ///< \ru Базовое тело. \en Base solid. + IDS_PROP_0551, ///< \ru Тело 1. \en Solid 1. + IDS_PROP_0552, ///< \ru Тело 2. \en Solid 2. + IDS_PROP_0553, ///< \ru Исходное тело. \en Initial solid. + IDS_PROP_0554, ///< \ru Режущая поверхность. \en Cutting surface. + IDS_PROP_0555, ///< \ru Оставляемая часть. \en A part to keep. + IDS_PROP_0556, ///< \ru Точка симметрии. \en Symmetry point. + IDS_PROP_0557, ///< \ru Ось X симметрии. \en Axis X of symmetry. + IDS_PROP_0558, ///< \ru Ось Y симметрии. \en Axis Y of symmetry. + IDS_PROP_0559, ///< \ru Поверхность. \en Surface. + IDS_PROP_0560, ///< \ru Внешняя оболочка. \en Outer shell. + IDS_PROP_0561, ///< \ru Пустотная оболочка. \en Void shell. + IDS_PROP_0562, ///< \ru Число пустот. \en Number of voids. + IDS_PROP_0563, ///< \ru Глубина 1. \en Depth 1. + IDS_PROP_0564, ///< \ru Глубина 2. \en Depth 2. + IDS_PROP_0565, ///< \ru Угол уклона 1. \en Slope angle 1. + IDS_PROP_0566, ///< \ru Угол уклона 2. \en Slope angle 2. + IDS_PROP_0567, ///< \ru Толщина стенки 1. \en Wall thickness 1. + IDS_PROP_0568, ///< \ru Толщина стенки 2. \en Wall thickness 2. + IDS_PROP_0569, ///< \ru Толщина. \en Thickness. + IDS_PROP_0570, ///< \ru Глубина. \en Depth. + + IDS_PROP_0571, ///< \ru Способ построения. \en Method of construction. + IDS_PROP_0572, ///< \ru Число оболочек. \en Number of shells. + IDS_PROP_0573, ///< \ru Количество треугольников. \en Number of triangles. + IDS_PROP_0575, ///< \ru Угол вращения 1. \en Rotation angle 1. + IDS_PROP_0576, ///< \ru Угол вращения 2. \en Rotation angle 2. + + IDS_PROP_0577, ///< \ru Первая вершина. \en The first vertex. + IDS_PROP_0578, ///< \ru Вторая вершина. \en The second vertex. + IDS_PROP_0579, ///< \ru Третья вершина. \en The third vertex. + IDS_PROP_0580, ///< \ru Четвертая вершина. \en The fourth vertex. + + IDS_PROP_0581, ///< \ru Способ построения 1. \en Method of construction 1. + IDS_PROP_0582, ///< \ru Способ построения 2. \en Method of construction 2. + IDS_PROP_0583, ///< \ru Расстояние 1. \en Distance 1. + IDS_PROP_0584, ///< \ru Расстояние 2. \en Distance 2. + IDS_PROP_0585, ///< \ru Треугольник. \en Triangle. + IDS_PROP_0586, ///< \ru Количество апексов. \en Number of apices. + IDS_PROP_0587, ///< \ru Количество полигонов. \en Number of polygons. + IDS_PROP_0588, ///< \ru Количество триангуляций. \en Number of triangulations. + IDS_PROP_0589, ///< \ru Контур. \en Contour. + IDS_PROP_0590, ///< \ru Число сечений. \en Number of sections. + IDS_PROP_0591, ///< \ru Сечение. \en Section. + IDS_PROP_0592, ///< \ru Параллельность. \en Parallelization. + IDS_PROP_0593, ///< \ru Ориентация образующей. \en Generatrix orientation. + IDS_PROP_0594, ///< \ru Положение образующей. \en Generatrix position. + IDS_PROP_0595, ///< \ru Сфероид (0) или тороид (1). \en Spheroid (0) or toroid (1). + IDS_PROP_0596, ///< \ru Полюс в начале. \en Pole at the beginning. + IDS_PROP_0597, ///< \ru Полюс в конце. \en Pole at the end. + IDS_PROP_0598, ///< \ru Продолжение. \en Extension. + IDS_PROP_0599, ///< \ru Смещение. \en Shift. + + IDS_PROP_0600, ///< \ru Оболочка тела. \en Shell. + IDS_PROP_0601, ///< \ru Ориентация ребра в цикле. \en Sense of edge in the loop. + IDS_PROP_0602, ///< \ru Ориентация кривой ребра. \en Edge curve orientation. + IDS_PROP_0603, ///< \ru Ориентация нормали оболочки. \en Orientation of a shell normal. + IDS_PROP_0604, ///< \ru Кривая ребра. \en Edge curve. + IDS_PROP_0605, ///< \ru Двумерная кривая ребра. \en Two-dimensional edge curve. + IDS_PROP_0606, ///< \ru Поверхность грани. \en Surface of a face. + IDS_PROP_0607, ///< \ru Вершина-начало. \en Start vertex. + IDS_PROP_0608, ///< \ru Вершина-конец. \en End vertex. + IDS_PROP_0609, ///< \ru Количество ссылок. \en References count. + IDS_PROP_0611, ///< \ru Грань плюс. \en Face plus. + IDS_PROP_0612, ///< \ru Грань минус. \en Face minus. + IDS_PROP_0613, ///< \ru Указатель на грань. \en Pointer to a face. + IDS_PROP_0614, ///< \ru Номер по порядку. \en Number by and index. + IDS_PROP_0615, ///< \ru Сортировка. \en Sorting. + IDS_PROP_0616, ///< \ru Пуансон или матрица. \en Punch or die. + IDS_PROP_0651, ///< \ru Разрезанное тело. \en Cutting solid. + IDS_PROP_0652, ///< \ru Плоскость раскроя. \en Cutting plane. + IDS_PROP_0654, ///< \ru Наличие штриховки. \en Whether there is hatching. + IDS_PROP_0655, ///< \ru Шаг штриховки. \en Hatching step. + IDS_PROP_0656, ///< \ru Угол штриховки. \en Hatching angle. + IDS_PROP_0657, ///< \ru Проекционная плоскость. \en Projection plane. + IDS_PROP_0658, ///< \ru Наличие невидимых линий. \en Whether there are invisible lines. + IDS_PROP_0659, ///< \ru Hash имени. \en Hash of name. + + IDS_PROP_0660, ///< \ru Коэффициент нейтрального слоя. \en Neutral layer coefficient. + IDS_PROP_0661, ///< \ru Радиус сгиба. \en Bend radius. + IDS_PROP_0662, ///< \ru Угол сгиба. \en Bend angle. + IDS_PROP_0663, ///< \ru Длина продолжения сгиба. \en Bend extension length. + IDS_PROP_0664, ///< \ru Смещение сгиба. \en Bend shift. + IDS_PROP_0665, ///< \ru Отступ от края сгиба 1. \en Distance from the bound of bend 1. + IDS_PROP_0666, ///< \ru Отступ от края сгиба 2. \en Distance from the bound of bend 2. + IDS_PROP_0667, ///< \ru Угол уклона края сгиба 1. \en Slope angle of the bound of bend 1. + IDS_PROP_0668, ///< \ru Угол уклона края сгиба 2. \en Slope angle of the bound of bend 2. + IDS_PROP_0669, ///< \ru Угол уклона продолжения сгиба 1. \en Slope angle of bend extension 1. + IDS_PROP_0670, ///< \ru Угол уклона продолжения сгиба 2. \en Slope angle of bend extension 2. + IDS_PROP_0671, ///< \ru Расширение продолжения сгиба 1. \en Expansion of extension of bend 1. + IDS_PROP_0672, ///< \ru Расширение продолжения сгиба 2. \en Expansion of extension of bend 2. + IDS_PROP_0673, ///< \ru Ширина разгрузки сгиба. \en Width of bend relief. + IDS_PROP_0674, ///< \ru Глубина разгрузки сгиба. \en Depth of bend relief. + IDS_PROP_0675, ///< \ru Радиус скругления разгрузки. \en Radius of relief rounding. + IDS_PROP_0676, ///< \ru Способ освобождения углов. \en Method of freeing the corners. + IDS_PROP_0677, ///< \ru Фиксированная часть грани слева. \en Fixed part of a face on the left. + IDS_PROP_0678, ///< \ru Строить разогнутым. \en Build in unbent state. + IDS_PROP_0679, ///< \ru Зазор. \en Gap. + IDS_PROP_0680, ///< \ru Перехлёстывающая сторона слева. \en Overlapping side on the left. + IDS_PROP_0681, ///< \ru С добавлением материала. \en With addition of material. + IDS_PROP_0682, ///< \ru Высота. \en Height. + IDS_PROP_0683, ///< \ru Коэффициент сгиба 1. \en Coefficient of bend 1. + IDS_PROP_0684, ///< \ru Радиус сгиба 1. \en Radius of bend 1. + IDS_PROP_0685, ///< \ru Коэффициент сгиба 2. \en Coefficient of bend 2. + IDS_PROP_0686, ///< \ru Радиус сгиба 2. \en Radius of bend 2. + IDS_PROP_0687, ///< \ru Радиус скругления эскиза. \en Radius of a sketch fillet. + IDS_PROP_0688, ///< \ru Радиус скругления основания. \en Radius of a base fillet. + IDS_PROP_0689, ///< \ru Радиус скругления дна. \en Radius of a bottom fillet. + IDS_PROP_0690, ///< \ru Открытая штамповка. \en Open stamping. + IDS_PROP_0691, ///< \ru Боковая стенка внутри. \en Side wall is inside. + IDS_PROP_0692, ///< \ru Ширина основания. \en Width of base. + IDS_PROP_0693, ///< \ru Ширина выпуклой части. \en Width of a salient part. + IDS_PROP_0694, ///< \ru Зазор рубленой законцовки. \en Gap of a cropped tip. + IDS_PROP_0695, ///< \ru Тип буртика. \en Bead type. + IDS_PROP_0696, ///< \ru Тип законцовки. \en Type of a tip. + IDS_PROP_0697, ///< \ru Вытяжка. \en Stretch. + IDS_PROP_0698, ///< \ru По нормали к толщине. \en By the normal to thickness. + IDS_PROP_0699, ///< \ru Способ замыкания цилиндрических частей. \en Method of cylindric parts closure. + IDS_PROP_0700, ///< \ru Разрешение на замыкание углов. \en Permission for corners closure. + + IDS_PROP_0701, ///< \ru Имя. \en Name. + IDS_PROP_0702, ///< \ru Значение. \en Value. + IDS_PROP_0703, ///< \ru Положение. \en Position. + IDS_PROP_0704, ///< \ru Число. \en Number. + IDS_PROP_0705, ///< \ru Ориентация. \en Orientation. + IDS_PROP_0706, ///< \ru Длина. \en Length. + IDS_PROP_0707, ///< \ru Толщина. \en Thickness. + IDS_PROP_0708, ///< \ru Угол. \en Angle. + IDS_PROP_0709, ///< \ru Параметр. \en Parameter. + IDS_PROP_0710, ///< \ru Геометрический объект. \en Geometric object. + IDS_PROP_0711, ///< \ru Точка. \en Point. + IDS_PROP_0712, ///< \ru Кривая. \en Curve. + IDS_PROP_0713, ///< \ru Поверхность. \en Surface. + IDS_PROP_0714, ///< \ru Вершина. \en Vertex. + IDS_PROP_0715, ///< \ru Ребро грани. \en Edge of a face. + IDS_PROP_0716, ///< \ru Цикл грани. \en Face loop. + IDS_PROP_0717, ///< \ru Грань. \en Face. + IDS_PROP_0718, ///< \ru Полюс при umin. \en Pole at umin. + IDS_PROP_0719, ///< \ru Полюс при umax. \en Pole at umax. + IDS_PROP_0720, ///< \ru Полюс при vmin. \en Pole at vmin. + IDS_PROP_0721, ///< \ru Полюс при vmax. \en Pole at vmax. + IDS_PROP_0724, ///< \ru Вершина. \en Vertex. + IDS_PROP_0725, ///< \ru Ребро. \en Edge. + IDS_PROP_0726, ///< \ru Цикл. \en Loop. + IDS_PROP_0727, ///< \ru Грань. \en Face. + IDS_PROP_0729, ///< \ru Количество граней. \en Number of faces. + IDS_PROP_0730, ///< \ru Количество операций. \en Number of operations. + IDS_PROP_0731, ///< \ru Количество объектов. \en Number of objects. + IDS_PROP_0732, ///< \ru Объединение граней. \en Faces unification. + IDS_PROP_0733, ///< \ru Обработка углов. \en Corners treatment. + IDS_PROP_0734, ///< \ru Операция объединения. \en Union operation. + IDS_PROP_0735, ///< \ru Операция пересечения. \en Intersection operation. + IDS_PROP_0736, ///< \ru Операция разности. \en Subtraction operation. + IDS_PROP_0737, ///< \ru Базовая операция. \en Base operations. + IDS_PROP_0738, ///< \ru Флаг состояния. \en Flag of state. + IDS_PROP_0739, ///< \ru Параметр полюса по U. \en Parameter of a pole by U. + IDS_PROP_0740, ///< \ru Номер грани. \en Number of a face. + IDS_PROP_0741, ///< \ru Номер ребра. \en Number of an edge. + IDS_PROP_0742, ///< \ru Номер грани плюс. \en Number of a face plus. + IDS_PROP_0743, ///< \ru Номер грани минус. \en Number of a face minus. + IDS_PROP_0744, ///< \ru Формировать твёрдое тело. \en Create a solid. + IDS_PROP_0745, ///< \ru Точность сшивки. \en Stitching tolerance. + IDS_PROP_0746, ///< \ru Через сгиб. \en Through a bend. + IDS_PROP_0747, ///< \ru Полюс. \en Pole. + IDS_PROP_0748, ///< \ru Край. \en Border. + IDS_PROP_0749, ///< \ru Шов. \en Seam. + IDS_PROP_0750, ///< \ru Линия перехода. \en Transition line. + IDS_PROP_0751, ///< \ru Адрес начальной вершины. \en Start vertex address. + IDS_PROP_0752, ///< \ru Адрес конечной вершины. \en End vertex address. + IDS_PROP_0753, ///< \ru Адрес грани слева. \en Address of a face on the left. + IDS_PROP_0754, ///< \ru Адрес грани справа. \en Address of a face on the right. + IDS_PROP_0755, ///< \ru Примитив разрезан. \en Primitive is cut. + IDS_PROP_0756, ///< \ru Листовой примитив. \en Sheet primitive. + IDS_PROP_0757, ///< \ru Внутренняя грань сгиба. \en Internal face of a bend. + IDS_PROP_0758, ///< \ru Внешняя грань сгиба. \en External face of a bend. + IDS_PROP_0759, ///< \ru Угол раствора конуса. \en Cone angle. + +// \ru Версии \en Versions + + IDS_PROP_0760, ///< \ru Версия. \en Version. + IDS_PROP_0761, ///< \ru Версия имени. \en Version of name. + IDS_PROP_0762, ///< \ru Версия операции. \en Version of operation. + IDS_PROP_0763, ///< \ru Версия объекта. \en Version of object. + +// \ru Информация от геометрической модели \en Information from geometric model + + IDS_PROP_0771, ///< \ru Количество вершин. \en Number of vertices. + IDS_PROP_0772, ///< \ru Количество кривых. \en Number of curves. + IDS_PROP_0773, ///< \ru Количество поверхностей. \en Number of surfaces. + IDS_PROP_0774, ///< \ru Количество тел. \en Number of solids. + IDS_PROP_0775, ///< \ru Количество полигональных объектов. \en Number of polygonal objects. + IDS_PROP_0776, ///< \ru Количество проволочных каркасов. \en Number of wireframes. + IDS_PROP_0777, ///< \ru Количество точечных каркасов. \en Number of point frames. + IDS_PROP_0778, ///< \ru Количество сборочных единиц. \en Number of assembly units. + IDS_PROP_0779, ///< \ru Количество вставок. \en Number of instances. + IDS_PROP_0780, ///< \ru Количество других объектов. \en Number of other objects. + IDS_PROP_0781, ///< \ru Количество регионов. \en Number of regions. + IDS_PROP_0782, ///< \ru Количество элементов. \en Number of elements. + IDS_PROP_0783, ///< \ru Количество сегментов. \en Number of segments. + IDS_PROP_0784, ///< \ru Количество всех граней. \en Number of all faces. + IDS_PROP_0785, ///< \ru Количество всех уникальных граней. \en Number of all unique faces. + + IDS_PROP_0791, ///< \ru Первая деформация. \en First strain. + IDS_PROP_0792, ///< \ru Вторая деформация. \en Second strain. + IDS_PROP_0793, ///< \ru Третья деформация. \en Third strain. + + IDS_PROP_0797, ///< \ru Модуль Юнга. \en Young's modulus. + IDS_PROP_0798, ///< \ru Коэффициент Пуассона. \en Poisson's ratio. + + IDS_PROP_0830, ///< \ru Число радиусов эквидистант. \en Number of offsets radii. + IDS_PROP_0831, ///< \ru Гладкий стык. \en Smooth joint. + IDS_PROP_0832, ///< \ru Тип обхода угла. \en Type of corner bypass. + IDS_PROP_0833, ///< \ru Радиус специального скругления. \en Radius of a special fillet. + IDS_PROP_0834, ///< \ru Тип законцовки. \en Type of a tip. + IDS_PROP_0835, ///< \ru Законцовка первого сегмента. \en Tip of the first segment. + IDS_PROP_0836, ///< \ru Тип законцовки в начале. \en Type of tip at the beginning. + IDS_PROP_0837, ///< \ru Тип законцовки в конце. \en Type of tip at the end. + IDS_PROP_0838, ///< \ru Параметр законцовки. \en Parameter of a tip. + + IDS_PROP_0839, ///< \ru Параметр построения заплатки. \en Parameter of a patch construction. + IDS_PROP_0840, ///< \ru Число кривых образующего контура. \en Number of curves of a generating contour. + IDS_PROP_0841, ///< \ru Даны образующие грани. \en The generating faces are given. + IDS_PROP_0842, ///< \ru Кривая образующего контура. \en Curve of a generaing contour. + IDS_PROP_0843, ///< \ru Ориентация кривой контура. \en Orientation of a curve of the contour. + IDS_PROP_0844, ///< \ru Сторона существующей грани оболочки. \en Side of an existent face of the shell. + IDS_PROP_0845, ///< \ru Да. \en Yes. + IDS_PROP_0846, ///< \ru Нет. \en No. + +// \ru Контейнер атрибутов \en Attribute container + + IDS_PROP_0847, ///< \ru Поставщик атрибутов. \en Attribute provider. + IDS_PROP_0848, ///< \ru Количество контейнеров. \en Number of containers. + IDS_PROP_0849, ///< \ru Контейнер. \en Container. + + IDS_PROP_0851, ///< \ru Количество атрибутов. \en Number of attributes. + + IDS_PROP_0853, ///< \ru При изменении. \en While changing. + IDS_PROP_0854, ///< \ru При конвертации. \en While convertation. + IDS_PROP_0855, ///< \ru При трансформировании. \en While transforming. + IDS_PROP_0856, ///< \ru При копировании. \en While copying. + IDS_PROP_0857, ///< \ru При объединении. \en While joining. + IDS_PROP_0858, ///< \ru При замене. \en While replacing. + IDS_PROP_0859, ///< \ru При разделении. \en While splitting. + IDS_PROP_0860, ///< \ru При удалении. \en While deleting. + IDS_PROP_0861, ///< \ru Объект свободен. \en The object is free. + IDS_PROP_0862, ///< \ru Копируемость. \en Whether it can be copied. + IDS_PROP_0863, ///< \ru Количество u-линий. \en The number of u-lines. + IDS_PROP_0864, ///< \ru Количество v-линий. \en The number of v-lines. + + IDS_PROP_0869, ///< \ru Имя исполнения. \en Embodiment name. + IDS_PROP_0870, ///< \ru Имя родительского исполнения. \en Parent embodiment name. + IDS_PROP_0871, ///< \ru Красный. \en Red. + IDS_PROP_0872, ///< \ru Зелёный. \en Green. + IDS_PROP_0873, ///< \ru Синий. \en Blue. + IDS_PROP_0874, ///< \ru Толщина. \en Thickness. + IDS_PROP_0875, ///< \ru Стиль. \en Slyle. + IDS_PROP_0876, ///< \ru Плотность. \en Density. + IDS_PROP_0877, ///< \ru Идентификатор. \en Identifier. + IDS_PROP_0878, ///< \ru Селектированность. \en Selectivity. + IDS_PROP_0879, ///< \ru Видимость. \en Visibility. + IDS_PROP_0880, ///< \ru Изменённость. \en Modified. + IDS_PROP_0881, ///< \ru Общий фон. \en Background. + IDS_PROP_0882, ///< \ru Диффузное отражение. \en Diffuse reflection. + IDS_PROP_0883, ///< \ru Зеркальное отражение. \en Specular reflection. + IDS_PROP_0884, ///< \ru Блеск. \en Shininess. + IDS_PROP_0885, ///< \ru Непрозрачность. \en Opacity. + IDS_PROP_0886, ///< \ru Излучение. \en Emission. + IDS_PROP_0887, ///< \ru Количество родительских объектов. \en Number of parent objects. + IDS_PROP_0888, ///< \ru Родительский объект. \en Parent object. + IDS_PROP_0889, ///< \ru Имя топологического объекта. \en Topological object name. + IDS_PROP_0890, ///< \ru Имя объекта. \en Object name. + IDS_PROP_0891, ///< \ru Хэш имени объекта. \en Object name hash. + + IDS_PROP_0900, ///< \ru Сопряжение в точке. \en Conjugation at point. + IDS_PROP_0901, ///< \ru Тип сопряжения. \en Conjugation type. + IDS_PROP_0902, ///< \ru Без сопряжения. \en Without conjugation. + IDS_PROP_0903, ///< \ru По позиции. \en By position. + IDS_PROP_0904, ///< \ru По касательной. \en By tangent. + IDS_PROP_0905, ///< \ru По нормали. \en By normal. + IDS_PROP_0906, ///< \ru По G2. \en By G2. + IDS_PROP_0907, ///< \ru По G3. \en By G3. + IDS_PROP_0908, ///< \ru Касательный вектор. \en Tangent vector. + IDS_PROP_0909, ///< \ru Первая производная касательного вектора. \en First derivative of tangent vector. + IDS_PROP_0910, ///< \ru Вторая производная касательного вектора. \en Second derivative of tangent vector. + IDS_PROP_0911, ///< \ru Можно ли двигать точки. \en Whether points can be moved. + IDS_PROP_0912, ///< \ru Только по направлению. \en Only along the direction. + IDS_PROP_0913, ///< \ru Сопряжение. \en Conjugation. + + IDS_PROP_0920, ///< \ru Тип параметризации. \en Parametrization type. + IDS_PROP_0921, ///< \ru Пользовательская. \en Custom. + IDS_PROP_0922, ///< \ru Равномерная. \en Uniform. + IDS_PROP_0923, ///< \ru По длине хорды. \en By chord length. + IDS_PROP_0924, ///< \ru Центростремительная. \en Centripetal. + + IDS_PROP_0925, ///< \ru Через вершины. \en Through vertices. + IDS_PROP_0926, ///< \ru Равномерная параметризация. \en Uniform parametrization. + + IDS_PROP_0927, ///< \ru Признак текущего исполнения. \en Mark of current embodiment. + +// \ru Конвертеры \en Converters + + IDS_PROP_1000, ///< \ru Заголовок. \en Title. + IDS_PROP_1001, ///< \ru Название. \en Name. + IDS_PROP_1002, ///< \ru Дата и время. \en Date and time. + IDS_PROP_1003, ///< \ru Автор(ы). \en Author(s)). + IDS_PROP_1004, ///< \ru Организация(и). \en Organization(s). + IDS_PROP_1005, ///< \ru Процессор STEP. \en Processor STEP. + IDS_PROP_1006, ///< \ru Система. \en System. + IDS_PROP_1007, ///< \ru Авторизация. \en Authorization. + + IDS_PROP_1010, ///< \ru Лицо и организация. \en Person and organization. + IDS_PROP_1011, ///< \ru Идентификатор лица. \en Identifier of a person. + IDS_PROP_1012, ///< \ru Фамилия. \en Surname. + IDS_PROP_1013, ///< \ru Имя. \en Name. + IDS_PROP_1014, ///< \ru Средние имена. \en Middle names. + IDS_PROP_1015, ///< \ru Титулы предшествующие. \en Prefix titles. + IDS_PROP_1016, ///< \ru Титулы завершающие. \en Suffix titles. + IDS_PROP_1017, ///< \ru Идентификатор организации. \en Identifier of organization. + IDS_PROP_1018, ///< \ru Название организации. \en Name of organization. + IDS_PROP_1019, ///< \ru Описание организации. \en Description of organization. + + IDS_PROP_1030, ///< \ru Изделие. \en Product. + IDS_PROP_1031, ///< \ru Идентификатор. \en Identifier. + IDS_PROP_1032, ///< \ru Название. \en Name. + IDS_PROP_1033, ///< \ru Описание. \en Description. + + IDS_PROP_1043, ///< \ru Элемент описания. \en Description element. + + /* + 1100 .. 1199 is a range for C3D Solver + */ + IDS_PROP_1100, ///< \ru Геометрический решатель. \en Geom solver. + IDS_PROP_1101, ///< \ru Схема сопряжений. \en Scheme of matings. + IDS_PROP_1102, ///< \ru Система ограничений. \en Constraint system. + IDS_PROP_1103, ///< \ru Ограничение. \en Constraint. + IDS_PROP_1104, ///< \ru Тип сопряжения. \en Type of mating. + IDS_PROP_1105, ///< \ru Тип ограничения. \en Type of constraint. + IDS_PROP_1106, ///< \ru Выравнивание. \en Alignment. + IDS_PROP_1107, ///< \ru Количество ограничений. \en Number of constraints. + IDS_PROP_1108, ///< \ru Тип взаимоориентации. \en Coorientation type. + IDS_PROP_1109, ///< \ru Сопряжение. \en Mate. + IDS_PROP_1110, ///< \ru Базовый объект. \en Base object. + IDS_PROP_1111, ///< \ru Объект 1. \en Object 1. + IDS_PROP_1112, ///< \ru Объект 2. \en Object 2. + IDS_PROP_1113, ///< \ru Вещественный параметр. \en Real parameter. + IDS_PROP_1114, ///< \ru Величина взаимоориентации. \en Value of coorientation. + + /* + Types of geometric constraint + */ + IDS_PROP_1130, ///< \ru Совпадение \en Coincident + IDS_PROP_1131, ///< \ru Параллельность \en Parallel + IDS_PROP_1132, ///< \ru Перпендикулярность \en Perpendicular + IDS_PROP_1133, ///< \ru Касание \en Tangent. + IDS_PROP_1134, ///< \ru Концентричность \en Concentric + IDS_PROP_1135, ///< \ru На расстоянии \en Distance + IDS_PROP_1136, ///< \ru По углом \en Angle + IDS_PROP_1137, ///< \ru По месту \en In place + IDS_PROP_1138, ///< \ru Механическая передача \en Transmittion + IDS_PROP_1139, ///< \ru Кулачковый механизм \en Cam mechanism + IDS_PROP_1140, ///< \ru Радиальный размер. \en Radial dimension. + IDS_PROP_1145, ///< \ru Симметричность \en Symmetric + IDS_PROP_1146, ///< \ru Зависимый объект \en Dependent + IDS_PROP_1147, ///< \ru Элемент паттерна \en Patterned + IDS_PROP_1148, ///< \ru Линейный паттерн \en Linear pattern + IDS_PROP_1149, ///< \ru Угловой паттерн \en Angular pattern + IDS_PROP_1199, // The last id for C3D Solver + + /* + \ru Новые описания без группировки \en New unsorted descriptions + */ + + IDS_PROP_2001, ///< \ru Внимание: \en Attention: + IDS_PROP_2002, ///< \ru Начало общих операций. \en Beginning of the shared operations. + IDS_PROP_2003, ///< \ru Начало группы операций. \en Beginning of the operations group. + IDS_PROP_2004, ///< \ru Начало первой группы операций. \en Beginning of the first operations group. + IDS_PROP_2005, ///< \ru Начало второй группы операций. \en Beginning of the second operations group. + IDS_PROP_2006, ///< \ru Начало объекта. \en Beginning of an object. + IDS_PROP_2007, ///< \ru Начало первого объекта. \en Beginning of the first object. + IDS_PROP_2008, ///< \ru Начало второго объекта. \en Beginning of the second object. + IDS_PROP_2009, ///< \ru Копировать атрибуты. \en Copy attributes. + IDS_PROP_2010, ///< \ru Количество общих групп операций. \en Number of shared operations groups. + IDS_PROP_2011, ///< \ru Количество выбранных граней. \en Number of selected faces. + IDS_PROP_2012, ///< \ru Количество выбранных ребёр. \en Number of selected edges. + IDS_PROP_2013, ///< \ru Количество выбранных вершин. \en Number of selected vertices. + IDS_PROP_2014, ///< \ru Секущий эскиз. \en Cutting sketch. + IDS_PROP_2015, ///< \ru Секущие 3D-кривые. \en Cutting 3D-curves. + IDS_PROP_2016, ///< \ru Секущие поверхности. \en Cutting surfaces. + IDS_PROP_2017, ///< \ru Секущее тело. \en Cutting solid. + + IDS_PROP_2018, ///< \ru Поверхность сопряжения на границе 0. \en Adjacent surface on the border 0. + IDS_PROP_2019, ///< \ru Поверхность сопряжения на границе 1. \en Adjacent surface on the border 1. + IDS_PROP_2020, ///< \ru Поверхность сопряжения на границе 2. \en Adjacent surface on the border 2. + IDS_PROP_2021, ///< \ru Поверхность сопряжения на границе 3. \en Adjacent surface on the border 3. + IDS_PROP_2022, ///< \ru Поверхность сопряжения на границе 4. \en Adjacent surface on the border 4. + IDS_PROP_2023, ///< \ru Сопряжение на границе 0. \en Conjugation on the boundary 0. + IDS_PROP_2024, ///< \ru Сопряжение на границе 1. \en Conjugation on the boundary 1. + IDS_PROP_2025, ///< \ru Сопряжение на границе 2. \en Conjugation on the boundary 2. + IDS_PROP_2026, ///< \ru Сопряжение на границе 3. \en Conjugation on the boundary 3. + IDS_PROP_2027, ///< \ru Сопряжение на границе 4. \en Conjugation on the boundary 4. + + IDS_PROP_LAST = 9999, ///< \ru Наибольшее значение. \en The greatest value. +}; + + +#endif // __MB_PROPERTY_TITLE_H diff --git a/C3d/Include/mb_rect.h b/C3d/Include/mb_rect.h new file mode 100644 index 0000000..2e87a8a --- /dev/null +++ b/C3d/Include/mb_rect.h @@ -0,0 +1,760 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Габаритный прямоугольник. + \en Bounding rectangle. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_RECT_H +#define __MB_RECT_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbRect; + +namespace c3d // namespace C3D +{ + typedef std::pair RectPtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index. + typedef std::pair ConstRectPtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index. + typedef std::vector RectsPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices. + typedef std::vector ConstRectsPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices. + typedef std::vector RectsVector; ///< \ru Вектор габаритных кубов. \en Vector of bounding boxes. +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Возможные положения двух габаритов относительно друг друга. + \en Possible locations of two bounding boxes relative to each other. \~ + \details \ru Возможные положения двух габаритов относительно друг друга. + \en Possible locations of two bounding boxes relative to each other. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +enum TaeTwoRectPos { + rp_FirstInside, ///< \ru Первый включает в себя второй габарит. \en The first bounding box includes the second one. + rp_SecondInside, ///< \ru Второй включает в себя первый габарит. \en The second bounding box includes the first one. + rp_Intersect, ///< \ru Габариты пересекаются. \en Bounding boxes intersect. + rp_NoIntersect ///< \ru Габариты не пересекаются. \en Bounding boxes do not intersect. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Габаритный прямоугольник. + \en Bounding rectangle. \~ + \details \ru Габаритный прямоугольник в двумерном пространстве. \n + Используется для быстрого оценочного определения близости двумерных объектов. + \en Bounding box in two-dimensional space. \n + Used for fast estimation of two-dimensional objects proximity. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbRect { +public : + double left; ///< \ru Левая граница габаритного прямоугольника. \en Left bound of bounding box. + double bottom; ///< \ru Нижняя граница габаритного прямоугольника. \en Bottom bound of bounding box. + double right; ///< \ru Правая граница габаритного прямоугольника. \en Right bound of bounding box. + double top; ///< \ru Верхняя граница габаритного прямоугольника. \en Top bound of bounding box. + +public: + /// \ru Конструктор пустого габарита. \en Constructor of an empty bounding box. + MbRect() { SetEmpty(); } + /// \ru Конструктор по заданным значениям границ. \en Constructor by given bounds. + MbRect( double _left, double _bottom, double _right, double _top ) : left(_left), bottom(_bottom), right(_right), top(_top) {} + /// \ru Конструктор по другому габариту. \en Constructor by another bounding box. + MbRect( const MbRect & r ) : left(r.left), bottom(r.bottom), right(r.right), top(r.top) {} + /// \ru Конструктор по двум диагональным точкам. \en The constructor by two diagonal points. + MbRect( const MbCartPoint & p1, const MbCartPoint & p2 ) { + Set(p1.x, p1.y, p2.x, p2.y); + Normalize(); + } + /// \ru Конструктор по габариту с последующей трансформацией по матрице. \en Constructor by bounding box with subsequent transformation by the matrix. + MbRect( const MbRect & r, const MbMatrix & m ) : left(r.left), bottom(r.bottom), right(r.right), top(r.top) { + Transform( m ); + } +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ + ~MbRect(); ///< \ru Деструктор. \en Destructor. +#endif + + /// \ru Установить заданные значения границ. \en Set given values of bounds. + void Set( double _left, double _bottom, double _right, double _top ); + /// \ru Установить заданные значения границ. \en Set given values of bounds. + void Set( const MbRect & r ); + /// \ru Установить заданные значения границ. \en Set given values of bounds. + void Set( const MbCartPoint & p1, const MbCartPoint & p2 ); + /// \ru Установить значения границ как окрестность точки. \en Set values of bounds as point neighbourhood. + void Set( const MbCartPoint & p, double eps ); + /// \ru Установить значения границ как окрестнсть точки. \en Set values of bounds as point neighbourhood. + void Set( const MbCartPoint & p, double dx, double dy ); + /// \ru Установить нулевым. \en Set to zero. + void SetNull(); + /// \ru Установить пустым ("вывернутым"). \en Set empty ("everted"). + void SetEmpty(); + /// \ru Проверить на пустоту. \en Check for emptiness. + bool IsEmpty() const; + /// \ru Проверить габарит на вырожденность по оси X. \en Check bounding box for degeneracy by X-axis. + bool IsDegenerateX() const; + /// \ru Проверить габарит на вырожденность по оси Y. \en Check bounding box for degeneracy by Y-axis. + bool IsDegenerateY() const; + /// \ru Проверить габариты на равенство. \en Check bounding boxes for equality. + bool IsSame( const MbRect &, double eps ) const; + /// \ru Проверить габариты на равенство. \en Check bounding boxes for equality. + bool IsSame( const MbRect &, double xeps, double yeps ) const; + + /// \ru Проверить габариты на равенство. \en Check bounding boxes for equality. + bool operator == ( const MbRect & other ) const; + /// \ru Проверить габариты на неравенство. \en Check bounding boxes for inequality. + bool operator != ( const MbRect & other ) const; + /// \ru Присвоить значение другого габарита. \en Assign a value of another bounding box. + void operator = ( const MbRect & other ) { Set( other ); } + + /// \ru Получить верхнюю границу. \en Get top bound. + double GetTop () const { return top; } + /// \ru Получить нижнюю границу. \en Get bottom bound. + double GetBottom() const { return bottom; } + /// \ru Получить левую границу. \en Get left bound. + double GetLeft () const { return left; } + /// \ru Получить правую границу. \en Get right bound. + double GetRight () const { return right; } + + /// \ru Установить верхнюю границу. \en Set top bound. + void SetTop ( double _top ) { top = _top; } + /// \ru Установить нижнюю границу. \en Set bottom bound. + void SetBottom( double _bottom ) { bottom = _bottom; } + /// \ru Установить левую границу. \en Set left bound. + void SetLeft ( double _left ) { left = _left; } + /// \ru Установить правую границу. \en Set right bound. + void SetRight ( double _right ) { right = _right; } + + /// \ru Получить минимум по X. \en Get minimum by X. + double GetXMin() const { return left; } + /// \ru Получить минимум по Y. \en Get minimum by Y. + double GetYMin() const { return bottom; } + /// \ru Получить максимум по X. \en Get maximum by X. + double GetXMax() const { return right; } + /// \ru Получить максимум по Y. \en Get maximum by Y. + double GetYMax() const { return top; } + + /// \ru Получить середину по X. \en Get middle by X. + double GetXMid() const { return 0.5 * ( left + right ); } + /// \ru Получить середину по Y. \en Get middle by Y. + double GetYMid() const { return 0.5 * ( bottom + top ); } + + /// \ru Установить минимум по X. \en Set minimum by X. + void SetXMin( double s ) { left = s; } + /// \ru Установить максимум по X. \en Set maximum by X. + void SetYMin( double s ) { bottom = s; } + /// \ru Установить минимум по Y. \en Set minimum by Y. + void SetXMax( double s ) { right = s; } + ///< \ru Установить максимум по Y. \en Set maximum by Y. + void SetYMax( double s ) { top = s; } + + /// \ru Найти ширину габарита. \en Find width of bounding box. + double Width() const { return right - left; } + /// \ru Найти высоту габарита. \en Find height of bounding box. + double Height() const { return top - bottom; } + /// \ru Дать длину по X. \en Get length by X. + double GetLengthX() const { return right - left; } //-V524 + /// \ru Дать длину по Y. \en Get length by Y. + double GetLengthY() const { return top - bottom; } //-V524 + /// \ru Дать половину периметра. \en Get half of perimeter. + double GetLength( double eps ) const; + /// \ru Дать площадь. \en Get area. + double GetSquare( double eps ) const; + /// \ru Дать длину диагонали. \en Get the diagonal length. + double GetDiagonal() const { return ::_hypot( left - right, top - bottom ); } + + /// \ru Вычислить габарит пересечения двух габаритов. \en Calculate bounding box of two bounding boxes intersection. + bool Intersection( const MbRect & rect1, const MbRect & rect2, double eps = Math::LengthEps ); + /// \ru Вычислить суммарный габарит двух габаритов. \en Calculate bounding box enclosing two bounding boxes. + bool Union ( const MbRect & rect1, const MbRect & rect2 ); + + /// \ru Проверить принадлежность габариту заданной точки. \en Check if the bounding box contains the given point. + bool Contains( const MbCartPoint & p, double eps = Math::LengthEps ) const; + /// \ru Проверить принадлежность габариту заданной точки. \en Check if the bounding box contains the given point. + bool Contains( double x, double y, double eps = Math::LengthEps ) const; + /// \ru Проверить принадлежность габариту заданной точки. \en Check if the bounding box contains the given point. + bool Contains( const MbCartPoint & p, double xeps, double yeps ) const; + /// \ru Проверить принадлежность габариту заданной точки. \en Check if the bounding box contains the given point. + bool Contains( double x, double y, double xeps, double yeps ) const; + /// \ru Проверить принадлежность габариту заданной координаты по X. \en Check if the bounding box contains the given X coordinate. + bool ContainsX( double x, double eps = Math::LengthEps ) const ; + /// \ru Проверить принадлежность габариту заданной координаты по Y. \en Check if the bounding box contains the given Y coordinate. + bool ContainsY( double y, double eps = Math::LengthEps ) const ; + /// \ru Вычислить коды расположения точки относительно прямоугольника. \en Calculate the codes of a point location relative to the rectangle. + void OutCodes( const MbCartPoint & p, unsigned int & outcodes, double eps = METRIC_PRECISION ) const; + + /** \brief \ru Вычислить расстояние до ближайшей границы габаритного прямоугольника. + \en Calculate the distance to the nearest boundary of the bounding box. \~ + \details \ru Найденное расстояние до ближайшей границы имеет отрицательное значение, если точка находится внутри, и положительное - если снаружи. + \en The calculated distance is negative if the point is inside, and is positive if it is outside. \~ + \param[in] point - \ru Исследуемая точка. + \en The investigated point. \~ + \return \ru Возвращает расстояние до границы. + \en Returns the distance to the boundary. \~ + */ + double DistanceToPoint( const MbCartPoint & point ) const; + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + double DistanceToPoint( const MbCartPoint & to, + unsigned int & outcodes ) const; + + /// \ru Вычислить минимальное и максимальное расстояния до точки. \en Calculate minimal and maximal distances to a point. + void CalcDistances( const MbCartPoint & to, + double & dmin, double & dmax, + unsigned int & outcodes ) const; + // \ru Пересекается ли габарит с другим габаритом. \en Whether the bounding box intersects with another bounding box. + /// \ru Проверить, пересекается ли габарит с другим габаритом с признаком пересечения. \en Whether the bounding box intersects with another bounding box with intersection attribute. + bool Intersect( const MbRect &, TaeTwoRectPos & ) const; + /// \ru Проверить пересекается ли габарит с другим габаритом. \en Whether the bounding box intersects with another bounding box. + bool Intersect( const MbRect & other, double eps = Math::LengthEps ) const; + /// \ru Проверить пересекается ли габарит с другим габаритом. \en Whether the bounding box intersects with another bounding box. + bool Intersect( const MbRect & other, double xeps, double yeps ) const; + /// \ru Сделать другой прямоугольник из этого, сжав его. \en Create new rectangle from the current one by shrinking. + MbRect CompressedBy( double dLeft, double dBottom, + double dRight, double dTop) const ; + + /// \ru Нормализовать себя. \en Normalize oneself. + MbRect & Normalize(); + /// \ru Преобразовать по матрице. \en Transform by matrix. + void Transform( const MbMatrix & ); + /// \ru Масштабировать. \en Scale. + void Scale( double sx, double sy ); + + /// \ru Включить в себя прямоугольник. \en Enclose a rectangle. + MbRect & operator |= ( const MbRect & ); + /// \ru Включить в себя точку. \en Enclose a point. + MbRect & operator |= ( const MbCartPoint & ); + /// \ru Включить в себя точку. \en Enclose a point. + MbRect & operator |= ( const MbHomogeneous & ); + /// \ru Включить в себя массив точек. \en Enclose an array of points. + MbRect & operator |= ( const SArray & ); + /// \ru Включить в себя массив точек. \en Enclose an array of points. + MbRect & operator |= ( const SArray & ); + + /// \ru Включить в себя точку,заданную как XY. \en Enclose a point specified as XY. + void Include( double x, double y ); + /// \ru Включить в себя координату X. \en Enclose an X-coordinate. + void IncludeX( double x ); + /// \ru Включить в себя координату Y. \en Enclose an Y-coordinate. + void IncludeY( double y ); + /// \ru Включить в себя интервал от X - dx до X + dx. \en Enclose a range from X - dx to X + dx. + void IncludeXInterval( double x, double dx ); + /// \ru Включить в себя интервал от Y - dy до Y + dy. \en Enclose a range from Y - dy to Y + dy. + void IncludeYInterval( double y, double dy ); + // \ru Сдвинуть прямоугольник \en Move rectangle + /// \ru Cдвинуть прямоугольник. \en Move rectangle. + void Move( const MbVector & to ); + /// \ru Cдвинуть прямоугольник. \en Move rectangle. + void Move( double dx, double dy ); + /// \ru Масштабировать относительно 0. \en Scale relative to 0. + void Scale( double scale ); + + /// \ru Расширить прямоугольник. \en Extend rectangle. + void Enlarge( double x, double y ); + /// \ru Расширить прямоугольник во все стороны. \en Extend rectangle in all directions. + void Enlarge( double delta ); + + /// \ru Поличить охватывающий прямоугольник. \en Get the covering rectangle. + void GetOusideRect( MbRect & r ) const { r = *this; } + /// \ru Вернуть точку центра габарита. \en Get center of the bounding box. + void GetCenter( MbCartPoint & p ) const { + p.x = (left + right) * 0.5; + p.y = (top + bottom) * 0.5; + } + + // \ru Вершины габаритного прямоугольника \en Vertices of bounding box + // Y + // | + // 3 - - - 2 + // | | + // | | + // 0 - - - 1 - X + // + + /// \ru Дать количество вершин. \en Get count of vertices. + size_t GetVerticesCount() const { return 4; } //-V112 + /// \ru Выдать вершину габаритного прямоугольника по индексу от 0 до 3. \en Get vertex of bounding rectangle by index in range from 0 to 3. + void GetVertex( size_t index, MbCartPoint & p ) const; + + /// \ru Получить ссылку на себя. \en Get reference to itself. + const MbRect & GetRect() const { return *this; } + + /// \ru Количество координат точки. \en The number of point coordinates. + static size_t GetDimension() { return 2; } + /// \ru Доступ к координате по индексу. \en Access to a coordinate by an index. + double GetMin( size_t k ) const { return k ? bottom : left; }; + /// \ru Доступ к координате по индексу. \en Access to a coordinate by an index. + double GetMax( size_t k ) const { return k ? top : right; }; + + /// \ru Получить ссылку на себя. \en Get reference to itself. + const MbRect & GetCube() const { return *this; } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbRect, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbRect ) + DECLARE_NEW_DELETE_CLASS_EX( MbRect ) +}; // MbRect + + +//------------------------------------------------------------------------------ +// \ru Установить заданные значения границ \en Set given values of bounds +// --- +inline void MbRect::Set( double _left, double _bottom, double _right, double _top ) +{ + left = _left; + top = _top; + right = _right; + bottom = _bottom; +} + + +//------------------------------------------------------------------------------ +// \ru Установить заданные значения границ \en Set given values of bounds +// --- +inline void MbRect::Set( const MbRect & r ) +{ + left = r.left; + top = r.top; + right = r.right; + bottom = r.bottom; +} + + +//------------------------------------------------------------------------------ +// \ru Установить значения границ как окрестность точки. \en Set values of bounds as point neighborhood. +// --- +inline void MbRect::Set( const MbCartPoint & p1, const MbCartPoint & p2 ) +{ + left = std_min( p1.x, p2.x ); + right = std_max( p1.x, p2.x ); + bottom = std_min( p1.y, p2.y ); + top = std_max( p1.y, p2.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Установить значения границ как окрестность точки. \en Set values of bounds as point neighborhood. +// --- +inline void MbRect::Set( const MbCartPoint & p, double eps ) +{ + eps = ::fabs( eps ); + left = p.x - eps; + right = p.x + eps; + bottom = p.y - eps; + top = p.y + eps; +} + + +//------------------------------------------------------------------------------ +// \ru Установить значения границ как окрестность точки. \en Set values of bounds as point neighborhood. +// --- +inline void MbRect::Set( const MbCartPoint & p, double dx, double dy ) +{ + dx = ::fabs( dx ); + dy = ::fabs( dy ); + + left = p.x - dx; + right = p.x + dx; + bottom = p.y - dy; + top = p.y + dy; +} + + +//------------------------------------------------------------------------------ +// \ru Установить нулевым \en Set to zero +// --- +inline void MbRect::SetNull() { + left = top = right = bottom = 0; +} + + +//------------------------------------------------------------------------------ +// \ru Установить пустым ("вывернутым") \en Set empty ("everted") +// --- +inline void MbRect::SetEmpty() { + Set( MB_MAXDOUBLE, MB_MAXDOUBLE, -MB_MAXDOUBLE, -MB_MAXDOUBLE ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на пустоту \en Check for emptiness +// --- +inline bool MbRect::IsEmpty() const { + return ( left > right ) || ( bottom > top ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка габарита по оси 0X \en Check bounding box by 0X-axis +// --- +inline bool MbRect::IsDegenerateX() const { + return fabs( right - left ) < Math::LengthEps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка габарита по оси 0Y \en Check bounding box by 0Y-axis +// --- +inline bool MbRect::IsDegenerateY() const { + return fabs( top - bottom ) < Math::LengthEps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка равенства с другим прямоугольником \en Check for equality with another rectangle +// --- +inline bool MbRect::IsSame( const MbRect & other, double eps ) const { + return ::fabs( other.left - left ) < eps && + ::fabs( other.right - right ) < eps && + ::fabs( other.top - top ) < eps && + ::fabs( other.bottom - bottom ) < eps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка равенства с другим прямоугольником \en Check for equality with another rectangle +// --- +inline bool MbRect::IsSame( const MbRect & other, double xeps, double yeps ) const { + return ::fabs( other.left - left ) < xeps && + ::fabs( other.right - right ) < xeps && + ::fabs( other.top - top ) < yeps && + ::fabs( other.bottom - bottom ) < yeps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка равенства с другим прямоугольником \en Check for equality with another rectangle +// --- +inline bool MbRect::operator == ( const MbRect & other ) const { + return ::fabs( other.left - left ) < Math::LengthEps && + ::fabs( other.right - right ) < Math::LengthEps && + ::fabs( other.top - top ) < Math::LengthEps && + ::fabs( other.bottom - bottom ) < Math::LengthEps; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка неравенства с другим прямоугольником \en Check for inequality with another rectangle +// --- +inline bool MbRect::operator != ( const MbRect & other ) const { + return !( other == *this ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная точка лежит внутри прямоугольника \en Check that a given point is inside the rectangle +// --- +inline bool MbRect::Contains( const MbCartPoint & p, double eps ) const { + return ( p.x >= (left - eps) ) && ( p.x <= (right + eps) ) && + ( p.y >= (bottom - eps) ) && ( p.y <= (top + eps) ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная точка лежит внутри прямоугольника \en Check that a given point is inside the rectangle +// --- +inline bool MbRect::Contains( double x, double y, double eps ) const { + return ( x >= (left - eps) ) && ( x <= (right + eps) ) && + ( y >= (bottom - eps) ) && ( y <= (top + eps) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная точка лежит внутри прямоугольника \en Check that a given point is inside the rectangle +// --- +inline bool MbRect::Contains( const MbCartPoint & p, double xeps, double yeps ) const { + return ( p.x >= (left - xeps) ) && ( p.x <= (right + xeps) ) && + ( p.y >= (bottom - yeps) ) && ( p.y <= (top + yeps) ); +} + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная точка лежит внутри прямоугольника \en Check that a given point is inside the rectangle +// --- +inline bool MbRect::Contains( double x, double y, double xeps, double yeps ) const { + return ( x >= (left - xeps) ) && ( x <= (right + xeps) ) && + ( y >= (bottom - yeps) ) && ( y <= (top + yeps) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная координата X лежит внутри прямоугольника \en Check that given X coordinate is inside the rectangle +// --- +inline bool MbRect::ContainsX( double x, double eps ) const { + return ( x > left - eps ) && ( x < right + eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на то, что заданная координата Y лежит внутри прямоугольника \en Check that given Y coordinate is inside the rectangle +// --- +inline bool MbRect::ContainsY( double y, double eps ) const { + return ( y > bottom - eps ) && ( y < top + eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление кодов расположения точки относительно прямоугольника \en Calculate codes of a point location relative to the rectangle +// \ru Бит 0 - точка слева от окна \en Bit 0 - point to the left of a window +// \ru Бит 1 - точка справа от окна \en Bit 1 - point to the right of a window +// \ru Бит 2 - точка ниже окна \en Bit 2 - the point is lower than a window +// \ru Бит 3 - точка выше окна \en Bit 3 - the point is higher than a window +// --- +inline void MbRect::OutCodes( const MbCartPoint & p, unsigned int & outcodes, double eps ) const { + outcodes = ( p.x < left - eps ) | + ( ( ( p.x > right + eps ) << 1 ) & 0x2 ) | + ( ( ( p.y < bottom - eps ) << 2 ) & 0x4 ) | //-V112 + ( ( ( p.y > top + eps ) << 3 ) & 0x8 ); + +} + + +//------------------------------------------------------------------------------ +// \ru Расстояние до точки: если расстояние < 0, то точка лежит внутри \en Distance to a point: if distance is less than 0 then point is inside +// --- +inline double MbRect::DistanceToPoint( const MbCartPoint & pnt ) const { + double dx = std_max( left-pnt.x, pnt.x-right ); + double dy = std_max( bottom-pnt.y, pnt.y-top ); + return std_max(dx,dy); +} + + +//------------------------------------------------------------------------------ +// \ru Расстояние до точки \en Distance to a point +// --- +inline double MbRect::DistanceToPoint( const MbCartPoint & to, + unsigned int & outcodes ) const +{ + if ( IsEmpty() ) { + outcodes = 0xFFFF; + return 1E+6; + } + + OutCodes( to, outcodes ); // \ru Вычисление кодов расположения точки \en Calculate codes of a point location + + double dx = std_min( fabs( to.x - left), fabs( to.x - right) ); + double dy = std_min( fabs( to.y - top), fabs( to.y - bottom) ); + + return ( outcodes == 0x0 ) ? std_min( dx, dy ) : // \ru Точка внутри прямоугольника \en Point is inside the rectangle + ( outcodes == 0x1 || outcodes == 0x2 ) ? dx : // \ru Точка по Y - внутри, по X - вне прямоугольника \en Point is inside rectangle by Y, outside by X + ( outcodes == 0x4 || outcodes == 0x8 ) ? dy : // \ru Точка по X - внутри, по Y - вне прямоугольника //-V112 \en Point is inside rectangle by X, outside by Y //-V112 + ::_hypot( dx, dy ); // \ru Точка по X и по Y - вне прямоугольника \en Point is outside the rectangle by X and Y +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление минимального и максимального расстояний до точки \en Calculate minimal and maximal distances to point +// --- +inline void MbRect::CalcDistances( const MbCartPoint & to, + double & dmin, double & dmax, + unsigned int & outcodes ) const +{ + dmin = DistanceToPoint( to, outcodes ); + + if ( outcodes != 0xFFFF ) { // \ru Прямоугольник не вырожден \en Rectangle is not degenerate + dmax = ::_hypot( to.x - left, to.y - bottom ); + + double d = ::_hypot( to.x - left, to.y - top ); + if ( d > dmax ) dmax = d; + + d = ::_hypot( to.x - right, to.y - bottom ); + if ( d > dmax ) dmax = d; + + d = ::_hypot( to.x - right, to.y - top ); + if ( d > dmax ) dmax = d; + } +} + + +//------------------------------------------------------------------------------ +// \ru Сделать другой прям-к из этого, сжав его \en Create a new rectangle from the current one by shrinking +// --- +inline MbRect MbRect::CompressedBy( double dLeft, double dBottom, double dRight, double dTop) const +{ + if ( IsEmpty() ) + return MbRect(); + + return MbRect(left+dLeft, bottom+dBottom, right-dRight, top-dTop); +} + + +//------------------------------------------------------------------------------ +// \ru Нормализовать себя \en Normalize oneself +// --- +inline MbRect & MbRect::Normalize() { + double c = UNDEFINED_DBL; + if ( left > right ) { c = left; left = right; right = c; } + if ( top < bottom ) { c = top; top = bottom; bottom = c; } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку \en Enclose a point +// --- +inline MbRect & MbRect::operator |=( const MbCartPoint & p ) { + Include( p.x, p.y ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку \en Enclose a point +// --- +inline MbRect & MbRect::operator |=( const MbHomogeneous & p ) { + Include( p.x, p.y ); + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя точку,заданную как XY \en Enclose a point secified as XY +// --- +inline void MbRect::Include( double x, double y ) { + left = std_min(left, x); + bottom = std_min(bottom, y); + right = std_max(right, x); + top = std_max(top, y); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя координату X \en Enclose an X-coordinate +// --- +inline void MbRect::IncludeX( double x ) { + left = std_min(left, x); + right = std_max(right, x); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя координату Y \en Enclose an Y-coordinate +// --- +inline void MbRect::IncludeY( double y ) { + bottom = std_min(bottom, y); + top = std_max(top, y); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя интервал от X - dx до X + dx \en Enclose a range from X - dx to X + dx +// --- +inline void MbRect::IncludeXInterval( double x, double dx ) { + left = std_min( left, x - dx ); + right = std_max( right, x + dx ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя интервал от Y - dy до Y + dy \en Enclose a range from Y - dy to Y + dy +// --- +inline void MbRect::IncludeYInterval( double y, double dy ) { + bottom = std_min( bottom, y - dy ); + top = std_max( top, y + dy ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить в себя прямоугольник \en Enclose a rectangle +// --- +inline MbRect& MbRect::operator |= ( const MbRect & other ) { + left = std_min(left, other.left); + bottom = std_min(bottom, other.bottom); + right = std_max(right, other.right); + top = std_max(top, other.top); + + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвинуть прямоугольник \en Move rectangle +// --- +inline void MbRect::Move( const MbVector & to ) { + Move( to.x, to.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Сдвинуть прямоугольник \en Move rectangle +// --- +inline void MbRect::Move( double dx, double dy ) { + if ( !IsEmpty() ) { + left += dx; + right += dx; + top += dy; + bottom += dy; + } +} + + +//------------------------------------------------------------------------------ +// \ru Промасштабировать относительно 0 \en Scale relative to 0 +// --- +inline void MbRect::Scale( double scale ) { + if ( !IsEmpty() ) { + left *= scale; + right *= scale; + top *= scale; + bottom *= scale; + } +} + + +//------------------------------------------------------------------------------ +// \ru Расширить прямоугольник \en Extend rectangle +// --- +inline void MbRect::Enlarge( double x, double y ) { + if ( !IsEmpty() ) { + left -= x; + right += x; + bottom -= y; + top += y; + } +} + + +//------------------------------------------------------------------------------ +// \ru Расширить прямоугольник во все стороны \en Extend the rectangle in all directions +// \ru НЕ ПРОВЕРЯЕТСЯ вырожденность прямоугольников !!! \en Rectangles degeneracy IS NOT CHECKED !!! +// --- +inline void MbRect::Enlarge( double delta ) { + left -= delta; + right += delta; + bottom -= delta; + top += delta; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка, пересекается ли прям-к с другим прям-ком \en Check if rectangle intersect another rectangle +// \ru НЕ ПРОВЕРЯЕТСЯ вырожденность прямоугольников !!! \en Rectangles degeneracy IS NOT CHECKED !!! +// --- +inline bool MbRect::Intersect( const MbRect & other, double eps ) const { + return std_max( left, other.left ) < std_min( right, other.right ) + eps && + std_max( bottom, other.bottom ) < std_min( top, other.top ) + eps; +} + +//------------------------------------------------------------------------------ +// \ru Проверка, пересекается ли прям-к с другим прям-ком \en Check if the rectangle intersect another rectangle +// \ru НЕ ПРОВЕРЯЕТСЯ вырожденность прямоугольников !!! \en Rectangles degeneracy IS NOT CHECKED !!! +// --- +inline bool MbRect::Intersect( const MbRect & other, double xeps, double yeps ) const { + return std_max( left, other.left ) < std_min( right, other.right ) + xeps && + std_max( bottom, other.bottom ) < std_min( top, other.top ) + yeps; +} + + +/** \} */ + + + + + +#endif + diff --git a/C3d/Include/mb_rect1d.h b/C3d/Include/mb_rect1d.h new file mode 100644 index 0000000..eb419de --- /dev/null +++ b/C3d/Include/mb_rect1d.h @@ -0,0 +1,471 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Габаритные объекты. Одномерный куб. + \en Bounding box objects. One-dimensional cube. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_RECT1D_H +#define __MB_RECT1D_H + + +#include + + +//------------------------------------------------------------------------------ +/// \ru Одномерный куб \en One-dimensional cube +/** + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbRect1D { +public: + double zmin; ///< \ru Начало диапазона. \en Start of range. + double zmax; ///< \ru Конец диапазона. \en End of range. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbRect1D ( ); + /// \ru Конструктор копирования. \en Copy constructor. + MbRect1D ( const MbRect1D & ); + /// \ru Конструктор по заданным значениям границ. \en Constructor by given bounds. + MbRect1D ( double pmin, double pmax, bool equalize = true ); + + /// \ru Инициализировать неустановленным. \en Initialize unspecified. + void Init ( ); + /// \ru Инициализировать другим кубом. \en Initialize by another cube. + void Init ( const MbRect1D & ); + /// \ru Инициализировать заданными значениями границ. \en Initialize by given bounds. + void Init ( double pmin, double pmax, bool equalize = true ); + + /// \ru Создать вывернутый одномерный куб. \en Create reverted one-dimensional cube. + void Invert (); + /// \ru Сократить одномерный куб на заданный коэффициент и расширить на дельта. \en Decrease one-dimensional cube by a given factor and increase by delta. + void Short ( double, bool bis = true, double delta = LENGTH_EPSILON ); + /// \ru Сократить одномерный куб на заданный коэффициент относительно точки и расширить на дельта. \en Decrease one-dimensional cube by a given factor relative to point and increase by delta. + void Short ( double, double, bool bis = true, double delta = LENGTH_EPSILON ); + + /// \ru Включить точку. \en Include point. + void Include ( double, bool bis = true, double delta = LENGTH_EPSILON ); + /// \ru Установить куб. \en Set cube. + void Include ( const MbRect1D & , bool bis = true, double delta = LENGTH_EPSILON ); + + /// \ru Включить точку. \en Include point. + void IncludeEx ( double ); + /// \ru Установить куб. \en Set cube. + void IncludeEx ( const MbRect1D & ); + + ///< \ru Выровнять диапазон. \en Justify range. + void Equalize ( double &, double & ) const; + /// \ru Выровнять диапазон (zmin, zmax). \en Justify range (zmin, zmax). + void Equalize ( ); + /// \ru Является ли область вывернутой. \en Check if region is reverted. + bool IsEmpty ( ) const; + /// \ru Является ли область вырожденной. \en Check if region is degenerate. + bool IsDegenert ( ) const; + + /// \ru Есть ли пересечение с другим прямоугольником. \en Is there intersection with another rectangle. + bool IsIntersect( const MbRect1D & ) const; + /// \ru Есть ли пересечение с точкой. \en Is there intersection with point. + bool IsIntersect( double ) const; + /// \ru Есть ли пересечение с другим прямоугольником. \en Is there intersection with another rectangle. + bool IsIntersect( double, double ) const; + /// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( double ) const; + + /// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to cube. + void SetInR ( double & ) const; + /// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to cube. + void SetInRect ( double & ) const; + /// \ru Загнать другую область в куб. \en Drive another region to cube. + void SetInRect ( MbRect1D & ) const; + + /// \ru Получить минимум. \en Get minimum. + double GetMin () const { return zmin; } + /// \ru Получить максимум. \en Get maximum. + double GetMax () const { return zmax; } + /// \ru Задать минимум. \en Set minimum. + void SetMin( double v ) { zmin = v; } + /// \ru Задать максимум. \en Set maximum. + void SetMax( double v ) { zmax = v; } + + /// \ru Получить характерный масштаб одномерного куба. \en Get characteristic scale of one-dimensional cube. + double GetScale () const; + + /// \ru Увеличить куб. \en Increase cube. + void Increase ( double ); + + /// \ru Проверить принадлежность границе первого параметра с точностью, заданной вторым. \en Check if first parameter belongs to bound with tolerance given by second parameter. + bool IsBound ( double, double ) const; + /// \ru Cдвинуть куб. \en Move cube. + void Move ( double ); + /// \ru Проверить два куба на равенство с заданной точностью. \en Check equality of two cubes with given tolerance. + bool IsEqual ( const MbRect1D &, double eps ) const; + /// \ru Найти габарит пересечения двух габаритов. \en Find bounding box of two bounding boxes intersection. + bool Intersection( const MbRect1D &, const MbRect1D &, double eps = LENGTH_EPSILON ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbRect1D & other, double accuracy ) const { + return ( (::fabs(zmin - other.zmin) < accuracy) && (::fabs(zmax - other.zmax) < accuracy) ); + } + /// \ru Проверить на равенство (точность PARAM_REGION). \en Check for equality (tolerance PARAM_REGION). + bool operator ==( const MbRect1D & ) const; + /// \ru Проверка на меньше (точность PARAM_REGION). \en Check for lesser (tolerance PARAM_REGION). + bool operator < ( const MbRect1D & ) const; +}; + + +//------------------------------------------------------------------------------ +// \ru Выровнять диапазон \en Justify range +// --- +inline void MbRect1D::Equalize( double & ozmin, double & ozmax ) const +{ + if ( ozmin > ozmax ) { + double maxvalue = ozmin; + ozmin = ozmax; + ozmax = maxvalue; + } +} + + +//------------------------------------------------------------------------------ +// \ru Выровнять диапазон \en Justify range +// --- +inline void MbRect1D::Equalize() +{ + Equalize( zmin, zmax ); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect1D::MbRect1D() + : zmin( MB_MAXDOUBLE ) + , zmax( -MB_MAXDOUBLE ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect1D::MbRect1D( double ozmin, double ozmax, bool equalize ) + : zmin( ozmin ) + , zmax( ozmax ) +{ + if ( equalize ) + Equalize(); // \ru Выровнять куб \en Justify cube +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect1D::MbRect1D( const MbRect1D & other ) + : zmin( other.zmin ) + , zmax( other.zmax ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect1D::Init() +{ + zmin = MB_MAXDOUBLE; + zmax = -MB_MAXDOUBLE; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect1D::Init( double ozmin, double ozmax, bool equalize ) +{ + zmin = ozmin; // \ru Присвоить значения \en Assign values + zmax = ozmax; + if ( equalize ) + Equalize(); // \ru Выровнять куб \en Justify cube +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect1D::Init( const MbRect1D & other ) +{ + zmin = other.zmin; + zmax = other.zmax; +} + + +//------------------------------------------------------------------------------ +// \ru Сократить одномерный куб на заданный коэфициент \en Decrease one-dimensional cube by given factor +// --- +inline void MbRect1D::Short( double ks, bool bis, double d ) +{ + double delta = bis ? d : 0; + double l = ( zmax - zmin ) * 0.5; + double cz = zmin + l; + l *= ks; + l += delta; + zmin = cz - l; + zmax = cz + l; +} + + +//------------------------------------------------------------------------------ +// \ru Сократить одномерный куб на заданный коэфициент относительно точки \en Decrease one-dimensional cube by given factor relative to point +// --- +inline void MbRect1D::Short( double ks, double cz, bool bis, double d ) +{ + double delta = bis ? d : 0; + zmax = cz > zmax ? cz + delta : ( zmax - cz ) * ks + cz + delta; + zmin = cz < zmin ? cz - delta : ( zmin - cz ) * ks + cz - delta; +} + + +//------------------------------------------------------------------------------ +// \ru Включить одномерную точку \en Include one-dimensional point +// --- +inline void MbRect1D::Include( double other, bool bis, double delta ) +{ + if ( other > zmax ) + zmax = bis ? other + delta : other; // \ru Расширить \en Increase + if ( other < zmin ) + zmin = bis ? other - delta : other; // \ru Расширить \en Increase +} + + +//------------------------------------------------------------------------------ +// \ru Добавить не пустой габарит \en Add non-empty bounding box +// --- +inline void MbRect1D::Include( const MbRect1D & other, bool bis, double delta ) +{ + if ( !other.IsEmpty() ) { + Include( other.zmin, bis, delta ); + Include( other.zmax, bis, delta ); + } +} + + +//------------------------------------------------------------------------------- +// \ru Включить точку \en Include point +// --- +inline void MbRect1D::IncludeEx( double other ) +{ + if ( other > zmax ) + zmax = other; + if ( other < zmin ) + zmin = other; +} + + +//------------------------------------------------------------------------------- +// \ru Установить куб \en Set cube +// --- +inline void MbRect1D::IncludeEx( const MbRect1D & other ) +{ + if ( !other.IsEmpty() ) { + IncludeEx( other.zmin ); + IncludeEx( other.zmax ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Является ли область пустой \en Check if region is empty +// --- +inline bool MbRect1D::IsEmpty() const +{ + return zmin > zmax; +} + + +//------------------------------------------------------------------------------ +// \ru Является ли область вырожденной \en Check if region is degenerate +// --- +inline bool MbRect1D::IsDegenert() const +{ + return zmax - zmin < LENGTH_REGION; +} + + +//------------------------------------------------------------------------------ +// \ru Включение точки в прямоугольник \en Point inclusion in rectangle +// --- +inline bool MbRect1D::IsIntersect( double other ) const +{ + return other <= zmax && other >= zmin; +} + + +//------------------------------------------------------------------------------ +// \ru Включение точки в прямоугольник \en Point inclusion in rectangle +// --- +inline bool MbRect1D::IsIntersect( double z1, double z2 ) const +{ + Equalize( z1, z2 ); + return std_max( zmin, z1 ) <= std_min( zmax, z2 ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с другим прямоугольником \en Check intersection with another rectangle +// --- +inline bool MbRect1D::IsIntersect( const MbRect1D & other ) const +{ + return std_max( zmin, other.zmin ) <= std_min( zmax, other.zmax ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect1D::IsEmptyInt( double other ) const +{ + return other <= zmax || other >= zmin; +} + + +//------------------------------------------------------------------------------ +// \ru Загнать одномерную точку в куб \en Drive one-dimensional point to cube +// --- +inline void MbRect1D::SetInR( double & z ) const +{ + if ( z < zmin ) + z = zmin; + else + if ( z > zmax ) + z = zmax; +} + + +//------------------------------------------------------------------------------ +// \ru Загнать одномерную точку в куб \en Drive one-dimensional point to cube +// --- +inline void MbRect1D::SetInRect( double & z ) const +{ + if ( IsEmpty() ) { + if( !IsEmptyInt(z) ) + z = zmin; + } + else { + SetInR( z ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Загнать другую область в куб \en Drive another region to cube +// --- +inline void MbRect1D::SetInRect( MbRect1D & other ) const +{ + SetInRect( other.zmin ); + SetInRect( other.zmax ); +} + + +//------------------------------------------------------------------------------ +// \ru Создать вывернутый одномерный куб \en Create reverted one-dimensional cube +// --- +inline void MbRect1D::Invert() +{ + double oldzmax = zmax; + zmax = -zmin; + zmin = -oldzmax; +} + + +//------------------------------------------------------------------------------ +// \ru Получить характерный масштаб одномерного куба \en Get characteristic scale of one-dimensional cube +// --- +inline double MbRect1D::GetScale() const +{ + return (zmax - zmin); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить куб \en Increase cube +// --- +inline void MbRect1D::Increase( double delta ) +{ + zmax += delta; + zmin -= delta; +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе первого параметра с точность заданной вторым \en Check if the first parameter belongs to bound with tolerance given by second parameter +// --- +inline bool MbRect1D::IsBound( double z, double delta ) const +{ + return ::fabs( z - zmin ) < delta || ::fabs( z - zmax ) < delta; +} + + +//------------------------------------------------------------------------------- +// \ru Сдвиг \en Move +// --- +inline void MbRect1D::Move( double shift ) +{ + zmin += shift; + zmax += shift; +} + + +//------------------------------------------------------------------------------- +// \ru Равны ли двы куба \en Check if two cubes are equal +// --- +inline bool MbRect1D::IsEqual( const MbRect1D & other, double eps ) const +{ + return ( ::fabs(zmin - other.zmin) < eps && ::fabs(zmax - other.zmax) < eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbRect1D::operator == ( const MbRect1D & other ) const +{ + return IsEqual( other, PARAM_REGION ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на меньше \en Check for lesser +// --- +inline bool MbRect1D::operator < ( const MbRect1D & other ) const +{ + return ( zmin < other.zmin - PARAM_REGION ) || + ( ( ::fabs( zmin - other.zmin ) < PARAM_REGION ) && ( zmax < other.zmax - PARAM_REGION ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Габарит пересечения двух габаритов \en Bounding box of two bounding boxes intersection +// --- +inline bool MbRect1D::Intersection( const MbRect1D & r1, const MbRect1D & r2, double eps ) +{ + bool isInt = false; + + if ( !r1.IsEmpty() && !r2.IsEmpty() ) { + eps = ::fabs( eps ); + zmin = std_max( r1.zmin, r2.zmin ); + zmax = std_min( r1.zmax, r2.zmax ); + if ( zmax > zmin + eps ) + isInt = true; + } + if ( !isInt ) + Init(); + + return isInt; +} + + +#endif // __MB_RECT1D_H \ No newline at end of file diff --git a/C3d/Include/mb_rect2d.h b/C3d/Include/mb_rect2d.h new file mode 100644 index 0000000..24a685f --- /dev/null +++ b/C3d/Include/mb_rect2d.h @@ -0,0 +1,810 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Габаритные объекты. Двумерный и трехмерный кубы. + \en Bounding box objects. Two-dimensional and three-dimensional cubes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __MB_RECT2D_H +#define __MB_RECT2D_H + + +#include +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Двумерный куб \en A two-dimensional cube +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Двумерный куб \en A two-dimensional cube +/** + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbRect2D { +public: + MbRect1D rx; ///< \ru Диапазон по x. \en Range for x. + MbRect1D ry; ///< \ru Диапазон по y. \en Range for y. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbRect2D(); + /// \ru Конструктор по заданным значениям границ. \en Constructor by given bounds. + MbRect2D( double xmin, double ymin, double xmax, double ymax ); + /// \ru Конструктор по двум диагональным точкам. \en The constructor by two diagonal points. + MbRect2D( const MbCartPoint &, const MbCartPoint & ); + /// \ru Конструктор по двум диагональным трехмерным точкам. \en The constructor by two diagonal three-dimensional points. + MbRect2D( const MbCartPoint3D &, const MbCartPoint3D & ); + /// \ru Конструктор копирования. \en Copy constructor. + MbRect2D( const MbRect2D & ); + + /// \ru Инициализировать неустановленным. \en Initialize unspecified. + void Init (); + /// \ru Инизиализировать заданными значениями границ. \en Initialize by given bounds. + void Init ( double xmin, double ymin, double xmax, double ymax ); + /// \ru Инизиализировать двумя диагональными точками. \en Initialize by two diagonal points. + void Init ( const MbCartPoint &, const MbCartPoint & ); + /// \ru Инизиализировать двумя диагональными трехмерными точками. \en Initialize by two diagonal three-dimensional points. + void Init ( const MbCartPoint3D &, const MbCartPoint3D & ); + /// \ru Инициализировать другим кубом. \en Initialize by another cube. + void Init ( const MbRect2D & ); + + /// \ru Создать вывернутый двумерный куб. \en Create everted two-dimensional cube. + void Invert (); + + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, double, double, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, const MbCartPoint &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, const MbVector &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, const MbCartPoint3D &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Сократить двумерный куб на заданный коэфициент. \en Decrease two-dimensional cube by given factor. + void Short ( double, const MbVector3D &, bool bis = true, double delta = Math::lengthEpsilon ); + + /// \ru Включить точку. \en Include point. + void Include ( double, double, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Включить точку. \en Include point. + void Include ( const MbCartPoint &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Включить точку. \en Include point. + void Include ( const MbVector &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Включить точку. \en Include point. + void Include ( const MbCartPoint3D &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Включить точку. \en Include point. + void Include ( const MbVector3D &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Включить другой двумерный куб. \en Include another two-dimensional cube. + void Include ( const MbRect2D &, bool bis = true, double delta = Math::lengthEpsilon ); + /// \ru Установить двумерный куб. \en Set two-dimensional cube. + void Include ( const MbCartPoint &, const MbCartPoint &, bool bis = true, double delta = Math::lengthEpsilon ); + + /// \ru Включить точку. \en Include point. + void IncludeEx ( double , double ); + /// \ru Включить точку. \en Include point. + void IncludeEx ( const MbCartPoint & ); + /// \ru Включить точку. \en Include point. + void IncludeEx ( const MbVector & ); + /// \ru Включить точку. \en Include point. + void IncludeEx ( const MbCartPoint3D & ); + /// \ru Включить точку. \en Include point. + void IncludeEx ( const MbVector3D & ); + /// \ru Включить другой двумерный куб. \en Include another two-dimensional cube. + void IncludeEx ( const MbRect2D & ); + /// \ru Установить двумерный куб. \en Set two-dimensional cube. + void IncludeEx ( const MbCartPoint &, const MbCartPoint & ); + + /// \ru Выровнять область. \en Justify the region. + void Equalize (); + /// \ru Выровнять область. \en Justify the region. + void Equalize ( MbCartPoint &, MbCartPoint & ) const; + /// \ru Выровнять область. \en Justify the region. + void Equalize ( double &, double &, double &, double & ) const; + /// \ru Проверить, является ли область пустой. \en Check if region is empty. + bool IsEmpty () const; + /// \ru Проверить, является ли область вырожденной. \en Check if region is degenerate. + bool IsDegenert () const; + + /// \ru Пересекается ли точка с прямоугольником. \en Check if point intersects with rectangle. + bool IsIntersect( const MbCartPoint3D & ) const; + /// \ru Пересекается ли точка с прямоугольником. \en Check if point intersects with rectangle. + bool IsIntersect( const MbCartPoint & ) const; + /// \ru Пересекается ли точка с прямоугольником. \en Check if point intersects with rectangle. + bool IsIntersect( double, double ) const; + /// \ru Пересекаются ли прямоугольники. \en Check if rectangles intersect. + bool IsIntersect( const MbRect2D & ) const; + /// \ru Пересекаются ли прямоугольники. \en Check if rectangles intersect. + bool IsIntersect( const MbCartPoint &, const MbCartPoint & ) const; + /// \ru Пересекаются ли прямоугольники. \en Check if rectangles intersect. + bool IsIntersect( const MbCartPoint3D &, const MbCartPoint3D & ) const; + /// \ru Пересекаются ли прямоугольники. \en Check if rectangles intersect. + bool IsIntersect( double, double, double, double ) const; + /// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( double, double ) const; + /// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( const MbVector & ) const; + ///< \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( const MbCartPoint & ) const; + /// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( const MbVector3D & ) const; + /// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty cube. + bool IsEmptyInt ( const MbCartPoint3D & ) const; + + /// \ru Загнать трехмерную точку в куб. \en Drive three-dimensional point to cube. + void SetInRect ( MbCartPoint3D & ) const; + /// \ru Загнать двумерную точку в куб. \en Drive two-dimensional point to cube. + void SetInRect ( MbCartPoint & ) const; + /// \ru Загнать другой куб в куб. \en Drive another cube to cube. + void SetInRect ( MbRect2D & ) const; + /// \ru Загнать двумерную точку в куб. \en Drive two-dimensional point to cube. + void SetInRect ( double &, double & ) const; + /// \ru Загнать в куб. \en Drive to cube. + void SetInRectX ( double & ) const; + /// \ru Загнать в куб. \en Drive to cube. + void SetInRectY ( double & ) const; + + /// \ru Вернуть минимальное значение параметра u. \en Get the minimum value of u. + double GetXMin() const { return rx.GetMin(); } + /// \ru Вернуть максимальное значение параметра u. \en Get the maximum value of u. + double GetXMax() const { return rx.GetMax(); } + /// \ru Вернуть минимальное значение параметра v. \en Get the minimum value of v. + double GetYMin() const { return ry.GetMin(); } + /// \ru Вернуть максимальное значение параметра v. \en Get the maximum value of v. + double GetYMax() const { return ry.GetMax(); } + + /// \ru Получить характерный масштаб двумерного куба по x. \en Get characteristic scale of two-dimensional cube by x. + double GetScaleX () const; + /// \ru Получить характерный масштаб двумерного куба по y. \en Get characteristic scale of two-dimensional cube by y. + double GetScaleY () const; + /// \ru Получить характерный масштаб двумерного куба. \en Get characteristic scale of two-dimensional cube. + double GetScale () const; + + /// \ru Увеличить куб по x. \en Increase cube at x. + void IncreaseX ( double ); + /// \ru Увеличить куб по y. \en Increase cube at y. + void IncreaseY ( double ); + ///< \ru Увеличить куб. \en Increase cube. + void Increase ( double ); + + /// \ru Принадлежит ли границе X первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to X bound with tolerance given by the second parameter. + bool IsBoundX ( double, double ) const; + /// \ru Принадлежит ли границе Y первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to Y bound with tolerance given by the second parameter. + bool IsBoundY ( double, double ) const; + /// \ru Принадлежит ли границе первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to bound with tolerance given by the second parameter. + bool IsBound ( double, double, double ) const; + /// \ru Принадлежит ли границе первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to bound with tolerance given by the second parameter. + bool IsBound ( const MbCartPoint &, double ) const; + /// \ru Принадлежит ли границе первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to bound with tolerance given by the second parameter. + bool IsBound ( const MbVector &, double ) const; + /// \ru Принадлежит ли границе первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to bound with tolerance given by the second parameter. + bool IsBound ( const MbCartPoint3D &, double ) const; + /// \ru Принадлежит ли границе первый параметр с точностью заданной вторым. \en Check if value given by the first parameter belongs to bound with tolerance given by the second parameter. + bool IsBound ( const MbVector3D &, double ) const; + /// \ru Cдвинуть куб. \en Move cube. + void Move ( const MbVector & ); + +}; + + +//------------------------------------------------------------------------------ +// \ru Выровнять область \en Justify region +// --- +inline void MbRect2D::Equalize( double &fx, double &fy, double &sx, double &sy ) const { + rx.Equalize( fx, sx ); + ry.Equalize( fy, sy ); +} + + +//------------------------------------------------------------------------------ +// \ru Выровнять диапазоны \en Justify ranges +// --- +inline void MbRect2D::Equalize( MbCartPoint &opmin, MbCartPoint &opmax ) const { + Equalize( opmin.x, opmin.y, opmax.x, opmax.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Выровнять диапазоны \en Justify ranges +// --- +inline void MbRect2D::Equalize() { + rx.Equalize(); + ry.Equalize(); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect2D::MbRect2D() + : rx(), ry() { +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect2D::MbRect2D( double pminx, double pminy, double pmaxx, double pmaxy ) + : rx( pminx, pmaxx ), ry( pminy, pmaxy ) { +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect2D::MbRect2D( const MbCartPoint &opmin, const MbCartPoint &opmax ) + : rx( opmin.x, opmax.x ), ry( opmin.y, opmax.y ) { +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect2D::MbRect2D( const MbCartPoint3D &opmin, const MbCartPoint3D &opmax ) + : rx( opmin.x, opmax.x ), ry( opmin.y, opmax.y ) { +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect2D::MbRect2D( const MbRect2D &other ) + : rx( other.rx ), ry( other.ry ) { +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать пустой \en Initialize as empty +// --- +inline void MbRect2D::Init() { + rx.Init(); + ry.Init(); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect2D::Init( double pminx, double pminy, double pmaxx, double pmaxy ) { + rx.Init( pminx, pmaxx ); + ry.Init( pminy, pmaxy ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect2D::Init( const MbCartPoint &opmin, const MbCartPoint &opmax ) { + rx.Init( opmin.x, opmax.x ); + ry.Init( opmin.y, opmax.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать \en Initialize +// --- +inline void MbRect2D::Init( const MbCartPoint3D &opmin, const MbCartPoint3D &opmax ) { + rx.Init( opmin.x, opmax.x ); + ry.Init( opmin.y, opmax.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать пустой \en Initialize as empty +// --- +inline void MbRect2D::Init( const MbRect2D &other ) { + rx.Init( other.rx ); + ry.Init( other.ry ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, bool bis, double d ) { + rx.Short( ks, bis, d ); + ry.Short( ks, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, double cx, double cy, bool bis, double d ) { + rx.Short( ks, cx, bis, d ); + ry.Short( ks, cy, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, const MbCartPoint &cp, bool bis, double d ) { + Short( ks, cp.x, cp.y, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, const MbVector &cp, bool bis, double d ) { + Short( ks, cp.x, cp.y, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, const MbCartPoint3D &cp, bool bis, double d ) { + Short( ks, cp.x, cp.y, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Сократить двумерный куб на заданный коэфициент \en Decrease two-dimensional cube by given factor +// --- +inline void MbRect2D::Short( double ks, const MbVector3D &cp, bool bis, double d ) { + Short( ks, cp.x, cp.y, bis, d ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить двумерную точку \en Include two-dimensional point +// --- +inline void MbRect2D::Include( double x, double y, bool bis, double delta ) { + rx.Include( x, bis, delta ); + ry.Include( y, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить двумерную точку \en Include two-dimensional point +// --- +inline void MbRect2D::Include( const MbCartPoint &other, bool bis, double delta ) { + Include( other.x, other.y, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить двумерную точку \en Include two-dimensional point +// --- +inline void MbRect2D::Include( const MbVector &other, bool bis, double delta ) { + Include( other.x, other.y, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить двумерную точку \en Include two-dimensional point +// --- +inline void MbRect2D::Include( const MbVector3D &other, bool bis, double delta ) { + Include( other.x, other.y, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить двумерную точку \en Include two-dimensional point +// --- +inline void MbRect2D::Include( const MbCartPoint3D &other, bool bis, double delta ) { + Include( other.x, other.y, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Установить двумерный куб \en Set two-dimensional cube +// --- +inline void MbRect2D::Include( const MbCartPoint &opmin, const MbCartPoint &opmax, bool bis, double delta ) { + Include( opmin, bis, delta ); + Include( opmax, bis, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Включить другой двумерный куб \en Include another two-dimensional cube +// --- +inline void MbRect2D::Include( const MbRect2D &other, bool bis, double delta ) { + rx.Include( other.rx, bis, delta ); + ry.Include( other.ry, bis, delta ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить \en Include +// --- +inline void MbRect2D::IncludeEx( double x, double y ) { + rx.IncludeEx( x ); + ry.IncludeEx( y ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить точку \en Include point +// --- +inline void MbRect2D::IncludeEx( const MbCartPoint &other ) { + IncludeEx( other.x, other.y ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить вектор \en Include vector +// --- +inline void MbRect2D::IncludeEx( const MbVector &other ) { + IncludeEx( other.x, other.y ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить точку \en Include point +// --- +inline void MbRect2D::IncludeEx( const MbCartPoint3D &other ) { + IncludeEx( other.x, other.y ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить точку \en Include point +// --- +inline void MbRect2D::IncludeEx( const MbVector3D &other ) { + IncludeEx( other.x, other.y ); +} + + +//------------------------------------------------------------------------------- +// \ru Установить двумерный куб \en Set two-dimensional cube +// --- +inline void MbRect2D::IncludeEx( const MbCartPoint &opmin, const MbCartPoint &opmax ) { + IncludeEx( opmin ); + IncludeEx( opmax ); +} + + +//------------------------------------------------------------------------------- +// \ru Включить другой двумерный куб \en Include another two-dimensional cube +// --- +inline void MbRect2D::IncludeEx( const MbRect2D &other ) { + rx.IncludeEx( other.rx ); + ry.IncludeEx( other.ry ); +} + + +//------------------------------------------------------------------------------ +// \ru Является ли двумерный куб пустым \en Check if two-dimensional cube is empty +// --- +inline bool MbRect2D::IsEmpty() const { + return rx.IsEmpty() || ry.IsEmpty(); +} + + +//------------------------------------------------------------------------------ +// \ru Является ли область вырожденной \en Check if region is degenerate +// --- +inline bool MbRect2D::IsDegenert() const { + return rx.IsDegenert() || ry.IsDegenert(); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с другим прямоугольником \en Check intersection with another rectangle +// --- +inline bool MbRect2D::IsIntersect( double fx, double fy, double sx, double sy ) const { + return rx.IsIntersect( fx, sx ) && ry.IsIntersect( fy, sy ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с другим прямоугольником \en Check intersection with another rectangle +// --- +inline bool MbRect2D::IsIntersect( const MbCartPoint &omin, const MbCartPoint &omax ) const { + return IsIntersect( omin.x, omin.y, omax.x, omax.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с другим прямоугольником \en Check intersection with another rectangle +// --- +inline bool MbRect2D::IsIntersect( const MbCartPoint3D &omin, const MbCartPoint3D &omax ) const { + return IsIntersect( omin.x, omin.y, omax.x, omax.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с другим габаритом \en Check intersection with another bounding box +// --- +inline bool MbRect2D::IsIntersect( const MbRect2D &other ) const { + return rx.IsIntersect( other.rx ) && ry.IsIntersect( other.ry ); +} + + +//------------------------------------------------------------------------------ +// \ru Лежит ли точка внутри области \en Is point inside region +// --- +inline bool MbRect2D::IsIntersect( double x, double y ) const { + return rx.IsIntersect( x ) && ry.IsIntersect( y ); +} + + +//------------------------------------------------------------------------------ +// \ru Лежит ли точка внутри области \en Is point inside region +// --- +inline bool MbRect2D::IsIntersect( const MbCartPoint &other ) const { + return rx.IsIntersect( other.x ) && ry.IsIntersect( other.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Лежит ли точка внутри области \en Is point inside region +// --- +inline bool MbRect2D::IsIntersect( const MbCartPoint3D &other ) const { + return rx.IsIntersect( other.x ) && ry.IsIntersect( other.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect2D::IsEmptyInt( double x, double y ) const { + return rx.IsEmptyInt( x ) || ry.IsEmptyInt( y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect2D::IsEmptyInt( const MbVector &p ) const { + return IsEmptyInt( p.x, p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect2D::IsEmptyInt( const MbCartPoint &p ) const { + return IsEmptyInt( p.x, p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect2D::IsEmptyInt( const MbVector3D &p ) const { + return IsEmptyInt( p.x, p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение с пустым кубом \en Is there intersection with empty cube +// --- +inline bool MbRect2D::IsEmptyInt( const MbCartPoint3D &p ) const { + return IsEmptyInt( p.x, p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать двумерную точку в куб \en Drive two-dimensional point to cube +// --- +inline void MbRect2D::SetInRectX( double &value ) const { + rx.SetInRect( value ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать двумерную точку в куб \en Drive two-dimensional point to cube +// --- +inline void MbRect2D::SetInRectY( double &value ) const { + ry.SetInRect( value ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать двумерную точку в куб \en Drive two-dimensional point to cube +// --- +inline void MbRect2D::SetInRect( double &x, double &y ) const { + rx.SetInRect( x ); + ry.SetInRect( y ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать двумерную точку в куб \en Drive two-dimensional point to cube +// --- +inline void MbRect2D::SetInRect( MbCartPoint &p ) const { + rx.SetInRect( p.x ); + ry.SetInRect( p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать трехмерную точку в куб \en Drive three-dimensional point to cube +// --- +inline void MbRect2D::SetInRect( MbCartPoint3D &p ) const { + rx.SetInRect( p.x ); + ry.SetInRect( p.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Загнать другой куб в куб \en Drive another cube to cube +// --- +inline void MbRect2D::SetInRect( MbRect2D &other ) const { + rx.SetInRect( other.rx ); + ry.SetInRect( other.ry ); +} + + +//------------------------------------------------------------------------------ +// \ru Создать вывернутый двумерный куб \en Create everted two-dimensional cube +// --- +inline void MbRect2D::Invert() { + rx.Invert(); + ry.Invert(); +} + + +//------------------------------------------------------------------------------ +// \ru Получить характерный масштаб двумрного куба \en Get characteristic scale of two-dimensional cube +// --- +inline double MbRect2D::GetScaleX() const { + return rx.GetScale(); +} + + +//------------------------------------------------------------------------------ +// \ru Получить характерный масштаб двумрного куба \en Get characteristic scale of two-dimensional cube +// --- +inline double MbRect2D::GetScaleY() const { + return ry.GetScale(); +} + + +//------------------------------------------------------------------------------ +// \ru Получить характерный масштаб двумрного куба \en Get characteristic scale of two-dimensional cube +// --- +inline double MbRect2D::GetScale() const { + return rx.GetScale() + ry.GetScale(); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить куб \en Increase cube +// --- +inline void MbRect2D::IncreaseX( double delta ) { + rx.Increase( delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить куб \en Increase cube +// --- +inline void MbRect2D::IncreaseY( double delta ) { + ry.Increase( delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличить куб \en Increase cube +// --- +inline void MbRect2D::Increase( double delta ) { + rx.Increase( delta ); + ry.Increase( delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBoundX( double x, double delta ) const { + return rx.IsBound( x, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBoundY( double y, double delta ) const { + return ry.IsBound( y, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBound ( double x, double y, double delta ) const { + return rx.IsBound( x, delta ) || ry.IsBound( y, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBound ( const MbCartPoint &p, double delta ) const { + return rx.IsBound( p.x, delta ) || ry.IsBound( p.y, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBound ( const MbVector &p, double delta ) const { + return rx.IsBound( p.x, delta ) || ry.IsBound( p.y, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBound ( const MbCartPoint3D &p, double delta ) const { + return rx.IsBound( p.x, delta ) || ry.IsBound( p.y, delta ); +} + + +//------------------------------------------------------------------------------ +// \ru Принадлежность границе \en Belonging to bound +// --- +inline bool MbRect2D::IsBound ( const MbVector3D &p, double delta ) const { + return rx.IsBound( p.x, delta ) || ry.IsBound( p.y, delta ); +} + + +//------------------------------------------------------------------------------- +// \ru Сдвиг \en Move +// --- +inline void MbRect2D::Move( const MbVector & vShift ) { + if ( ::fabs(vShift.x) > EXTENT_EQUAL ) { + rx.Move( vShift.x ); + } + if ( ::fabs(vShift.y) > EXTENT_EQUAL ) { + ry.Move( vShift.y ); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Трехмерный куб \en Three-dimensional cube +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Трехмерный куб \en Three-dimensional cube +/** + \ingroup Mathematic_Base_3D +*/ +// --- +class MbRect3D { +public: + MbRect1D rx; ///< \ru Диапазон по x \en Range for x + MbRect1D ry; ///< \ru Диапазон по y \en Range for y + MbRect1D rz; ///< \ru Диапазон по z \en Range for z + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbRect3D(); + +private: + MbRect3D ( const MbRect3D & ); // \ru Не реализован \en Not implemented + void operator = ( const MbRect3D & ); // \ru Не реализован \en Not implemented +}; + + +/** \} */ + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbRect3D::MbRect3D() + : rx(), ry(), rz() { +} + + +#endif + diff --git a/C3d/Include/mb_rough.h b/C3d/Include/mb_rough.h new file mode 100644 index 0000000..336d668 --- /dev/null +++ b/C3d/Include/mb_rough.h @@ -0,0 +1,206 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Условное обозначения шероховатости. Условное обозначение линия-выноска. + \en Roughness conventional notation. Leader conventional notation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_ROUGH_H +#define __MB_ROUGH_H + + +#include +#include + + +class MATH_CLASS MbPlacement3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Обозначение шероховатости. + \en Roughness notation. \~ + \details \ru Обозначение шероховатости поверхности детали.\n + \en Roughness notation of detail surface.\n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbRough : public MbPointsSymbol +{ +private: + MbTopologyItem * item; ///< \ru Топологический объект, которому принадлежит шероховатость (не владеет). \en Topological object which roughness belongs to (doesn't own). + +protected: + /// \ru Конструктор-копия. \en Copy constructor. + MbRough( const MbRough & ); + /// \ru Умолчательный конструктор. \en Default constructor. + MbRough(); +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор условного обозначения на базовых точках. + \en Constructor of conventional notation on base points. \~ + \param[in] _points - \ru Базовые точки условного обозначения в мировой системе координат. + \en Conventional notation base points in world coordinate system. \~ + \param[in] _name - \ru Имя условного обозначения объекта. + \en Object's conventional notation name. \~ + \param[in] _component - \ru Компонент условного обозначения. + \en Component of conventional notation. \~ + \param[in] _item - \ru Топологический объект, которому принадлежит шероховатость. + \en Topological object, which roughness belongs to. \~ + \param[in] _stateCalc - \ru Тип расчета видимости точек. + \en Points visibility calculation type. \~ + */ + MbRough( const SArray & _points, MbName * _name, + uint _component, MbTopologyItem * _item, StateCalc _stateCalc = st_strong ); + /// \ru Деструктор. \en Destructor. + virtual ~MbRough(); + +public: + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA () const; + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); + + /** \} */ + /** \ru \name Собственные функции шероховатости. + \en \name Own functions of roughness. + \{ */ + + /// \ru Получить топологический объект, которому принадлежит шероховатость. \en Get topological object, which roughness belongs to. + MbTopologyItem * GetTopologicItem() const; + /// \ru Установить топологический объект, которому принадлежит шероховатость. \en Set topological object, which roughness belongs to. + void SetTopologicItem( MbTopologyItem * _item ); + /** \} */ + +private: + MbRough & operator = ( const MbRough & ); + + DECLARE_PERSISTENT_CLASS( MbRough ) +}; + +IMPL_PERSISTENT_OPS( MbRough ) + +//------------------------------------------------------------------------------ +/** \brief \ru Условное обозначение линия-выноска. + \en Leader conventional notation. \~ + \details \ru Условное обозначение линия-выноска.\n + \en Leader conventional notation.\n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbLeader : public MbSymbol { + +protected: + PArray branches; ///< \ru Узлы обозначения линия-выноска (не владеет). \en Leader notation nodes (doesn't own). + +protected: + /// \ru Конструктор-копия. \en Copy constructor. + MbLeader( const MbLeader & ); + /// \ru Умолчательный конструктор. \en Default constructor. + MbLeader(); +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор условного обозначения на базовых точках. + \en Constructor of conventional notation on base points. \~ + \param[in] _branches - \ru Узлы обозначения линия-выноска. + \en Leader notation nodes. \~ + \param[in] _name - \ru Имя условного обозначения. + \en Conventional notation name. \~ + \param[in] _component - \ru Компонент условного обозначения. + \en Component of conventional notation. \~ + \param[in] _stateCalc - \ru Тип расчета видимости точек. + \en Points visibility calculation type. \~ + */ + MbLeader( const PArray & _branches, MbName * _name, + uint _component, StateCalc _stateCalc = st_strong ); + /// \ru Деструктор. \en Destructor. + virtual ~MbLeader(); + +public: + /// \ru Инициализация. \en Initialization. + void Init( const MbLeader & ); + +public: + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + + virtual MbeSpaceType IsA () const; + virtual MbSpaceItem & Duplicate ( MbRegDuplicate * = NULL ) const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); + virtual void Transform ( const MbMatrix3D &, MbRegTransform * = NULL ); + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); + + virtual void GetProperties( MbProperties & ); + virtual void SetProperties( const MbProperties & ); + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции условного обозначения. + \en \name Functions of conventional notation. + \{ */ + + /// \ru Включить свой габарит в габаритный куб cube. \en Include own bounding box into 'cube' bounding box. + virtual void IncludeGab ( MbCube & ) const; + /// \ru Находится ли условное обозначение на плоскости OXY плейсмента place. \en Check if conventional notation on OXY plane of 'place' placement. + virtual bool IsSymbolOnPlace ( const MbPlacement3D & ) const; + /// \ru Находится ли условное обозначение на или под плоскостью OXY плейсмента place. \en Check if conventional notation on OXY plane of 'place' placement or under it. + virtual bool IsSymbolUnderPlace( const MbPlacement3D & ) const; + /// \ru Находится ли условное обозначение на или внутри оболочки faceShell. \en Check if conventional notation on 'faceShell' shell or inside it. + virtual bool IsSymbolInShell ( const MbFaceShell & ) const; + /// \ru Получить массив условных обозначений на базовых точках, принадлежащих данному обозначению. \en Get an array of notation conventions on the base points which belong to this notation. + virtual void GetPointsSymbols ( RPArray & ) const; + + /** \} */ + /** \ru \name Собственные функции обозначения линия-выноска. + \en \name Own functions of leader notation. + \{ */ + + /// \ru Получить количество узлов обозначения линия-выноска. \en Get count of leader notation nodes. + ptrdiff_t GetBranchesCount () const; + + /** \brief \ru Получить узел. + \en Get node. \~ + \details \ru Получить узел обозначения по индексу. + \en Get notation node by index. \~ + \param[in] ind - \ru Индекс узла. + \en Node index. \~ + \return \ru Узел по указанному индексу,\n + в случае некорректного индекса - последний узел из списка. + \en Node by specified index,\ n + in case of incorrect index - the last node from list. \~ + */ + const MbRough & GetBranch( size_t ind ) const; + + /** \brief \ru Установить узел. + \en Set node. \~ + \details \ru Установить узел обозначения с указанным индексом. + \en Set notation node by given index. \~ + \param[in] rough - \ru Новый узел. + \en New node. \~ + \param[in] ind - \ru Индекс узла. + \en Node index. \~ + */ + void SetBranch( const MbRough & rough, size_t ind ); + /** \} */ +private: + // \ru Не реализованные методы класса. \en Not implemented class methods. + void operator = ( const MbLeader & ); + + DECLARE_PERSISTENT_CLASS( MbLeader ) +}; + +IMPL_PERSISTENT_OPS( MbLeader ) + + +#endif // __MB_ROUGH_H diff --git a/C3d/Include/mb_symbol.h b/C3d/Include/mb_symbol.h new file mode 100644 index 0000000..7e7f730 --- /dev/null +++ b/C3d/Include/mb_symbol.h @@ -0,0 +1,303 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение классов условных обозначений. + \en Conventional notation classes definition. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_SYMBOL_H +#define __MB_SYMBOL_H + + +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbName; +class MATH_CLASS MbFaceShell; + + +//------------------------------------------------------------------------------ +/** \brief \ru Условное обозначение. + \en Conventional notation. \~ + \details \ru Абстрактный базовый класс условного обозначения MbSymbol. \n + \en Abstract base class of conventional notation MbSymbol. \n \~ + \ingroup Legend +*/ +/*\ru Иерархия классов условных обозначений + + -MbSymbol (абстрактный базовый класс) + тип расчета видимости + имя + компонент + / \ + / \ + / \ + MbLeader (линия-выноска) MbPointsSymbol (обозначение на базовых точках) + + массив MbRough'ов + массив MbCartPoint3D + / + / + / + MbRough (обозначение шероховатости) + + MbTopologyItem + + Пока для условных обозначений мы только определяем видимость при проецировании. + Фактически это сводится к определению видимости MbPointsSymbol, а это в свою + очередь - к определению видимости точки со следующими условиями: + - для MbPointsSymbol точку не могут закрывать ребра + - для MbRough точку закрывают все ребра, кроме тех, которые принадлежат MbTopologyItem + \en Conventional notation classes hierarchy + + -MbSymbol (abstract base class) + visibility calculation type + name + component + / \ + / \ + / \ + MbLeader (leader) MbPointsSymbol (notation on base points) + + array of MbRough's + array of MbCartPoint3D's + / + / + / + MbRough (roughness notation) + + MbTopologyItem + + Yet for conventional notations we only define visibility at projection. + Actually it is reduced to determination of MbPointsSymbol visibility, so it, in + turn, to definition of point visibility with following conditions: + - in case of MbPointsSymbol edges can not hide a point + - in case of MbRough point is hid by all edges except that belongs to MbTopologyItem \~ +*/ +// --- +class MATH_CLASS MbSymbol : public MbLegend { + +public: + /** \brief \ru Тип расчета видимости. + \en Visibility calculation type. \~ + \details \ru Тип расчета видимости. + \en Visibility calculation type. \~ + */ + enum StateCalc { + st_strong = 0, ///< \ru Точно, все точки должны быть видимы. \en Strong, all points have to be visible. + st_loose = 1, ///< \ru Не строго, хотя бы одна точка должна быть видима. \en Not strong, at least one point has to be visible. + }; + +protected: + StateCalc stateCalc; ///< \ru Тип расчета видимости. \en Visibility calculation type. + TOwnPointer name; ///< \ru Имя обозначения \en Notation name + uint compHash; ///< \ru Компонент условного обозначения (не владеет). \en Component of conventional notation (doesn't own). + size_t ident; ///< \ru Идентификатор нити. \en Thread identifier. + +protected: + /// \ru Умолчательный конструктор. \en Default constructor. + MbSymbol(); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор условного обозначения. \n + \en Constructor of conventional notation. \n \~ + \param[in] _name - \ru Имя обозначения. + \en Notation name. \~ + \param[in] _component - \ru Компонент условного обозначения + \en Component of conventional notation \~ + \param[in] _ident - \ru Идентификатор нити. + \en A thread identifier. \~ + \param[in] _stateCalc - \ru Тип расчета видимости. + \en Visibility calculation type. \~ + */ + MbSymbol( MbName * _name, uint _component, StateCalc _stateCalc = st_strong ); + + /// \ru Конструктор-копия. \en Copy constructor. + MbSymbol( const MbSymbol & ); + +public: + virtual ~MbSymbol(); + +public: + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const = 0; + virtual MbeSpaceType Type() const; + virtual MbSpaceItem & Duplicate ( MbRegDuplicate * = NULL ) const = 0; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; + virtual bool IsSimilar ( const MbSpaceItem & ) const; + virtual bool SetEqual ( const MbSpaceItem & ) = 0; + virtual void Transform ( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ) = 0; + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; + virtual void AddYourGabaritTo ( MbCube & ) const {}; + virtual void CalculateMesh ( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + virtual MbProperty & CreateProperty ( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create own property. + virtual void GetProperties ( MbProperties & ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties ( const MbProperties & ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const = 0; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ) = 0; // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Собственные функции условного обозначения. + \en \name Own functions of conventional notation. + \{ */ + // \ru Функции, относящиеся к расчету видимости обозначения stateCalc \en Functions related to 'stateCalc' calculation of notation visibility + /// \ru Получить тип расчета видимости. \en Get visibility calculation type. + StateCalc GetStateCalc () const; + /// \ru Точный ли тип расчета видимости. \en Check if visibility calculation type is strong. + bool IsStrongStateCalc () const; + /// \ru Установить тип расчета видимости. \en Set visibility calculation type. + void SetStateCalc ( StateCalc _stateCalc ); + + // \ru Функции, относящиеся к имени name \en Functions related to 'name' name + /// \ru Есть ли непустое имя. \en Is there a non-empty name. + bool IsName () const; + /// \ru Получить имя обозначения. \en Get notation name. + MbName * GetName () const; + /// \ru Установить имя обозначения. \en Set notation name. + void SetName ( MbName & ); + + // \ru Функции, относящиеся к компоненту обозначения component \en Functions related to 'component' component of notation + /// \ru Получить компонент обозначения. \en Get notation component. + uint GetComponent () const; + /// \ru Установить компонент обозначения. \en Set notation component. + void SetComponent ( uint ); + + // \ru Функции, относящиеся к идентификатору нити ident \en Functions related to 'ident' thread identifier + /// \ru Получить идентификатор нити. \en Get the thread identifier. + size_t GetIdentifier () const; + /// \ru Установить идентификатор нити. \en Set thread identifier. + void SetIdentifier ( size_t ); + + // \ru Виртуальные функции, различающиеся у различных условных обозначений \en Virtual functions, that differs in different notations + /// \ru Включить свой габарит в габаритный куб cube. \en Include own bounding box into 'cube' bounding box. + virtual void IncludeGab ( MbCube & ) const = 0; + /// \ru Находится ли условное обозначение на плоскости OXY плейсмента. \en Check if conventional notation on the OXY plane of placement. + virtual bool IsSymbolOnPlace ( const MbPlacement3D & ) const = 0; + /// \ru Находится ли условное обозначение на или под плоскостью OXY плейсмента. \en Check if conventional notation on the OXY plane of placement or under it. + virtual bool IsSymbolUnderPlace( const MbPlacement3D & ) const = 0; + /// \ru Находится ли обозначение внутри или на оболочке. \en Check if notation on shell or inside it. + virtual bool IsSymbolInShell ( const MbFaceShell & ) const = 0; + /// \ru Получить массив условных обозначений на базовых точках, принадлежащих данному обозначению. \en Get an array of notation conventions on the base points which belong to this notation. + virtual void GetPointsSymbols ( RPArray & ) const = 0; + /** \} */ + +private: + MbSymbol & operator = ( const MbSymbol & ); + DECLARE_PERSISTENT_CLASS( MbSymbol ) +}; + +IMPL_PERSISTENT_OPS( MbSymbol ) + +//------------------------------------------------------------------------------ +/** \brief \ru Условное обозначение на базовых точках. + \en Conventional notation on base points. \~ + \details \ru Условное обозначение на базовых точках. \n + \en Conventional notation on base points. \n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbPointsSymbol : public MbSymbol { + +protected: + SArray points; ///< \ru Базовые точки обозначения в мировой системе координат. \en Notation base points in world coordinate system. + +private: + SArray * steps; ///< \ru Данные об участках сложных разрезов. \en Data about the portions of complex sections. + +protected: + MbPointsSymbol( const MbPointsSymbol & ); ///< \ru Конструктор-копия. \en Copy-constructor. + MbPointsSymbol(); ///< \ru Умолчательный конструктор. \en Default constructor. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор условного обозначения на базовых точках. \n + \en Constructor of conventional notation on base points. \n \~ + \param[in] _points - \ru Набор точек. + \en Set of points. \~ + \param[in] _name - \ru Имя обозначения. + \en Notation name. \~ + \param[in] _component - \ru Компонент условного обозначения. + \en Component of conventional notation. \~ + \param[in] _stateCalc - \ru Тип расчета видимости. + \en Visibility calculation type. \~ + */ + MbPointsSymbol( const SArray & _points, MbName * _name, + uint _component, StateCalc _stateCalc = st_strong ); + /// \ru Деструктор. \en Destructor. + virtual ~MbPointsSymbol(); + +public: + + void Init( const MbPointsSymbol & ); ///< \ru Инициализация. \en Initialization. + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA () const; + virtual MbSpaceItem & Duplicate ( MbRegDuplicate * = NULL ) const; + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); + virtual void Transform ( const MbMatrix3D &, MbRegTransform * = NULL ); + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции условного обозначения. + \en \name Functions of conventional notation. + \{ */ + + // \ru Виртуальные функции, различающиеся у различных условных обозначений \en Virtual functions that differs in different notations + // \ru Включить свой габарит в габаритный куб cube. \en Include own bounding box into 'cube' bounding box. + virtual void IncludeGab ( MbCube & ) const; + // \ru Находится ли условное обозначение на плоскости OXY плейсмента place. \en Check if conventional notation on OXY plane of 'place' placement. + virtual bool IsSymbolOnPlace ( const MbPlacement3D & ) const; + // \ru Находится ли условное обозначение на или под плоскостью OXY плейсмента place. \en Check if conventional notation on OXY plane of 'place' placement or under it. + virtual bool IsSymbolUnderPlace( const MbPlacement3D & ) const; + // \ru Находится ли условное обозначение на или внутри оболочки faceShell. \en Check if conventional notation on 'faceShell' shell or inside it. + virtual bool IsSymbolInShell ( const MbFaceShell & ) const; + // \ru Получить массив условных обозначений на базовых точках, принадлежащих данному обозначению. \en Get an array of notation conventions on the base points which belong to this notation. + virtual void GetPointsSymbols ( RPArray & ) const; + + /** \} */ + /** \ru \name Cобственные функции обозначения на базовых точках. + \en \name Own functions of conventional notation on base points. + \{ */ + + // \ru Функции, относящиеся к базовым точкам обозначения points \en Functions related to 'points' notation base points + /// \ru Получить базовые точки обозначения. \en Get notation base points. + const SArray & GetPoints () const; + /// \ru Получить количество базовых точек обозначения. \en Get count of notation base points. + ptrdiff_t GetPointsCount() const; + /// \ru Получить базовую точку обозначения c индексом ind. \en Get notation base point by 'ind' index. + const MbCartPoint3D & GetPoint( size_t ind ) const; + /// \ru Установить базовую точку обозначения с указанным индексом. \en Set notation base point by given index. + void SetPoint( const MbCartPoint3D &, size_t ); + + /// \ru Принадлежит ли условное обозначение участку сложного разреза с указанным номером? \en Is symbol belong portion of complex section with the specified number? + bool StepFound( size_t mapper ) const; + /// \ru Запомнить номер участка сложного разреза, которому принадлежит условное обозначение. \en Remember portion of complex section, which owns the symbol. + void SetStepIndex( size_t mapper ); + /// \ru Очистить данные об участках сложных разрезов. \en Clear data about the portions of complex sections. + void ClearSteps(); + /** \} */ + +private: + // \ru Не реализованные методы класса. \en Not implemented class methods. + void operator = ( const MbPointsSymbol & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPointsSymbol ) +}; + +IMPL_PERSISTENT_OPS( MbPointsSymbol ) + +#endif // __MB_SYMBOL_H diff --git a/C3d/Include/mb_thread.h b/C3d/Include/mb_thread.h new file mode 100644 index 0000000..faf7b58 --- /dev/null +++ b/C3d/Include/mb_thread.h @@ -0,0 +1,887 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Определение резьбы. + \en Thread definition. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_THREAD_H +#define __MB_THREAD_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbSolid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тип отображения. + \en Mapping type. \~ + \details \ru Тип отображения резьбы. + \en A type of thread mapping. \~ + \ingroup Mapping +*/ +// --- +enum MbeThrMapType { + tmt_CompleteView = 0, ///< \ru Полный вид. Система координат в строителе отображения резьбы ThreadMapperStruct определяет плоскость вида. Отображаем все. \en Full view. Coordinate system in creator of thread mapping ThreadMapperStruct determines plane of view. Map all. + tmt_CuttedView, ///< \ru Вид-разрез. Система координат в строителе отображения резьбы ThreadMapperStruct определяет плоскость разреза. Отображаем только то, что за плоскостью. \en The cutaway-view. Coordinate system in creator of thread mapping ThreadMapperStruct determines plane of cutaway. Map only that behind plane. + tmt_SectionView, ///< \ru Сечение. Система координат в строителе отображения резьбы ThreadMapperStruct определяет плоскость сечения. Отображаем только то что на плоскости. \en Section. Coordinate system in creator of thread mapping ThreadMapperStruct determines section plane. Map only that on plane. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Состояние резьбы. + \en Thread state. \~ + \details \ru Состояние резьбы. + \en Thread state. \~ + \ingroup Mapping +*/ +// --- +enum MbeThrState { + ts_NotChanged = 0, ///< \ru Не изменилась. \en Not changed. + ts_Changed, ///< \ru Изменилась. \en Changed. + ts_Degenerated, ///< \ru Выродилась. \en Degenerated. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Метод подгонки резьбы. + \en Method of thread fitting (adapting). \~ + \details \ru Метод подгонки начала и конца резьбы. + \en Method of fitting start and end of thread. \~ + \ingroup Mapping +*/ +// --- +enum MbeThrAdapt { + ta_UsingNothing = 0, ///< \ru Не подгонять, только проверить. \en No fit, check only. + ta_UsingGabarit, ///< \ru По габариту тела. \en By solid bounding box. + ta_UsingSurfaces, ///< \ru По поверхностям тела под резьбой. \en By solid surfaces below thread. + ta_UsingSolid, ///< \ru По телу. \en By solid. + ta_TypesCount ///< \ru Количество типов адаптации. \en Count of thread fitting methods. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ошибки при проверке резьбового соединения. + \en Threaded joint check errors. \~ + \details \ru Ошибки при проверке резьбового соединения. + \en Threaded joint check errors. \~ + \ingroup Legend +*/ +// --- +enum MbeThreadedJointCheckErrors { + tjc_NoErrors = 0, ///< \ru Нет ошибок. \en No errors. + tjc_SameThread = 1, ///< \ru Ошибка - одна и та же резьба. \en Error - the same thread. + tjc_WrongThreadParameters = 2, ///< \ru Ошибка - некорректные параметры резьбы. \en Error - wrong thread parameters. + tjc_NormalsMismatch = 3, ///< \ru Ошибка - несоответствие по нормалям (обе внешние или обе внутренние). \en Error - normals mismatch (both threads are outer or inner). + tjc_RotationsMismatch = 5, ///< \ru Ошибка - несоответствие вращательных направлений нарезки (одна левая, другая правая). \en Error - the mismatch of rotational directions of the cut (one is left rotation, the other is right rotation). + tjc_AngularMismatch = 6, ///< \ru Ошибка - угловое несоответствие конических резьб. \en Error - angular mismatch of tapered threads. + tjc_AxesNotCollinear = 7, ///< \ru Ошибка - оси резьб не коллинеарны. \en Error - threads axes are not collinear. + tjc_DepthOverlapMismatch = 8, ///< \ru Ошибка - недостаточное перекрытие по глубине поперек оси. \en Error - insufficient depth overlap transverse to both axes. + tjc_LengthOverlapMismatch = 9, ///< \ru Ошибка - недостаточное перекрытие по длине вдоль оси. \en Error - insufficient length overlap along the axis. + tjc_PositionsCount = 10, ///< \ru Количество позиций списка. \en List's positions count. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры проверки резьбовых соединений. + \en Threaded joint check parameters. \~ + \details \ru Параметры проверки резьбовых соединений.\n + \en Threaded joint check parameters.\n \~ + \ingroup Legend +*/ +// --- +struct MATH_CLASS MbThreadedJointCheckParameters { +protected: + double metricAccuracy; ///< \ru Метрическая точность. \en Metric accuracy. + double angleAccuracy; ///< \ru Угловая точность. \en Angular accuracy. + double minLengthOverlap; ///< \ru Минимальная длина перекрытия резьб вдоль оси. \en Minimal thread overlap along axis. + double minDepthOverlap; ///< \ru Минимальная глубина перекрытия резьб. \en Minimal thread depth overlap. + + bool checkFullDepth; ///< \ru Требование полного перекрытия резьб по глубине (иначе - minDepthOverlap). \en Full thread depth overlap required (otherwise - minDepthOverlap). + bool checkRotCoherence; ///< \ru Проверить согласованность вращений резьб. \en Check threaded rotations matching. + bool collectErros; ///< \ru Собрать все ошибки сопряжения. \en Collect all threaded joint errors. + +public: + MbThreadedJointCheckParameters() + : metricAccuracy ( METRIC_PRECISION ) + , angleAccuracy ( ANGLE_REGION ) + , minLengthOverlap ( METRIC_PRECISION ) + , minDepthOverlap ( c3d::MIN_RADIUS ) + , checkFullDepth ( false ) + , checkRotCoherence( false ) + , collectErros ( false ) + {} + MbThreadedJointCheckParameters( const MbThreadedJointCheckParameters & par ) + : metricAccuracy ( par.metricAccuracy ) + , angleAccuracy ( par.angleAccuracy ) + , minLengthOverlap ( par.minLengthOverlap ) + , minDepthOverlap ( par.minDepthOverlap ) + , checkFullDepth ( par.checkFullDepth ) + , checkRotCoherence( par.checkRotCoherence ) + , collectErros ( par.collectErros ) + {} + MbThreadedJointCheckParameters & operator = ( const MbThreadedJointCheckParameters & par ) + { + metricAccuracy = par.metricAccuracy; + angleAccuracy = par.angleAccuracy; + minLengthOverlap = par.minLengthOverlap; + minDepthOverlap = par.minDepthOverlap; + checkFullDepth = par.checkFullDepth; + checkRotCoherence = par.checkRotCoherence; + collectErros = par.collectErros; + return *this; + } +public: + double GetMetricAccuracy() const { return metricAccuracy; } ///< \ru Угловая точность. \en Angular accuracy. + double GetAngleAccuracy() const { return angleAccuracy; } ///< \ru Метрическая точность. \en Metric accuracy. + double GetMinLengthOverlap() const { return minLengthOverlap; } ///< \ru Минимальная длина перекрытия резьб вдоль оси. \en Minimal thread overlap along axis. + double GetMinDepthOverlap() const { return minDepthOverlap; } ///< \ru Минимальная глубина перекрытия резьб. \en Minimal thread depth overlap. + bool CheckFullDepthOverlap() const { return checkFullDepth; } ///< \ru Проверять полное перекрытия резьб по глубине (иначе - только на глубину minDepthOverlap). \en Check full thread depth overlap (otherwise - minDepthOverlap only). + bool CheckRotationsMatching() const { return checkRotCoherence; } ///< \ru Проверить согласованность вращений резьб. \en Check threaded rotations matching. + bool CollectErrors() const { return collectErros; } ///< \ru Собрать все ошибки сопряжения. \en Collect all threaded joint errors. + + void SetFullDepthCheck ( bool s ) { checkFullDepth = s; } ///< \ru Установить требование проверки полного перекрытия резьб по глубине. \en Set full thread depth overlap check (otherwise - minDepthOverlap). + void SetRotationsMatchingCheck ( bool s ) { checkRotCoherence = s; } ///< \ru Установить состояние проверки согласованности вращений резьб. \en Set threaded rotation matching check. + void SetCollectErrors ( bool s ) { collectErros = s; } ///< \ru Установить состояние сбора всех ошибок сопряжения. \en Set gathering state of all errors of threaded joint. + + /// \ru Установить метрическую точность. \en Set metric accuracy. + bool SetMetricAccuracy( double mAcc ) + { + bool res = true; + mAcc = ::fabs( mAcc ); + metricAccuracy = mAcc; + if ( metricAccuracy < EXTENT_EQUAL ) { + metricAccuracy = EXTENT_EQUAL; + res = false; + } + else if ( metricAccuracy > METRIC_NEAR ) { + metricAccuracy = METRIC_NEAR; + res = false; + } + return res; + } + /// \ru Установить угловую точность. \en Set angular accuracy. + bool SetAngularAccuracy( double aAcc ) + { + bool res = true; + aAcc = ::fabs( aAcc ); + angleAccuracy = aAcc; + if ( angleAccuracy < EXTENT_EQUAL ) { + angleAccuracy = EXTENT_EQUAL; + res = false; + } + else if ( angleAccuracy > PARAM_NEAR ) { + angleAccuracy = PARAM_NEAR; + res = false; + } + return res; + } + /// \ru Установить минимальную глубина перекрытия резьб. \en Set minimal thread depth overlap. + void SetLengthOverlap( double v ) { minLengthOverlap = v; } + /// \ru Установить минимальную длина перекрытия резьб вдоль оси. \en Set minimal thread overlap along axis. + void SetDepthOverlap ( double v ) { minDepthOverlap = v; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Резьба. + \en Thread. \~ + \details \ru Резьба отверстий и валов.\n + \en Thread of holes and shafts.\n \~ + \ingroup Legend +*/ +// --- +class MATH_CLASS MbThread : public MbLegend { +public: + typedef std::pair ThreadLimiter; + typedef std::pair ThreadLimiters; + typedef std::vector ThreadedJointErrors; +protected: + MbPlacement3D place; ///< \ru Система координат резьбы (в мировой системе координат). \en A thread coordinate system (in the world coordinate system). + double radObj; ///< \ru Начальный радиус резьбы на поверхности. \en Initial thread radius on surface. + double radThr; ///< \ru Начальный радиус резьбы в теле. \en Initial thread radius in solid. + double length; ///< \ru Длина резьбы. \en Thread length. + double angle; ///< \ru Угол конусности поверхности резьбы. \en Conicity angle of thread surface. + +private: // \ru Временные данные для проецирования резьб \en Temporary data for projection of threads + MbName * name; // \ru Имя резьбы (именно указатель, т.к. имя из 3D потом идет ссылкой в аннотационные кривые). \en Thread name (just pointer, because name from 3D later goes as reference to annotation curves). + c3d::ConstLumpsSet bodies; // \ru Рабочий массив тел, на которых нарезана резьба, может быть пустой. \en Working array of threaded solids can be empty. + // \ru Наполнять с помощью функции AddBodies. \en Fill using AddBodies function. +private: // \ru Данные не влияющие на неизменность. \en Data not influencing on invariableness. + mutable MbFace * faceObj; + mutable MbFace * faceThr; + mutable MbCube cube; // \ru Габаритный куб резьбы. \en Bounding box of thread. + mutable MbeThrState state; // \ru Состояние резьбы. \en Thread state. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] place - \ru Система координат. + \en Coordinate system. \~ + \param[in] rObj - \ru Начальный радиус резьбы на поверхности. + \en Initial thread radius on surface. \~ + \param[in] rThr - \ru Начальный радиус резьбы в теле. + \en Initial thread radius in solid. \~ + \param[in] len - \ru Длина резьбы. + \en Thread length. \~ + \param[in] ang - \ru Угол конусности поверхности резьбы. + \en Conicity angle of thread surface. \~ + */ + MbThread( const MbPlacement3D & place, double rObj, double rThr, double len, double ang ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] place - \ru Система координат. + \en Coordinate system. \~ + \param[in] rObj - \ru Начальный радиус резьбы на поверхности. + \en Initial thread radius on surface. \~ + \param[in] rThr - \ru Начальный радиус резьбы в теле. + \en Initial thread radius in solid. \~ + \param[in] begPos - \ru Положение начала резьбы вдоль оси Z системы координат. + \en Thread start position along the Z axis of the coordinate system. \~ + \param[in] begPos - \ru Положение конца резьбы вдоль оси Z системы координат. + \en Thread end position along the Z axis of the coordinate system. \~ + \param[in] ang - \ru Угол конусности поверхности резьбы. + \en Conicity angle of thread surface. \~ + */ + MbThread( const MbPlacement3D & place, double rObj, double rThr, double begPos, double endPos, double ang ); + + /// \ru Деструктор. \en Destructor. + virtual ~MbThread(); + +private: + MbThread(); ///< \ru Конструктор. \en Constructor. + MbThread( const MbThread & ); ///< \ru Конструктор копирования. \en Copy-constructor. + const MbThread & operator = ( const MbThread & thr ) { Init( thr ); return *this; } + +public: + + /**\ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; + virtual MbeSpaceType Type() const; + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; + virtual bool IsSame ( const MbSpaceItem &, double accuracy = LENGTH_EPSILON ) const; + virtual bool IsSimilar ( const MbSpaceItem & ) const; + virtual bool SetEqual( const MbSpaceItem & ); + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); + virtual void Rotate ( const MbAxis3D &, double, MbRegTransform * = NULL ); + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; + virtual void AddYourGabaritTo( MbCube & ) const; + virtual void Refresh(); + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + // \ru Тестовые функции геометрического объекта \en Test functions of a geometric object + virtual MbProperty & CreateProperty( MbePrompt ) const; // \ru Создать собственное свойство \en Create own property + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + +public : + /** \} */ + /**\ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация.\n + \en Initialization.\n \~ + \param[in] place - \ru Система координат. + \en Coordinate system. \~ + \param[in] radObj - \ru Начальный радиус резьбы (на поверхности). + \en Initial thread radius (on surface). \~ + \param[in] radThr - \ru Конечный радиус резьбы. + \en Final thread radius. \~ + \param[in] len - \ru Длина резьбы. + \en Thread length. \~ + \param[in] ang - \ru Угол. + \en Angle. \~ + */ + bool SetThreadParams( const MbPlacement3D & place, double radObj, double radThr, double len, double ang ); + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация.\n + \en Initialization.\n \~ + \param[in] place - \ru Система координат. + \en Coordinate system. \~ + \param[in] diamObj - \ru Начальный диаметр. + \en Initial diameter. \~ + \param[in] depth - \ru Глубина нарезки + \en Depth of threading \~ + \param[in] bOutThr - \ru Признак внешней резьбы.\n + если true - резьба внешняя,\n + если false - резьба внутренняя. + \en External thread attribute.\n + if true then thread is external,\n + If false then thread is internal. \~ + \param[in] len - \ru Длина резьбы. + \en Thread length. \~ + \param[in] ang - \ru Угол. + \en Angle. \~ + */ + bool SetThreadParams( const MbPlacement3D & place, double diamObj, double depth, bool bOutThr, double len, double ang ); + + /** \} */ + /**\ru \name Функции работы с именами. + \en \name Functions for working with names. + \{ */ + + /** \brief \ru Установить имя. + \en Set name. \~ + \details \ru Установить имя резьбы.\n + \en Set thread name.\n \~ + \param[in] n - \ru Новое имя. + \en New name. \~ + */ + void SetName( const MbName & n ) { name = const_cast(&n); } + + /** \brief \ru Получить имя. + \en Get name. \~ + \details \ru Получить имя резьбы.\n + \en Get thread name.\n \~ + \return \ru Указатель на имя. + \en Pointer to name. \~ + */ + MbName * GetName() const { return name; } + + /** \brief \ru Есть ли имя. + \en Is there a name. \~ + \details \ru Есть ли имя у резьбы.\n + \en Is there a name of a thread.\n \~ + \return \ru true, если имя есть и оно не пустое. + \en True if there is name and it is not empty. \~ + */ + bool IsName() const { return ((name != NULL) ? name->IsEmpty() : false); } + + /** \} */ + /**\ru \name Функции работы с телами, на которых нарезана резьба. + \en \name Functions for operating with threaded solids. + \{ */ + + /** \brief \ru Добавить тела. + \en Add solids. \~ + \details \ru Добавить тела, на которых нарезана резьба.\n + Не добавляются нулевые указатели из присланного массива, + не добавляются повторяющиеся объекты. + \en Add threaded solids.\n + Null pointers from specified array are not added, + duplicate objects also not added. \~ + \param[in] lumps - \ru Набор тел. + \en Set of solids. \~ + */ + template + void AddBodies( const ConstLumps & initBodies ) + { + for ( size_t k = 0, cnt = initBodies.size(); k < cnt; ++k ) { + bodies.insert( initBodies[k] ); + } + } + + /** \brief \ru Найти тело. + \en Find solid. \~ + \details \ru Найти тело в массиве.\n + \en Find solid in array.\n \~ + \return \ru Индекс тела.\n + SYS_MAX_T, если тело не найдено. + \en Solid index.\n + SYS_MAX_T, if solid isn't found. \~ + */ + bool IsBody( const MbLump * ) const; + + size_t GetBodiesCount() const { return bodies.size(); } ///< \ru Количество тел. \en Count of solids. + + /** \brief \ru Получить тела. + \en Get solids. \~ + \details \ru Получить массив тел.\n + \en Get array of solids.\n \~ + \param[out] lumps - \ru Результат - набор тел. + \en Set of solids as result. \~ + */ + template + void GetBodies( ConstLumps & lumps ) const { lumps.reserve( lumps.size() + bodies.size() ); std::copy( bodies.begin(), bodies.end(), std::back_inserter(lumps) ); } + + /** \brief \ru Отцепить тела, не принадлежащие этой резьбе. + \en Detach solids unsuitable for this thread. \~ + \details \ru Отцепить тела, не принадлежащие этой резьбе.\n + \en Detach solids unsuitable for this thread.\n \~ + */ + void DetachWrongBodies(); + + /// \ru Отцепить тела, на которых нарезана резьба. \en Detach threaded solids. + void DetachBodies(); + + /** \} */ + /**\ru \name Функции доступа к данным. Информация о резьбе. + \en \name Functions for access to data. Information about thread. + \{ */ + + /** \brief \ru Корректны ли параметры. + \en Check if parameters are correct. \~ + \details \ru Корректны ли параметры резьбы:\n + - резьба не должна быть вырожденной,\n + - система координат резьбы должна быть ортонормированной,\n + - значения радиусов и длины должны быть + не меньше минимального радиуса объекта MIN_RADIUS, + не больше максимального радиуса объекта MAX_RADIUS,\n + - радиусы должны быть различны,\n + - угол не должен превосходить полный оборот,\n + - резьба не должна иметь самопересечения. + \en Check if thread parameters are correct:\n + - thread should not be degenerate,\n + - thread coordinate system should be orthonormalized,\n + - values of radius and length should be + not less than minimal radius of object MIN_RADIUS, + not greater than maximal radius of object MAX_RADIUS,\n + - radii should be different,\n + - angle should not be greater than full turn,\n + - thread should not have self-intersections. \~ + \return + */ + bool IsValid() const; + + /** \brief \ru Является ли резьба конической. + \en Check if thread is conic. \~ + \details \ru Является ли резьба конической.\n + \en Check if thread is conic.\n \~ + \return \ru true, если значение угла не нулевое. + \en True if value of angle is non-zero. \~ + */ + bool IsConical() const; + + /** \brief \ru Является ли резьба внешней. + \en Check if thread is external. \~ + \details \ru Является ли резьба внешней.\n + Резьба внешняя, если начальный радиус резьбы больше конечного. + \en Check if thread is external.\n + Thread is external if initial radius of thread is greater than final one. \~ + \return \ru Признак внешней резьбы. + \en External thread attribute. \~ + */ + bool IsOutside() const; + + /** \brief \ru Является ли резьба левой. + \en Check if thread is left. \~ + \details \ru Является ли резьба левой.\n + \en Check if thread is left.\n \~ + \return \ru true, если система координат резьбы левая. + \en True if thread coordinate system is left. \~ + */ + bool IsLeft() const { return place.IsLeft(); } + + /// \ru Получить СК резьбы в мировой СК. \en Get thread coordinate system in world coordinate system. + const MbPlacement3D & GetPlacement() const { return place; } + + /// \ru Получить начальный радиус резьбы на поверхности. \en Get initial thread radius on surface. + double GetObjBegRadius() const { return radObj; } + /// \ru Получить конечный радиус резьбы на поверхности. \en Get final thread radius on surface. + double GetObjEndRadius() const; + /// \ru Получить начальный радиус резьбы в теле. \en Get initial thread radius in solid. + double GetThrBegRadius() const { return radThr; } + /// \ru Получить конечный радиус резьбы в теле. \en Get final thread radius in solid. + double GetThrEndRadius() const; + + /// \ru Получить длину резьбы. \en Get thread length. + double GetLength() const { return length; } + /// \ru Получить угол конусности поверхности резьбы. \en Get conicity angle of thread surface. + double GetAngle() const { return angle; } + /// \ru Узнать состояние резьбы. \en Get thread state. + MbeThrState GetState() const { return state; } + + /// \ru Глубина нарезки. \en Depth of threading. + double GetDepth() const { return ::fabs(radThr - radObj); } + /// \ru Получить начальную точку резьбы на оси. \en Get start point of thread on axis. + void GetBegAxisPoint( MbCartPoint3D & ) const; + /// \ru Получить конечную точку резьбы на оси. \en Get start point of thread on axis. + void GetEndAxisPoint( MbCartPoint3D & ) const; + + /** \brief \ru Сопрягаются ли резьбы. + \en Check if threads are mating. \~ + \details \ru Сопрягаются ли резьбы (внутренняя с внешней.\n + 1) Резьбы должны иметь одинаковый угол.\n + 2) Одна резьба должна быть внутренней, другая внешней.\n + 3) У обоих объектов должны быть корректные параметры.\n + 4) Оси резьб должны быть параллельны.\n + \en Check if threads are mated (internal with external).\n + 1) Threads must have same angle.\n + 2) One of threads must be internal, other - external.\n + 3) Each object must have correct parameters.\n + 4) Axes of threads must be parallel.\n \~ + \param[in] otherThread - \ru Вторая резьба. + \en Second thread. \~ + \return \ru true, если резьбы сопрягаемые. + \en True if threads are mating. \~ + */ + bool IsMatedTo( const MbThread & otherThread ) const; + + /** \brief \ru Сопрягаются ли резьбы. + \en Check if threads are mating. \~ + \details \ru Сопрягаются ли резьбы (внутренняя с внешней.\n + 1) Резьбы должны иметь одинаковый угол.\n + 2) Одна резьба должна быть внутренней, другая внешней.\n + 3) У обоих объектов должны быть корректные параметры.\n + 4) Оси резьб должны быть параллельны.\n + \en Check if threads are mated (internal with external).\n + 1) Threads must have same angle.\n + 2) One of threads must be internal, other - external.\n + 3) Each object must have correct parameters.\n + 4) Axes of threads must be parallel.\n \~ + \param[in] otherThread - \ru Вторая резьба. + \en Second thread. \~ + \param[in] checkParams - \ru Параметры проверки резьбовых соединений. + \en Threaded joint check parameters. \~ + \return \ru true, если резьбы сопрягаемые. + \en True if threads are mating. \~ + */ + bool IsMatedTo( const MbThread & otherThread, + const MbThreadedJointCheckParameters & checkParams, + ThreadedJointErrors * thrJointErrors = NULL ) const; + + /// \ru Принадлежит ли резьба грани. \en Check if thread belongs to face. + bool IsFaceThread( const MbFace *, const MbMatrix3D & ) const; + + /** \brief \ru Принадлежит ли резьба телу. + \en Check if thread belongs to solid. \~ + \details \ru Принадлежит ли резьба телу.\n + \en Check if thread belongs to solid.\n \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in] matrix - \ru Матрица преобразования в мировую систему координат. + \en A matrix of transformation to the world coordinate system. \~ + \param[out] simObjNumbers - \ru Индексы граней, которым может принадлежать резьба. + \en Indices of faces thread belongs to. \~ + \param[out] intObjNumbers - \ru Индексы граней, c которым может пересекаться резьба. + \en Indices of faces intersecting with thread. \~ + \return \ru true, если резьба принадлежит одной из граней тела. + \en True if thread belongs to one of solid faces. \~ + */ + bool IsBodyThread( const MbSolid & solid, const MbMatrix3D & matrix, + c3d::IndicesVector * simObjNumbers = NULL, + c3d::IndicesVector * intObjNumbers = NULL ) const; + + /** \brief \ru Принадлежит ли резьба телу. + \en Check if thread belongs to solid. \~ + \details \ru Принадлежит ли резьба телу.\n + \en Check if thread belongs to solid.\n \~ + \param[in] solid - \ru Тело с матрицей преобразования в мировую систему координат. + \en A solid with a matrix of transformation to the world coordinate system. \~ + \return \ru true, если резьба принадлежит одной из граней тела. + \en True if thread belongs to one of solid faces. \~ + */ + bool IsBodyThread( const MbLump & lump ) const { return IsBodyThread( lump.GetSolid(), lump.GetMatrixFrom() ); } + + /** \brief \ru Адаптировать начало и конец резьбы к телу. + \en Fit start and end of thread to solid. \~ + \details \ru Адаптировать начало и конец резьбы к телу, если резьба может принадлежать телу.\n + \en Fit start and end of thread to solid if thread can belong to solid.\n \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in] matrix - \ru Матрица преобразования в мировую систему координат. + \en A matrix of transformation to the world coordinate system. \~ + \param[in] thrAdapt - \ru Метод подгонки резьбы. + \en Method of thread fitting. \~ + \param[in] limiters - \ru Начальный и конечный ограничители резьбы. + \en Beginning and ending thread limiters. \~ + \return \ru true в случае успеха операции. + \en True if the operation is successful. \~ + */ + bool AdaptToBody( const MbSolid & solid, const MbMatrix3D & matrix, MbeThrAdapt thrAdapt, const ThreadLimiters * limiters = NULL ); + + /** \brief \ru Выдать начало и конец изменённой резьбы относительно исходной. + \en Get limit positions of the modified thread in regard to an initial thread. \~ + \details \ru Выдать начало и конец изменённой резьбы относительно исходной вдоль оси Z системы координат исходной резьбы.\n + \en Get limit positions of the modified thread in regard to an initial thread. + Positions are defined along the Z axis of the initial coordinate system. \n \~ + \param[in] thread - \ru Исходная резьба. + \en Initial thread. \~ + \param[out] begPos - \ru Положение начала резьбы. + \en Thread start position. \~ + \param[out] endPos - \ru Положение конца резьбы. + \en Thread end position. \~ + \return \ru true Если резьбы подобны. + \en True if these threads are similar to each other. \~ + */ + bool GetLimitPositions( const MbThread & thread, double & begPos, double & endPos ) const; + + /** \brief \ru Найти тела, которым может принадлежать резьба. + \en Find solids thread belongs to. \~ + \details \ru Найти тела, которым может принадлежать резьба.\n + \en Find solids thread belongs to.\n \~ + \param[in] solids - \ru Набор тел. + \en Set of solids. \~ + \param[in] matrices - \ru Набор матриц преобразования тел в мировую систему координат. + Количество должно соответствовать количеству тел. + \en Set of matrices of solid transformation to the world coordinate system. + Count must be equal to count of solids. \~ + \param[out] solidsNumbers - \ru Номера тел, которым может принадлежать резьба. + \en Indices of solids thread belongs to. \~ + \return \ru true, если резьба принадлежит хотя бы одному телу. + \en True if thread belongs at least to one of solids. \~ + */ + template + bool FindThreadBodies( const SolidsVector & solids, const MatricesVector & matrices, + IndicesVector & solidsNumbers ) const; + +public: + /// \ru Рассчитать габаритный куб резьбы. \en Calculate bounding box of thread. + const MbCube & CalculateGabarit() const; + + /** \brief \ru Рассчитать габаритный куб резьбы. + \en Calculate bounding box of thread. \~ + \details \ru Рассчитать габаритный куб резьбы в локальной системе координат.\n + \en Calculate bounding box of thread in local coordinate system.\n \~ + \param[in] mIntoLocal - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[out] cubeLocal - \ru Результат - посчитанный габарит. + \en Calculated bounding box as result. \~ + */ + void CalculateLocalGabarit( const MbMatrix3D & mIntoLocal, MbCube & cubeLocal ) const; + + void Init( const MbThread & ); // \ru Инициализировать копию \en Initialize copy (may be public if required) + /** \} */ + + const MbFace * _GetObjectFace() const { return faceObj; } + const MbFace * _GetThreadFace() const { return faceThr; } + +private: // \ru Закрытые собственные функции резьбы \en Own private functions of thread + MbeThrState SetState( MbeThrState ) const; // \ru Установить состояние резьбы. \en Set thread state. + MbeThrState CheckState(); // \ru Проверить и скорректировать состояние резьбы. \en Check and correct thread state. + bool SetDepth ( double ); // \ru Изменить глубину резьбы. \en Change thread depth. + bool SetLength( double ); // \ru Изменить длину резьбы. \en Change thread length. + bool SetLimits( double zMin, double zMax ); // \ru Изменить резьбу по новым положениям начала и конца. \en Change begin and end of the thread. + + void CreateThreadFaces() const; // \ru Создать резьбовые грани в СК мира. \en Create threaded faces in world coordinate system. + void UpdateThreadFaces() const; // \ru Обновить резьбовые грани. \en Update threaded faces. + void MoveThreadFaces( const MbVector3D & ) const; // \ru Сдвинуть резьбовые грани. \en Move threaded faces. + void DeleteThreadFaces() const; // \ru Удалить резьбовые грани. \en Delete threaded faces. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbThread ) +}; + +IMPL_PERSISTENT_OPS( MbThread ) + + +//------------------------------------------------------------------------------ +// \ru Начальная точка резьбы на оси \en Start point of thread on axis +// --- +inline void MbThread::GetBegAxisPoint( MbCartPoint3D & p ) const { + p.Init( place.GetOrigin() ); +} + +//------------------------------------------------------------------------------ +// \ru Конечная точка резьбы на оси \en End point of thread on axis +// --- +inline void MbThread::GetEndAxisPoint( MbCartPoint3D & p ) const { + p.Set( place.GetOrigin(), place.GetAxisZ(), length ); +} + + +//------------------------------------------------------------------------------ +// \ru Получить конечный радиус поверхности резьбы \en Get final radius of thread surface +// --- +inline double MbThread::GetObjEndRadius() const { + return (radObj + length * ::tan( angle )); +} + +//------------------------------------------------------------------------------ +// \ru Получить конечный радиус резьбы \en Get final radius of thread +// --- +inline double MbThread::GetThrEndRadius() const { + return (radThr + length * ::tan( angle )); +} + + +//------------------------------------------------------------------------------ +// \ru Найти тела, которым может принадлежать резьба. \en Find solids thread belongs to. +// --- +template +bool MbThread::FindThreadBodies( const SolidsVector & solids, const MatricesVector & matrices, IndicesVector & indices ) const +{ + const size_t solidsCnt = solids.size(); + + if ( solidsCnt > 0 && solidsCnt == matrices.size() ) { + const size_t indicesCnt0 = indices.size(); + + if ( cube.IsEmpty() ) + CalculateGabarit(); + + indices.reserve( indices.size() + 2 ); + + MbCube solidCube; + for ( size_t i = 0; i < solidsCnt; ++i ) { + const MbSolid * solid = solids[i]; + if ( solid != NULL && solid->GetShell() != NULL ) { + solidCube.SetEmpty(); + solid->AddYourGabaritTo( solidCube ); + if ( cube.Intersect( solidCube ) && IsBodyThread( *solid, matrices[i] ) ) + indices.push_back( i ); + } + } + return (indices.size() > indicesCnt0); + } + + return false; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить некорректные резьбы. + \en Delete incorrect threads. \~ + \details \ru Удалить вырожденные и некорректно расположенные относительно плоскости вида резьбы.\n + Из набора резьб удаляются:\n + 1) нулевые указатели,\n + 2) резьбы с некорректными параметрами,\n + 3) резьбы без имен,\n + 4) повторяющиеся резьбы (в случае повторов появляется предупреждение - таких ситуаций быть не должно),\n + 5) некорректно расположенные относительно плоскости вида: + ось резьбы должна быть параллельна или перпендикулярна оси Z плоскости. + \en Delete degenerate threads and ones incorrectly located relative to plane of view.\ + From set of threads will be deleted:\n + 1) null-pointers,\n + 2) threads with incorrect parameters,\n + 3) threads without names,\n + 4) duplicate threads (warning raised in case of duplication - shouldn't be such situations),\n + 5) incorrectly located relative to plane of view: + thread axis must be parallel or perpendicular to Z-axis of plane. \~ + \param[in,out] threads - \ru Набор резьб. + \en Set of threads. \~ + \param[in] placeSec - \ru Плоскость вида. + \en Plane of view. \~ + \param[in] checkThreadNames - \ru Проверять наличие имени у резьбы. + \en Whether a name of thread exists. \~ + \ingroup Mapping +*/ +// --- +template +bool CheckThreads( ThreadsVector & threads, const MbPlacement3D * placeSec, bool checkThreadNames, double angleEps = Math::angleRegion ) +{ + size_t cntThreads = threads.size(); + + if ( cntThreads > 0 ) { + for ( size_t i = threads.size(); i--; ) { + MbThread * thr = threads[i]; + + if ( (thr == NULL) || !thr->IsValid() ) + threads.erase( threads.begin() + i ); + else if ( checkThreadNames && (thr->GetName() == NULL) ) // C3D-695 : KOMPAS-25125 + threads.erase( threads.begin() + i ); + else { + if ( threads.size() > 1 ) { + for ( ptrdiff_t j = i - 1; j >= 0; j-- ) { + if ( thr == threads[j] ) { + threads[i] = NULL; + threads.erase( threads.begin() + i ); + C3D_ASSERT_UNCONDITIONAL( false ); // Error case! + break; + } + } + } + } + thr->DetachWrongBodies(); + } + + if ( !threads.empty() && (placeSec != NULL) ) { + const MbVector3D & axisZsec = placeSec->GetAxisZ(); + for ( size_t i = threads.size(); i--; ) { + const MbThread * thr = threads[i]; + const MbVector3D & axisZthr = thr->GetPlacement().GetAxisZ(); + bool isColinear = axisZthr.Colinear( axisZsec, angleEps ); + bool isOrthogonal = axisZthr.Orthogonal( axisZsec, angleEps ); + if ( !isColinear && !isOrthogonal ) + threads.erase( threads.begin() + i ); + } + } + } + + return (threads.size() > 0); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить центральную точку. + \en Get a central point. \~ + \details \ru Получить центральную точку замкнутого ребра или замкнутой цепочки ребер. + \en Get a central point of closed edge or closed chain of edges. \~ + \param[in] edge - \ru Ребро. + \en Edge. \~ + \param[out] pnt - \ru Результат - центральная точка. + \en Central point as result. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (bool) GetThreadEdgeCentre( const MbCurveEdge & edge, MbCartPoint3D & pnt ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти граничные точки резьбы. + \en Find the boundary point of the thread.\~ + \details \ru Найти граничные точки резьбы по локальному габариту ребер, + соединяющих грань резьбы и смежную с ней грань. + Точка на оси резьбы упорядочена вдоль направления оси резьбы. + \en Find the boundary point of the thread on the edges size. + The point on the thread axis streamlined along the direction of the thread axis.\~ + \param[in] threadFace - \ru Грань резьбы. + \en The face of thread. \~ + \param[in] threadAxis - \ru Ось резьбы. + \en The axis of thread. \~ + \param[in] face - \ru Грань, смежная с гранью резьбы. + \en Face adjacent to the edge of the thread. \~ + \param[out] threadDir - \ru Направление резьбы. + \en The direction of the thread. \~ + \param[out] facePnt1 - \ru Начальная точка на смежной грани. + \en Starting point on the adjacent face. \~ + \param[out] facePnt2 - \ru Конечная точка на смежной грани. + \en The final point on the adjacent face. \~ + \param[out] axisPnt1 - \ru Начальная точка на оси резьбы. + \en Starting point for the thread axis. \~ + \param[out] axisPnt2 - \ru Конечная точка на оси резьбы. + \en Endpoint to the thread axis. \~ + \param[in] dr - \ru Глубина резьбы. + \en Thread depth. \~ + \param[in] findCommonEdges - \ru Искать общие ребра. + \en Find common edges. \~ + \result \ru Возвращает true, если получилось определить. + \en Returns true, if successful. \~ + \ingroup Mapping +*/ +// --- +MATH_FUNC (bool) CalculateThreadLimits( const MbFace & threadFace, + const MbAxis3D & threadAxis, + const MbFace & face, + MbVector3D & threadDir, + MbCartPoint3D & facePnt1, + MbCartPoint3D & facePnt2, + MbCartPoint3D & axisPnt1, + MbCartPoint3D & axisPnt2, + double dr = 0.0, + bool findCommonEdges = true ); + + +#endif // __MB_THREAD_H diff --git a/C3d/Include/mb_variables.h b/C3d/Include/mb_variables.h new file mode 100644 index 0000000..e6396ec --- /dev/null +++ b/C3d/Include/mb_variables.h @@ -0,0 +1,484 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Константы и переменные. + \en Constants and variables. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_VARIABLES_H +#define __MB_VARIABLES_H + +#include +#include +#include +#include + + +/** \ru \name Общие константы + \en \name Common constants + \{ */ +#define MB_MAXDOUBLE (1.0E+300) ///< \ru Максимальное значение double 1.7976931348623158E+308. \en Maximum value of double 1.7976931348623158E+308. +#define MB_MINDOUBLE (1.0E-300) ///< \ru Минимальное значение double 2.2250738585072014E-308. \en Minimum value of double 2.2250738585072014E-308. + +// \ru Математические константы, округленные до 21 значащей цифры, определены в math.h \en Mathematical constants rounded to 21 significant digits, defined in math.h +#if !defined( _MATH_DEFINES_DEFINED ) +#ifdef C3D_WINDOWS// _MSC_VER // \ru Константы определены в math.h [Linux] \en Constants defined in math.h [Linux] +#define M_E 2.71828182845904523536 ///< \ru Экспонента. \en Exponent. +#define M_LOG2E 1.44269504088896340736 ///< \ru Логарифм M_E по основанию 2. \en Logarithm M_E to base 2. +#define M_LOG10E 0.434294481903251827651 ///< \ru Логарифм M_E по основанию 10. \en Logarithm M_E to base 10. +#define M_LN2 0.693147180559945309417 ///< \ru Натуральный логарифм 2. \en Natural logarithm 2. +#define M_PI_4 0.785398163397448309616 ///< M_PI / 4.0 +#define M_1_PI 0.318309886183790671538 ///< 1.0 / M_PI +#define M_2_PI 0.636619772367581343076 ///< 2.0 / M_PI +#define M_SQRT1_2 0.707106781186547524401 ///< \ru Корень из одной второй, sqrt(1/2). \en Root of one half, sqrt(1/2). +#else // C3D_WINDOWS + #ifndef M_E + #define M_E 2.71828182845904523536 ///< \ru Экспонента. \en Exponent. + #endif // M_E + #ifndef M_LOG2E + #define M_LOG2E 1.44269504088896340736 ///< \ru Логарифм M_E по основанию 2. \en Logarithm M_E to base 2. + #endif // M_LOG2E + #ifndef M_LOG10E + #define M_LOG10E 0.434294481903251827651 ///< \ru Логарифм M_E по основанию 10. \en Logarithm M_E to base 10. + #endif // M_LOG10E + #ifndef M_LN2 + #define M_LN2 0.693147180559945309417 ///< \ru Натуральный логарифм 2. \en Natural logarithm 2. + #endif // M_LN2 + #ifndef M_PI_4 + #define M_PI_4 0.785398163397448309616 ///< M_PI / 4.0 + #endif // M_PI_4 + #ifndef M_1_PI + #define M_1_PI 0.318309886183790671538 ///< 1.0 / M_PI + #endif // M_1_PI + #ifndef M_2_PI + #define M_2_PI 0.636619772367581343076 ///< 2.0 / M_PI + #endif // M_2_PI + #ifndef M_SQRT1_2 + #define M_SQRT1_2 0.707106781186547524401 ///< \ru Корень из одной второй, sqrt(1/2). \en Root of one half, sqrt(1/2). + #endif // M_SQRT1_2 +#endif // C3D_WINDOWS +#ifndef M_LN10 + #define M_LN10 2.30258509299404568402 ///< \ru Натуральный логарифм 10, ln(10). \en Natural logarithm 10, ln(10). +#endif +#ifndef M_PI + #define M_PI 3.14159265358979323846 ///< \ru Отношение длины окружности к её диаметру, pi. \en Relation between circle length and its diameter, pi. +#endif +#ifndef M_PI_2 + #define M_PI_2 1.57079632679489661923 ///< M_PI / 2.0 +#endif +#ifndef M_2_SQRTPI + #define M_2_SQRTPI 1.12837916709551257390 ///< \ru Два разделить на корень из числа пи, 2/sqrt(pi). \en Two divided by root of pi, 2/sqrt(pi). +#endif +#ifndef M_SQRT2 + #define M_SQRT2 1.41421356237309504880 ///< \ru Корень из двух, sqrt(2). \en Root of two, sqrt(2). +#endif +#endif // _MATH_DEFINES_DEFINED +#define M_1_SQRTPI 0.564189583547756286948 ///< \ru Единица, деленная на корень из числа пи, 1/sqrt(pi). \en One divided by root of pi, 1/sqrt(pi). +#define M_PI2 (M_PI*2.0) ///< \ru Отношение длины окружности к её радиусу, 2.0 * M_PI, 6.28318530717958647692 \en Relation between circle length and its radius, 2.0 * M_PI, 6.28318530717958647692 +#define M_DEGRAD (M_PI/180.0) ///< \ru Коэффициент перевода градусов в радианы. \en Factor of conversion from degrees to radians. +#define M_RADDEG (180.0/M_PI) ///< \ru Коэффициент перевода радиан в градусы. \en Factor of conversion from radians to degrees. +#define M_FI 1.61803398874989484 ///< \ru Число золотого сечения, 1/M_FI = 0.6180339887499. \en Golden ratio, 1/M_FI = 0.6180339887499. +#define MM_INCH 25.4 ///< \ru Количество миллиметров в дюйме. \en Millimeters per inch. + + +#define EPSILON 1E-10 ///< \ru Погрешность. \en Tolerance. +#define MAXIMON 1E+10 ///< \ru 10 в 10-й степени. \en 10 to the power of 10. +#define MAX_OVERALL_DIM 1E+12 ///< \ru Максимальное значение габарита. \en Maximal value of bounding box. + +#define DETERMINANT_MAX 1E+137 ///< \ru Максимальная величина. \en Maximal value. +#define DETERMINANT_MIN 1E-171 ///< \ru Минимальная величина. \en Minimal value. + +#define UNDEFINED_DBL -MB_MAXDOUBLE ///< \ru Неопределенный double. \en Undefined double. +#define UNDEFINED_INT_T SYS_MIN_ST ///< \ru Неопределенный int. \en Undefined int. + +#define DEVIATION_SAG M_PI * 0.04 ///< \ru Угловая толерантность. \en Angular tolerance. + +#define NULL_EPSILON 1E-30 ///< \ru Погрешность для проверки на равенство нулю. \en Tolerance for equality to zero. +#define NULL_REGION 1E-20 ///< \ru Погрешность для проверки на равенство нулю. \en Tolerance for equality to zero. + +#define DOUBLE_EPSILON 1E-16 ///< \ru Погрешность. \en Tolerance. +#define DOUBLE_REGION 1E-15 ///< \ru Погрешность. \en Tolerance. +#define EXTENT_EQUAL 1E-14 ///< \ru Погрешность. \en Tolerance. +#define EXTENT_EPSILON 1E-12 ///< \ru Погрешность. \en Tolerance. +#define EXTENT_REGION 1E-11 ///< \ru Погрешность. \en Tolerance. +#define LENGTH_EPSILON 1E-10 ///< \ru Погрешность длины. \en Tolerance for length. +#define LENGTH_REGION 1E-9 ///< \ru Погрешность региона. \en Tolerance for region. + +#define METRIC_EPSILON 1E-8 ///< \ru Погрешность расстояния в итерационных функциях. \en Tolerance for distance in iterative functions. +#define METRIC_REGION 1E-7 ///< \ru Неразличимая метрическая область. \en Indistinguishable metric region. +#define METRIC_PRECISION 1E-6 ///< \ru Метрическая погрешность. \en Metric tolerance. +#define METRIC_ACCURACY 1E-5 ///< \ru Наибольшая метрическая погрешность (абсолютная точность в мм ("размер" атома 5e-8 мм)). \en The largest metric tolerance (absolute tolerance expressed in mm ("size" of atom is 5e-8 mm)). +#define METRIC_NEAR 1E-4 ///< \ru Метрическая близость. \en Metric proximity tolerance. + +#define PARAM_EPSILON 1E-8 ///< \ru Погрешность параметра в итерационных функциях. \en Tolerance for parameter in iterative functions. +#define PARAM_REGION 1E-7 ///< \ru Неразличимая параметрическая область. \en Indistinguishable parametric region. +#define PARAM_PRECISION 1E-6 ///< \ru Параметрическая погрешность. \en Parametric tolerance. +#define PARAM_ACCURACY 1E-5 ///< \ru Наибольшая параметрическая погрешность. \en The largest parametric tolerance. +#define PARAM_NEAR 1E-4 ///< \ru Параметрическая близость. \en Parametric proximity. + +#define ANGLE_EPSILON PARAM_EPSILON*M_PI ///< \ru Погрешность угла. \en Angular tolerance. +#define ANGLE_REGION ANGLE_EPSILON*40 ///< \ru Погрешность угла, при которой углы считаются равными. \en Angular tolerance for equality of angles. + +#define FAIR_MAX_DEGREE 11 ///< \ru Максимальный порядок NURBS при аппроксимации. \en Maxinum degree of the NURBS approximation. + + +namespace c3d // namespace C3D +{ + +const double METRIC_DELTA = 0.05; ///< \ru Величина отшагивания. \en Metric offset. +const double PARAM_DELTA_MIN = 0.005; ///< \ru Минимальная доля приращения параметра. \en Minimal portion of parameter increment. +const double PARAM_DELTA_MAX = 1.0; ///< \ru Максимальная доля приращения параметра. \en Maximal portion of parameter increment. + +const double MIN_LENGTH = 1.0E-4; ///< \ru Минимальная длина объекта. \en Minimal object length. +const double MAX_LENGTH = 5.0E+7; ///< \ru Максимальная длина объекта. \en Maximal object length. +const double MIN_RADIUS = 1.0E-4; ///< \ru Минимальный радиус объекта. \en Minimal object radius. +const double MAX_RADIUS = 2.5E+7; ///< \ru Максимальный радиус объекта. \en Maximal object radius. + +const double DELTA_MIN = 1E-3; ///< \ru Коэффициент уменьшения. \en Reduction factor. +const double DELTA_MID = 1E-2; ///< \ru Коэффициент уменьшения. \en Reduction factor. +const double DELTA_MOD = 1E-1; ///< \ru Коэффициент уменьшения. \en Reduction factor. +const double DELTA_MAX = 1E+3; ///< \ru Коэффициент увеличения. \en Magnification factor. +const double POWER_1 = 1E+1; ///< \ru Коэффициент увеличения. \en Magnification factor. +const double POWER_2 = 1E+2; ///< \ru Коэффициент увеличения. \en Magnification factor. +const double POWER_3 = 1E+3; ///< \ru Коэффициент увеличения. \en Magnification factor. +const double POWER_4 = 1E+4; ///< \ru Коэффициент увеличения. \en Magnification factor. +const double POWER_5 = 1E+5; ///< \ru Коэффициент увеличения. \en Magnification factor. + +const double ONE_THIRD = 0.33333333333333333333; ///< 1/3. +const double TWO_THIRD = 0.66666666666666666666; ///< 2/3. +const double ONE_SIXTH = 0.166666666666666666667; ///< 1/6. +const double ONE_FIFTH = 0.2; ///< 1/5. +const double TWO_FIFTH = 0.4; ///< 2/5. +const double ONE_QUARTER = 0.25; ///< 1/4. +const double ONE_EIGHTH = 0.125; ///< 1/8. +const double ONE_HALF = 0.5; ///< 1/2. + +// \ru Способы построения поверхности сопряжения (скругления или фаски). \en Ways for construction of smooth surface (fillet or chamfer). +const double _CONIC_MIN_ = 0.05; ///< \ru Минимальный коэффициент полноты сечения поверхности сопряжения (при 0.5 - парабола, меньше - эллипс). \en Minimum factor of smooth surface section completeness (0.5 for parabola, less for ellipse). +const double _CONIC_MAX_ = 0.95; ///< \ru Максимальный коэффициент полноты сечения поверхности сопряжения (при 0.5 - парабола, больше - гипербола). \en Maximum factor of smooth surface section completeness (0.5 for parabola, greater for hyperbola). +const double _ARC_ = 0.0; ///< \ru Коэффициент полноты сечения поверхности скругления при u = const соответствует дуге окружности. \en Factor of smooth surface section completeness in case of u = const corresponds to circle arc. + +const int32 TEN = 10; ///< \ru Число 10. \en Number 10. +const int32 TWENTY = 20; ///< \ru Число 20. \en Number 20. +const int32 TESSERA_MAX = 4000; ///< \ru Максимальное количество ячеек в строке и ряду триангуляционной сетки. \en Maximum count of cell in rows and columns for triangulation grid. +const int32 COUNT_MAX = 512; ///< \ru Коэффициент увеличения. \en Magnification factor. +const int32 COUNT_MID = 256; ///< \ru Коэффициент увеличения. \en Magnification factor. +const int32 COUNT_MIN = 128; ///< \ru Коэффициент увеличения. \en Magnification factor. +const int32 COUNT_BIN = 64; ///< \ru Уровень вложенности. \en Inclusion level. +const int32 WIRE_MAX = 256; ///< \ru Максимальное количество линий отрисовочной сетки. \en The maximum number of mesh lines. + +const int32 ITERATE_COUNT = 16; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 ITERATE_LIMIT = 32; ///< \ru Количество итераций для построения касательных окружностей. \en Count of iterations for construction of tangent circles. + +const int32 NEWTON_COUNT = 8; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 NEWTON_COUNT_2X = 16; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 NEWTON_COUNT_3X = 24; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 NEWTON_COUNT_4X = 32; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 NEWTON_COUNT_8X = 64; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. + +const int32 LIMIT_COUNT = 4; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. +const int32 COUNT_DELTA = 10; ///< \ru Коэффициент увеличения или уменьшения. \en Reduction or magnification factor. +const int32 COUNT_DELTA_2X = 20; ///< \ru Коэффициент увеличения или уменьшения. \en Reduction or magnification factor. +const int32 ITEMS_COUNT = 12; ///< \ru Число точек в шаговом методе. \en Number of points in step method. + +const int32 BEZIER_DEGREE = 4; ///< \ru Порядок Безье-сплайна по умолчанию. \en Default degree of Bezier-spline. +const int32 NURBS_DEGREE = 4; ///< \ru Порядок NURBS по умолчанию. \en Degree of NURBS. + +const int32 NURBS_POINTS_COUNT = 6; ///< \ru Число точек для NURBS по умолчанию для прямого редактирования. \en Default number of points for NURBS direct editing. +const int32 NURBS_POINTS_MAX_COUNT = 100; ///< \ru Максимальное число точек для NURBS по умолчанию для прямого редактирования. \en Default maximum number of points for NURBS direct editing. +const int32 APPROX_POINTS_MUL_COEFF = 3; ///< \ru Коэффициент увеличения количества точек для метода наименьших квадратов. \en Factor of points count incrementing in method of least squares. + +const int32 SPACE_DIM = 3; ///< \ru Размерность 3D-пространства. \en Dimension of 3D space. + +const int32 TRT_FREE = 0; ///< \ru Сопряжение отсутствует. \en No conjugation. +const int32 TRT_TANGENT = 1; ///< \ru Сопряжение по касательной. \en Tangent conjugation. +const int32 TRT_NORMAL = 2; ///< \ru Сопряжение по нормали. \en Normal conjugation. + + +/** \ru \name Способ информирования о нарушении требований.~ + \en \name Assert violation notification. +*/ +enum eAssertViolationNotify { + avn_Mute, ///< \ru Не сообщать о нарушении требований. \en Mute assert violations. + avn_CERR, ///< \ru Выводить сообщение в поток ошибок. \en Write message into error stream. + avn_ASSERT ///< \ru Обработка макросом ASSERT. \en ASSERT macro application. +}; + +} // namespace C3D + + +#define MB_AMBIENT 0.4 ///< \ru Коэффициент рассеянного освещения (фон). \en Coefficient of backlighting. +#define MB_DIFFUSE 0.7 ///< \ru Коэффициент диффузного отражения. \en Coefficient of diffuse reflection. +#define MB_SPECULARITY 0.8 ///< \ru Коэффициент зеркального отражения. \en Coefficient of specular reflection. +#define MB_SHININESS 50.0 ///< \ru Блеск (показатель степени в законе зеркального отражения). \en Shininess (index according to the law of specular reflection). +#define MB_OPACITY 1.0 ///< \ru Коэффициент суммарного отражения (коэффициент непрозрачности). \en Coefficient of total reflection (opacity coefficient). +#define MB_EMISSION 0.0 ///< \ru Коэффициент излучения. \en Emissivity coefficient. + +#define MB_DEFCOLOR 0x7F7F7F ///< \ru Цвет по умолчанию при импорте и экспорте (серый). \en Default color for import and export (grey). +#define MB_C3DCOLOR 0xFF7F00 ///< \ru Цвет по умолчанию для геометрических объектов. \en Default color for geometric objects. + +/// \ru Битовые флаги для матрицы и локальной системы координат. \en Bit flags for matrix and local coordinate system. +#define MB_IDENTITY 0x00 ///< \ru Единичная матрица. \en Identity. +#define MB_TRANSLATION 0x01 ///< \ru Присутствует смещение. \en Translation. +#define MB_ROTATION 0x02 ///< \ru Присутствует вращение. \en Rotation. +#define MB_SCALING 0x04 ///< \ru Присутствует масштабирование (компонент не 1.0). \en Scaling (factor is not equal to 1.0). +#define MB_REFLECTION 0x08 ///< \ru Присутствует зеркальная инверсия. \en Reflection. +#define MB_LEFT 0x08 ///< \ru Присутствует зеркальная инверсия (признак левой системы координат). \en Reflection (left coordinate system attribute). +#define MB_ORTOGONAL 0x10 ///< \ru Присутствует ортогональность, взводится только в случае аффинности. \en Orthogonality, is set up in case of affinity. +#define MB_AFFINE 0x20 ///< \ru Отсутствует ортогональность и нормированность (аффинное преобразование). \en Absence of orthogonality and normalization (affine transformation). +#define MB_PERSPECTIVE 0x40 ///< \ru Присутствует вектор перспективы (не нулевой). \en Vector of perspective (non-zero). +#define MB_UNSET 0x80 ///< \ru Битовые флаги не установлены. \en Bit flags not set. + +/** \} */ + + +class MATH_CLASS MbRefItem; +class VersionContainer; + + +//------------------------------------------------------------------------------ +/** \brief \ru Общие статические данные алгоритмов и функций. + \en Common static data of algorithms and functions. \~ + \details \ru Общие статические данные содержат константы, которые используются + в вычислениях как предельные величины. \n + Статические данные не подлежат изменению. \n + \en Common static data contains constants used + in computations as limit quantities. \n + Static data cannot be changed. \n \~ + \ingroup Base_Items +*/ +// --- +class MATH_CLASS Math { +public: + // \ru Константы \en Constants + static const double PI2; ///< \ru Отношение длины окружности к её радиусу. \en Relation between circle length and its radius. + static const double invPI2; ///< \ru Отношение радиуса окружности к её длине. \en Relation between circle radius and its length. + static const double RADDEG; ///< \ru Количество угловых градусов в радиане. \en Count of angular degrees in radian. + static const double DEGRAD; ///< \ru Количество радиан в угловом градусе. \en Count of radians in angular degree. + + static double doubleRegion; ///< \ru Относительная погрешность double. \en Relative tolerance for double. + static double region; ///< \ru Погрешность (PARAM_REGION). \en Tolerance (PARAM_REGION). + static double precision; ///< \ru Погрешность аппроксимации (PARAM_PRECISION). \en Approximation tolerance (PARAM_PRECISION). + static double accuracy; ///< \ru Погрешность (PARAM_ACCURACY). \en Tolerance (PARAM_ACCURACY). + + static double determinantMax; ///< \ru Максимально возможное значение определителя (DETERMINANT_MAX). \en Maximum possible value of determinant (DETERMINANT_MAX). + static double determinantMin; ///< \ru Минимально возможное значение определителя (DETERMINANT_MIN). \en Minimum possible value of determinant (DETERMINANT_MIN). + + static double LengthEps; ///< \ru Точность вычисления длины (PARAM_PRECISION). \en Length calculation tolerance (PARAM_PRECISION). + static double AngleEps; ///< \ru Точность вычисления угла. \en Angular tolerance. + static double NewtonEps; ///< \ru Точность численного решения уравнений. \en Tolerance of numerical solution of equation. + static double NewtonReg; ///< \ru Точность проверки решения уравнений. \en Solution of equation checking tolerance. + + static double lengthEpsilon; ///< \ru Погрешность длины. \en Tolerance for length. + static double lengthRegion; ///< \ru Погрешность региона. \en Tolerance for region. + + static double metricEpsilon; ///< \ru Погрешность расстояния в итерационных функциях. \en Tolerance for distance in iterative functions. + static double metricRegion; ///< \ru Неразличимая метрическая область. \en Indistinguishable metric region. + static double metricPrecision; ///< \ru Метрическая погрешность. \en Metric tolerance. + static double metricAccuracy; ///< \ru Наибольшая метрическая погрешность. \en Maximum metric tolerance. + static double metricNear; ///< \ru Метрическая близость. \en Metric proximity tolerance. + + static double paramEpsilon; ///< \ru Точность параметра кривой. \en Curve parameter tolerance. + static double paramRegion; ///< \ru Точность проверки параметра кривой. \en Curve parameter checking tolerance. + static double paramPrecision; ///< \ru Параметрическая погрешность. \en Parametric tolerance. + static double paramAccuracy; ///< \ru Наибольшая параметрическая погрешность. \en The largest parametric tolerance. + static double paramNear; ///< \ru Параметрическая близость. \en Parametric proximity. + + static double angleEpsilon; ///< \ru Минимальная различимый угол. \en Minimum distinguishable angle. + static double angleRegion; ///< \ru Неразличимая угловая область. \en Indistinguishable angular region. + + static double lowRenderAng; ///< \ru Угол для минимального количества отображаемых сегментов. \en Angle for minimum mapping segments count. + static double higRenderAng; ///< \ru Угол для максимального количества отображаемых сегментов. \en Angle for maximum mapping segments count. + + static double lengthMin; ///< \ru Квадрат минимальной различимой длины. \en Square of minimum distinguishable length. + static double lengthMax; ///< \ru Максимальная метрическая длина в системе. \en Maximum metric length in system. + + static double deviateSag; ///< \ru Угловая толерантность. \en Angular tolerance. + static double visualSag; ///< \ru Величина стрелки прогиба для визуализации. \en Value of sag for visualization. + + static double minLength; ///< \ru Минимально допустимая длина. \en Minimum legal length. + static double maxLength; ///< \ru Максимально допустимая длина. \en Maximum legal length. + static double minRadius; ///< \ru Минимально допустимый радиус. \en Minimum legal radius. + static double maxRadius; ///< \ru Максимально допустимый радиус. \en Maximum legal radius. + + static double metricDelta; ///< \ru Величина отшагивания. \en Metric offset. + static double paramDeltaMin; ///< \ru Минимальное приращение параметра. \en Minimum increment of parameter. + static double paramDeltaMax; ///< \ru Максимальное приращение параметра. \en Maximum increment of parameter. + + static double deltaMin; ///< \ru Минимальное приращение. \en Minimum increment. + static double deltaMax; ///< \ru Максимальное приращение. \en Maximum increment. + + static size_t newtonCount; ///< \ru Число приближений в итерационном методе. \en Number of approximations in iterative method. + static size_t newtonLimit; ///< \ru Количество итераций решения системы уравнений методом Newton. \en Iterations count for solving system of equations by Newton method. + static size_t curveDegree; ///< \ru Порядок кривой (NURBS_DEGREE). \en Curve degree (NURBS_DEGREE). + static size_t uSurfaceDegree; ///< \ru Порядок поверхности по U. \en Surface degree by U. + static size_t vSurfaceDegree; ///< \ru Порядок поверхности по V. \en Surface degree by V. + + static size_t tempIndex; ///< \ru Временный коэффициент. \en Temporary coefficient. + static size_t nameIndex; ///< \ru Индекс имени. \en Name index. + static size_t currentIndex; ///< \ru Текущее имя. \en Current name. + static size_t mathState; ///< \ru Состояние математического ядра. \en State of mathematical kernel. + + +private: + static const VersionContainer & defaultVersionContainer; ///< \ru Математическая версия по умолчанию. \en Default mathematical version. + + static const MbUuid mathID; ///< \ru Идентификатор ядра как приложения. \en Kernel ID. + + static bool namesComplete; ///< \ru Флаг полного именования объекта. \en Flag of object full naming. + ///< \ru Проименовать грани, рёбра, вершины оболочки после её создания (true) \en Name faces, edges, vertices of shell after creation (true) + ///< \ru Проименовать только грани оболочки после её создания (false) \en Name only faces of shell after creation (false) + static MbeMultithreadedMode multithreadedMode; ///< \ru Флаг режима многопоточных вычислений (по умолчанию максимальный). \en Flag of multithreading mode (maximum by default). + ///< \ru mtm_Off - Многопоточные вычисления отключены. \en Multithreading is off. + ///< \ru mtm_Standard - Включена многопоточность ядра при обработке независимых объектов. \en Kernel multithreading is ON for independent objects. + ///< \ru mtm_SafeItems - Обеспечивается потокобезопасность объектов типа MbItem. Выключена многопоточность ядра при обработке зависимых объектов. \en Ensured thread-safety of dependent objects MbItem. Kernel multithreading is OFF for objects with shared data. + ///< \ru mtm_Items - Обеспечивается потокобезопасность объектов типа MbItem. Включена многопоточность ядра при обработке зависимых объектов. \en Ensured thread-safety of dependent objects MbItem. Kernel multithreading is ON for objects with shared data. + ///< \ru mtm_Max - Включена максимальная многопоточность ядра. \en Maximal kernel multithreading is ON. + static c3d::eAssertViolationNotify assertViolationNotification; ///< \ru Способ оповещения о нарушении требований. \en The way of assert violation notification. +public: + static MbRefItem * selectCurve; ///< \ru Запомненный объект (для отладки). \en Stored object (for debug). + static MbRefItem * selectSurface; ///< \ru Запомненный объект (для отладки). \en Stored object (for debug). + static MbRefItem * selectEdge; ///< \ru Запомненный объект (для отладки). \en Stored object (for debug). + static MbRefItem * selectFace; ///< \ru Запомненный объект (для отладки). \en Stored object (for debug). + static MbRefItem * selectSolid; ///< \ru Запомненный объект (для отладки). \en Stored object (for debug). + +public: + + // \ru Функции статических данных \en Functions of static data + + /// \ru Математическая версия по умолчанию. \en Default mathematical version. + static const VersionContainer & DefaultVersion(); + /// \ru Математическая версия по умолчанию. \en Default mathematical version. + static VERSION DefaultMathVersion(); + + /// \ru Идентификатор ядра как приложения. \en Kernel ID. + static const MbUuid & MathID(); + + /// \ru Установить значения переменных по умолчанию. \en Set default values of variables. + static void SetDefaultValues(); + /// \ru Установить значение переменной. + /// Необходимо учитывать, что изменение глобальных переменных может привести + /// к непредсказуемым результатам при распараллеливании вычислений. + /// \en Set value of variable. + /// It is necessary to keep in mind that modification of global variable could lead to + /// unpredictable results when using parallel calculations. + static void SetUserValue( int index, double value ); + +/** \brief \ru Необходимо ли полное именование объекта. + \en Is it necessary to full object naming. \~ + \details \ru Необходимо ли полное именование объекта. + Если возвращает true, то после создания оболочки именуются грани, рёбра, вершины, + если возвращает false, то после создания оболочки именуются только грани. \n + \en Is it necessary to full object naming. + If returns true then faces, edges, vertices are named after shell creation, + If returns false then only faces are named after shell creation. \n \~ + \ingroup Base_Items +*/ + static bool NamesComplete(); + +/** \brief \ru Установить необходимость полного именования объекта. + \en Set flag of full object naming. \~ + \details \ru Установить необходимость полного именования объекта. + Если передано true, то после создания оболочки будут именоваться грани, рёбра, вершины, + если передано false, то после создания оболочки будут именоваться только грани. \n + \en Set flag of full object naming. + If passed true then faces, edges, vertices are named after shell creation, + if passed false then only faces are named after shell creation. \n \~ + \ingroup Base_Items +*/ + static void SetNamesComplete( bool b ); + +/** \brief \ru Используются ли многопоточные вычисления? + \en Are multithreaded calculations used? \~ + \details \ru Используются ли многопоточные вычисления? \n + \en Are multithreaded calculations used? \n \~ + \ingroup Base_Items +*/ + static bool Multithreaded(); + +/** \brief \ru Разрешить использовать многопоточные вычисления. + \en Set flag for use multithreaded calculations. \~ + \details \ru Разрешить использовать многопоточные вычисления. \n + Если передано true, то будут использоваться многопоточные вычисления. Устанавливается стандартный режим + если передано false, то не будут использоваться многопоточные вычисления. \n + \en Set flag for use multithreaded calculations. + If passed true then will use multithreaded calculations, multithreaded mode will be set to the standard mode + if passed false then will not use multithreaded calculations. \n \~ + \ingroup Base_Items +*/ + static void SetMultithreaded( bool b ); + +/** \brief \ru Режим многопоточных вычислений + \en Multithreaded mode \~ + \details \ru Режим многопоточных вычислений \n + \en Multithreaded mode \n \~ + \ingroup Base_Items +*/ + static MbeMultithreadedMode MultithreadedMode(); + +/** \brief \ru Проверить режим многопоточных вычислений + \en Check multithreaded mode \~ + \details \ru Проверить режим многопоточных вычислений \n + \en Check multithreaded mode \n \~ + \ingroup Base_Items +*/ + static bool CheckMultithreadedMode( MbeMultithreadedMode ); + +/** \brief \ru Установить режим многопоточных вычислений. + \en Set flag for mode of multithreaded calculations. \~ + \details \ru Установить режим многопоточных вычислений. \n + \en Set flag for mode of multithreaded calculations. \n \~ + \ingroup Base_Items +*/ + static void SetMultithreadedMode( MbeMultithreadedMode ); + + /** \brief \ru Получить режим оповещения о нарушении требований. + \en Get the mode of assert violations notification. \~ + \ingroup Base_Items + */ + static c3d::eAssertViolationNotify CheckAssertNotify(); + + /** \brief \ru Установить режим оповещения о нарушении требований. + \en Set the mode of assert violations notification. \~ + \ingroup Base_Items + */ + static void SetAssertNotify( c3d::eAssertViolationNotify ); + +}; + + +//------------------------------------------------------------------------------ +// Оставить от пути только имя файла. +// --- +MATH_FUNC( const char* ) C3DFileNameOnly( const char* path ); + +#if defined( C3D_WINDOWS ) + #define C3D_ASSERT_AS_CERR(expr) std::cerr << "C3D ASSERT VIOLATION in " << C3DFileNameOnly(__FILE__) << "@" << __LINE__ << std::endl; +#else + #define C3D_ASSERT_AS_CERR(expr) fprintf(stderr, "C3D ASSERT VIOLATION in file %s, %d:\n `%s' in function: %s.\n", C3DFileNameOnly(__FILE__), __LINE__, #expr, __PRETTY_FUNCTION__); +#endif + +#ifdef C3D_DEBUG +#define C3D_ASSERT_UNCONDITIONAL(expr) \ + { const c3d::eAssertViolationNotify notify = Math::CheckAssertNotify(); \ + if ( c3d::avn_ASSERT == notify ) { _ASSERT(false); } \ + else if ( c3d::avn_CERR == notify ) { C3D_ASSERT_AS_CERR(expr) } \ + } + +//------------------------------------------------------------------------------ +// Не рекомендуется использовать с параметром-константой +// (при сборке в VS2012 выдается - warning C4127: conditional expression is constant). +// --- +#define C3D_ASSERT(expr) \ + if (!(expr)) \ + C3D_ASSERT_UNCONDITIONAL(expr) + +#else + #define C3D_ASSERT_UNCONDITIONAL(expr) ((void)0) + #define C3D_ASSERT(expr) ((void)0) +#endif + + +#endif // __MB_VARIABLES_H diff --git a/C3d/Include/mb_vector.h b/C3d/Include/mb_vector.h new file mode 100644 index 0000000..83eae5d --- /dev/null +++ b/C3d/Include/mb_vector.h @@ -0,0 +1,1144 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерный вектор. + \en Two-dimensional vector. \~ + \details \ru Определены классы: двумерный вектор и нормализованный двумерный вектор. + Также определены функции, находящие различные соотношения между двумя векторами. + \en Defined classes: two-dimensional vector and normalized two-dimensional vector. + Also defined functions finding various relations between two vectors. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_VECTOR_H +#define __MB_VECTOR_H + + +#include +#include + + +class MATH_CLASS MbDirection; +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbPlacement; +class MATH_CLASS MbHomogeneous; +class MATH_CLASS MbMatrix; +class MATH_CLASS MbProperties; + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерный вектор. + \en Two-dimensional vector. \~ + \details \ru Двумерный вектор. Определены алгебраические и геометрические операции + для вектора с числом, точкой и другим вектором. + \en Two-dimensional vector. Defined algebraic and geometric operations + for vector and number, point or another vector. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbVector { +public : + double x; ///< \ru Первая компонента вектора. \en First component of vector. + double y; ///< \ru Вторая компонента вектора. \en Second component of vector. + + static const MbVector zero; ///< \ru Нулевой вектор. \en Zero vector. + static const MbVector xAxis; ///< \ru Вектор "X" стандартного базиса. \en "X" vector of standard basis. + static const MbVector yAxis; ///< \ru Вектор "Y" стандартного базиса. \en "Y" vector of standard basis. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbVector () : x( 0.0 ), y( 0.0 ) {} + /// \ru Конструктор по координатам. \en The constructor by coordinates. + MbVector ( double xx, double yy ) : x( xx ), y( yy ) {} + /// \ru Конструктор копирования. \en Copy constructor. + MbVector ( const MbVector & dir ) : x( dir.x ), y( dir.y ) {} + /// \ru Конструктор по двум точкам. \en The constructor by two points. + MbVector ( const MbCartPoint & p1, const MbCartPoint & p2 ) { Init( p1, p2 ); } + /// \ru Конструктор по точке. \en Constructor by point. + MbVector ( const MbCartPoint & p ); + /// \ru Конструктор по углу. \en Constructor by angle. + explicit MbVector ( double a ) : x( ::cos(a) ), y( ::sin(a) ) {} + /// \ru Конструктор по единичному вектору направления. \en Constructor by unit vector of direction. + explicit MbVector ( const MbDirection & dir ); + + /// \ru Инициализировать по заданным точкам. \en Initialize by given points. + MbVector & Init( const MbCartPoint & p1, const MbCartPoint & p2 ); + /// \ru Инициализировать по заданным координатам. \en Initialize by given coordinates. + MbVector & Init( double xx, double yy ) { x = xx; y = yy; return *this; } + /// \ru Инициализировать по заданному вектору. \en Initialize by given vector. + template + MbVector & Init( const Vector & v ) { x = v.x; y = v.y; return *this; } + + /// \ru Обнулить вектор. \en Set vector coordinates to zero. + MbVector & SetZero() { x = y = 0.0; return *this; } + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbVector & with ) const; + /// \ru Проверить на равенство. \en Check for equality. + bool Equal( const MbVector & with ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbVector & with ) const; + + /// \ru Вычислить длину вектора. \en Calculate vector length. + double Length() const; + /// \ru Рассчитать квадрат длины вектора. \en Calculate vector length square + double Length2() const; + /// \ru Нормализовать вектор. \en Normalize a vector. + bool Normalize(); + /// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector. + MbVector GetNormalized() const; + /// \ru Повернуть вектор на угол angle. \en Rotate vector by an angle 'angle'. + MbVector & Rotate( double angle ); + /// \ru Повернуть вектор на угол, заданный направлением. \en Rotate vector by an angle that defined by direction. + MbVector & Rotate( const MbDirection & angle ); + /// \ru Преобразовать в соответствии с матрицей matr. \en Transform according to matrix 'matr'. + MbVector & Transform( const MbMatrix & matr); + /// \ru Вычислить угол по нормализованному вектору. \en Calculate an angle by normalized vector. + double DirectionAngle() const; + + /// \ru Сложить два вектора. \en Sum up two vectors. + MbVector operator + ( const MbVector & ) const; + /// \ru Сложить вектор и точку. \en Sum up vector and point. + MbVector operator + ( const MbCartPoint & ) const; + /// \ru Вычесть из вектора вектор. \en Subtract vector from vector. + MbVector operator - ( const MbVector & ) const; + /// \ru Вычесть из вектора точку. \en Subtract point from vector. + MbVector operator - ( const MbCartPoint & ) const; + /// \ru Унарный минус. \en Unary minus. + MbVector operator - () const; + /// \ru Умножить вектор на число. \en Multiply vector by number. + MbVector operator * ( double factor ) const; + /// \ru Разделить вектор на число. \en Divide vector by number. + MbVector operator / ( double factor ) const; + + /// \ru Сложить два вектора. \en Sum up two vectors. + MbVector & operator += ( const MbVector & ); + /// \ru Вычесть из вектора вектор. \en Subtract vector from vector. + MbVector & operator -= ( const MbVector & ); + /// \ru Умножить вектор на число. \en Multiply vector by number. + MbVector & operator *= ( double ); + /// \ru Разделить вектор на число. \en Divide vector by number. + MbVector & operator /= ( double ); + + /// \ru Скалярное умножение двух векторов. \en Scalar product of two vectors. + double operator * ( const MbVector & ) const; + /// \ru Скалярное умножение двух векторов. \en Scalar product of two vectors. + double operator * ( const MbDirection & ) const; + /// \ru Векторное умножение двух векторов. \en Vector product of two vectors. + double operator | ( const MbVector & ) const; + /// \ru Вычислить вектор как копию данного вектора, преобразованную матрицей. \en Calculate the vector as this copy transformed by the matrix. + MbVector operator * ( const MbMatrix & ) const; + + /// \ru Делает вектор перпендикулярным самому себе, а именно задает вектор (-y, x). \en Makes a vector orthogonal to itself, namely sets the vector (-y, x). + MbVector & Perpendicular(); + /// \ru Выдать перпендикуляр к вектору, а именно вектор (-y, x). \en Returns a vector orthogonal to this vector, namely the vector (-y, x). + MbVector operator ~ () const; + /// \ru Присвоить вектору значения координат точки. \en Assign point coordinate values to vector. + MbVector & operator = ( const MbCartPoint & ); + /// \ru Присвоить вектору значения однородных координат точки. \en Assign uniform point coordinate values to vector. + MbVector & operator = ( const MbHomogeneous & ); + /// \ru Присвоить вектору значения нормализованного вектора. \en Assign normalized vector values to vector. + MbVector & operator = ( const MbDirection & ); + /// \ru Доступ к координате по индексу. \en Access to a coordinate by an index. + double & operator [] ( size_t i ) { return i ? y : x; }; + /// \ru Значение координаты по индексу. \en The value of a coordinate by an index. + double operator [] ( size_t i ) const { return i ? y : x; }; + + /// \ru Количество координат точки. \en The number of point coordinates. + static size_t GetDimension() { return 2; } + + /// \ru Дать положение вектора относительно текущего вектора. \en Give vector location relative to current vector. + int Relative( const MbVector & ) const; + /// \ru Проверить на вырожденность. \en Check for degeneracy. + bool IsDegenerate( double lenEps = Math::LengthEps ) const; + /// \ru Проверить нормализован ли вектор. \en Check if vector is normalized. + bool IsNormalized( double eps = LENGTH_EPSILON ) const; + /// \ru Проверить коллинеарность по скалярному произведению. \en Check colinearity by dot product. + bool RoundColinear( const MbVector & with, double eps = Math::paramNear ) const; + /// \ru Проверить коллинеарность. \en Check colinearity. + bool Colinear ( const MbVector & with, double eps = Math::AngleEps ) const; + /// \ru Проверить ортогональность. \en Check orthogonality. + bool Orthogonal ( const MbVector & with, double eps = Math::AngleEps ) const; + /// \ru Проверить коллинеарность. \en Check colinearity. + bool operator || ( const MbVector & with ) const { return Colinear(with); } + + /// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite. + void Invert(); + /// \ru Масштабировать компоненты вектора. \en Scale components of vector. + void Scale( double sx, double sy ) { x *= sx, y *= sy; } + + // \ru Присвоение вектору значений \en Assign values to vector + /// \ru Приравнять вектору вектор v1, умноженный на t1. \en Equate vector with vector v1 multiplied by t1. + void Set( const MbVector & v1, double t1 ); + /// \ru Приравнять вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector with sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbVector & v1, double t1, const MbVector & v2, double t2 ); + /// \ru Приравнять вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector with sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ); + /// \ru Приравнять вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector with sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ); + /// \ru Приравнять вектору сумму нормализованных векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector with sum of normalized vectors v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector coordinates with sum of points v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector coordinates with coordinates of sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbCartPoint & v1, double t1, const MbCartPoint & v2, double t2, + const MbCartPoint & v3, double t3, const MbCartPoint & v4, double t4 ); + // \ru Добавление вектору значений \en Addition values to a vector + /// \ru Прибавить к вектору вектор v1, умноженный на t1. \en Add vector v1 multiplied by t1 to a vector. + void Add( const MbVector & v1, double t1 ); + /// \ru Прибавить к вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Add sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly to a vector. + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2 ); + /// \ru Прибавить к вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Add sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly to a vector. + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ); + /// \ru Прибавить к вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Add sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly to a vector. + void Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ); + /// \ru Прибавить к вектору сумму единичных векторов v1 и v2, умноженные на t1 и t2 соответственно. \en Add sum of unit vectors v1 and v2 multiplied with t1 and t2 correspondingly to a vector. + void Add( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ); + + /// \ru Дать максимальную по модулю компоненту вектора. \en Give the largest absolute value of a vector. + double MaxFactor() const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbVector & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbVector ) + DECLARE_NEW_DELETE_CLASS( MbVector ) + DECLARE_NEW_DELETE_CLASS_EX( MbVector ) +}; // MbVector + + +//------------------------------------------------------------------------------ +// \ru Длина вектора. \en Vector length. +// --- +inline double MbVector::Length() const +{ + return ::_hypot( x, y ); +} + + +//------------------------------------------------------------------------------ +// \ru Квадрат длины вектора. \en Vector length square. +// --- +inline double MbVector::Length2() const +{ + return ( x * x + y * y ); +} + + +//------------------------------------------------------------------------------ +// \ru Нормализация вектора \en Normalize a vector +// --- +inline bool MbVector::Normalize() +{ + double len = ::_hypot( x, y ); +// C3D_ASSERT( len > LENGTH_EPSILON || len < NULL_EPSILON ); + bool res = ( len >= NULL_EPSILON ); + if ( res && ::fabs(len - 1.0) > NULL_EPSILON ) { + double one_len = 1.0 / len; + x *= one_len; + y *= one_len; + C3D_ASSERT( ::fabs(1.0 - ::_hypot(x, y)) < LENGTH_EPSILON ); + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector. +// --- +inline MbVector MbVector::GetNormalized() const +{ + double len = ::_hypot( x, y ); + if ( len >= NULL_EPSILON && ::fabs(len - 1.0) > NULL_EPSILON ) + len = 1.0 / len; + MbVector res( x * len, y * len ); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух векторов; результат - вектор \en Addition of two vectors; result is vector +// --- +inline MbVector MbVector::operator + ( const MbVector & vector ) const +{ + return MbVector(x + vector.x, y + vector.y); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух векторов; результат - вектор \en Subtraction of two vectors; result is vector +// --- +inline MbVector MbVector::operator - ( const MbVector & v1 ) const +{ + return MbVector( x - v1.x, y - v1.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус \en Unary minus +// --- +inline MbVector MbVector::operator - () const +{ + return MbVector( -x, -y ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiply vector by number +// --- +inline MbVector MbVector::operator * ( double factor ) const +{ + return MbVector( x * factor, y * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение скаляра на вектор \en Multiply scalar by vector +// --- +inline MbVector operator * ( double factor, const MbVector & v ) +{ + return v*factor; +} + + +//------------------------------------------------------------------------------ +// \ru Деление вектора на число \en Division of vector by number +// --- +inline MbVector MbVector::operator / ( double factor ) const +{ + if ( ::fabs(factor) > NULL_EPSILON ) + return MbVector( x / factor, y / factor ); + return MbVector( x, y ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух векторов \en Addition of two vectors +// --- +inline MbVector & MbVector::operator += ( const MbVector & vector ) +{ + x += vector.x; + y += vector.y; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух векторов \en Subtraction of two vectors +// --- +inline MbVector & MbVector::operator -= ( const MbVector & vector ) +{ + x -= vector.x; + y -= vector.y; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiplication of vector by number +// --- +inline MbVector & MbVector::operator *= ( double factor ) +{ + x *= factor; + y *= factor; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Деление вектора на число \en Division of vector by number +// --- +inline MbVector & MbVector::operator /= ( double factor ) +{ + if ( ::fabs(factor) > NULL_EPSILON ) { + x /= factor; + y /= factor; + } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Скалярное умножение двух векторов \en Scalar product of two vectors +// --- +inline double MbVector::operator * ( const MbVector & vector ) const +{ + return x * vector.x + y * vector.y; +} + + +//------------------------------------------------------------------------------ +// \ru Векторное умножение двух векторов \en Vector product of two vectors +// --- +inline double MbVector::operator | ( const MbVector & vector ) const +{ + return x * vector.y - y * vector.x; +} + + +//------------------------------------------------------------------------------ +// \ru Перпендикуляр к вектору; результат - вектор \en Perpendicular to a vector; result is vector +// --- +inline MbVector MbVector::operator ~ () const +{ + return MbVector( -y, x ); +} + + +//------------------------------------------------------------------------------ +// \ru Перпендикуляр к вектору; результат - вектор \en Perpendicular to a vector; result is vector +// \ru Поворот влево на 90 градусов \en Rotation to the left by 90 degrees +// --- +inline MbVector & MbVector::Perpendicular() +{ + double temp = x; + x = - y; + y = temp; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Положение вектора относительно текущего вектора. \en Vector location relative to current vector. +// \ru Возвращает результат : \en Returning result: +// \ru +1 - слева по направлению; \en +1 - on the left by direction; +// \ru 0 - вектора коллинеарны; \en 0 - vectors are collinear; +// \ru -1 - справа по направлению. \en -1 - on the right by direction. +// --- +inline int MbVector::Relative( const MbVector & rel ) const +{ + double l1 = Length(); + double l2 = rel.Length(); + + if ( l1 < Math::LengthEps || l2 < Math::LengthEps ) + return 0; + + double yy = (- rel.x * y + rel.y * x) / (l1*l2); + return ( ::fabs(yy) < Math::LengthEps ) ? 0 : ( yy > 0.0 ) ? + 1 : - 1; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbVector::operator == (const MbVector & with) const +{ + return ( ::fabs( x - with.x ) < Math::LengthEps ) && + ( ::fabs( y - with.y ) < Math::LengthEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbVector::Equal(const MbVector & with ) const +{ + return ( x == with.x && y == with.y ); //-V550 +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbVector::operator != (const MbVector & with) const +{ + return !(*this == with); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на вырожденность \en Check for degeneracy +// --- +inline bool MbVector::IsDegenerate( double lenEps ) const +{ + return ( ::fabs( x ) < lenEps ) && + ( ::fabs( y ) < lenEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Является ли вектор нормированным \en Check if vector is normalized +// --- +inline bool MbVector::IsNormalized( double eps ) const +{ + return ( ::fabs( Length() - 1.0) < eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Сменить направление вектора на противоположное \en Change vector direction to opposite +// --- +inline void MbVector::Invert() +{ + x = -x; + y = -y; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений \en Assign values to vector +// --- +inline void MbVector::Set( const MbVector & v1, double t1 ) +{ + x = v1.x * t1; + y = v1.y * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений \en Assign values to vector +// --- +inline void MbVector::Set( const MbVector & v1, double t1, const MbVector & v2, double t2 ) +{ + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений \en Assign values to vector +// --- +inline void MbVector::Set( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений \en Assign values to vector +// --- +inline void MbVector::Set( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление вектору значений \en Addition values to a vector +// --- +inline void MbVector::Add( const MbVector & v1, double t1 ) +{ + x += v1.x * t1; + y += v1.y * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление вектору значений \en Addition values to a vector +// --- +inline void MbVector::Add( const MbVector & v1, double t1, const MbVector & v2, double t2 ) +{ + x += v1.x * t1 + v2.x * t2; + y += v1.y * t1 + v2.y * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление вектору значений \en Addition values to a vector +// --- +inline void MbVector::Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление вектору значений \en Addition values to a vector +// --- +inline void MbVector::Add( const MbVector & v1, double t1, const MbVector & v2, double t2, + const MbVector & v3, double t3, const MbVector & v4, double t4 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; +} + + +//------------------------------------------------------------------------------- +// \ru Максимальная по модулю компонента вектора \en The largest absolute value of a vector +// --- +inline double MbVector::MaxFactor() const +{ + return std_max( ::fabs( x ), ::fabs( y ) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbVector::IsSame( const MbVector & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Двумерный нормализованный вектор. \en Two-dimensional normalized vector. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерный нормализованный вектор. + \en Two-dimensional normalized vector. \~ + \details \ru Двумерный нормализованный вектор. Определены алгебраические и геометрические операции + для нормализованного вектора с числом и другим вектором. + \en Two-dimensional normalized vector. Defined algebraic and geometric operations + for normalized vector and number or another vector. \~ + \ingroup Mathematic_Base_2D +*/ +// --- +class MATH_CLASS MbDirection { +public : + double ax; ///< \ru Первая компонента вектора. \en First component of vector. + double ay; ///< \ru Вторая компонента вектора. \en Second component of vector. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbDirection () : ax( 1.0 ), ay( 0.0 ) {} + /// \ru Конструктор по координатам. \en The constructor by coordinates. + MbDirection ( double _ax, double _ay ) : ax( _ax ), ay( _ay ) { Normalize(); } + /// \ru Конструктор по углу. \en Constructor by angle. + explicit MbDirection ( double a ) : ax( ::cos(a) ), ay( ::sin(a) ) {} + /// \ru Конструктор копирования. \en Copy constructor. + MbDirection ( const MbDirection & dir ) : ax( dir.ax ), ay( dir.ay ) {} + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbDirection ( const MbCartPoint & p1, const MbCartPoint & p2 ) { Calculate( p1, p2 ); } + + /// \ru Повернуть нормализованный вектор на угол angle. \en Rotate normalized vector by an angle 'angle'. + void Rotate( double angle ); + /// \ru Повернуть вектор на угол, заданный направлением. \en Rotate vector by an angle that defined by direction. + void Rotate( const MbDirection & ); + /// \ru Преобразовать в соответствии с матрицей matr. \en Transform according to matrix 'matr'. + void Transform( const MbMatrix & ); + /// \ru Вычислить угол по нормализованному вектору. \en Calculate an angle by normalized vector. + double DirectionAngle() const; + /// \ru Вычислить направление по 2 точкам. \en Calculate direction by two points. + void Calculate( const MbCartPoint & from, const MbCartPoint & to); + /// \ru Нормализовать вектор. \en Normalize a vector. + void Normalize(); + + /// \ru Унарный минус. \en Unary minus. + MbDirection operator - () const; + /// \ru Сложить два нормализованных вектора. \en Sum up two normalized vectors. + MbDirection operator + ( const MbDirection & ) const; + /// \ru Найти перпендикуляр к нормализованному вектору. \en Find perpendicular to a normalized vector. + MbDirection operator ~ () const; + + /// \ru Найти перпендикуляр к нормализованному вектору. \en Find perpendicular to a normalized vector. + void Perpendicular(); + + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbDirection & ) const; + /// \ru Проверить на равенство. \en Check for equality. + bool Equal( const MbDirection & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbDirection & ) const; + + /// \ru Проверить коллинеарность. \en Check colinearity. + bool Colinear ( const MbDirection &, double eps = Math::AngleEps ) const; + /// \ru Проверить ортогональность. \en Check orthogonality. + bool Orthogonal( const MbDirection &, double eps = Math::AngleEps ) const; + /// \ru Проверить коллинеарность. \en Check colinearity. + bool Colinear ( const MbVector & with, double eps = Math::AngleEps ) const; + /// \ru Проверить ортогональность. \en Check orthogonality. + bool Orthogonal( const MbVector & with, double eps = Math::AngleEps ) const; + /// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite. + void Invert(); + + /// \ru Присвоить значение вектору по заданному углу. \en Assign value to vector by given angle. + void operator = ( double angle ) { Set( angle ); } + /// \ru Присвоить значение вектору по заданному вектору. \en Assign value to vector by given vector. + void operator = ( const MbVector & ); + /// \ru Присвоить значение вектору по заданной точке. \en Assign value to vector by given point. + void operator = ( const MbCartPoint & ); + /// \ru Умножить вектор на число. \en Multiply vector by number. + MbVector operator * ( double ) const; + /// \ru Сложить два вектора. \en Sum up two vectors. + void operator += ( const MbDirection & ); + /// \ru Найти разность векторов. \en Find the difference of vectors. + void operator -= ( const MbDirection & ); +// void operator *= ( double ); + + /// \ru Скалярное умножение двух векторов. \en Scalar product of two vectors. + double operator * ( const MbDirection & ) const; + /// \ru Векторное умножение двух векторов. \en Vector product of two vectors. + double operator | ( const MbDirection & ) const; + + /// \ru Инициализировать по координатам. \en Initialize by coordinates. + void Init( double xx, double yy ) { ax = xx; ay = yy; Normalize(); } + /// \ru Инициализировать по координатам другого вектора. \en Initialize by coordinates of a vector. + void Init( const MbDirection & dir ) { ax = dir.ax; ay = dir.ay; } + /// \ru Инициализировать по заданному углу. \en Initialize by given angle. + void Set( double angle ) { ax = ::cos( angle ); ay = ::sin( angle ); } + + /// \ru Найти положение вектора относительно текущего вектора. \en Find vector location relative to current vector. + int Relative( const MbDirection & ) const; + /// \ru Проверить на вырожденность. \en Check for degeneracy. + bool IsDegenerate( double lenEps = Math::LengthEps ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbDirection & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbDirection ) + DECLARE_NEW_DELETE_CLASS( MbDirection ) + DECLARE_NEW_DELETE_CLASS_EX( MbDirection ) +}; // MbDirection + + +/** \} */ + + +//------------------------------------------------------------------------------ +// \ru Нормализация вектора \en Normalize a vector +// --- +inline void MbDirection::Normalize() +{ + double len = ::_hypot( ax, ay ); + + if ( len >= NULL_EPSILON ) { + double k = 1.0 / len; + ax *= k; + ay *= k; + } +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор по нормализованному вектору \en Constructor by a normalized vector +// --- +inline MbVector::MbVector( const MbDirection & dir ) +{ + x = dir.ax; + y = dir.ay; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений нормализованного вектора \en Assign normalized vector values to vector +// --- +inline MbVector & MbVector::operator = ( const MbDirection & dir ) +{ + x = dir.ax; + y = dir.ay; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Скалярное умножение двух векторов \en Scalar product of two vectors +// --- +inline double MbVector::operator * ( const MbDirection & vector ) const +{ + return x * vector.ax + y * vector.ay; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектору значений \en Assign values to vector +// --- +inline void MbVector::Set( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ) +{ + x = v1.ax * t1 + v2.ax * t2; + y = v1.ay * t1 + v2.ay * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавление вектору значений \en Addition values to a vector +// --- +inline void MbVector::Add( const MbDirection & v1, double t1, const MbDirection & v2, double t2 ) +{ + x += v1.ax * t1 + v2.ax * t2; + y += v1.ay * t1 + v2.ay * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение вектора \en Assignment of vector +// --- +inline void MbDirection::operator = ( const MbVector & vect ) +{ + double d = vect.Length(); + + if ( d >= NULL_EPSILON ) { + ax = vect.x / d; + ay = vect.y / d; + } + else { + ax = ay = 0.0; + } +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус \en Unary minus +// --- +inline MbDirection MbDirection::operator - () const +{ + return MbDirection( - ax, - ay ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух нормализованных векторов \en Addition of two normalized vectors +// \ru Результат - нормализованный вектор \en Result is normalized vector +// --- +inline MbDirection MbDirection::operator + ( const MbDirection & dir ) const +{ + double xx = ax + dir.ax; + double yy = ay + dir.ay; + double d = ::_hypot( xx, yy ); + + if ( d <= NULL_EPSILON ) + return MbDirection( ax, ay ); + + double k = 1.0 / d; + + return MbDirection( xx*k, yy*k ); +} + + +//------------------------------------------------------------------------------ +// \ru Перпендикуляр к нормализованному вектору \en Perpendicular to a normalized vector +// --- +inline MbDirection MbDirection::operator ~ () const +{ + return MbDirection( - ay, ax ); +} + + +//------------------------------------------------------------------------------ +// \ru Перпендикуляр к нормализованному вектору \en Perpendicular to a normalized vector +// --- +inline void MbDirection::Perpendicular() +{ + double temp = ax; + ax = - ay; + ay = temp; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiplication of vector by number +// --- +inline MbVector MbDirection::operator * ( double factor ) const +{ + return MbVector( ax * factor, ay * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух векторов \en Addition of two vectors +// --- +inline void MbDirection::operator += ( const MbDirection & dir ) +{ + double xx = ax + dir.ax; + double yy = ay + dir.ay; + double d = ::_hypot( xx, yy ); + if ( d > NULL_EPSILON ) { + ax = xx / d; + ay = yy / d; + } +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух векторов \en Subtraction of two vectors +// --- +inline void MbDirection::operator -= ( const MbDirection & dir ) +{ + double xx = ax - dir.ax; + double yy = ay - dir.ay; + double d = ::_hypot( xx, yy ); + if ( d > NULL_EPSILON ) { + ax = xx/d; + ay = yy/d; + } +} + + +//------------------------------------------------------------------------------ +// \ru Оператор \en Operator +// --- +//inline void MbDirection::operator *= ( double factor ) +//{ +// ax *= factor; +// ay *= factor; +//} + + +//------------------------------------------------------------------------------ +// \ru Скалярное умножение двух векторов \en Scalar product of two vectors +// --- +inline double MbDirection::operator * ( const MbDirection & dir2 ) const +{ + return ax * dir2.ax + ay * dir2.ay; +} + + +//------------------------------------------------------------------------------ +// \ru Векторное умножение двух векторов \en Vector product of two vectors +// --- +inline double MbDirection::operator | ( const MbDirection & dir2 ) const +{ + return ax * dir2.ay - ay * dir2.ax; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbDirection::operator == ( const MbDirection & with) const +{ + return ( ::fabs( ax - with.ax ) < Math::LengthEps ) && + ( ::fabs( ay - with.ay ) < Math::LengthEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbDirection::Equal( const MbDirection & with ) const +{ + return ( ax == with.ax && ay == with.ay ); //-V550 +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на неравенство \en Check for inequality +// --- +inline bool MbDirection::operator != ( const MbDirection & with) const +{ + return !(*this == with); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка коллинеарности \en Check for colinearity +// --- +inline bool MbDirection::Colinear( const MbDirection & with, double eps ) const +{ + return (::fabs( ax * with.ay - ay * with.ax ) < eps); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка ортогональности \en Check for orthogonality +// --- +inline bool MbDirection::Orthogonal( const MbDirection & with, double eps ) const +{ + return (::fabs(*this * with) <= eps); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка коллинеарности \en Check for colinearity +// --- +inline bool MbDirection::Colinear( const MbVector & with, double eps ) const +{ + MbVector vect( *this ); + return vect.Colinear( with, eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка ортогональности \en Check for orthogonality +// --- +inline bool MbDirection::Orthogonal( const MbVector & with, double eps ) const +{ + MbVector vect( *this ); + return vect.Orthogonal( with, eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на вырожденность \en Check for degeneracy +// --- +inline bool MbDirection::IsDegenerate( double lenEps ) const +{ + return ( ::fabs( ax ) < lenEps ) && + ( ::fabs( ay ) < lenEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Сменить направление вектора на противоположное \en Change vector direction to opposite +// --- +inline void MbDirection::Invert() +{ + ax = -ax; + ay = -ay; +} + + +//------------------------------------------------------------------------------ +// \ru Положение вектора относительно текущего вектора \en Vector location relative to current vector +// \ru Возвращает результат : \en Returning result: +// \ru +1 - слева по направлению; \en +1 - on the left by direction; +// \ru 0 - вектора коллинеарны; \en 0 - vectors are collinear; +// \ru -1 - справа по направлению. \en -1 - on the right by direction. +// --- +inline int MbDirection::Relative( const MbDirection & rel ) const +{ + double y = - rel.ax * ay + rel.ay * ax; + return ( ::fabs( y ) < Math::LengthEps ) ? 0 : ( y > 0 ) ? + 1 : - 1; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbDirection::IsSame( const MbDirection & other, double accuracy ) const +{ + return ( (::fabs(ax - other.ax) < accuracy) && + (::fabs(ay - other.ay) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Чтение вектора из потока. \en Reading vector from stream. +// --- +inline reader & CALL_DECLARATION operator >> ( reader & in, MbVector & obj ) { + in >> obj.x; + in >> obj.y; + return in; +} + + +//------------------------------------------------------------------------------ +/// \ru Запись вектора в поток. \en Writing vector to stream. +// --- +inline writer & CALL_DECLARATION operator << ( writer & out, const MbVector & obj ) { + out << obj.x; + out << obj.y; + return out; +} + + +//------------------------------------------------------------------------------ +/// \ru Чтение нормализованного вектора из потока. \en Reading normalized vector from stream. +// --- +inline reader & CALL_DECLARATION operator >> ( reader & in, MbDirection & obj ) { + in >> obj.ax; + in >> obj.ay; + return in; +} + + +//------------------------------------------------------------------------------ +/// \ru Запись нормализованного вектора в поток. \en Writing normalized vector to stream. +// --- +inline writer & CALL_DECLARATION operator << ( writer & out, const MbDirection & obj ) { + out << obj.ax; + out << obj.ay; + return out; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление минимального угла между двумя векторами + \en Calculate minimal angle between two vectors \~ + \details \ru Вычисление угла между двумя векторами (-пи ... пи) + Возвращает результат со знаком:\n + <0 находится слева от вектора v1\n + >0 находится справа от вектора v2 + \en Calculate angle between two vectors (-pi ... pi) + Returns signed result:\n + <0 to the left of vector v1\n + >0 to the right of vector v2 \~ + \note \ru Нормализация векторов не требуется + \en Normalization of vectors is not required \~ + \ingroup Mathematic_Base_2D +*/ +inline +double Angle2Vectors( const MbVector & v1, const MbVector & v2 ) +{ + if ( v1.MaxFactor() < NULL_REGION || v2.MaxFactor() < NULL_REGION ) + return 0; + return ::atan2( v1|v2/*y*/, v1*v2/*x*/ ); +} + +//------------------------------------------------------------------------------ +/// \ru Вычислить "векторное" произведение двух векторов. \en Calculate "vector" product of two vectors. +// --- +inline +double SetVecM( const MbVector & vF, const MbVector & vS ) { + return (vF.x * vS.y) - (vF.y * vS.x); +} + + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/// \ru Вектор, повернутый на pi/2 радиан против часовой стрелки. \en Vector rotated by pi/2 radians counterclockwise. +//--- +inline +MbVector Perpendicular( MbVector vec ) { + return vec.Perpendicular(); +} + +//------------------------------------------------------------------------------ +/// \ru Проверить на равенство нулю длину вектора с заданной точностью. \en Check vector length to be equaled to zero with given tolerance. +// --- +inline +bool IsNull( const MbVector & vec, double eps ) { + return ::fabs(vec.x) < eps && ::fabs(vec.y) < eps; +} + +} // namespace C3D + +#endif // __MB_VECTOR_H diff --git a/C3d/Include/mb_vector3d.h b/C3d/Include/mb_vector3d.h new file mode 100644 index 0000000..967b970 --- /dev/null +++ b/C3d/Include/mb_vector3d.h @@ -0,0 +1,756 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вектор в трехмерном пространстве. + \en Vector in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MB_VECTOR3D_H +#define __MB_VECTOR3D_H + + +#include +#include + + +class MATH_CLASS MbVector; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbHomogeneous3D; +class MATH_CLASS MbFloatVector3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbProperties; + + +//------------------------------------------------------------------------------ +/** \brief \ru Вектор в трехмерном пространстве. + \en Vector in three-dimensional space. \~ + \details \ru Вектор описывает перемещение или направление в трёхмерном пространстве + и определяется тремя компонентами x, y, z в декартовой системе координат. \n + Вектор не привязан к точкам пространства и поэтому не имеет метода, + перемещающего его в пространстве. \n + \en Vector describes translation or direction in three-dimensional space + and is defined by three coordinates x, y, z in the Cartesian coordinate system. \n + Vector is not binded to space points and therefore has not method + for translating it in space. \n \~ + \ingroup Mathematic_Base_3D +*/ +// --- +class MATH_CLASS MbVector3D { +public : + double x; ///< \ru Первая компонента вектора. \en First component of vector. + double y; ///< \ru Вторая компонента вектора. \en Second component of vector. + double z; ///< \ru Третья компонента вектора. \en Third component of vector. + + static const MbVector3D zero; ///< \ru Нулевой вектор. \en Zero vector. + static const MbVector3D xAxis; ///< \ru Вектор "X" стандартного базиса. \en "X" vector of standard basis. + static const MbVector3D yAxis; ///< \ru Вектор "Y" стандартного базиса. \en "Y" vector of standard basis. + static const MbVector3D zAxis; ///< \ru Вектор "Z" стандартного базиса. \en "Z" vector of standard basis. + +public : + /// \ru Конструктор без параметров, вектор нулевой. \en Constructor without parameters, vector is zero. + MbVector3D () : x( 0.0 ), y( 0.0 ), z( 0.0 ) {} + /// \ru Конструктор по координатам. \en The constructor by coordinates. + MbVector3D ( double a, double b, double c ) : x( a ), y( b ), z( c ) {} + /// \ru Конструктор-копия. \en Copy constructor. + MbVector3D ( const MbVector3D & v ) : x( v.x ), y( v.y ), z( v.z ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbVector3D ( const MbFloatVector3D & ); + /// \ru Конструктор по точке. \en Constructor by point. + MbVector3D ( const MbCartPoint3D & p ); + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbVector3D ( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ) { Init( p1, p2 ); } + /// \ru Конструктор по двумерному вектору в плоскости XOY локальной системы координат place. \en Constructor by two-dimensional vector in XOY plane of local coordinate system 'place'. + MbVector3D ( const MbVector & v2d, const MbPlacement3D & place ) { Init( v2d, place ); } + + /// \ru Инициализировать по двумерному вектору в плоскости XOY локальной системы координат place. \en Initialize by two-dimensional vector in XOY plane of local coordinate system 'place'. + void Init( const MbVector &, const MbPlacement3D & ); + /// \ru Инициализировать по двумерному вектору. \en Initialize by two-dimensional vector. + void InitXY( const MbVector & ); + /// \ru Инициализировать по координатам. \en Initialize by coordinates. + void Init( double a, double b, double c ) { x = a; y = b; z = c; } + /// \ru Инициализировать по другому вектору. \en Initialize by another vector. + template + void Init( const Vector & v ) { x = v.x; y = v.y; z = v.z; } + /// \ru Инициализировать по двум точкам. \en Initialize by two points. + void Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + /// \ru Увеличить координаты на заданные величины. \en Increase coordinates by given values. + void Add ( double a, double b, double c ) { x += a; y += b; z += c; } + /// \ru Увеличить координаты на значение координат заданного вектора. \en Increase coordinates by values of given vector. + void Add ( const MbVector3D & v ) { x += v.x; y += v.y; z += v.z; } + + /// \ru Обнулить координаты вектора. \en Set coordinates of vector to zero. + void SetZero() { x = y = z = 0.0; } + /// \ru Является ли вектор нулевым? \en Check if vector is zero. + bool IsZero ( double eps = Math::lengthEpsilon ) const; + + /// \ru Преобразовать согласно матрице. Матрица действует на вектор справа. \en Transform according to the matrix. A matrix acts on a vector from the right. + MbVector3D & Transform( const MbMatrix3D & matr ); + /// \ru Повернуть вокруг оси на заданный угол. \en Rotate at given angle around axis. + MbVector3D & Rotate( const MbVector3D & axis, double angle ); + /// \ru Повернуть вокруг оси на заданный угол. \en Rotate at given angle around axis. + MbVector3D & Rotate( const MbAxis3D & axis, double angle ); + /// \ru Повернуть вокруг оси (по её номеру) на заданный угол ( 0 - ось X, 1 - ось Y, 2 - ось Z ). \en Rotate around the axis (by its number) at a given angle ( 0 - X-axis, 1 - Y-axis, 2 - Z-axis ). + MbVector3D & RotateXYZ( int number, double angle ); + + /// \ru Проверить вектор на вырожденность. \en Check vector for degeneracy. + bool IsDegenerate( double comEps = Math::region ) const; + /// \ru Проверить вектор на нормированность. \en Check if vector is normalized. + bool IsNormalized( double eps = Math::lengthEpsilon ) const; + /// \ru Проверить коллинеарность векторов с заданной точностью (по косинусу угла между векторами). \en Check if vectors are colinear with given tolerance (by cosine of angle between vectors). + bool RoundColinear( const MbVector3D & with, double eps = Math::paramNear ) const; + /// \ru Проверить коллинеарность векторов с заданной точностью (по синусу угла между векторами). \en Check if vectors are colinear with given tolerance (by sine of angle between vectors). + bool Colinear ( const MbVector3D & with, double eps = Math::angleRegion ) const; + /// \ru Проверить ортогональность векторов с заданной точностью. \en Check if vectors are orthogonal with given tolerance. + bool Orthogonal( const MbVector3D & with, double eps = Math::angleRegion ) const; + /// \ru Рассчитать длину вектора. \en Calculate vector length. + double Length() const; + /// \ru Рассчитать квадрат длины вектора. \en Calculate vector length square + double Length2() const; + /// \ru Рассчитать угол между векторами. \en Calculate angle between vectors. + double Angle( const MbVector3D & with ) const; + /// \ru Нормализовать вектор. \en Normalize a vector. + bool Normalize(); + /// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector. + MbVector3D GetNormalized() const; + /// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite. + MbVector3D& Invert(); + /// \ru Вернуть составляющую часть вектора, параллельную вектору v. \en Get parallel to vector v part of vector. + MbVector3D TangentComponent( const MbVector3D & v ) const; + /// \ru Вернуть составляющую часть вектора, ортогональную вектору v. \en Get orthogonal to vector v part of vector. + MbVector3D NormalComponent ( const MbVector3D & v ) const; + + /// \ru Учесть перспективу для первой производной. \en Perspective for first derivative is to be considered. + void PspDerivative ( double, const MbCartPoint3D & ); + /// \ru Учесть перспективу для производной второго порядка. \en Perspective for second derivative is to be considered. + void PspDerivative2 ( double, const MbCartPoint3D &, const MbVector3D & ); + /// \ru Учесть перспективу для смешанной производной второго порядка. \en Perspective for second order mixed derivative is to be considered. + void PspDerivative2Mix ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & ); + /// \ru Учесть перспективу для производной третьего порядка. \en Perspective for third derivative is to be considered. + void PspDerivative3 ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & ); + /// \ru Учесть перспективу для смешанной производной третьего порядка. \en Perspective for third order mixed derivative is to be considered. + void PspDerivative3Mix ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D &, + const MbVector3D &, const MbVector3D & ); + /// \ru Учесть перспективу для нормали. \en Perspective for normal is to be considered. + void PspNormal ( double, const MbCartPoint3D & ); + /// \ru Учесть перспективу для производной нормали. \en Perspective for derivative of normal is to be considered. + void PspNormalDerivative( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & ); + + /// \ru Проверить на равенство. \en Check for equality. + bool operator == ( const MbVector3D & ) const; + /// \ru Проверить на неравенство. \en Check for inequality. + bool operator != ( const MbVector3D & ) const; + /// \ru Сложить векторы. \en Sum up two vectors. + MbVector3D operator + ( const MbVector3D & ) const; + /// \ru Найти разность векторов. \en Find the difference of vectors. + MbVector3D operator - ( const MbVector3D & ) const; + /// \ru Сложить вектор с точкой. \en Sum up vector and point. + MbVector3D operator + ( const MbCartPoint3D & ) const; + /// \ru Вычесть из вектора точку. \en Subtract point from vector. + MbVector3D operator - ( const MbCartPoint3D & ) const; + /// \ru Унарный минус. \en Unary minus. + MbVector3D operator - () const; + + /// \ru Сложить векторы. \en Sum up two vectors. + MbVector3D & operator += ( const MbVector3D & ); + /// \ru Вычесть из вектора точку. \en Subtract point from vector. + MbVector3D & operator -= ( const MbVector3D & ); + /// \ru Умножить вектор на число. \en Multiply vector by number. + MbVector3D & operator *= ( double ); + /// \ru Разделить вектор на число. \en Divide vector by number. + MbVector3D & operator /= ( double ); + + /// \ru Вычислить скалярное произведение двух векторов. \en Calculate dot product of two vectors. + double operator * ( const MbVector3D & ) const; + /// \ru Вычислить векторное произведение двух векторов. \en Calculate vector product of two vectors. + MbVector3D operator | ( const MbVector3D & ) const; + /// \ru Вычислить прямое произведение двух векторов. \en Calculate direct product of two vectors. + MbMatrix3D operator & ( const MbVector3D & ) const; + /// \ru Вычислить вектор как копию данного вектора, преобразованную матрицей. \en Calculate the vector as this copy transformed by the matrix. + MbVector3D operator * ( const MbMatrix3D & ) const; + + /// \ru Присвоить вектору значения координат точки. \en Assign point coordinate values to vector. + MbVector3D & operator = ( const MbCartPoint3D & ); + /// \ru Присвоить вектору значения однородных координат точки. \en Assign uniform point coordinate values to vector. + MbVector3D & operator = ( const MbHomogeneous3D & ); + /// \ru Присвоить вектору координаты другого вектора. \en Assign coordinates of another vector to the vector. + MbVector3D & operator = ( const MbFloatVector3D & ); + + /// \ru Получить доступ к координате по индексу. \en Access to coordinate by an index. + double & operator [] ( size_t i ) { return i ? (--i ? z : y) : x; }; + /// \ru Получить значение координаты по индексу. \en Get coordinate value by an index. + double operator [] ( size_t i ) const { return i ? (--i ? z : y) : x; }; + /// \ru Получить количество координат точки. \en Get point coordinates count. + static size_t GetDimension() { return 3; } + + /// \ru Приравнять вектору вектор v1, умноженный на t1. \en Equate vector with vector v1 multiplied by t1. + void Set( const MbVector3D & v1, double t1 ); + /// \ru Приравнять вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector with sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ); + /// \ru Приравнять вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector with sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ); + /// \ru Приравнять вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector with sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ); + + /// \ru Приравнять координаты вектора координатам точки v1, умноженных на t1. \en Equate coordinates of vector with coordinates of point v1 multiplied by t1. + void Set( const MbCartPoint3D & v1, double t1 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector coordinates with sum of points v1 and v2 multiplied with t1 and t2 correspondingly. + void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector coordinates with coordinates of sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly. + void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ); + /// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly. + void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ); + + /// \ru Прибавить к вектору вектор v1, умноженный на t1. \en Add vector v1 multiplied by t1 to a vector. + void Add( const MbVector3D & v1, double t1 ); + /// \ru Прибавить к вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Add sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly to a vector. + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ); + /// \ru Прибавить к вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Add sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly to a vector. + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ); + /// \ru Прибавить к вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Add sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly to a vector. + void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ); + + /// \ru Прибавить к координатам вектора координаты точки v1, умноженных на t1. \en Add coordinates of point v1 multiplied by t1 to coordinates of vector. + void Add( const MbCartPoint3D & v1, double t1 ); + /// \ru Прибавить к координатам вектора координаты точек v1 и v2, умноженных на числа t1 и t2, соответственно. \en Add sum of coordinates of points v1 and v2 multiplied with t1 and t2 correspondingly to coordinates of vector. + void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 ); + /// \ru Прибавить к координатам вектора координаты точек v1, v2 и v3, умноженных на числа t1, t2 и t3, соответственно. \en Add sum of coordinates of points v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly to coordinates of vector. + void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3 ); + /// \ru Прибавить к координатам вектора координаты точек v1, v2, v3 и v4, умноженных на числа t1, t2, t3 и t4, соответственно. \en Add sum of coordinates of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly to coordinates of vector. + void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2, + const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 ); + + /// \ru Задать векторное произведение двух заданных векторов. \en Set vector product of two given vectors. + void SetVecM( const MbVector3D & vF, const MbVector3D & vS ); + /// \ru Задать векторное произведение двух заданных векторов, умноженное на mulKoef. \en Set vector product of two given vectors multiplied by mulKoef. + void SetVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef ); + /// \ru Добавить к вектору векторное произведение двух заданных векторов. \en Add vector product of two given vectors to vector. + void AddVecM( const MbVector3D & vF, const MbVector3D & vS ); + /// \ru Добавить к вектору векторное произведение двух заданных векторов, умноженное на mulKoef. \en Add vector product of two given vectors multiplied by mulKoef to vector. + void AddVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef ); + + /// \ru Найти максимальную по модулю компоненту вектора. \en Find the largest absolute value of a vector. + double MaxFactor() const; + /// \ru Масштабировать компоненты. \en Scale components. + void Scale( double sx, double sy, double sz ) { x *= sx, y *= sy, z *= sz; } + /// \ru Масштабировать компоненты. \en Scale components. + void Scale( double s ) { x *= s, y *= s, z *= s; } + + /// \ru Округлить компоненты вектора. \en Round components of vector. + bool SetRoundedValue( bool total, double eps ); + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbVector3D & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbVector3D, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( MbVector3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbVector3D ) +}; // MbVector3D + + +//------------------------------------------------------------------------------ +// \ru Сложить два вектора; результат - вектор. \en Sum up two vectors; result is vector. +// --- +inline MbVector3D MbVector3D::operator + ( const MbVector3D & vector ) const +{ + return MbVector3D( x + vector.x, y + vector.y, z + vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычесть из вектора вектор; результат - вектор. \en Subtract vector from vector; result is vector. +// --- +inline MbVector3D MbVector3D::operator - ( const MbVector3D & v2 ) const +{ + return MbVector3D ( x - v2.x, y - v2.y, z - v2.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус. \en Unary minus. +// --- +inline MbVector3D MbVector3D::operator - () const +{ + return MbVector3D ( - x, - y, - z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложить два вектора. \en Sum up two vectors. +// --- +inline MbVector3D & MbVector3D::operator += ( const MbVector3D & vector ) +{ + x += vector.x; + y += vector.y; + z += vector.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Вычесть из вектора вектор. \en Subtract vector from vector. +// --- +inline MbVector3D & MbVector3D::operator -= ( const MbVector3D & vector ) +{ + x -= vector.x; + y -= vector.y; + z -= vector.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Умножить вектор на число. \en Multiply vector by number. +// --- +inline MbVector3D & MbVector3D::operator *= ( double factor ) +{ + x *= factor; + y *= factor; + z *= factor; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Разделить вектор на число. \en Divide vector by number. +// --- +inline MbVector3D & MbVector3D::operator /= ( double factor ) +{ + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication + C3D_ASSERT( factor != 0.0 ); //-V550 + double invFactor = ( 1.0 / factor ); + x *= invFactor; + y *= invFactor; + z *= invFactor; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить скалярное произведение двух векторов. \en Calculate dot product of two vectors. +// --- +inline double MbVector3D::operator * ( const MbVector3D & vector ) const +{ + return ( x * vector.x + y * vector.y + z * vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить векторное произведение двух векторов. \en Calculate vector product of two vectors. +// --- +inline MbVector3D MbVector3D::operator | ( const MbVector3D & vect2 ) const +{ + return MbVector3D( y * vect2.z - z * vect2.y, + z * vect2.x - x * vect2.z, + x * vect2.y - y * vect2.x ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на равенство. \en Check for equality. +// --- +inline bool MbVector3D::operator == ( const MbVector3D & with ) const +{ + return ( ::fabs( x - with.x ) < Math::region && + ::fabs( y - with.y ) < Math::region && + ::fabs( z - with.z ) < Math::region ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на неравенство. \en Check for inequality. +// --- +inline bool MbVector3D::operator != ( const MbVector3D & with ) const +{ + return !( *this == with ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить на вырожденность. \en Check for degeneracy. +// --- +inline bool MbVector3D::IsDegenerate( double comEps ) const +{ + return ( ::fabs( x ) < comEps && + ::fabs( y ) < comEps && + ::fabs( z ) < comEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить, является ли вектор нормированным. \en Check if vector is normalized. +// --- +inline bool MbVector3D::IsNormalized( double eps ) const +{ + return ( ::fabs( Length() - 1.0) < eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверить, является ли вектор нулевым. \en Check if vector is zero. +// --- +inline bool MbVector3D::IsZero( double eps ) const +{ + return ( ::fabs(x) < eps && + ::fabs(y) < eps && + ::fabs(z) < eps ); +} + + +//------------------------------------------------------------------------------ +// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite. +// --- +inline MbVector3D & MbVector3D::Invert() +{ + x = - x; + y = - y; + z = - z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Найти длину вектора. \en Find vector length. +// --- +inline double MbVector3D::Length() const +{ + return ::sqrt( x * x + y * y + z * z ); +} + + +//------------------------------------------------------------------------------ +// \ru Найти квадрат длины вектора. \en Find vector length square. +// --- +inline double MbVector3D::Length2() const +{ + return ( x * x + y * y + z * z ); +} + + +//------------------------------------------------------------------------------ +// \ru Нормализовать вектор. \en Normalize a vector. +// --- +inline bool MbVector3D::Normalize() +{ + double len = Length(); +// C3D_ASSERT( len > LENGTH_EPSILON || len < NULL_EPSILON ); + bool res = ( len >= NULL_EPSILON ); + if ( res && ::fabs(len - 1.0) > NULL_EPSILON ) { + double one_len = 1.0 / len; + x *= one_len; + y *= one_len; + z *= one_len; + C3D_ASSERT( ::fabs(Length() - 1.0) < LENGTH_EPSILON ); + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector. +// --- +inline MbVector3D MbVector3D::GetNormalized() const +{ + double len = Length(); + if ( len >= NULL_EPSILON && ::fabs(len - 1.0) > NULL_EPSILON ) + len = 1.0 / len; + MbVector3D res( x * len, y * len, z * len ); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Выдать компоненту вектора в направлении vector. \en Give part of vector coincident to direction 'vector'. +// --- +inline MbVector3D MbVector3D::TangentComponent( const MbVector3D & vector ) const +{ + MbVector3D res( vector ); + res.Normalize(); + res *= res * (*this); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Выдать компоненту вектора в направлении ортогональном vector. \en Give part of vector in direction orthogonal to 'vector'. +// --- +inline MbVector3D MbVector3D::NormalComponent( const MbVector3D & vector ) const +{ + MbVector3D res( vector ); + res.Normalize(); + res *= res * (*this); + res.Init( x-res.x, y-res.y, z-res.z ); + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbVector3D::Set( const MbVector3D & v1, double t1 ) +{ + x = v1.x * t1; + y = v1.y * t1; + z = v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ) +{ + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3; + y = v1.y * t1 + v2.y * t2 + v3.y * t3; + z = v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить вектору значения. \en Assign values to vector. +// --- +inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ) +{ + x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору значения. \en Add values to vector. +// --- +inline void MbVector3D::Add( const MbVector3D & v1, double t1 ) +{ + x += v1.x * t1; + y += v1.y * t1; + z += v1.z * t1; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору значения. \en Add values to vector. +// --- +inline void MbVector3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 ) +{ + x += v1.x * t1 + v2.x * t2; + y += v1.y * t1 + v2.y * t2; + z += v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору значения. \en Add values to vector. +// --- +inline void MbVector3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3; + y += v1.y * t1 + v2.y * t2 + v3.y * t3; + z += v1.z * t1 + v2.z * t2 + v3.z * t3; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору значения. \en Add values to vector. +// --- +inline void MbVector3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2, + const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 ) +{ + x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4; + y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4; + z += v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4; +} + + +//------------------------------------------------------------------------------ +/// \ru Умножить вектор на число. \en Multiply vector by number. +// --- +inline MbVector3D operator * ( const MbVector3D & vector, double factor ) +{ + return MbVector3D( vector.x * factor, vector.y * factor, vector.z * factor ); +} + + +//------------------------------------------------------------------------------ +/// \ru Разделить вектор на число. \en Divide vector by number. +// --- +inline MbVector3D operator / ( const MbVector3D & vector, double factor ) +{ + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication + C3D_ASSERT( factor != 0.0 ); //-V550 + double invFactor = ( 1.0 / factor ); + return MbVector3D( vector.x * invFactor, vector.y * invFactor, vector.z * invFactor ); +} + + +//------------------------------------------------------------------------------ +/// \ru Умножить вектор на число. \en Multiply vector by number. +// --- +inline MbVector3D operator * ( double factor, const MbVector3D & vector ) +{ + return vector * factor; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить векторное произведение векторов. \en Calculate vector product of vectors. +// --- +inline void MbVector3D::SetVecM( const MbVector3D & vF, const MbVector3D & vS ) +{ + x = vF.y * vS.z - vF.z * vS.y; + y = vF.z * vS.x - vF.x * vS.z; + z = vF.x * vS.y - vF.y * vS.x; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить векторное произведение векторов, умноженное на число. \en Calculate vector product of vectors multiplied by number. +// --- +inline void MbVector3D::SetVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef ) +{ + x = ( vF.y * vS.z - vF.z * vS.y ) * mulKoef; + y = ( vF.z * vS.x - vF.x * vS.z ) * mulKoef; + z = ( vF.x * vS.y - vF.y * vS.x ) * mulKoef; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору векторное произведение векторов. \en Add vector product of vectors to vector. +// --- +inline void MbVector3D::AddVecM( const MbVector3D & vF, const MbVector3D & vS ) +{ + x += vF.y * vS.z - vF.z * vS.y; + y += vF.z * vS.x - vF.x * vS.z; + z += vF.x * vS.y - vF.y * vS.x; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить к вектору векторное произведение векторов, умноженное на число. \en Add vector product of vectors multiplied by number to vector. +// --- +inline void MbVector3D::AddVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef ) +{ + x += (vF.y * vS.z - vF.z * vS.y) * mulKoef; + y += (vF.z * vS.x - vF.x * vS.z) * mulKoef; + z += (vF.x * vS.y - vF.y * vS.x) * mulKoef; +} + + +//------------------------------------------------------------------------------- +// \ru Найти максимальную по модулю компоненту вектора. \en Find the largest absolute value of a vector. +// --- +inline double MbVector3D::MaxFactor() const +{ + double ax = ::fabs( x ); + double ay = ::fabs( y ); + double az = ::fabs( z ); + return ( ((ax > ay) && (ax > az)) ? ax : ((ay > az) ? ay : az) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbVector3D::IsSame( const MbVector3D & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(z - other.z) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Глобальные функции \en Global functions +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Вычислить векторное произведение векторов. \en Calculate vector product of vectors. +// --- +inline +void SetVecM( MbVector3D & vVec, const MbVector3D & vF, const MbVector3D & vS ) +{ + vVec.x = ( vF.y * vS.z - vF.z * vS.y ); + vVec.y = ( vF.z * vS.x - vF.x * vS.z ); + vVec.z = ( vF.x * vS.y - vF.y * vS.x ); +} + +//------------------------------------------------------------------------------ +/// \ru Вычислить векторное произведение векторов, умноженное на число. \en Calculate vector product of vectors multiplied by number. +// --- +inline +void SetVecM( MbVector3D & vVec, const MbVector3D & vF, const MbVector3D & vS, double mulKoef ) +{ + vVec.x = ( vF.y * vS.z - vF.z * vS.y ) * mulKoef; + vVec.y = ( vF.z * vS.x - vF.x * vS.z ) * mulKoef; + vVec.z = ( vF.x * vS.y - vF.y * vS.x ) * mulKoef; +} + + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить, что вектор ненулевой с заданной точностью. + \en Check equality of vector to zero with given tolerance. \~ + \details \ru Проверка ненулевого вектора с заданной точностью. + Вектор считается ненулевым, если его координаты превосходят заданную погрешность. + \en Check equality of vector to zero with given tolerance. + Vector is nonzero if its coordinates are greater than given tolerance. \~ + \param[in] vec - \ru Вектор. + \en A vector. \~ + \param[in] eps - \ru Погрешность координат. + \en Coordinate tolerance. \~ + \return \ru Возвращает true, если вектор ненулевой. + \en Returns true if the vector is nonzero. \~ + \ingroup Mathematic_Base_3D +*/ +// --- +inline +bool Nonzero( const MbVector3D & vec, double eps ) { + return ::fabs(vec.x) > eps || ::fabs(vec.y) > eps || ::fabs(vec.z) > eps; +} + +} // namespace C3D + + +#endif // __MB_VECTOR3D_H diff --git a/C3d/Include/mesh.h b/C3d/Include/mesh.h new file mode 100644 index 0000000..c9afdfc --- /dev/null +++ b/C3d/Include/mesh.h @@ -0,0 +1,422 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Полигональный геометрический объект (фасетный объект). + \en The polygonal geometric object - Mesh. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_H +#define __MESH_H + + +#include +#include +#include + + +class MATH_CLASS MbMesh; +namespace c3d // namespace C3D +{ +typedef SPtr MeshSPtr; +typedef SPtr ConstMeshSPtr; + +typedef std::vector MeshesVector; +typedef std::vector ConstMeshesVector; + +typedef std::vector MeshesSPtrVector; +typedef std::vector ConstMeshesSPtrVector; +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Полигональный объект модели - фасетный объект. + \en The polygonal geometric object - Mesh. \~ + \details \ru Фасетный объект - это объект геометрической модели, наследник MbItem, являющийся + множеством примитивов #MbPrimitive, аппроксимирующих некоторый + геометрический объект для ускорения визуализации, вычисления инерционных + характеристик, определения столкновений и других расчетов.\n + + Например, сетку можно построить на основе множества точек, полученных замерами + реального физического тела. Полигональный объект содержит множество точек, являющимися + узлами (вершинами) в таких структурах данных: + множество указателей на триангуляции MbGrid (наборы стыкующихса треугольных и четырёхугольных пластин), + множество указателей на полигоны MbPolygon3D (наборы точек, описывающих ломаные линии), + множество указателей на апексы MbApex3D (точки, описывающие положение вершин или объектов-точек).\n + + \en Mesh is an object of geometric model (subclass MbItem) which is + the set of primitives #MbPrimitive which approximate some + geometric object for speed up rendering, calculation of inertial + characteristics, collision detection and other calculations.\n + + For example, the mesh can be create on the basis of a point set obtained measurements + of the real physical solid. Polygonal object contains a set of points which are + nodes (vertices) in the data structures: + a set of pointers to triangulations MbGrid (sets of mating triangular and quadrangular plates), + a set of pointers to polygons MbPolygon3D (sets of points which describe the polylines), + a set of pointers to apexes MbApex3D (points wich describe the position of vertices or objects-points). \n \~ + + \par \ru Применение + Полигональный объект используется для представления геометрических объектов в упрощенном виде, \n + для визуализации геометрических объектов, \n + для расчетов столкновений геометрических объектов, \n + для вычисления масс-инерционных характеристик. \n + Если фасетный объект аппроксимирует тело #MbSolid, то фасетный объект, как тело, может быть + замкнутым или незамкнутым.\n + Граничные точки разных триангуляций для замкнутого объекта совпадают, но имеют в них разные нормали. + + \en Usage + The mesh is used to represent geometric objects in a polygonal form, \n + for visualization of geometric objects, \n + for calculations of geometry objects collisions, \n + for calculation of the mass-inertial properties. \n + If the mesh approximates the solid #MbSolid then polygonal object as a solid can be + closed or unclosed. \n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbMesh : public MbItem +{ +private: + RPArray grids; ///< \ru Множество указателей на триангуляции. \en A set of pointers to triangulations. + RPArray wires; ///< \ru Множество указателей на полигоны. \en A set of pointers to polygons. + RPArray peaks; ///< \ru Множество указателей на апексы. \en A set of pointers to apexes. + const MbRefItem * item; ///< \ru Источник сетки. \en Source of mesh. + MbeSpaceType type; ///< \ru Тип сетки отражает характер, но не связан напрямую с item. \en A mesh type describes the character but it is not related to "item". + bool closed; ///< \ru Замкнутость указывает на отсутствие края в триангуляции. \en Closedness indicates the absence of edge in the triangulation. + bool exact; ///< \ru Объекты построены на числах double. \en Objects builded on double data. + + /** \brief \ru Габаритный куб объекта. + \en Bounding box of object. \~ + \details \ru Габаритный куб объекта расчитывается только при запросе габарита объекта. Габаритный куб в конструкторе объекта и после модификации объекта принимает неопределенное значение. + \en Bounding box of object is calculated only at the request. Bounding box of object is undefined after object constructor and after object modifications \n \~ + */ + mutable MbCube cube; + +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbMesh( const MbMesh & ); + /// \ru Конструктор копирования с регистратором. \en Copy constructor with registrator. + explicit MbMesh( const MbMesh & other, MbRegDuplicate * iReg ); + +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbMesh( bool _exact = false ); + /// \ru Деструктор \en Destructor + virtual ~MbMesh(); + +public: + VISITING_CLASS( MbMesh ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en Type of the object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равным. \en Make equal objects. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create own property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a polygonal copy of the given object. + virtual MbItem* CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Добавить себя в присланный полигональный объект mesh без копирования. \en Add itself to the given polygonal object "mesh" without copying. + virtual bool AddYourMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + // \ru Разрезать полигональный объект одной или двумя параллельными плоскостями. \en Cut polygonal form of an object by one or two parallel planes. + virtual MbItem* CutMesh( const MbPlacement3D & cutPlace, double distance ) const; + // \ru Найти ближайший объект или имя ближайшего объекта. \en Find the nearest object or name of nearest object. + // \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. \~ + virtual bool NearestMesh( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType, + const MbAxis3D & axis, double maxDistance, bool gridPriority, double & t, double & dMin, + MbItem *& find, SimpleName & findName, + MbRefItem *& element, SimpleName & elementName, + MbPath & path, MbMatrix3D & from ) const; + + /** \ru \name Функции полигонального объекта. + \en \name Function of polygonal object. + \{ */ + /// \ru Является ли полигональный объект аппроксимацией точки? \en Whether the polygonal object is approximation of point. + bool IsAPointMesh () const; + /// \ru Является ли полигональный объект аппроксимацией кривой? \en Whether the polygonal object is approximation of curve. + bool IsACurveMesh () const; + /// \ru Является ли полигональный объект аппроксимацией поверхности? \en Whether the polygonal object is approximation of surface. + bool IsASurfaceMesh() const; + /// \ru Является ли полигональный объект аппроксимацией твёрдого тела? \en Whether the polygonal object is approximation of solid. + bool IsASolidMesh () const; + /// \ru Содержат ли контейнеры сетки данные? \en Whether containers of mesh contain data. + bool IsComplete() const { return (grids.size() > 0) || (wires.size() > 0) || (peaks.size() > 0); } + /// \ru Зарезервировать место для пластин. \en Reserve space for the plates. + void GridsReserve(size_t cnt, bool fill = false ); + /// \ru Зарезервировать место для полигонов. \en Reserve space for the polygons. + void PolygonsReserve( size_t cnt ) { wires.Reserve( cnt ); } + /// \ru Зарезервировать место для апексов. \en Reserve space for the apexes. + void ApexReserve( size_t cnt ) { peaks.Reserve( cnt ); } + /// \ru Обнулить данные объекта. \en Set object data to null. + void Flush(); + /// \ru Освободить лишнюю память. \en Free the unnecessary memory. + void Adjust() { grids.Adjust(); wires.Adjust(); peaks.Adjust(); } + + /// \ru Выдать количество триангуляций. \en Get the number of triangulations. + size_t GridsCount() const { return grids.size(); } + /// \ru Добавить триангуляцию. \en Add triangulation. + void AddGrid( MbGrid & gr ); + /// \ru Добавить новую пустую триангуляцию и выдать её для заполнения. \en Add new empty triangulation and give it to fill. + MbGrid * AddGrid(); + /// \ru Отсоединить триангуляцию с заданным номером. \en Detach triangulation with a given number. + MbGrid * DetachGrid( size_t i ); + /// \ru Отсоединить все триангуляции. \en Detach all triangulations. + template + void DetachAllGrids( GridsVector & gridsVector ) { + gridsVector.reserve( gridsVector.size() + grids.size() ); + for( size_t i = 0, iCount = grids.size(); i < iCount; ++i ) { + MbGrid * gr = grids[i]; + if ( gr != NULL ) { + gr->DecRef(); + gridsVector.push_back( gr ); + } + grids.clear(); +#ifdef STANDARD_C11 + grids.shrink_to_fit(); +#endif + cube.SetEmpty(); + } + } + /// \ru Вернуть указатель на триангуляцию по её номеру. \en Return pointer to triangulation by it number. + const MbGrid * GetGrid( size_t i ) const { return ( (i < grids.size()) ? grids[i]: NULL ); } + /// \ru Вернуть указатель на триангуляцию по её номеру для модификации. \en Return the pointer to triangulation by its number to be modified. + MbGrid * SetGrid( size_t i ) { return ( (i < grids.size()) ? grids[i]: NULL ); } + /// \ru Получить указатели на триангуляции. \en Get pointers to triangulations. + template + void GetGrids( GridsVector & gridsVector ) const { + size_t gridsCnt = grids.size(); + gridsVector.reserve( gridsVector.size() + gridsCnt ); + for ( size_t k = 0; k < gridsCnt; ++k ) { + const MbGrid * grid = grids[k]; + gridsVector.push_back( grid ); + } + } + /// \ru Выдать количество полигонов. \en Get the number of polygons. + size_t PolygonsCount() const { return wires.size(); } + /// \ru Добавить полигон. \en Add polygon. + void AddPolygon( MbPolygon3D & ); + /// \ru Добавить новый пустой полигон и выдать его для заполнения. \en Add new empty polygon and give it to fill. + MbPolygon3D * AddPolygon(); + /// \ru Отсоединить полигон с заданным номером. \en Detach polygon with a given number. + MbPolygon3D * DetachPolygon( size_t i ); + /// \ru Отсоединить все полигоны. \en Detach all polygons. + template + void DetachAllPolygons( PolygonsVector & polyVector ) { + polyVector.reserve( polyVector.size() + wires.size() ); + for( size_t i = 0, iCount = wires.size(); i < iCount; ++i ) { + MbPolygon3D * pl = wires[i]; + if ( pl != NULL ) { + pl->DecRef(); + polyVector.push_back( pl ); + } + wires.clear(); +#ifdef STANDARD_C11 + wires.shrink_to_fit(); +#endif + cube.SetEmpty(); + } + } + /// \ru Вернуть указатель на полигон по его номеру. \en Return the pointer to polygon by its number. + const MbPolygon3D * GetPolygon( size_t i ) const { return ( (i < wires.size()) ? wires[i]: NULL ); } + /// \ru Вернуть указатель на полигон по его номеру. \en Return the pointer to polygon by its number. + MbPolygon3D * SetPolygon( size_t i ) { return ( (i < wires.size()) ? wires[i]: NULL ); } + /// \ru Получить указатели на полигоны. \en Get pointers to polygons. + template + void GetPolygons( PolygonsVector & polyVector ) const { + size_t polyCnt = wires.size(); + polyVector.reserve( polyVector.size() + polyCnt ); + for ( size_t k = 0; k < polyCnt; ++k ) { + const MbPolygon3D * poly = wires[k]; + polyVector.push_back( poly ); + } + } + /// \ru Выдать количество апексов. \en Get the number of apexes. + size_t ApexesCount() const { return peaks.size(); } + /// \ru Добавить новый апекс. \en Add new apex. + void AddApex( MbApex3D & ap ); + /// \ru Добавить новый пустой апекс и выдать его для заполнения. \en Add new empty apex and give it to fill. + MbApex3D * AddApex(); + /// \ru Отсоединить апекс с заданным номером. \en Detach apex with a given number. + MbApex3D * DetachApex( size_t i ); + /// \ru Отсоединить все вершины. \en Detach all apexes. + template + void DetachAllApexes( ApexesVector & peakVector ) { + peakVector.reserve( peakVector.size() + peaks.size() ); + for( size_t i = 0, iCount = peaks.size(); i < iCount; ++i ) { + MbApex3D * peak = peaks[i]; + if ( peak != NULL ) { + peak->DecRef(); + peakVector.push_back( peak ); + } + peaks.clear(); +#ifdef STANDARD_C11 + peaks.shrink_to_fit(); +#endif + cube.SetEmpty(); + } + } + /// \ru Вернуть указатель на апекс по его номеру. \en Return the pointer to apex by its number. + const MbApex3D * GetApex( size_t i ) const { return ( (i < peaks.size()) ? peaks[i]: NULL ); } + /// \ru Вернуть указатель на апекс по его номеру для модификации. \en Return the pointer to apex by its number to be modified. + MbApex3D * SetApex( size_t i ) { return ( (i < peaks.size()) ? peaks[i]: NULL ); } + /// \ru Получить указатели на вершины. \en Get pointers to apexes. + template + void GetApexes( ApexesVector & peakVector ) const { + size_t peaksCnt = peaks.size(); + peakVector.reserve( peakVector.size() + peaksCnt ); + for ( size_t k = 0; k < peaksCnt; ++k ) { + const MbApex3D * peak = peaks[k]; + peakVector.push_back( peak ); + } + } + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a polygonal copy of the given object. + MbMesh * CreateMeshByExistingItem( const MbRefItem & ) const; + + /// \ru Инициализировать объект. \en Initialize an object. + void InitMesh( const MbMesh & ); + /// \ru Добавить объекты сетки из присланной сетки. \en Add objects of mesh from a given mesh. + bool AddMesh( const MbMesh &, bool checkSamePointers ); + + /// \ru Получить пространственный объект, для которого построен полигональный объект. \en Get a spatial object for which a polygonal object is constructed. + const MbSpaceItem * SpaceItem() const { return ((item != NULL && item->RefType() == rt_SpaceItem) ? (const MbSpaceItem *)item : NULL); } + /// \ru Получить двумерный объект, для которого построен полигональный объект. \en Get a two-dimensional object for which a polygonal object is constructed. + const MbPlaneItem * PlaneItem() const { return ((item != NULL && item->RefType() == rt_PlaneItem) ? (const MbPlaneItem *)item : NULL); } + /// \ru Получить объект геометрической модели, для которого построен полигональный объект. \en Get a model geometric object for which a polygonal object is constructed. + const MbItem * Item() const + { + const MbItem * modelItem = NULL; + if ( item != NULL ) { + MbeRefType refType = item->RefType(); + if ( refType == rt_SpaceItem ) { + if ( static_cast(item)->Family() == st_Item ) + modelItem = static_cast(item); + } + } + return modelItem; + } + /// \ru Получить объект, для которого построен полигональный объект. \en Get an object for which a polygonal object is constructed. + const MbRefItem * GetRefItem() const { return item; } + /// \ru Запомнить объект, для которого построен полигональный объект. \en Remember an object for which a polygonal object is constructed. + void SetRefItem( const MbRefItem * g ) { item = g; } + /// \ru Сбросить все запомненные объекты. \en Reset all reference objects. + void ResetRefItems(); + /// \ru Установить тип полигонального объекта. \en Set a type of polygonal object. + void SetMeshType( MbeSpaceType t ) { type = t; } + /// \ru Дать тип полигонального объекта. \en Get a type of polygonal object. + MbeSpaceType GetMeshType() const { return type; } + + /// \ru Установить имя всем триангуляциям. \en Set the name of all triangulations. + void SetGridName( SimpleName n ); + /// \ru Установить имя всем полигонам. \en Set the name of all polygons. + void SetPolygonName( SimpleName n ); + /// \ru Установить имя всем апексам. \en Set the name of all apexes. + void SetApexName( SimpleName n ); + + /// \ru Замкнутость объекта. \en Object closedness. + bool IsClosed() const { return closed; } + /// \ru Установить (не)замкнутость объекта. \en Set object (un-) closedness. + void SetClosed( bool c ) { closed = c; } + /// \ru Объекты на числах double. \en Objects on double data. + bool IsExact() const { return exact; } + + /** + \brief \ru Определить положение объекта относительно плоскости. + \en Define the object position relative to the plane. \~ + \details \ru Определить положение объекта относительно плоскости XY локальной системы координат. + \en Define the object position relative to the plane XY of a local coordinate system. \~ + \param[in] pl - \ru Локальная система координат, задающая плоскость. + \en A local coordinate system which defines a plane. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \param[in] onlyInItem - \ru Интересует только положение объекта над плоскостью XY локальной системы координат. + \en Whether the object position relative to the XY-plane of a local coordinate system is interested only. \~ + \return \ru iloc_OnItem - объект пересекает плоскость XY локальной системы координат,\n + iloc_InItem - объект расположен над плоскостью XY локальной системы координат,\n + iloc_OutOfItem - объект расположен под плоскостью XY локальной системы координат. + \en Iloc_OnItem - object intersects the XY-plane of a local coordinate system,\n + iloc_InItem - object is located over the XY plane of a local coordinate system,\n + iloc_OutOfItem - object is located under the XY plane of a local coordinate system. \~ + */ + MbeItemLocation GetLocation( const MbPlacement3D & pl, double eps, bool onlyInItem = false ) const; + + /** + \brief \ru Определить положение объекта относительно трубы. + \en Define the object position relative to the tube. \~ + \details \ru Определить, расположен ли объект внутри трубы прямоугольного сечения, + заданного прямоугольником в плоскости XY локальной системы координат. + \en Define whether the object is inside the tube of rectangular section, + given by a rectangle in the XY plane of a local coordinate system. \~ + \param[in] place - \ru Локальная система координат, в в плоскости XY которой лежит сечение трубы. + \en A local coordinate system in the XY plane of which a tube section is located. \~ + \param[in] rect - \ru Прямоугольник, задающая сечение трубы. + \en A rectangle which defines a tube section. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \param[in] onlyInItem - \ru Интересует только положение объекта внутри трубы. + \en Whether the object position relative to the tube is interested only. \~ + \return \ru true, если объект расположен внутри трубы. + \en Returns true if the object is inside the tube. \~ + */ + bool InsideLocation( const MbPlacement3D & place, MbRect & rect, double eps ) const; + + /// \ru Перевести все объекты в треугольники и уравнять число точек и нормалей. \en Convert all objects to triangles and equalize the number of points and normals. + void ConvertAllToTriangles(); + /// \ru Общее количество всех треугольников. \en The total number of all (adjacent and nonadjacent) triangles. + size_t AllTrianglesCount() const; + /// \ru Общее количество всех четырёхугольников. \en The total number of all (adjacent and nonadjacent) quadrangles. + size_t AllQuadranglesCount() const; + /// \ru Общее количество всех точек триангуляций. \en The total number of all points of triangulations. + size_t AllPointsCount() const; + /// \ru Общее количество всех нормалей триангуляций. \en The total number of all normals of triangulations. + size_t AllNormalsCount() const; + /// \ru Общее количество всех параметров триангуляций. \en The total number of all parameters of triangulations. + size_t AllParamsCount() const; + /// \ru Общее количество всех точек полигонов. \en The total number of all points of poligons. + size_t AllPolyPointsCount() const; + /** \} */ + + /** \brief \ru Найти пересечение прямой линии и полигонального объекта. + \en Find the intersection of a straight line with the polygonal object. \~ + \details \ru Для всех треугольников определяется пересечение с прямой линии и вычисляется минимальное значение + параметра точки пересечения на секущей прямой линии. \n + \en For all the triangles the intersection with the straight line is determined and the minimum value of + the intersection point parameter on the secant straight line is calculated. \n \~ + \param[in] line - \ru Прямая линия, для которой вычисляется пересечение с и полигонального объекта. + \en Straight line to calculate the intersection of triangulation with. \~ + \param[out] crossPnt - \ru Точка пересечения. + \en The intersection point. \~ + \param[out] tRes - \ru Параметр точки пересечения на линии. + \en Parameter of the intersection point on the line. \~ + \return \ru Найдено ли пересечение (true - В случае успеха). + \en Whether the intersection is found (true if success). \~ + */ + bool LineIntersection( const MbFloatAxis3D & line, + MbFloatPoint3D & crossPnt, + float & tRes ); + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbMesh & operator = ( const MbMesh & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMesh ) +}; // MbMesh + +IMPL_PERSISTENT_OPS( MbMesh ) + +#endif // __MESH_H diff --git a/C3d/Include/mesh_float_point.h b/C3d/Include/mesh_float_point.h new file mode 100644 index 0000000..138eec2 --- /dev/null +++ b/C3d/Include/mesh_float_point.h @@ -0,0 +1,228 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерная точка полигона или триангуляции. + \en Two-dimensional point of polygon or triangulation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_FLOAT_POINT_H +#define __MESH_FLOAT_POINT_H + + +#include + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/// \ru Конвертация числа из double в float с проверкой перед присваиванием. \en Conversion of number from double to float with check before assignment. +// --- +inline float D2F( double v ) +{ + float fv = 0; + + if ( v > FLT_MAX ) + fv = FLT_MAX; + else if ( v < -FLT_MAX ) + fv = -FLT_MAX; + else if ( ::fabs(v) > FLT_EPSILON ) + fv = (float)v; + + return fv; +} + +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерная точка. + \en A two-dimensional point. \~ + \details \ru Класс MbFloatPoint служит для представления точки на плоскости, + также как аналогичный класс #MbCartPoint, который отличается более высокой + точностью представления. MbFloatPoint имеет структуру данных, состоящей из + пары чисел с плавающей точкой одинарной точности (float). Применяется в + полигоне (MbPolygon) для аппроксимации двухмерных кривых. + \en MbFloatPoint class is used to present a point on the plane, + as a similar #MbCartPoint class which has a higher + tolerance of representation. MbFloatPoint has a data structure which consists of + a pair of numbers with a single precision floating point (float). It is used in + the polygon (MbPolygon) to approximate two-dimensional curves. \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbFloatPoint { +public: + float x; ///< \ru Первая координата точки. \en A first point coordinate. + float y; ///< \ru Вторая координата точки. \en A second point coordinate. + + /// \ru Конструктор. \en Constructor. + MbFloatPoint() { x = y = 0; } + /// \ru Конструктор. \en Constructor. + MbFloatPoint( double xx, double yy ) : x( c3d::D2F(xx ) ), y( c3d::D2F(yy ) ) {} + /// \ru Конструктор. \en Constructor. + explicit MbFloatPoint( const MbCartPoint & p ) : x( c3d::D2F(p.x) ), y( c3d::D2F(p.y) ) {} + /// \ru Конструктор. \en Constructor. + explicit MbFloatPoint( const MbVector & p ) : x( c3d::D2F(p.x) ), y( c3d::D2F(p.y) ) {} + /// \ru Конструктор. \en Constructor. + MbFloatPoint( const MbFloatPoint & p ) : x( p.x ), y( p.y ) {} + +public: + + // \ru Общие функции объекта. \en Common functions of object. + void Move ( const MbVector & v ); ///< \ru Сдвиг. \en Translation. + void Rotate( const MbCartPoint &, const MbDirection & ); ///< \ru Вращение. \en Rotation. + void Transform( const MbMatrix & matr ); ///< \ru Преобразовать согласно матрице. \en Transform according to the matrix. + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + + void GetCartPoint( MbCartPoint & p ) const { p.x = x; p.y = y; } ///< \ru Выдать декартову точку. \en Get the Cartesian point. + void GetVector ( MbVector & p ) const { p.x = x; p.y = y; } ///< \ru Выдать вектор. \en Get the vector. + + void operator = ( const MbCartPoint & ); ///< \ru Присвоение точки значений. \en The assignment of values to the point. + void operator = ( const MbVector & ); ///< \ru Присвоение точки значений. \en The assignment of values to the point. + void operator = ( const MbFloatPoint & ); ///< \ru Присвоение точки значений. \en The assignment of values to the point. + + bool operator == ( const MbFloatPoint & ) const; ///< \ru Проверка на равенство. \en The check for equality. + bool operator < ( const MbFloatPoint & ) const; ///< \ru Проверка на меньше. \en The check for "less". + bool operator > ( const MbFloatPoint & ) const; ///< \ru Проверка на больше. \en The check for "greater". + + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbFloatPoint & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX(MbFloatPoint, MATH_FUNC_EX); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX(MbFloatPoint, MATH_FUNC_EX); +}; // MbFloatPoint + + +//------------------------------------------------------------------------------ +// \ru Сдвиг \en Translation +// --- +inline void MbFloatPoint::Move( const MbVector & v ) { + x += (float)v.x; + y += (float)v.y; +} + + +//------------------------------------------------------------------------------ +// \ru Вращение \en Rotation +// --- +inline void MbFloatPoint::Rotate( const MbCartPoint & c, const MbDirection & angle ) { + x -= (float)c.x; + y -= (float)c.y; + + double xx = (x * angle.ax) - (y * angle.ay); + double yy = (x * angle.ay) + (y * angle.ax); + + x = (float)( xx + c.x ); + y = (float)( yy + c.y ); +} + + +//------------------------------------------------------------------------------ +// \ru Преобразовать согласно матрице \en Transform according to the matrix +// --- +inline void MbFloatPoint::Transform( const MbMatrix & matr ) { + double xx = x * matr.El(0, 0) + y * matr.El(1, 0) + matr.El(2, 0); + double yy = x * matr.El(0, 1) + y * matr.El(1, 1) + matr.El(2, 1); + + x = (float)xx; + y = (float)yy; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assigning of values to point +// --- +inline void MbFloatPoint::operator = ( const MbCartPoint & v ) { + x = c3d::D2F(v.x); + y = c3d::D2F(v.y); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assigning of values to point +// --- +inline void MbFloatPoint::operator = ( const MbVector & v ) { + x = c3d::D2F(v.x); + y = c3d::D2F(v.y); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений вектора \en Assigning of vector values to point +// --- +inline void MbFloatPoint::operator = ( const MbFloatPoint & v ) { + x = v.x; + y = v.y; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbFloatPoint::operator == ( const MbFloatPoint & with ) const { + return ( ::fabs( x - with.x ) < Math::LengthEps ) && + ( ::fabs( y - with.y ) < Math::LengthEps ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на меньше \en Check for "less" +// --- +inline bool MbFloatPoint::operator < ( const MbFloatPoint & with ) const { + return ( x < with.x - Math::LengthEps ) || + ( ( fabs( x - with.x ) < Math::LengthEps ) && ( y < with.y - Math::LengthEps ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на больше \en The check for "greater" +// --- +inline bool MbFloatPoint::operator > ( const MbFloatPoint & with ) const { + return ( x > with.x + Math::LengthEps ) || + ( ( fabs( x - with.x ) < Math::LengthEps ) && ( y > with.y + Math::LengthEps ) ); +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор присвоения точки значений float-точки \en Constructor of assignment of float-point values to point +// --- +inline MbCartPoint::MbCartPoint( const MbFloatPoint & fp ) { + x = fp.x; + y = fp.y; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точки значений float-точки \en Assigning of float-point values to point +// --- +inline void MbCartPoint::operator = ( const MbFloatPoint & fp ) { + x = fp.x; + y = fp.y; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbFloatPoint::IsSame( const MbFloatPoint & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) ); +} + +#endif // __MESH_FLOAT_POINT_H diff --git a/C3d/Include/mesh_float_point3d.h b/C3d/Include/mesh_float_point3d.h new file mode 100644 index 0000000..4203509 --- /dev/null +++ b/C3d/Include/mesh_float_point3d.h @@ -0,0 +1,1010 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Точка, вектор и ось, основанные на числе одинарной точности (float). + \en Point, vector and axis based on single precision floating point number (float). \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_FLOAT_POINT3D_H +#define __MESH_FLOAT_POINT3D_H + +#include +#include + + +#define MB_MAXFLOAT MAXIMON // \ru Максимальное значение. \en Maximum value. + + +class MATH_CLASS MbFloatVector3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Трехмерная точка. + \en Three-dimensional point. \~ + \details \ru Класс MbFloatPoint3D служит для представления точки трехмерного + пространства, также как аналогичный класс #MbCartPoint3D, который отличается + более высокой точностью представления. MbFloatPoint3D имеет структуру данных, + состоящей из трех чисел с плавающей точкой одинарной точности (float). Применяется + для полигонального представления трехмерных геометрических объектов в таких структурах + данных, как полигон (#MbPolygon3D) или триангуляция (#MbGrid).\n + \en MbFloatPoint3D class is used for a three-dimensional point representation + as well as a similar #MbCartPoint3D class which differs + by higher precision of representation. MbFloatPoint3D has data structure + consisting of a triple of a single precision floating point numbers (float). Used + for polygonal representation of a three-dimensional geometric objects in such data structures + as polygon (#MbPolygon3D) or triangulation (#MbGrid).\n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbFloatPoint3D { +public: + float x; ///< \ru Первая координата точки. \en First coordinate of point. + float y; ///< \ru Вторая координата точки. \en Second coordinate of point. + float z; ///< \ru Третья координата точки. \en Third coordinate of point. + +public : + /** + \brief \ru Конструктор по умолчанию + \en Default constructor \~ + \details \ru Конструирует точку с координатами (0.0, 0.0, 0.0). + \en Constructs a point with coordinates (0.0, 0.0, 0.0). \~ + */ + MbFloatPoint3D(); + /// \ru Конструктор по евклидовой точке. \en Constructor by Euclidean point. + explicit MbFloatPoint3D( const MbCartPoint3D & ); + /// \ru Конструктор по радиус-вектору. \en Constructor by a radius-vector. + explicit MbFloatPoint3D( const MbVector3D & ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbFloatPoint3D( const MbFloatPoint3D & ); + /// \ru Конструктор по радиус-вектору. \en Constructor by a radius-vector. + explicit MbFloatPoint3D( const MbFloatVector3D & ); + /// \ru Конструктор. \en Constructor. + MbFloatPoint3D( double xx, double yy, double zz ); + +public: + + /** \ru \name Функции точки. + \en \name Functions of point. + \{ */ + /// \ru Инициализация по точке. \en Initialize by point. + void Init( const MbCartPoint3D & ); + /// \ru Инициализация по радиус-вектору. \en Initialization by a radius-vector. + void Init( const MbVector3D & ); + /// \ru Инициализация по координатам. \en Initialization by coordinates. + void Init( double xx, double yy, double zz ); + + // \ru Общие функции объекта. \en Common functions of object. + + void Set( const MbFloatPoint3D & v1, float t1, const MbFloatPoint3D & v2, float t2 ); + /** + \brief \ru Приравнять координаты сумме координат точки и вектора. + \en Equate coordinates to sum of point coordinates and vector coordinates. \~ + \details \ru Приравнять координаты сумме координат точки v1 и вектора v2, умноженного на число t2. + \en Equate coordinates to sum of v1 point coordinates and v2 vector coordinates multiplied by t2. \~ + \param[in] v1 - \ru Исходная точка. + \en The initial point. \~ + \param[in] v2 - \ru Исходный вектор. + \en The initial vector. \~ + \param[in] t2 - \ru Число, на которое умножаются координаты исходного вектора v2. + \en Factor the coordinates of the initial vector v2 are multiplied by. \~ + */ + MbFloatPoint3D & Set( const MbFloatPoint3D & v1, const MbFloatVector3D & v2, float t2 ); + + void Transform( const MbMatrix3D & ); ///< \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Move ( const MbVector3D & ); ///< \ru Сдвинуть вдоль вектора \en Translate along a vector. + void Rotate ( const MbAxis3D &, double angle ); ///< \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + void TransformAsVector( const MbMatrix3D & ); ///< \ru Преобразовать элемент согласно матрице как вектор (без учета смещения). \en Transform an element as vector according to the matrix (without taking translation into account). + void RotateAsVector ( const MbAxis3D &, double angle ); ///< \ru Повернуть вокруг оси на угол как вектор (без учета смещения). \en Rotate an element as a vector by an angle about an axis (without taking translation into account). + + void GetCartPoint( MbCartPoint3D &p ) const { p.x = x; p.y = y; p.z = z; } ///< \ru Выдать декартову точку \en Get the Cartesian point + void GetVector ( MbVector3D &p ) const { p.x = x; p.y = y; p.z = z; } ///< \ru Выдать вектор \en Get the vector + + void operator = ( const MbCartPoint3D & ); ///< \ru Присвоить значение точки. \en Assign values of point. + void operator = ( const MbVector3D & ); ///< \ru Присвоить значение вектора. \en Assign values of vector. + void operator = ( const MbFloatPoint3D & ); ///< \ru Присвоить значение точки. \en Assign values of point. + bool operator == ( const MbFloatPoint3D & ) const; ///< \ru Проверка на равенство. \en Check for equality. + + float DistanceToPoint ( const MbFloatPoint3D & ) const; ///< \ru Вычислить расстояние до точки. \en Calculate distance to point. + float DistanceToPoint2( const MbFloatPoint3D & ) const; ///< \ru Вычислить квадрат расстояния до точки. \en Calculate squared distance to point. + + void operator += ( const MbFloatPoint3D & ); ///< \ru Добавить координаты точки. \en Add coordinates of point. + void operator -= ( const MbFloatPoint3D & ); ///< \ru Вычесть координаты точки. \en Subtract coordinates of point. + void operator += ( const MbFloatVector3D & ); ///< \ru Добавить координаты вектора. \en Add coordinates of vector. + void operator -= ( const MbFloatVector3D & ); ///< \ru Вычесть координаты вектора. \en Subtract coordinates of vector. + + MbFloatPoint3D operator + ( const MbFloatVector3D &vector ) const; ///< \ru Сложение точки и вектора. \en Addition of point and vector. + MbFloatPoint3D operator - ( const MbFloatVector3D &vector ) const; ///< \ru Вычитание вектора из точки. \en Subtraction of vector from point. + MbFloatVector3D operator + ( const MbFloatPoint3D &pnt ) const; ///< \ru Сложение двух точек. \en Addition of two points. + MbFloatVector3D operator - ( const MbFloatPoint3D &pnt ) const; ///< \ru Вычитание двух точек. \en Subtraction of two points. + + /// \ru Выдать координату по её номеру. \en Get coordinate by its index. + float & operator[](size_t i) { C3D_ASSERT( i < 3 ); return (&x)[i]; } + /// \ru Выдать координату по её номеру. \en Get coordinate by its index. + float operator[](size_t i) const { C3D_ASSERT( i < 3 ); return (&x)[i]; } + + /// \ru Равны ли координаты нулю с указанной точностью. \en Whether coordinates is equal to zero with specified tolerance. + bool IsZero ( double eps = Math::lengthEpsilon ) const { return fabs(x) < eps && + fabs(y) < eps && + fabs(z) < eps; } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbFloatPoint3D & other, double accuracy ) const; + + /** \} */ + DECLARE_NEW_DELETE_CLASS( MbFloatPoint3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbFloatPoint3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX(MbFloatPoint3D, MATH_FUNC_EX); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX(MbFloatPoint3D, MATH_FUNC_EX); +}; // MbFloatPoint3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Трехмерный вектор. + \en Three-dimensional vector. \~ + \details \ru Трехмерный вектор, как тип данных, похож на #MbVector3D, однако основан + на более грубом представлении числа с плавающей точкой. Применяется в + структурах данных триангуляции (MbGrid) для аппроксимированного + представления объектов. \n + \en Three-dimensional vector as data type is similar to #MbVector3D, however based + on more rough floating point number representation. It is used in + such data structures as triangulation (MbGrid) for approximated + representation of objects. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbFloatVector3D { +public: + float x; ///< \ru Первая компонента вектора. \en First component of vector. + float y; ///< \ru Вторая компонента вектора. \en Second component of vector. + float z; ///< \ru Третья компонента вектора. \en Third component of vector. + +public: + /// \ru Конструктор. \en Constructor. + MbFloatVector3D(); + /// \ru Конструктор. \en Constructor. + explicit MbFloatVector3D( const MbCartPoint3D & ); + /// \ru Конструктор. \en Constructor. + explicit MbFloatVector3D( const MbFloatPoint3D & ); + /// \ru Конструктор. \en Constructor. + explicit MbFloatVector3D( const MbVector3D & ); + /// \ru Конструктор. \en Constructor. + MbFloatVector3D( const MbFloatVector3D & ); + /// \ru Конструктор по разнице пары точек: this = p2 - p1. \en Constructor by difference of two points: this = p2 - p1. + MbFloatVector3D( const MbFloatPoint3D & p1, const MbFloatPoint3D & p2 ) : x( p2.x - p1.x ), y( p2.y - p1.y ), z( p2.z - p1.z ) {} + /// \ru Конструктор по координатам. \en Constructor by coordinates. + MbFloatVector3D( float xx, float yy, float zz ); + /// \ru Деструктор. \en Destructor. + ~MbFloatVector3D() {} + +public: + + /** \ru \name Функции вектора. + \en \name Functions of vector. + \{ */ + /// \ru Инициализация по координатам. \en Initialization by coordinates. + void Init( float a, float b, float c ) { x = a; y = b; z = c; } + /// \ru Инициализация по точке. \en Initialize by point. + void Init( const MbFloatPoint3D & p ) { x = p.x; y = p.y; z = p.z; } + /// \ru Инициализация по точкам. \en Initialize by points. + void Init( const MbFloatPoint3D & p1, const MbFloatPoint3D & p2 ); + /// \ru Инициализация по вектору. \en Initialize by vector. + void Init( const MbFloatVector3D & v ) { x = v.x; y = v.y; z = v.z; } + /// \ru Задать векторное произведение двух заданных векторов. \en Set vector product of two given vectors. + void SetVecM( const MbFloatVector3D & vF, const MbFloatVector3D & vS ) { + x = vF.y * vS.z - vF.z * vS.y; + y = vF.z * vS.x - vF.x * vS.z; + z = vF.x * vS.y - vF.y * vS.x; + } + + /// \ru Инициализация по сумме векторов с коэффициентами. \en Initialize by sum of vectors with coefficients + void Set( const MbFloatVector3D &v1, float t1, const MbFloatVector3D &v2, float t2 ); + /// \ru Инициализация по сумме точек с коэффициентами. \en Initialize by sum of points with coefficients + void Set( const MbFloatPoint3D &v1, float t1, const MbFloatPoint3D &v2, float t2 ); + + void Transform( const MbMatrix3D & ); ///< \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Rotate ( const MbAxis3D &, double angle ); ///< \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + bool Normalize(); ///< \ru Нормализовать вектор. \en Normalize a vector. + void Invert(); ///< \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite. + + float Length () const; ///< \ru Длина вектора. \en Length of vector. + float Length2() const; ///< \ru Квадрат длины вектора. \en Squared length of vector. + + MbFloatVector3D operator - () const; ///< \ru Оператор вычитания векторов. \en Operator of subtraction of vectors. + + MbFloatVector3D operator + ( const MbFloatVector3D & vector ) const; ///< \ru Сложение двух векторов; результат - вектор. \en Addition of two vectors; result is vector. + MbFloatVector3D operator - ( const MbFloatVector3D & vector ) const; ///< \ru Вычитание двух векторов; результат - вектор. \en Subtraction of two vectors; result is vector. + + MbFloatVector3D operator + ( const MbFloatPoint3D & pnt ) const; ///< \ru Сложение вектора и точки. \en Addition of vector and point. + MbFloatVector3D operator - ( const MbFloatPoint3D & pnt ) const; ///< \ru Вычитание из вектора точки. \en Subtraction of point from vector. + + MbFloatVector3D & operator += ( const MbFloatVector3D & vector ); ///< \ru Добавить вектор. \en Add a vector. + MbFloatVector3D & operator -= ( const MbFloatVector3D & vector ); ///< \ru Вычесть вектор. \en Subtract a vector. + + MbFloatVector3D & operator *= ( float f ); ///< \ru Умножить на коэффициент. \en Multiply by a factor. + MbFloatVector3D & operator /= ( float f ); ///< \ru Делить на коэффициент. \en Divide by a factor. + + void operator = ( const MbCartPoint3D & ); ///< \ru Присвоить значение точки. \en Assign values of point. + void operator = ( const MbVector3D & ); ///< \ru Присвоить значение вектора. \en Assign values of vector. + void operator = ( const MbFloatPoint3D & ); ///< \ru Присвоить значение точки. \en Assign values of point. + bool operator == ( const MbFloatVector3D & vector ) const; ///< \ru Проверить на равенство. \en + + float operator * ( const MbFloatVector3D & vector ) const; ///< \ru Скалярное умножение двух векторов. \en Dot-product of two vectors. + MbFloatVector3D operator | ( const MbFloatVector3D & vector ) const; ///< \ru Векторное умножение двух векторов. \en Vector-product of two vectors. + + float & operator[](size_t i) { C3D_ASSERT( i < 3 ); return (&x)[i]; } + float operator[](size_t i) const { C3D_ASSERT( i < 3 ); return (&x)[i]; } + + /// \ru Равен ли вектор нулю с указанной точностью. \en Whether vector is equal to zero with specified tolerance. + bool IsZero ( double eps = Math::lengthEpsilon ) const { return fabs(x) < eps && + fabs(y) < eps && + fabs(z) < eps; } + /// \ru Выдать вектор (по аналогии с MbFloatPoint3D). \en Get vector (by analogy with MbFloatPoint3D). + void GetVector( MbVector3D & p ) const { p.x = x; p.y = y; p.z = z; } + + float MaxFactor() const; ///< \ru Выдать максимальную по модулю компонент вектора. \en Get the largest absolute value of a vector. + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbFloatVector3D & other, double accuracy ) const; + + /** \} */ + DECLARE_NEW_DELETE_CLASS( MbFloatVector3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbFloatVector3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX(MbFloatVector3D, MATH_FUNC_EX); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX(MbFloatVector3D, MATH_FUNC_EX); +}; // MbFloatVector3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Ось. + \en Axis. \~ + \details \ru Ось представляет собой вектор, привязанный к фиксированной точке. \n + \en Axis represents the vector attached to the fixed point. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbFloatAxis3D +{ + MbFloatPoint3D origin; ///< \ru Положение начала. \en Position of the origin. + MbFloatVector3D axisZ; ///< \ru Направление оси (вектор единичной длины). \en Axis direction (unit length vector). + +public : + /// \ru Пустой конструктор, ось расположена в начале глобальных координат и совпадает с третьей осью глобальных координат. \en Empty constructor. The axis is in the origin of global coordinates and coincides with the third axis of global coordinates. + MbFloatAxis3D(); + /// \ru Конструктор по точке и вектору. \en Constructor by a point and a vector. + MbFloatAxis3D( const MbFloatPoint3D & initOrigin, const MbFloatVector3D & initAxisZ ); + /// \ru Конструктор по точке и вектору. \en Constructor by a point and a vector. + explicit MbFloatAxis3D( const MbCartPoint3D & initOrigin, const MbVector3D & initAxisZ ); + /// \ru Конструктор по двум точкам. \en Constructor by two points. + MbFloatAxis3D( const MbFloatPoint3D & initOrigin, const MbFloatPoint3D & initPoint ); + /// \ru Конструктор по другой оси. \en Constructor by another axis. + MbFloatAxis3D( const MbFloatAxis3D & initAxis ); + /// \ru Конструктор по другой оси. \en Constructor by another axis. + explicit MbFloatAxis3D( const MbAxis3D & initAxis ); + /// \ru Деструктор \en Destructor + ~MbFloatAxis3D(); + +public : + + /// \ru Инициализация по другой оси. \en The initialization by another axis. + void Init( const MbFloatAxis3D & initAxis ); + /// \ru Инициализация по точке и вектору. \en The initialization by a point and a vector. + void Init( const MbFloatPoint3D & initOrigin, const MbFloatVector3D & initAxisZ ); + /// \ru Инициализация по точке и вектору. \en The initialization by a point and a vector. + void Init( const MbCartPoint3D & initOrigin, const MbVector3D & initAxisZ ); + /// \ru Инициализация по двум точкам. \en The initialization by two points. + void Init( const MbFloatPoint3D & initOrigin, const MbFloatPoint3D & initPoint ); + + /** \ru \name Функции трехмерного объекта + \en \name Functions of a three-dimensional object + \{ */ + void Transform( const MbMatrix3D & ); ///< \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Move ( const MbVector3D & ); ///< \ru Сдвинуть вдоль вектора \en Translate along a vector. + void Rotate ( const MbAxis3D &, double angle ); ///< \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + MbFloatAxis3D & Duplicate() const; ///< \ru Сделать копию элемента. \en Create a copy of the element. + float DistanceToPoint( const MbFloatPoint3D & ) const; ///< \ru Вычислить расстояние до точки. \en Calculate distance to point. + float DistanceToSegment( const MbFloatPoint3D & p1, const MbFloatPoint3D & p2 ) const; ///< \ru Вычислить расстояние до отрезка. \en Calculate distance to segment. + bool PointProjection( const MbFloatPoint3D & pnt, float & tRes ) const; ///< \ru Вычислить проекцию точки на ось. \en Calculate point projection to the exis. + /** \} */ + + /** \ru \name Функции доступа к полям. + \en \name Functions for access to fields. + \{ */ + const MbFloatPoint3D & GetOrigin() const { return origin; } ///< \ru Получить начало оси. \en Get origin of axis. + const MbFloatVector3D & GetAxisZ () const { return axisZ; } ///< \ru Получить вектор оси. \en Get vector of axis. + MbFloatPoint3D & SetOrigin() { return origin; } ///< \ru Изменить начало оси. \en Change origin of axis. + MbFloatVector3D & SetAxisZ () { return axisZ; } ///< \ru Изменить вектор оси. \en Change vector of axis. + + MbFloatAxis3D & operator = ( const MbFloatAxis3D & init ) { origin = init.origin; axisZ = init.axisZ; return *this; } ///< \ru Присвоение значений. \en Assignment of values. + /** \} */ + /// \ru Являются ли объекты равными? \en Are the objects equal? + bool IsSame( const MbFloatAxis3D & other, double accuracy ) const; + /// \ru Дать пространственную точку по параметру на оси. \en Get the space point by a parameter on axis. + void PointOn( const float & t, MbFloatPoint3D & p ) const { p.Set( origin, axisZ, t ); } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbFloatAxis3D, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbFloatAxis3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbFloatAxis3D ) +}; // MbFloatAxis3D + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Трехмерная точка полигона. \en A three-dimensional point of a polygon. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbFloatPoint3D::MbFloatPoint3D() + : x( 0.0 ) + , y( 0.0 ) + , z( 0.0 ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +inline MbFloatPoint3D::MbFloatPoint3D( const MbCartPoint3D & p ) + : x( (float)p.x ) + , y( (float)p.y ) + , z( (float)p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatPoint3D::MbFloatPoint3D( const MbVector3D & p ) + : x( (float)p.x ) + , y( (float)p.y ) + , z( (float)p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatPoint3D::MbFloatPoint3D( const MbFloatPoint3D & p ) + : x( p.x ) + , y( p.y ) + , z( p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatPoint3D::MbFloatPoint3D( const MbFloatVector3D & p ) + : x( p.x ) + , y( p.y ) + , z( p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatPoint3D::MbFloatPoint3D( double xx, double yy, double zz ) + : x( (float)xx ) + , y( (float)yy ) + , z( (float)zz ) +{} + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbFloatPoint3D::Init( const MbCartPoint3D & p ) { + x = (float)p.x; y = (float)p.y; z = (float)p.z; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbFloatPoint3D::Init( const MbVector3D & p ) { + x = (float)p.x; y = (float)p.y; z = (float)p.z; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbFloatPoint3D::Init( double xx, double yy, double zz ) { + x = (float)xx; y = (float)yy; z = (float)zz; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbFloatPoint3D::Set( const MbFloatPoint3D & v1, float t1, + const MbFloatPoint3D & v2, float t2 ) +{ + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline MbFloatPoint3D & MbFloatPoint3D::Set( const MbFloatPoint3D & v1, const MbFloatVector3D & v2, float t2 ) +{ + x = v1.x + v2.x * t2; + y = v1.y + v2.y * t2; + z = v1.z + v2.z * t2; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Сдвиг \en Translation +// --- +inline void MbFloatPoint3D::Move( const MbVector3D & to ) +{ + x += (float)to.x; + y += (float)to.y; + z += (float)to.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assignment of values to point +// --- +inline void MbFloatPoint3D::operator = ( const MbCartPoint3D & v ) +{ + x = (float)v.x; + y = (float)v.y; + z = (float)v.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assignment of values to point +// --- +inline void MbFloatPoint3D::operator = ( const MbVector3D & v ) +{ + x = (float)v.x; + y = (float)v.y; + z = (float)v.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений вектора \en Assignment of vector values to point +// --- +inline void MbFloatPoint3D::operator = ( const MbFloatPoint3D & v ) +{ + x = v.x; + y = v.y; + z = v.z; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка на равенство \en Check for equality +// --- +inline bool MbFloatPoint3D::operator == ( const MbFloatPoint3D & with ) const +{ + return IsSame( with, Math::lengthEpsilon ); +} + + +//------------------------------------------------------------------------------ +// \ru Квадрат расстояния от точки до точки \en Squared distance from point to point +// --- +inline float MbFloatPoint3D::DistanceToPoint2( const MbFloatPoint3D & to ) const +{ + float coordDiff[3] = { ( x - to.x ), ( y - to.y ), ( z - to.z ) }; + coordDiff[0] *= coordDiff[0]; + coordDiff[1] *= coordDiff[1]; + coordDiff[2] *= coordDiff[2]; + return coordDiff[0] + coordDiff[1] + coordDiff[2]; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить коoрдинаты точки \en Add coordinates of point +// --- +inline void MbFloatPoint3D::operator += ( const MbFloatPoint3D & with ) +{ + x += with.x; + y += with.y; + z += with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Вычесть коoрдинаты точки \en Subtract coordinates of point +// --- +inline void MbFloatPoint3D::operator -= ( const MbFloatPoint3D & with ) +{ + x -= with.x; + y -= with.y; + z -= with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить коoрдинаты \en Add coordinates +// --- +inline void MbFloatPoint3D::operator += ( const MbFloatVector3D & with ) +{ + x += with.x; + y += with.y; + z += with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Вычесть коoрдинаты \en Subtract coordinates +// --- +inline void MbFloatPoint3D::operator -= ( const MbFloatVector3D & with ) +{ + x -= with.x; + y -= with.y; + z -= with.z; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение точки на число \en Multiplication of a point by a factor +// --- +inline MbFloatPoint3D operator * ( const MbFloatPoint3D &pnt, float factor ) { + return MbFloatPoint3D( pnt.x * factor, pnt.y * factor, pnt.z * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Деление точки на число \en Division of a point by a factor +// --- +inline MbFloatPoint3D operator / ( const MbFloatPoint3D & pnt, float factor ) +{ + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division is 5.7 times slower than multiplication + C3D_ASSERT( ::fabs(factor) > NULL_EPSILON ); + float invFactor = (float)( 1.0 / factor ); + return MbFloatPoint3D( pnt.x * invFactor, pnt.y * invFactor, pnt.z * invFactor ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение точки на число \en Multiplication of a point by a factor +// --- +inline MbFloatPoint3D operator * ( float factor, const MbFloatPoint3D & pnt ) { + return MbFloatPoint3D( pnt.x * factor, pnt.y * factor, pnt.z * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение точки и вектора \en Sum of a vector and a point +// --- +inline MbFloatPoint3D MbFloatPoint3D::operator + ( const MbFloatVector3D & vector ) const { + return MbFloatPoint3D( x + vector.x, y + vector.y, z + vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание вектора из точки \en Subtraction of a vector from a point +// --- +inline MbFloatPoint3D MbFloatPoint3D::operator - ( const MbFloatVector3D & vector ) const { + return MbFloatPoint3D( x - vector.x, y - vector.y, z - vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух точек \en Sum of two points +// --- +inline MbFloatVector3D MbFloatPoint3D::operator + ( const MbFloatPoint3D & pnt ) const { + return MbFloatVector3D( x + pnt.x, y + pnt.y, z + pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух точек \en Subtraction of two points +// --- +inline MbFloatVector3D MbFloatPoint3D::operator - ( const MbFloatPoint3D & pnt ) const { + return MbFloatVector3D( x - pnt.x, y - pnt.y, z - pnt.z ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbFloatPoint3D::IsSame( const MbFloatPoint3D & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(z - other.z) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Трехмерный вектор нормали триангуляции. \en Three-dimensional vector of triangulation normal. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatVector3D::MbFloatVector3D() + : x( 0.0 ) + , y( 0.0 ) + , z( 0.0 ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatVector3D::MbFloatVector3D( const MbCartPoint3D & p ) + : x( (float)p.x ) + , y( (float)p.y ) + , z( (float)p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatVector3D::MbFloatVector3D( const MbFloatPoint3D & p ) + : x( p.x ) + , y( p.y ) + , z( p.z ) +{} + + +//------------------------------------------------------------------------------ +// конструктор +// --- +inline MbFloatVector3D::MbFloatVector3D( const MbVector3D & p ) + : x( (float)p.x ) + , y( (float)p.y ) + , z( (float)p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatVector3D::MbFloatVector3D( const MbFloatVector3D & p ) + : x( p.x ) + , y( p.y ) + , z( p.z ) +{} + + +//------------------------------------------------------------------------------ +// \ru Конструктор \en Constructor +// --- +inline MbFloatVector3D::MbFloatVector3D( float xx, float yy, float zz ) + : x( xx ) + , y( yy ) + , z( zz ) +{} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по двум точкам \en Initialization by two points +// --- +inline void MbFloatVector3D::Init( const MbFloatPoint3D & p1, const MbFloatPoint3D & p2 ) { + x = p2.x - p1.x; + y = p2.y - p1.y; + z = p2.z - p1.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbFloatVector3D::Set( const MbFloatVector3D & v1, float t1, + const MbFloatVector3D & v2, float t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение значений \en Values assignment +// --- +inline void MbFloatVector3D::Set( const MbFloatPoint3D & v1, float t1, + const MbFloatPoint3D & v2, float t2 ) { + x = v1.x * t1 + v2.x * t2; + y = v1.y * t1 + v2.y * t2; + z = v1.z * t1 + v2.z * t2; +} + + +//------------------------------------------------------------------------------ +// \ru Сложение двух векторов; результат - вектор \en Addition of two vectors; result is a vector +// --- +inline MbFloatVector3D MbFloatVector3D::operator + ( const MbFloatVector3D & vector ) const { + return MbFloatVector3D( x + vector.x, y + vector.y, z + vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание двух векторов; результат - вектор \en Subtraction of two vectors; result is a vector +// --- +inline MbFloatVector3D MbFloatVector3D::operator - ( const MbFloatVector3D & v2 ) const { + return MbFloatVector3D ( x - v2.x, y - v2.y, z - v2.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Сложение вектора и точки \en Addition of a vector and a point +// --- +inline MbFloatVector3D MbFloatVector3D::operator + ( const MbFloatPoint3D & pnt ) const { + return MbFloatVector3D( x + pnt.x, y + pnt.y, z + pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычитание из вектора точки \en Subtraction of a point from a vector +// --- +inline MbFloatVector3D MbFloatVector3D::operator - ( const MbFloatPoint3D & pnt ) const { + return MbFloatVector3D( x - pnt.x, y - pnt.y, z - pnt.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Унарный минус \en Unary minus +// --- +inline MbFloatVector3D MbFloatVector3D::operator - () const { + return MbFloatVector3D ( - x, - y, - z ); +} + + +//------------------------------------------------------------------------------ +// \ru Увеличение вектора \en Increase vector +// --- +inline MbFloatVector3D & MbFloatVector3D::operator += ( const MbFloatVector3D & v ) { + x += v.x; y += v.y; z += v.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Уменьшение вектора \en Decrease vector +// --- +inline MbFloatVector3D & MbFloatVector3D::operator -= ( const MbFloatVector3D & v ) { + x -= v.x; y -= v.y; z -= v.z; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiplication of a vector by a factor +// --- +inline MbFloatVector3D & MbFloatVector3D::operator *= ( float f ) { + x *= f; y *= f; z *= f; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Деление вектора на число \en Division of a vector by a factor +// --- +inline MbFloatVector3D & MbFloatVector3D::operator /= ( float f ) +{ + C3D_ASSERT( ::fabs(f) > NULL_EPSILON ); + f = (float)( 1.0 / f ); + x *= f; y *= f; z *= f; + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Скалярное умножение двух векторов \en Dot-product of two vectors +// --- +inline float MbFloatVector3D::operator * ( const MbFloatVector3D & vector ) const { + return ( x * vector.x + y * vector.y + z * vector.z ); +} + + +//------------------------------------------------------------------------------ +// \ru Векторное умножение двух векторов \en Vector-product of two vectors +// --- +inline MbFloatVector3D MbFloatVector3D::operator | ( const MbFloatVector3D & vect2 ) const { + return MbFloatVector3D( y * vect2.z - z * vect2.y, + z * vect2.x - x * vect2.z, + x * vect2.y - y * vect2.x ); +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assignment of values to point +// --- +inline void MbFloatVector3D::operator = ( const MbCartPoint3D & v ) +{ + x = (float)v.x; + y = (float)v.y; + z = (float)v.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений \en Assignment of values to point +// --- +inline void MbFloatVector3D::operator = ( const MbVector3D & v ) +{ + x = (float)v.x; + y = (float)v.y; + z = (float)v.z; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоение точке значений вектора \en Assignment of vector values to point +// --- +inline void MbFloatVector3D::operator = ( const MbFloatPoint3D & v ) +{ + x = v.x; + y = v.y; + z = v.z; +} + + +//------------------------------------------------------------------------------ +// Проверить на равенство. +// --- +inline bool MbFloatVector3D::operator == ( const MbFloatVector3D & with ) const { + return IsSame( with, Math::region ); +} + + +//------------------------------------------------------------------------------ +// \ru Длина вектора \en Length of vector +// --- +inline float MbFloatVector3D::Length () const { + return (float)sqrt( Length2() ); +} + + +//------------------------------------------------------------------------------ +// \ru Квадрат длины вектора \en Squared length of vector +// --- +inline float MbFloatVector3D::Length2() const { + return x * x + y * y + z * z; +} + + +//------------------------------------------------------------------------------ +// \ru Нормализация вектора \en Normalize a vector +// --- +inline bool MbFloatVector3D::Normalize() +{ + double len = Length(); + bool res = ( len >= NULL_EPSILON ); + if ( res && ::fabs( len - 1.0 ) > NULL_EPSILON ) { + double one_len = 1.0 / len; + x *= (float)one_len; + y *= (float)one_len; + z *= (float)one_len; + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiplication of a vector by a factor +// --- +inline MbFloatVector3D operator * ( const MbFloatVector3D &vector, float factor ) { + return MbFloatVector3D( vector.x * factor, vector.y * factor, vector.z * factor ); +} + + +//------------------------------------------------------------------------------ +// \ru Деление вектора на число \en Division of a vector by a factor +// --- +inline MbFloatVector3D operator / ( const MbFloatVector3D & vector, float factor ) { + // \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division is 5.7 times slower than multiplication + C3D_ASSERT( ::fabs(factor) > NULL_EPSILON ); + float invFactor = (float)( 1.0 / factor ); + return MbFloatVector3D( vector.x * invFactor, vector.y * invFactor, vector.z * invFactor ); +} + + +//------------------------------------------------------------------------------ +// \ru Умножение вектора на число \en Multiplication of a vector by a factor +// --- +inline MbFloatVector3D operator * ( float factor, const MbFloatVector3D &vector ) { + return vector * factor; +} + + +//------------------------------------------------------------------------------ +// \ru Сменить направление вектора на противоположное \en Change vector direction to the opposite one +// --- +inline void MbFloatVector3D::Invert() +{ + x = - x; + y = - y; + z = - z; +} + + +//------------------------------------------------------------------------------- +// \ru Максимальная по модулю компонента вектора \en The largest absolute value of a vector +// --- +inline float MbFloatVector3D::MaxFactor() const +{ + float ax = ::fabs( x ); + float ay = ::fabs( y ); + float az = ::fabs( z ); + return ( ((ax > ay) && (ax > az)) ? ax : ((ay > az) ? ay : az) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbFloatVector3D::IsSame( const MbFloatVector3D & other, double accuracy ) const +{ + return ( (::fabs(x - other.x) < accuracy) && + (::fabs(y - other.y) < accuracy) && + (::fabs(z - other.z) < accuracy) ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Ось. \en The axis. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Являются ли объекты равными? + \en Are the objects equal? \~ + \details \ru Равными считаются объекты, данные которых равны с заданной точностью. + \en The objects are equal if their data are equal with a given accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. +*/ +inline bool MbFloatAxis3D::IsSame( const MbFloatAxis3D & other, double accuracy ) const +{ + return ( origin.IsSame( other.origin, accuracy ) && + axisZ.IsSame( other.axisZ, accuracy ) ); +} + + +#endif // __MESH_FLOAT_POINT3D_H diff --git a/C3d/Include/mesh_grid.h b/C3d/Include/mesh_grid.h new file mode 100644 index 0000000..5e37c7b --- /dev/null +++ b/C3d/Include/mesh_grid.h @@ -0,0 +1,902 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Tриангуляция. + \en Triangulation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_GRID_H +#define __MESH_GRID_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbRect; + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Триангуляция на числах double. + \en Triangulation on double data. \~ + \details \ru Триангуляция представляет собой набор треугольных и четырёхугольных пластин, стыкующихся друг с другом по общим сторонам.\n + Триангуляция состоит из согласованных наборов точек, нормалей, параметров триангулируемой поверхности и наборов треугольников и четырехугольников. + Каждый треугольник - это три номера из набора точек, определяющих вершины треугольника, каждый четырехугольник - это четыре номера из набора точек, определяющих вершины четырехугольника. \n + \en Triangulation represents a set of triangular and quadrangular plates which are joined to each other by their common sides.\n + The triangulation consists of a sets of points, normals, surface parameters and a sets of triangles and quadrangles. + The triangle is represented as three indices from the set of points defining vertices of triangle, the quadrangle is represented as four indices from the set of points defining vertices of quadrangle.\n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbExactGrid : public MbGrid { +private: + std::vector points; ///< \ru Множество контрольных точек триангуляции (согласовано с множеством параметров, если последнее не пустое, или пусто, если не пусто множество параметров). \en Set of control points of triangulation (synchronized with set of parameters if the last is not empty, or empty if the set of parameters isn't empty). + std::vector normals; ///< \ru Множество нормалей в контрольных точках согласовано с множеством контрольных точек. \en Set of normals at control points is synchronized with the set of control points. + std::vector params; ///< \ru Множество параметров - двумерных точек на параметрической области триангулируемой поверхности (может быть пустым). \en Set of parameters of two-dimensional points in parametric domain of surface being triangulated(can be empty). + std::vector escorts; ///< \ru Множество значений для дополнительной информации в точках. \en The set of values for additional information of points. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbExactGrid( const MbExactGrid & init ); + // \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbExactGrid( const MbExactGrid & init, MbRegDuplicate * iReg ); +public: + // \ru Конструктор без параметров. \en Constructor without parameters. + MbExactGrid(); + // \ru Деструктор. \en Destructor. + virtual ~MbExactGrid(); + +public: + + // \ru \name Общие функции примитива. \en \name Common functions of primitive. + + virtual MbePrimitiveType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbExactGrid & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ); // \ru Преобразовать сетку согласно матрице. \en Transform mesh according to the matrix. + virtual void Move ( const MbVector3D & to ); // \ru Сдвиг сетки. \en Move mesh. + virtual void Rotate ( const MbAxis3D & axis, double angle ); // \ru Поворот сетки вокруг оси. \en Rotation of mesh about an axis. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & pnt ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual double DistanceToLine( const MbAxis3D & axis, double maxDistance, double & t ) const; // \ru Вычислить расстояние до оси. \en Calculate the distance to an axis. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru Выдать количество точек. \en Get the number of points. + virtual size_t PointsCount() const { return points.size(); } + // \ru Выдать количество нормалей. \en Get the number of normals. + virtual size_t NormalsCount() const { return normals.size(); } + // \ru Выдать количество параметров. \en Get the number of parameters. + virtual size_t ParamsCount() const { return params.size(); } + // \ru Выдать количество значений. \en Get count of values. + virtual size_t EscortsCount() const { return escorts.size(); } + // \ru Выдать количество точек минус 1 (максимальный индекс). \en Get the number of points minus one (maximal index). + virtual ptrdiff_t PointsMaxIndex() const { ptrdiff_t n = points.size(); return ( n - 1 ); } + // \ru Выдать количество нормалей минус 1 (максимальный индекс). \en Get the number of normals minus one (maximal index). + virtual ptrdiff_t NormalsMaxIndex() const { ptrdiff_t n = normals.size(); return ( n - 1 ); } + // \ru Выдать количество параметров минус 1 (максимальный индекс). \en Get the number of parameters minus one (maximal index). + virtual ptrdiff_t ParamsMaxIndex() const { ptrdiff_t n = params.size(); return ( n - 1 ); } + + // \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D, const MbVector3D & n3D ); + // \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D ); + // \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D, const MbVector3D & n3D ); + // \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D ); + // \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbVector3D & n3D ); + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam ( const MbCartPoint & p2D ); + + // \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D ); + // \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint( const MbFloatPoint3D & p3D ); + // \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam( const MbFloatPoint & p2D ); + + // \ru Добавить в триангуляцию точки. \en Add points to triangulation. + template + void AddPoints ( const PointsVector & pnts ) { + size_t addCnt = pnts.size(); + points.reserve( points.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + points.push_back( pnts[k] ); + } + // \ru Добавить в триангуляцию нормали. \en Add normals to triangulation. + template + void AddNormals( const NormalsVector & nrms ) { + size_t addCnt = nrms.size(); + normals.reserve( normals.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + normals.push_back( nrms[k] ); + } + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + template + void AddParams( const ParamsVector & prms ) { + size_t addCnt = prms.size(); + params.reserve( params.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + params.push_back( prms[k] ); + } + + // \ru Добавить в коллекцию данных. \en Add scores to collection. + virtual void AddEscorts( const std::vector & scores ) { escorts.insert(escorts.end(), scores.begin(), scores.end()); } + + // \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbCartPoint3D & p ) const; + // \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbVector3D & n ) const; + // \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbCartPoint & p ) const; + // \ru Выдать дополнительную информацию по её номеру. \en Get additional information by its index. + virtual const uint32 & GetEscort( size_t i ) const; + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbFloatPoint3D & p ) const; + /// \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbFloatVector3D & n ) const; + /// \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbFloatPoint & p ) const; + + // \ru Выдать точку с заданным номером. \en Get point by the given index. + const MbCartPoint3D & GetPoint ( size_t i ) const; + // \ru Выдать нормаль с заданным номером. \en Get normal by the given index. + const MbVector3D & GetNormal( size_t i ) const; + // \ru Выдать параметр с заданным номером. \en Get parameter by the given index. + const MbCartPoint & GetParam ( size_t i ) const; + + // \ru Установить точку с заданным номером. \en Set point by the given index. + virtual void SetPoint ( size_t i, const MbCartPoint3D & p ); + // \ru Установить нормаль с заданным номером. \en Set normal by the given index. + virtual void SetNormal( size_t i, const MbVector3D & n ); + // \ru Установить параметр с заданным номером. \en Set parameter by the given index. + virtual void SetParam ( size_t i, const MbCartPoint & p ); + // \ru Установить дополнительную информацию по её номеру. \en Set additional information by its index. + virtual void SetEscort( size_t i, const uint32 & e ); + + // \ru Удалить точку с заданным номером. \en Delete point by the given index. + virtual void PointRemove ( size_t i ); + // \ru Удалить нормаль с заданным номером. \en Delete normal by the given index. + virtual void NormalRemove( size_t i ); + // \ru Удалить параметры поверхности с заданным номером. \en Delete parameters of surface by the given index. + virtual void ParamRemove ( size_t i ); + + // \ru Удалить точки. \en Delete points. + virtual void PointsDelete(); + // \ru Удалить нормали. \en Delete normal. + virtual void NormalsDelete(); + // \ru Удалить параметры. \en Delete papams. + virtual void PapamsDelete(); + // \ru Удалить дополнительную информацию. \en Delete additional information. + virtual void EscortsDelete(); + + /// \ru Инвертировать нормали. \en Invert normals. + virtual void NormalsInvert(); + + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th triangle in general numbering (with strips). + virtual bool GetTriangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D & n2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2 ) const; + + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2, MbCartPoint & r3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2, MbCartPoint3D & p3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2, MbFloatPoint3D & n3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D &n2, MbVector3D & n3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2, MbFloatVector3D & n3 ) const; + + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbVector3D & ) const; + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbFloatVector3D & ) const; + // \ru Если количество точек больше количества нормалей, то добавить недостающие нормали (только для плоской триангуляции). \en If count of points is greater than count of normals, then add missing normals (only for planar triangulation). + virtual void SynchronizNormals (); + + // \ru Выдать контейнер параметров. \en Get the container of parameters. + template + void GetParams( ParamsVector & paramsVector ) const { + paramsVector.reserve( paramsVector.size() + params.size() ); + for ( size_t i = 0, iCount = params.size(); i < iCount; i++ ) + paramsVector.push_back( params[i] ); + } + // \ru Выдать контейнер точек. \en Get the container of points. + template + void GetPoints( PointsVector & pointsVector ) const { + pointsVector.reserve( pointsVector.size() + points.size() ); + for ( size_t i = 0, iCount = points.size(); i < iCount; i++ ) + pointsVector.push_back( points[i] ); + } + // \ru Выдать контейнер нормалей. \en Get the container of normals. + template + void GetNormals( NormalsVector & normalsVector ) const { + normalsVector.reserve( normalsVector.size() + normals.size() ); + for ( size_t i = 0, iCount = normals.size(); i < iCount; i++ ) + normalsVector.push_back( normals[i] ); + } + + // \ru Расширить присланный габаритный прямоугольник так, чтобы он включал в себя проекцию данного объекта на глобальную плоскость XY. \en Extend given bounding box so that it enclose projection of this object to the global XY-plane. + virtual void AddRect( MbRect & rect ) const; + // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual void AddCube( MbCube & r ) const; + + // \ru Определить, пересекается ли проекция на глобальную плоскость XY треугольника с заданным номером с присланным прямоугольником. \en Determine whether the projection of triangle with a given index to the global XY-plane intersects the given rectangle. + bool TriangleIntersectRect( size_t i, MbRect & rect ) const { return (i points; ///< \ru Множество контрольных точек триангуляции (согласовано с множеством параметров, если последнее не пустое, или пусто, если не пусто множество параметров). \en Set of control points of triangulation (synchronized with set of parameters if the last is not empty, or empty if the set of parameters isn't empty). + std::vector normals; ///< \ru Множество нормалей в контрольных точках согласовано с множеством контрольных точек. \en Set of normals at control points is synchronized with the set of control points. + std::vector params; ///< \ru Множество параметров - двумерных точек на параметрической области триангулируемой поверхности (может быть пустым). \en Set of parameters of two-dimensional points in parametric domain of surface being triangulated(can be empty). + std::vector escorts; ///< \ru Множество значений для дополнительной информации в точках. \en The set of values for additional information of points. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbFloatGrid( const MbFloatGrid & init ); + // \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbFloatGrid( const MbFloatGrid & init, MbRegDuplicate * iReg ); +public: + // \ru Конструктор без параметров. \en Constructor without parameters. + MbFloatGrid(); + // \ru Деструктор. \en Destructor. + virtual ~MbFloatGrid(); + +public: + + // \ru \name Общие функции примитива. \en \name Common functions of primitive. + + virtual MbePrimitiveType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbFloatGrid & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ); // \ru Преобразовать сетку согласно матрице. \en Transform mesh according to the matrix. + virtual void Move ( const MbVector3D & to ); // \ru Сдвиг сетки. \en Move mesh. + virtual void Rotate ( const MbAxis3D & axis, double angle ); // \ru Поворот сетки вокруг оси. \en Rotation of mesh about an axis. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & pnt ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual double DistanceToLine( const MbAxis3D & axis, double maxDistance, double & t ) const; // \ru Вычислить расстояние до оси. \en Calculate the distance to an axis. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru Выдать количество точек. \en Get the number of points. + virtual size_t PointsCount() const { return points.size(); } + // \ru Выдать количество нормалей. \en Get the number of normals. + virtual size_t NormalsCount() const { return normals.size(); } + // \ru Выдать количество параметров. \en Get the number of parameters. + virtual size_t ParamsCount() const { return params.size(); } + // \ru Выдать количество значений. \en Get count of values. + virtual size_t EscortsCount() const { return escorts.size(); } + // \ru Выдать количество точек минус 1 (максимальный индекс). \en Get the number of points minus one (maximal index). + virtual ptrdiff_t PointsMaxIndex() const { ptrdiff_t n = points.size(); return ( n - 1 ); } + // \ru Выдать количество нормалей минус 1 (максимальный индекс). \en Get the number of normals minus one (maximal index). + virtual ptrdiff_t NormalsMaxIndex() const { ptrdiff_t n = normals.size(); return ( n - 1 ); } + // \ru Выдать количество параметров минус 1 (максимальный индекс). \en Get the number of parameters minus one (maximal index). + virtual ptrdiff_t ParamsMaxIndex() const { ptrdiff_t n = params.size(); return ( n - 1 ); } + + // \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D, const MbVector3D & n3D ); + // \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D ); + // \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D, const MbVector3D & n3D ); + // \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D ); + // \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbVector3D & n3D ); + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam ( const MbCartPoint & p2D ); + + // \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D ); + // \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint( const MbFloatPoint3D & p3D ); + // \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbFloatVector3D & n3D ); + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam( const MbFloatPoint & p2D ); + + // \ru Добавить в триангуляцию точки. \en Add points to triangulation. + template + void AddPoints ( const PointsVector & pnts ) { + size_t addCnt = pnts.size(); + points.reserve( points.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + points.push_back( pnts[k] ); + } + // \ru Добавить в триангуляцию нормали. \en Add normals to triangulation. + template + void AddNormals( const NormalsVector & nrms ) { + size_t addCnt = nrms.size(); + normals.reserve( normals.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + normals.push_back( nrms[k] ); + } + // \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + template + void AddParams( const ParamsVector & prms ) { + size_t addCnt = prms.size(); + params.reserve( params.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + params.push_back( prms[k] ); + } + + // \ru Добавить в коллекцию данных. \en Add scores to collection. + virtual void AddEscorts( const std::vector & scores ) { escorts.insert(escorts.end(), scores.begin(), scores.end()); } + + // \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbCartPoint3D & p ) const; + // \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbVector3D & n ) const; + // \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbCartPoint & p ) const; + // \ru Выдать дополнительную информацию по её номеру. \en Get additional information by its index. + virtual const uint32 & GetEscort( size_t i ) const; + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbFloatPoint3D & p ) const; + /// \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbFloatVector3D & n ) const; + /// \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbFloatPoint & p ) const; + + // \ru Выдать точку с заданным номером. \en Get point by the given index. + const MbFloatPoint3D & GetPoint ( size_t i ) const; + // \ru Выдать нормаль с заданным номером. \en Get normal by the given index. + const MbFloatVector3D & GetNormal( size_t i ) const; + // \ru Выдать параметр с заданным номером. \en Get parameter by the given index. + const MbFloatPoint & GetParam ( size_t i ) const; + + // \ru Установить точку с заданным номером. \en Set point by the given index. + virtual void SetPoint ( size_t i, const MbCartPoint3D & p ); + // \ru Установить нормаль с заданным номером. \en Set normal by the given index. + virtual void SetNormal( size_t i, const MbVector3D & n ); + // \ru Установить параметр с заданным номером. \en Set parameter by the given index. + virtual void SetParam ( size_t i, const MbCartPoint & p ); + // \ru Установить дополнительную информацию по её номеру. \en Set additional information by its index. + virtual void SetEscort( size_t i, const uint32 & e ); + + // \ru Удалить точку с заданным номером. \en Delete point by the given index. + virtual void PointRemove ( size_t i ); + // \ru Удалить нормаль с заданным номером. \en Delete normal by the given index. + virtual void NormalRemove( size_t i ); + // \ru Удалить параметры поверхности с заданным номером. \en Delete parameters of surface by the given index. + virtual void ParamRemove ( size_t i ); + + // \ru Удалить точки. \en Delete points. + virtual void PointsDelete(); + // \ru Удалить нормали. \en Delete normal. + virtual void NormalsDelete(); + // \ru Удалить параметры. \en Delete papams. + virtual void PapamsDelete(); + // \ru Удалить дополнительную информацию. \en Delete additional information. + virtual void EscortsDelete(); + + /// \ru Инвертировать нормали. \en Invert normals. + virtual void NormalsInvert(); + + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th triangle in general numbering (with strips). + virtual bool GetTriangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D & n2 ) const; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2 ) const; + + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2, MbCartPoint & r3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2, MbCartPoint3D & p3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2, MbFloatPoint3D & n3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D &n2, MbVector3D & n3 ) const; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2, MbFloatVector3D & n3 ) const; + + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbVector3D & ) const; + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbFloatVector3D & ) const; + // \ru Если количество точек больше количества нормалей, то добавить недостающие нормали (только для плоской триангуляции). \en If count of points is greater than count of normals, then add missing normals (only for planar triangulation). + virtual void SynchronizNormals (); + + // \ru Выдать контейнер параметров. \en Get the container of parameters. + template + void GetParams( ParamsVector & paramsVector ) const { + paramsVector.reserve( paramsVector.size() + params.size() ); + for ( size_t i = 0, iCount = params.size(); i < iCount; i++ ) + paramsVector.push_back( params[i] ); + } + // \ru Выдать контейнер точек. \en Get the container of points. + template + void GetPoints( PointsVector & pointsVector ) const { + pointsVector.reserve( pointsVector.size() + points.size() ); + for ( size_t i = 0, iCount = points.size(); i < iCount; i++ ) + pointsVector.push_back( points[i] ); + } + // \ru Выдать контейнер нормалей. \en Get the container of normals. + template + void GetNormals( NormalsVector & normalsVector ) const { + normalsVector.reserve( normalsVector.size() + normals.size() ); + for ( size_t i = 0, iCount = normals.size(); i < iCount; i++ ) + normalsVector.push_back( normals[i] ); + } + + // \ru Расширить присланный габаритный прямоугольник так, чтобы он включал в себя проекцию данного объекта на глобальную плоскость XY. \en Extend given bounding box so that it enclose projection of this object to the global XY-plane. + virtual void AddRect( MbRect & rect ) const; + // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual void AddCube( MbCube & r ) const; + + // \ru Определить, пересекается ли проекция на глобальную плоскость XY треугольника с заданным номером с присланным прямоугольником. \en Determine whether the projection of triangle with a given index to the global XY-plane intersects the given rectangle. + virtual bool TriangleIntersectRect( size_t i, MbRect & rect ) const { return (i & cutPlaces, + MbFloatPoint3D & crossPnt, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Найти пересечение прямой линии и триангуляции. + \en Find the intersection of a straight line with the triangulation. \~ + \details \ru Для всех треугольников определяется пересечение с прямой линии и вычисляется минимальное значение + параметра точки пересечения на секущей прямой линии. \n + \en For all the triangles the intersection with the straight line is determined and the minimum value of + the intersection point parameter on the secant straight line is calculated. \n \~ + \param[in] grid - \ru Триангуляция. + \en Triangulation. \~ + \param[in] line - \ru Прямая линия, для которой вычисляется пересечение с триангуляцией. + \en Straight line to calculate the intersection of triangulation with. \~ + \param[out] tRes - \ru Параметр точки пересечения линии. + \en Parameter of the intersection point on the line. \~ + \return \ru Найдено ли пересечение (true - В случае успеха). + \en Whether the intersection is found (true if success). \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) LineGridIntersect( const MbGrid & grid, + const MbFloatAxis3D & line, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от линии до полигона. + \en Calculate squared distance from a line to a polygon. \~ + \details \ru При вычислении квадрата расстояния от линии до полигона проверяется расстояние от каждого + сегмента полигона до первого попадания в окрестность delta. + Возвращается значение параметра ближайшей точки на линии tRes и квадрат расстояния + от этой точки до сегмента полигона. \n + \en During calculation of squared distance from a line to a polygon the distance from each + segment of the polygon is checked until the first getting to 'delta' neighborhood. + Returns the value of the nearest point parameter on tRes line and the squared distance + from this point to a segment of the polygon. \n \~ + \param[in] grid - \ru Триангуляция. + \en Triangulation. \~ + \param[in] edgeInd - \ru Индекс тестируемого полигона. + \en Index of polygon to check. \~ + \param[in] line - \ru Линия, до которой вычисляется расстояние. + \en Line to calculate the distance to. \~ + \param[in] delta - \ru Радиус окрестности вокруг линии. + \en Neighborhood radius around the line. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToGridEdgeDistanceSquared( const MbGrid & grid, + size_t edgeInd, + const MbFloatAxis3D & line, + float delta, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от линии до полигона. + \en Calculate squared distance from a line to a polygon. \~ + \details \ru При вычислении квадрата расстояния от линии до полигона проверяется расстояние от каждого + сегмента полигона до первого попадания в окрестность delta. + Возвращается значение параметра ближайшей точки на линии tRes, вектор между ближайшими точками и квадрат + расстояния от этой точки до сегмента полигона. \n + \en During calculation of squared distance from a line to a polygon the distance from each + segment of the polygon is checked until the first getting to 'delta' neighborhood. + Returns the value of the nearest point parameter on the line, the vector between the nearest points + and the squared distance from this point to a segment of the polygon. \n \~ + \param[in] grid - \ru Триангуляция. + \en Triangulation. \~ + \param[in] edgeInd - \ru Индекс тестируемого полигона. + \en Index of polygon to check. \~ + \param[in] line - \ru Линия, до которой вычисляется расстояние. + \en Line to calculate the distance to. \~ + \param[in] vDelta - \ru Габарит окрестности вокруг линии. + \en The dimensions of the area around the line. \~ + \param[out] vRes - \ru Вектор от ближайшей точки на линии до ближайшей точки на полигоне. + \en Vector from the nearest point on the line to the nearest point on the polygon. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToGridEdgeDistanceSquared( const MbGrid & grid, + size_t edgeInd, + const MbFloatAxis3D & line, + const MbFloatVector3D & vDelta, + MbFloatVector3D & vRes, + float & tRes ); + + +#endif // __MESH_GRID_H diff --git a/C3d/Include/mesh_plane_grid.h b/C3d/Include/mesh_plane_grid.h new file mode 100644 index 0000000..9d630cd --- /dev/null +++ b/C3d/Include/mesh_plane_grid.h @@ -0,0 +1,356 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Tриангуляция двумерной области. + \en Triangulation of two-dimensional region. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// "PGrid.cpp" +// \ru PGrid.h - заголовочный файл триангуляции массива двумерных точек. \en PGrid.h - header file of two-dimensional point array triangulation. +// \ru Содержит следующие разделы: \en Contains the following sections: +// \ru - Триангуляция двумерной области \en - Triangulation of a two-dimensional region +// \ru - Вершина полигона \en - Vertex of a polygon +// \ru - Многоугольник \en - Polygon +// \ru - Аппроксимация плоской области треугольными пластинами \en - Approximation of a planar region by triangular plates +// \ru - Трингуляция двумерного региона \en - Triangulation of a two-dimensional region +// \ru - Выпуклая триангуляция неупорядоченного массива двумерных точек \en - Convex triangulation of unordered array of two-dimensional points +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_PLANE_GRID_H +#define __MESH_PLANE_GRID_H + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbRegion; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS ProgressBarWrapper; + + +//------------------------------------------------------------------------------ +/** \brief \ru Tреугольник. + \en Triangle. \~ + \details \ru Tреугольник определен, как тройка точек, заданных индексами + вершин триангуляции MbPlanarGrid. \n + \en Triangle is defined as triple of points defined by indices + of vertices of MbPlanarGrid triangulation. \n \~ + \ingroup Algorithms_2D +*/ +// --- +class MbTri { +protected : + size_t pIndex[3]; // \ru Номера вершин треугольника в массиве точек \en Indices of triangle vertices in array of points + +public : + MbTri() { pIndex[0] = pIndex[1] = pIndex[2] = SYS_MAX_T; } + MbTri( size_t j0, size_t j1, size_t j2, bool orientation ) { Init( j0, j1, j2, orientation ); } + ~MbTri() {} +private: + MbTri( const MbTri & ); // \ru Не реализовано \en Not implemented + void operator = ( const MbTri & ); // \ru Не реализовано \en Not implemented +public : + + void Init( size_t j0, size_t j1, size_t j2, bool orientation ) + { + if ( orientation ) { // \ru Совпадает направление обхода \en Traverse direction coincides + pIndex[0] = j0; + pIndex[1] = j1; + pIndex[2] = j2; + } + else { + pIndex[1] = j1; + pIndex[2] = j0; + pIndex[0] = j2; + } + } + + bool GetTriangle ( size_t & i0, size_t & i1, size_t & i2 ) const + { + i0 = pIndex[0]; + i1 = pIndex[1]; + i2 = pIndex[2]; + return true; + } + + size_t GetIndex( size_t n ) const { return pIndex[n % 3]; } + + bool IsTriangleEdge( size_t k0, size_t k1, size_t & eInd ) const + { + eInd = SYS_MAX_T; + + if ( k0 == pIndex[0] && k1 == pIndex[1] ) + eInd = 0; + else if ( k0 == pIndex[1] && k1 == pIndex[2] ) + eInd = 1; + else if ( k0 == pIndex[2] && k1 == pIndex[0] ) + eInd = 2; + + return (eInd != SYS_MAX_T); + } +}; // MbTri + + +//------------------------------------------------------------------------------ +/** \brief \ru Tриангуляция двумерной области. + \en Triangulation of a two-dimensional region. \~ + \details \ru Tриангуляция двумерной области. \n + \en Triangulation of a two-dimensional region. \n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MbPlanarGrid { +private: + SArray points; ///< \ru Вершины триангуляции. \en Vertices of triangulation. + SArray triangles; ///< \ru Множество треугольников. \en Array of triangles. + +public: + MbPlanarGrid() : points( 0, 1 ), triangles( 0, 1 ) {} + ~MbPlanarGrid() {}; + +public: + void PointsReserve ( size_t size ) { points.Reserve( size ); } + void TrianglesReserve ( size_t size ) { triangles.Reserve( size ); } + void PointsSetMaxDelta ( uint16 size ) { points.SetMaxDelta( size ); } + void TrianglesSetMaxDelta( uint16 size ) { triangles.SetMaxDelta( size ); } + void PointsAdjust() { points.Adjust(); } + void TrianglesAdjust() { triangles.Adjust(); } + + size_t GetPointsCount () const { return points.Count(); } + size_t GetTrianglesCount() const { return triangles.Count(); } + + void AddTriangle( size_t j0, size_t j1, size_t j2, bool o ) { triangles.Add()->Init( j0, j1, j2,o ); } + void AddPoint ( const MbFloatPoint & p ) { points.Add( p ); } + void AddPoint ( const MbCartPoint & p ) { points.Add( p ); } + /// \ru Выдать декартову точку. \en Get Cartesian point. + bool GetPoint ( size_t k, MbCartPoint & p ) const; + /// \ru Выдать точку. \en Get point. + bool GetPoint ( size_t k, MbFloatPoint & p ) const; + /// \ru Получить индексы точек треугольника. \en Get indices of points of the triangle. + bool GetTriangle( size_t k, size_t & i0, size_t & i1, size_t & i2 ) const; + /// \ru Получить точки треугольника. \en Get points of the triangle. + bool GetTrianglePoints( size_t k, MbCartPoint & p0, MbCartPoint & p1, MbCartPoint & p2 ) const; + +OBVIOUS_PRIVATE_COPY( MbPlanarGrid ) +}; + + +//------------------------------------------------------------------------------ +/// \ru Выдать декартову точку \en Get Cartesian point +// --- +inline bool MbPlanarGrid::GetPoint( size_t k, MbCartPoint & p ) const +{ + if ( k < points.Count() ) { + p = points[k]; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/// \ru Выдать точку \en Get point +// --- +inline bool MbPlanarGrid::GetPoint( size_t k, MbFloatPoint & p ) const +{ + if ( k < points.Count() ) { + p = points[k]; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +/// \ru Вершина полигона \en Vertex of a polygon +// --- +class TriVertex { +private: + TriVertex * next; ///< \ru Следующая вершина \en Next vertex + TriVertex * prev; ///< \ru Предыдущая вершина \en Previous vertex + size_t index; ///< \ru Номер точки в массиве точек триангуляции \en Index of point in array of points of triangulation + +public: + TriVertex( size_t i ) : index(i) { next = this; prev = this; } + +public: + ~TriVertex() {} + +public: + /// \ru Смежная вершина (следующая или предыдущая). \en Adjacent vertex (next or previous). + TriVertex * Neighbor ( MbeMoveType ) const; + /// \ru Следующая вершина. \en Next vertex. + TriVertex * Next () const { return next; } + /// \ru Предыдущая вершина. \en Previous vertex. + TriVertex * Prev () const { return prev; } + /// \ru Номер точки текущей вершины. \en Index of point of current vertex. + size_t Index () const { return index; } + /// \ru Вставить вершину после текущей. \en Insert vertex after the current one. + TriVertex * Insert ( TriVertex & ); + /// \ru Исключить текущую вершину (возвращает исключенную, текущей становится предыдущая) \en Exclude the current vertex (returns excluded vertex, previous vertex becomes the current one) + TriVertex * Detach (); + /// \ru Соединить две цепочки вершин. \en Connect two vertex chains. + void Splice ( TriVertex & ); + /// \ru Разделить цепочку вершин вершиной. \en Disconnect vertex chain by a vertex. + TriVertex * Split ( TriVertex & ); + +OBVIOUS_PRIVATE_COPY( TriVertex ) +}; + + +//------------------------------------------------------------------------------ +/// \ru Многоугольник \en Polygon +// --- +class TriPoly { +private: + TriVertex * vertex; ///< \ru Текущая вершина. \en Current vertex. + intptr_t size; ///< \ru Количество вершин. \en Count of vertices. + +public: + TriPoly() : vertex( NULL ), size( 0 ) {} + TriPoly( TriVertex * vert ) : vertex( vert ), size( 0 ) { Resize(); } + +public: + ~TriPoly(); + +public: + intptr_t Size() const { return size; } ///< \ru Размер цепочки вершин \en Size of vertex chain + size_t Index() const { return (vertex != NULL) ? vertex->Index() : SYS_MAX_T; } ///< \ru Индекс вершины \en Index of vertex + + TriVertex * This() const { return vertex; } ///< \ru Текущая вершина \en Current vertex + TriVertex * Next() const; ///< \ru Следующая вершина \en Next vertex + TriVertex * Prev() const; ///< \ru Предыдущая вершина \en Previous vertex + TriVertex * Neighbor( MbeMoveType rotation ) const; ///< \ru Соседняя вершина \en Neighboring vertex + + TriVertex * Advance ( MbeMoveType rotation ); ///< \ru Перемещение указателя текущей вершины на соседа \en Move current vertex pointer to the neighbor + TriVertex * SetVertex( TriVertex * ); ///< \ru Перемещение указателя текущей вершины на указанную \en Move current vertex pointer to the given one + + TriVertex * Insert( TriVertex & ); ///< \ru Вставка новой вершины \en Insert new vertex + void Remove(); ///< \ru Удаление текущей вершины \en Remove the current vertex + + TriPoly * Split( TriVertex &, bool createNew ); ///< \ru Резка многоугольника вдоль хорды \en Cutting of polygon along a chord + bool GetTriangle( size_t & k0, size_t & k1, size_t & k2 ) const; ///< \ru Получить индексы вершин треугольника (когда вершин больше 2) \en Get indices of triangle vertices (when there are more than 2 vertices) + + template + bool CalculateGab( const SArray & pnts, Gab & rect ) const; + +private: + void Resize(); ///< \ru Обновление размера \en Set size to zero + +OBVIOUS_PRIVATE_COPY( TriPoly ) +}; + + +//------------------------------------------------------------------------------ +// \ru Посчитать габарит цепочки вершин \en Calculate bounding box of vertex chain +// --- +template +bool TriPoly::CalculateGab( const SArray & pnts, Gab & rect ) const +{ + bool isDone = false; + + rect.SetEmpty(); + size_t pntsCnt = pnts.Count(); + + if ( Size() > 0 && pntsCnt > 0 ) { + const TriVertex * v0 = This(); + size_t ind0 = v0->Index(); + + if ( ind0 < pntsCnt ) { + isDone = true; + const Point & pnt0 = pnts[ind0]; + rect |= pnt0; + + TriVertex * v = v0->Next(); + while( v0 != v && isDone ) { + isDone = false; + size_t ind = v->Index(); + if ( ind < pntsCnt ) { + const Point & pnt = pnts[ind]; + rect |= pnt; + v = v->Next(); + isDone = true; + } + } + } + } + + C3D_ASSERT( isDone ); + return isDone; +} + + +/* +//------------------------------------------------------------------------------ +// \ru Треугольник со ссылками на смежные(соседние) с ним треугольники \en Triangle with references to triangles adjacent (neighboring) to it +// --- +class MbLinkedTri : public MbTri { +protected: + MbTri * neighbors[3]; // \ru Соседние треугольники \en Neighboring triangles + // \ru Нумерация соседних треугольников: \en Numeration of neighboring triangles: + // \ru 0 - смежный через ребро на вершинах 0,1 \en 0 - adjacent at edge with vertices 0,1 + // \ru 1 - смежный через ребро на вершинах 1,2 \en 1 - adjacent at edge with vertices 1,2 + // \ru 2 - смедный через ребра на вершинах 2,0 \en 2 - adjacent at edge with vertices 2,0 + +public: + MbLinkedTri() : MbTri() { neighbors[0] = neighbors[1] = neighbors[2] = NULL; }; + ~MbLinkedTri() {}; +public: + MbTri * GetNeighbor( size_t n ) const { return neighbors[n % 3]; } + void SetNeighbor( size_t n, MbTri * neighbor ) { neighbors[n % 3] = neighbor; } + bool IsBoundary() const; // \ru Является ли треугольник граничным \en Whether the triangle is boundary + +OBVIOUS_PRIVATE_COPY( MbLinkedTri ) +}; + + +//------------------------------------------------------------------------------ +// \ru Является ли треугольник граничным \en Whether the triangle is boundary +// --- +inline bool MbLinkedTri::IsBoundary() const +{ + bool isBoundary = (neighbors[0] == NULL) || + (neighbors[1] == NULL) || + (neighbors[2] == NULL); + return isBoundary; +} +// */ + + +//------------------------------------------------------------------------------ +// \ru Аппроксимация плоской области треугольными пластинами \en Approximation of planar region by triangular plates +// \ru Функция удаляет полигионы точек из массива \en The function removes polygons of points from the array +// --- +MATH_FUNC (void) CalculatePlanarGrid( PArray< SArray > & poly, MbPlanarGrid & grid ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Трингуляция двумерного региона + \en Triangulation of a two-dimensional region \~ + \details \ru Трингуляция двумерного региона. + Регион region должен быть корректным (на некорректном работает неправильно) + \en Triangulation of a two-dimensional region. + 'region' region has to be correct (improper handling of incorrect ones) \~ + \ingroup Polygonal_Objects +*/ +// --- +MATH_FUNC (void) TriangulateRegion( const MbRegion & region, double sag, MbPlanarGrid & grid ); + + +//------------------------------------------------------------------------------ +/// \ru Выпуклая триангуляция неупорядоченного массива двумерных точек \en Convex triangulation of unordered array of two-dimensional points +// --- +MATH_FUNC (bool) TriangulateConvexCloud( const SArray & uvPnts, double xEps, double yEps, const MbMatrix3D & from, + SArray & triangles, + ProgressBarWrapper * progBar ); + + +#endif // __PGRID_H diff --git a/C3d/Include/mesh_polygon.h b/C3d/Include/mesh_polygon.h new file mode 100644 index 0000000..0711805 --- /dev/null +++ b/C3d/Include/mesh_polygon.h @@ -0,0 +1,389 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Полигоны. + \en Polygons. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_POLYGON_H +#define __MESH_POLYGON_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPolyline; + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Полигон на числах double. + \en Polygon on double data. \~ + \details \ru Полигон представляет собой упорядоченное множество точек в пространстве, + последовательное соединение которых даёт ломаную линию, аппроксимирующую некоторый объект или часть объекта. \n + \en Polygon is an ordered set of points in space, + sequential connection of these points produces polyline that approximates an object or part of an object. \n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbExactPolygon3D : public MbPolygon3D { +private : + std::vector points; ///< \ru Множество точек полигона. \en Array of points of a polygon. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent copying by default + MbExactPolygon3D( const MbExactPolygon3D & ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbExactPolygon3D( const MbExactPolygon3D &, MbRegDuplicate * ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbExactPolygon3D(); + /// \ru Деструктор \en Destructor + virtual ~MbExactPolygon3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType IsA() const; // \ru Вернуть тип объекта \en Get the object type. + virtual MbExactPolygon3D & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта \en Create a copy of the object + virtual void Transform( const MbMatrix3D & ); // \ru Преобразовать полигон согласно матрице \en Transform polygon according to the matrix + virtual void Move ( const MbVector3D & ); // \ru Сдвиг полигона \en Translation of the polygon. + virtual void Rotate ( const MbAxis3D &, double angle ); // \ru Поворот полигона вокруг оси \en Rotation of the polygon around an axis + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to the point. + virtual double DistanceToLine( const MbAxis3D &, double maxDistance, double & t ) const; // \ru Вычислить расстояние до оси. \en Calculate the distance to the axis. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru \name Функции полигона. \en \name Functions of polygon. + + // \ru Выдать размер занимаемой памяти. \en Get the size of taken memory. + virtual size_t SizeOf() const; + // \ru Зарезервировать место для полигона. \en Reserve memory for polygon. + virtual void Reserve( size_t cnt ) { points.reserve( points.size() + cnt ); } + // \ru Удалить лишнюю память. \en Free the unnecessary memory. + virtual void Adjust() { + #ifdef STANDARD_C11 + points.shrink_to_fit(); + #endif + } + // \ru Очистить полигон удалив все точки. \en Clear the polygon by deleting all the points. + virtual void Flush(); + // \ru Выдать количество точек. \en Get count of points. + virtual size_t Count() const { return points.size(); } + // \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbCartPoint3D & dpnt ); + // \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbFloatPoint3D & fpnt ); + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbCartPoint3D & dp ) const; + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbFloatPoint3D & fp ) const; + + /// \ru Установить точку с номером. \en Set point by index. + virtual void SetPoint( size_t i, MbCartPoint3D & pnt ) { points[i] = pnt; } + + /// \ru Установить точку с номером. \en Set point by index. + template + void SetPoint( size_t i, Point & pnt ) { points[i].x = (float)pnt.x; points[i].y = (float)pnt.y; points[i].z = (float)pnt.z; cube.SetEmpty(); } + /// \ru Выдать точку по её номеру. \en Get point by its index. + template + void GetPoint( size_t i, Point & pnt ) const { pnt.x = points[i].x; pnt.y = points[i].y; pnt.z = points[i].z; } + + /// \ru Выдать точку по её номеру. \en Get point by its index. + const MbCartPoint3D & GetPoint( size_t i ) const { return points[i]; } + + /// \ru Выдать все точки полигона. \en Get all the points of the polygon. + template + void GetPoints( PointsVector & pnts ) const + { + size_t cnt = points.size(); + pnts.clear(); + pnts.reserve( cnt ); + for ( size_t k = 0; k < cnt; k++ ) { + pnts.push_back( points[k] ); + } + } + // \ru Проверить, лежат ли точки полигона в одной плоскости c заданной точностью metricAccuracy. Если да, то инициализировать плоскость plane. + // \en Check whether all points of polygon lie on the same plane with the given metricAccuracy accuracy. If so, then initialize 'plane' plane. \~ + virtual bool IsPlanar( MbPlacement3D & plane, double metricAccuracy = Math::metricRegion ) const; + /// \ru Если точки полигона лежат в одной плоскости, то инициализировать plane и заполнить полигон poly. \en If points of polygon lie on the same plane, then initialize 'plane' and fill the 'poly' polygon. + virtual bool GetPlanePolygon( MbPlacement3D & plane, MbPolygon & poly ) const; + + // \ru Проверить наличие точек в объекте. \en Check existence of points in object. + virtual bool IsComplete() const { return (points.size() > 0); } + + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void AddPolygon( const MbPolygon3D & other ); + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void operator += ( const MbPolygon3D & other ); + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbPolygon3D & other, double eps ) const; + // \ru Инициировать по другому полигону. \en Init by other polygon. + virtual void Init( const MbPolygon3D & other ); + + /// \ru Создать ломаную по полигону. \en Create a polyline on the base of the polygon. + virtual MbPolyline3D * CreatePolyline() const; + + /** \} */ + + // \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const MbCartPoint3D * GetAddr() const { return &(points[0]); } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbExactPolygon3D & ); + + DECLARE_NEW_DELETE_CLASS( MbExactPolygon3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbExactPolygon3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbExactPolygon3D, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbExactPolygon3D, MATH_FUNC_EX ); +}; // MbExactPolygon3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Полигон на числах float. + \en Polygon on float data. \~ + \details \ru Полигон представляет собой упорядоченное множество точек в пространстве, + последовательное соединение которых даёт ломаную линию, аппроксимирующую некоторый объект или часть объекта. \n + \en Polygon is an ordered set of points in space, + sequential connection of these points produces polyline that approximates an object or part of an object. \n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbFloatPolygon3D : public MbPolygon3D { +private : + std::vector points; ///< \ru Множество точек полигона. \en Array of points of a polygon. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent copying by default + MbFloatPolygon3D( const MbFloatPolygon3D & ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbFloatPolygon3D( const MbFloatPolygon3D &, MbRegDuplicate * ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbFloatPolygon3D(); + /// \ru Деструктор \en Destructor + virtual ~MbFloatPolygon3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType IsA() const; // \ru Вернуть тип объекта \en Get the object type. + virtual MbFloatPolygon3D & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта \en Create a copy of the object + virtual void Transform( const MbMatrix3D & ); // \ru Преобразовать полигон согласно матрице \en Transform polygon according to the matrix + virtual void Move ( const MbVector3D & ); // \ru Сдвиг полигона \en Translation of the polygon. + virtual void Rotate ( const MbAxis3D &, double angle ); // \ru Поворот полигона вокруг оси \en Rotation of the polygon around an axis + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to the point. + virtual double DistanceToLine( const MbAxis3D &, double maxDistance, double & t ) const; // \ru Вычислить расстояние до оси. \en Calculate the distance to the axis. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + // \ru \name Функции полигона. \en \name Functions of polygon. + + // \ru Выдать размер занимаемой памяти. \en Get the size of taken memory. + virtual size_t SizeOf() const; + // \ru Зарезервировать место для полигона. \en Reserve memory for polygon. + virtual void Reserve( size_t cnt ) { points.reserve( points.size() + cnt ); } + // \ru Удалить лишнюю память. \en Free the unnecessary memory. + virtual void Adjust() { + #ifdef STANDARD_C11 + points.shrink_to_fit(); + #endif + } + // \ru Очистить полигон удалив все точки. \en Clear the polygon by deleting all the points. + virtual void Flush(); + // \ru Выдать количество точек. \en Get count of points. + virtual size_t Count() const { return points.size(); } + // \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbCartPoint3D & dpnt ); + // \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbFloatPoint3D & fpnt ); + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbCartPoint3D & dp ) const; + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbFloatPoint3D & fp ) const; + + /// \ru Установить точку с номером. \en Set point by index. + virtual void SetPoint( size_t i, MbCartPoint3D & pnt ) { points[i].x = (float)pnt.x; points[i].y = (float)pnt.y; points[i].z = (float)pnt.z; cube.SetEmpty(); } + + /// \ru Установить точку с номером. \en Set point by index. + template + void SetPoint( size_t i, Point & pnt ) { points[i].x = (float)pnt.x; points[i].y = (float)pnt.y; points[i].z = (float)pnt.z; cube.SetEmpty(); } + /// \ru Выдать точку по её номеру. \en Get point by its index. + template + void GetPoint( size_t i, Point & pnt ) const { pnt.x = points[i].x; pnt.y = points[i].y; pnt.z = points[i].z; } + + /// \ru Выдать точку по её номеру. \en Get point by its index. + const MbFloatPoint3D & GetPoint( size_t i ) const { return points[i]; } + + /// \ru Выдать все точки полигона. \en Get all the points of the polygon. + template + void GetPoints( PointsVector & pnts ) const + { + size_t cnt = points.size(); + pnts.clear(); + pnts.reserve( cnt ); + for ( size_t k = 0; k < cnt; k++ ) { + pnts.push_back( points[k] ); + } + } + // \ru Проверить, лежат ли точки полигона в одной плоскости c заданной точностью metricAccuracy. Если да, то инициализировать плоскость plane. + // \en Check whether all points of polygon lie on the same plane with the given metricAccuracy accuracy. If so, then initialize 'plane' plane. \~ + virtual bool IsPlanar( MbPlacement3D & plane, double metricAccuracy = Math::metricRegion ) const; + /// \ru Если точки полигона лежат в одной плоскости, то инициализировать plane и заполнить полигон poly. \en If points of polygon lie on the same plane, then initialize 'plane' and fill the 'poly' polygon. + virtual bool GetPlanePolygon( MbPlacement3D & plane, MbPolygon & poly ) const; + + // \ru Проверить наличие точек в объекте. \en Check existence of points in object. + virtual bool IsComplete() const { return (points.size() > 0); } + + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void AddPolygon( const MbPolygon3D & other ); + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void operator += ( const MbPolygon3D & other ); + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbPolygon3D & other, double eps ) const; + // \ru Инициировать по другому полигону. \en Init by other polygon. + virtual void Init( const MbPolygon3D & other ); + + /// \ru Создать ломаную по полигону. \en Create a polyline on the base of the polygon. + virtual MbPolyline3D * CreatePolyline() const; + + /** \} */ + + // \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const MbFloatPoint3D * GetAddr() const { return &(points[0]); } + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbFloatPolygon3D & ); + + DECLARE_NEW_DELETE_CLASS( MbFloatPolygon3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbFloatPolygon3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbFloatPolygon3D, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbFloatPolygon3D, MATH_FUNC_EX ); +}; // MbFloatPolygon3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Двумерный полигон. + \en Two-dimensional polygon. \~ + \details \ru Двумерный полигон представляет собой упорядоченное множество точек в + двумерном пространстве, последовательное соединение которых даёт ломаную линию, + аппроксимирующую некоторый двумерный объект. \n + \en Two-dimensional polygon is an ordered set of points in + two-dimensional space, sequential connection of them produces a polyline + that approximate a two-dimensional object. \n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbPolygon : public MbRefItem { +private: + SArray points; ///< \ru Множество точек полигона. \en Array of points of a polygon. + double sag; ///< \ru Стрелка прогиба, с которой рассчитан полигон. \en Sag used for calculation of a polygon. + mutable MbRect rect; ///< \ru Габарит полигона (не записывается в поток и не читаeтся). \en Bounding box of polygon (not read from stream and not written to stream). + mutable double length; ///< \ru Длина полигона (не записывается в поток и не читаeтся). \en Length of a polygon (not read from stream and not written to stream). + +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbPolygon(); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPolygon( const MbPolygon & ); + /// \ru Деструктор. \en Destructor. + ~MbPolygon(); + +public: + /// \ru Обеспечить резерв памяти под additionalSpace элементов. \en Reserve memory for additionalSpace elements. + void Reserve( size_t additionalSpace ); + /// \ru Установить максимальное из приращений. \en Set the maximum increment. + void SetMaxDelta( uint16 delta ); + /// \ru Удалить лишнюю память. \en Free the unnecessary memory. + void Adjust(); + /// \ru Вернуть количество точек. \en Get count of points. + size_t Count() const { return points.size(); } + + /// \ru HardFlush очистить полигон (освободить всю память). \en HardFlush clear the polygon (free all the memory). + void HardFlushPoints(); + /// \ru Flush очистить полигон \en Flush clear polygon + void SimpleFlushPoints(); + + /// \ru Добавить новую точку. \en Add a new point. + void AddPoint ( double x, double y ); + /// \ru Добавить новую точку. \en Add a new point. + void AddPoint ( const MbCartPoint & ); + /// \ru Добавить полигон. \en Add a polygon. + void AddPolygon ( const MbPolygon & ); + /// \ru Удалить точку. \en Remove the point. + bool RemovePoint( size_t index ); + + /// \ru Выдать очередную точку. \en Get the next point. + bool GetPoint ( size_t i, MbCartPoint & ) const; + /// \ru Выдать очередную точку. \en Get the next point. + bool GetPoint ( size_t i, MbFloatPoint & ) const; + /// \ru Изменить точку. \en Change a point. + bool SetPoint ( size_t i, const MbCartPoint & ); + /// \ru Изменить точку. \en Change a point. + bool SetPoint ( size_t i, const MbFloatPoint & ); + /// \ru Выдать очередную точку. \en Get the next point. + bool GetCoords( size_t i, double & x, double & y ) const; + /// \ru Заполнить контейнер. \en Fill the container. + void GetPoints( SArray & ) const; + /// \ru Заполнить контейнер. \en Fill the container. + void GetPoints( SArray & ) const; + /// \ru Выдать точку. \en Get point. + const MbFloatPoint & GetPoint( size_t i ) const { return points[i]; } + + /// \ru Сдвинyть полигон. \en Move the polygon. + void Move ( const MbVector & ); + /// \ru Повернуть полигон вокруг точки. \en Rotate a polygon about a point. + void Rotate( const MbCartPoint &, const MbDirection & ); + /// \ru Преобразовать полигон согласно матрице. \en Transform a polygon according to the matrix. + void Transform( const MbMatrix & ); + /// \ru Инверсия направления. \en Inverse the direction. + void Inverse(); + + /// \ru Вернуть габарит. \en Get bounding box. + const MbRect & GetRect() const; + /// \ru Вернуть длину полигона. \en Get length of the polygon. + double GetLength() const; + /// \ru Получить стрелку прогиба. \en Get sag. + double GetSag() const { return sag; } + /// \ru Установить стрелку прогиба. \en Set sag. + void SetSag( double s ) { sag = s; } + /// \ru Является ли полигон выпуклым. \en Whether the polygon is convex. + bool IsConvex() const; + /// \ru Площадь полигона. \en Area of the polygon. + double Area() const; + + void operator = ( const MbPolygon & ); + + /// \ru Создать ломаную на основе полигона. \en Create a polyline from the polygon. + MbPolyline * ConvertToPolyline() const; + + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const MbFloatPoint * GetAddr() const { return points.GetAddr(); } + +private: + // \ru Рассчитать габарит. \en Calculate bounding box. + void CalculateRect() const; + // \ru Рассчитать длину полигона. \en Calculate length of the polygon. + void CalculateLength() const; + // \ru Сбросить временные данные. \en Reset temporary data. + void ResetMutable() const; + + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbPolygon, MATH_FUNC_EX ) + DECLARE_NEW_DELETE_CLASS( MbPolygon ) + DECLARE_NEW_DELETE_CLASS_EX( MbPolygon ) +}; + + +#endif // __MESH_POLYGON_H diff --git a/C3d/Include/mesh_primitive.h b/C3d/Include/mesh_primitive.h new file mode 100644 index 0000000..4180359 --- /dev/null +++ b/C3d/Include/mesh_primitive.h @@ -0,0 +1,1268 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Базовый класс для структур данных сетки (#MbMesh). Вершина. Полигон. + \en Base class for mesh data structures (#MbMesh). Vertex. Polygon. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_PRIMITIVE_H +#define __MESH_PRIMITIVE_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbRect; +class MATH_CLASS MbCurve; +class MATH_CLASS MbPolyline3D; +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbPrimitive; +class MATH_CLASS MbPolygon3D; +class MATH_CLASS MbPolygon; +class MATH_CLASS MbFloatAxis3D; +class MATH_CLASS MbFloatPoint3D; + + +namespace c3d // namespace C3D +{ +typedef SPtr PrimitiveSPtr; +typedef SPtr ConstPrimitiveSPtr; + +typedef std::vector PrimitivesVector; +typedef std::vector ConstPrimitivesVector; + +typedef std::vector PrimitivesSPtrVector; +typedef std::vector ConstPrimitivesSPtrVector; + +typedef std::set PrimitivesSet; +typedef PrimitivesSet::iterator PrimitivesSetIt; +typedef PrimitivesSet::const_iterator PrimitivesSetConstIt; +typedef std::pair PrimitivesSetRet; + +typedef std::set ConstPrimitivesSet; +typedef ConstPrimitivesSet::iterator ConstPrimitivesSetIt; +typedef ConstPrimitivesSet::const_iterator ConstPrimitivesSetConstIt; +typedef std::pair ConstPrimitivesSetRet; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы примитивов. + \en Types of primitives. \~ + \details \ru Типы примитивов полигонального объекта. + \en Get type of primitive of polygonal object. \~ + \ingroup Polygonal_Objects +*/ +// --- +enum MbePrimitiveType { + pt_Apex3D, ///< \ru Апекс. \en Apex. + pt_ExactApex3D, ///< \ru Апекс на числах double. \en Apex on double data. + pt_FloatApex3D, ///< \ru Апекс на числах float. \en Apex on float data. + pt_Polygon3D, ///< \ru Полигон. \en Polygon. + pt_ExactPolygon3D, ///< \ru Полигон на числах double. \en Polygon on double data. + pt_FloatPolygon3D, ///< \ru Полигон на числах float. \en Polygon on float data. + pt_Grid, ///< \ru Триангуляция. \en Triangulation. + pt_ExactGrid, ///< \ru Триангуляция на числах double. \en Triangulation on double data. + pt_FloatGrid, ///< \ru Триангуляция на числах float. \en Triangulation on float data. +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Примитив. + \en Primitive. \~ + \details \ru Родительский класс элемента полигонального объекта служит для + аппроксимации геометрического объекта. Каждый экземпляр класса MbPrimitive несет имя и + указатель на исходный геометрический объект (если есть такой) и атрибуты.\n + MbPrimitive является предком для триангуляции (#MbGrid), полигона (#MbPolygon3D) и апекса (#MbApex3D). + \en Parent class for polygonal elements is used to represent the approximated geometric object. + Each instance of MbPrimitive class has name and pointer to the source geometric object (if it exists) and attributes.\n + MbPrimitive is ancestor for triangulation (#MbGrid), polygon (#MbPolygon3D), and apex (#MbApex3D). \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbPrimitive : public MbAttributeContainer, public MbRefItem { +protected: + SimpleName name; ///< \ru Имя примитива. \en Name of primitive. + const MbRefItem * parentItem; ///< \ru Породивший объект (не владеем). \en Begetter object (don't own). + MbeRefType type; ///< \ru Тип примитива. \en Type of primitive. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbPrimitive( const MbPrimitive & ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbPrimitive( const MbPrimitive &, MbRegDuplicate * iReg ); + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbPrimitive(); +public: + /// \ru Деструктор \en Destructor + virtual ~MbPrimitive(); + +public: + + /** \ru \name Общие функции примитива. + \en \name Common functions of primitive. + \{ */ + /// \ru Получить тип объекта. \en Get the object type. + virtual MbePrimitiveType Type() const = 0; + /// \ru Регистрационный тип (для копирования, дублирования). \en Registration type (for copying, duplication). + virtual MbeRefType RefType() const; + + /** \brief \ru Создать копию примитива. + \en Create a copy of primitive. \~ + \details \ru Создать копию примитива с использованием регистратора. + Регистратор используется для предотвращения многократного копирования примитива, + входящего в состав нескольких объектов копируемых одновременно. + При копировании одиночного объекта или набора не связанных между собой объектов допустимо не использовать регистратор. + Регистратор необходимо использовать, если надо последовательно копировать несколько взаимосвязанных объектов. + Взаимосвязь представляет собой наличие в объектах ссылок на общие примитивы. + Тогда, при копировании без использования регистратора, можно получить набор копий, + содержащих ссылки на разные копии одного и того же вложенного примитива, что ведет к потере связи между копиями. + \en Create a copy of primitive using the registrator. + Registrator is used for preventing multiple copying of primitive + contained in several simultaneously copied objects. + It is allowed not to use the registrator while copying a single object or a set of disconnected objects. + The registrator must be used to copy several correlated objects successively. + Correlation is an existence of references to common primitives in objects. + Then, while copying without using the registrator, one can get a set of copies + which contains references to the different copies of a single included primitive, what leads to loss of connection between the copies. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \return \ru Копия объекта. + \en The object copy. \~ + */ + virtual MbPrimitive & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; + + /** \brief \ru Преобразовать примитив согласно матрице. + \en Transform primitive according to the matrix. \~ + \details \ru Преобразовать примитив согласно матрице c использованием регистратора. + Регистратор служит для предотвращения многократного преобразования примитива, + входящего в состав нескольких объектов, трансформируемых одновременно. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных примитивов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих примитивов, подлежащих трансформации. + \en Transform primitive according to the matrix using the registrator. + The registrator is used for preventing multiple transformation of primitive + contained in several simultaneously transformed objects. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested primitives, since it is not ruled out + that several objects from the set contain references to one or several common primitives subject to transformation. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + */ + virtual void Transform( const MbMatrix3D & matr ) = 0; + + /** \brief \ru Сдвинуть примитив вдоль вектора. + \en Move primitive along a vector. \~ + \details \ru Сдвинуть примитив вдоль вектора с использованием регистратора. + Регистратор служит для предотвращения многократного преобразования примитива, + входящего в состав нескольких объектов, трансформируемых одновременно. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных примитивов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих примитивов, подлежащих сдвигу. + \en Move primitive along the vector using the registrator. + The registrator is used for preventing multiple transformation of primitive + contained in several simultaneously transformed objects. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested primitives, since it is not ruled out + that several objects from the set contain references to one or several common primitives subject to moving. \~ + \param[in] to - \ru Вектор сдвига. + \en Movement vector. \~ + */ + virtual void Move( const MbVector3D & to ) = 0; + + /** \brief \ru Повернуть примитив вокруг оси на заданный угол. + \en Rotate primitive about an axis by a given angle. \~ + \details \ru Повернуть примитив вокруг оси на заданный угол с использованием регистратора. + Регистратор служит для предотвращения многократного преобразования примитива, + входящего в состав нескольких объектов, трансформируемых одновременно. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных примитивов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих примитивов, подлежащих повороту. + \en Rotate primitive about an axis by a given angle using the registrator. + The registrator is used for preventing multiple transformation of primitive + contained in several simultaneously transformed objects. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested primitives, since it is not ruled out + that several objects from the set contain references to one or several common primitives subject to rotation. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + */ + virtual void Rotate( const MbAxis3D & axis, double angle ) = 0; + + // \ru Тип контейнера атрибутов. \en Type of attribute container. + virtual MbeImplicationType ImplicationType() const; + /// \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual void AddYourGabaritTo( MbCube & r ) const = 0; + /// \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual double DistanceToPoint( const MbCartPoint3D & pnt ) const = 0; + /// \ru Вычислить расстояние до оси. \en Calculate the distance to the axis. + virtual double DistanceToLine( const MbAxis3D & axis, double maxDistance, double & t ) const = 0; + /// \ru Выдать свойства объекта. \en Get properties of the object. + virtual void GetProperties( MbProperties & ) = 0; + /// \ru Записать свойства объекта. \en Set properties of the object. + virtual void SetProperties( const MbProperties & ) = 0; + + // \ru Выдать имя примитива. \en Get name of primitive. + SimpleName GetPrimitiveName() const { return name; } + // \ru Установить имя примитива. \en Set name of primitive. + void SetPrimitiveName( SimpleName n ) { name = n; } + /// \ru Выдать породивший примитив объект. \en Get begetter object of primitive. + const MbRefItem * GetItem() const { return parentItem; } + /// \ru Установить породивший примитив объект. \en Set begetter object of primitive. + void SetItem( const MbRefItem * g ) { parentItem = g; } + /// \ru Дать тип объекта. \en Get type of object. + MbeRefType GetPrimitiveType() const { return type; } + /// \ru Установить тип объекта. \en Set type of object. + void SetPrimitiveType( MbeRefType t ) { type = t; } + + /// \ru Удовлетворяет ли примитив критериям поиска ближайшего объекта? \en Does the primitive satisfy the nearest object search criteria? + bool NearestType( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType ) const; + + /// \ru Получить пространственный объект, для которого построен примитив. \en Get spatial object for which the primitive is constructed. + const MbSpaceItem * SpaceItem() const { return ((parentItem != NULL && parentItem->RefType() == rt_SpaceItem) ? (const MbSpaceItem *)parentItem : NULL); } + /// \ru Получить двумерный объект, для которого построен примитив. \en Get two-dimensional object for which the primitive is constructed. + const MbPlaneItem * PlaneItem() const { return ((parentItem != NULL && parentItem->RefType() == rt_PlaneItem) ? (const MbPlaneItem *)parentItem : NULL); } + /// \ru Получить топологический объект, для которого построен примитив. \en Get the topological object for which the primitive is constructed. + const MbTopItem * TopItem() const { return ((parentItem != NULL && parentItem->RefType() == rt_TopItem) ? (const MbTopItem *)parentItem : NULL); } + /// \ru Получить объект геометрической модели, для которого построен примитив. \en Get geometric model object for which the primitive is constructed. + const MbItem * Item() const { return ((parentItem != NULL && parentItem->RefType() == rt_SpaceItem) ? (static_cast(parentItem)) : NULL); } + + /// \ru Чтение примитива из потока. \en Reading of primitive from the stream. + void PrimitiveRead ( reader & in ); + /// \ru Запись примитива в поток. \en Writing of primitive to the stream. + void PrimitiveWrite( writer & out ) const; + /** \} */ +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en Declaration without implementation of the assignment operator to prevent an assignment by default + void operator = ( const MbPrimitive & init ); +}; // MbPrimitive + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Апекс (точка). + \en Apex (point). \~ + \details \ru Апекс определяет положение точки, вершины или другого точечного объекта в пространстве.\n + \en Apex defines position of a point, of a vertex or the other point-object in space.\n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbApex3D : public MbPrimitive { + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent a copying by default + MbApex3D( const MbApex3D & init ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbApex3D( const MbApex3D & init, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbApex3D() : MbPrimitive() {} + /// \ru Деструктор \en Destructor + virtual ~MbApex3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType Type() const; // \ru Тип объекта. \en A type of an object. + virtual MbePrimitiveType IsA() const = 0; // \ru Тип объекта. \en A type of an object. + virtual MbApex3D & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ) = 0; // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D & to ) = 0; // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D & axis, double angle ) = 0; // \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & pnt ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to the point. + virtual double DistanceToLine( const MbAxis3D & axis, double maxDistance, double & t ) const; // \ru Вычислить расстояние до оси. \en Calculate the distance to the axis. + virtual void GetProperties( MbProperties &properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + + /** \ru \name Функции апекса. + \en \name Functions of the apex. + \{ */ + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbCartPoint3D & vert ) = 0; + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbFloatPoint3D & vert ) = 0; + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbCartPoint3D & p ) const = 0; + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbFloatPoint3D & p ) const = 0; + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbApex3D & init, double eps ) const = 0; + /// \ru Инициировать по другому объекту. \en Init by other apex. + virtual void Init( const MbApex3D & other ) = 0; + + /** \} */ +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbApex3D & init ); + +}; // MbApex3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Апекс на числах double. + \en Apex on double data. \~ + \details \ru Апекс определяет положение точки, вершины или другого точечного объекта в пространстве.\n + \en Apex defines position of a point, of a vertex or the other point-object in space.\n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbExactApex3D : public MbApex3D { +private : + MbCartPoint3D vertex; ///< \ru Положение апекса. \en Position of the apex. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent a copying by default + MbExactApex3D( const MbExactApex3D & init ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbExactApex3D( const MbExactApex3D & init, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbExactApex3D() : MbApex3D(), vertex() {} + /// \ru Конструктор по точке. \en Constructor by point. + MbExactApex3D( const MbFloatPoint3D & vert ) : MbApex3D(), vertex( vert.x, vert.y, vert.z ) {} + /// \ru Конструктор по точке. \en Constructor by point. + MbExactApex3D( const MbCartPoint3D & vert ) : MbApex3D(), vertex( vert ) {} + /// \ru Деструктор \en Destructor + virtual ~MbExactApex3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbExactApex3D & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D & to ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D & axis, double angle ); // \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + + /** \ru \name Функции апекса. + \en \name Functions of the apex. + \{ */ + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbCartPoint3D & vert ); + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbFloatPoint3D & vert ); + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbCartPoint3D & p ) const { p = vertex; } + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbFloatPoint3D & p ) const { p.Init( vertex.x, vertex.y, vertex.z );} + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbApex3D & init, double eps ) const; + /// \ru Инициировать по другому объекту. \en Init by other apex. + virtual void Init( const MbApex3D & other ); + + /** \} */ +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbExactApex3D & init ); + + DECLARE_NEW_DELETE_CLASS( MbExactApex3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbExactApex3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbExactApex3D, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbExactApex3D, MATH_FUNC_EX ); +}; // MbExactApex3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Апекс на числах float. + \en Apex on float data. \~ + \details \ru Апекс определяет положение точки, вершины или другого точечного объекта в пространстве.\n + \en Apex defines position of a point, of a vertex or the other point-object in space.\n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbFloatApex3D : public MbApex3D { +private : + MbFloatPoint3D vertex; ///< \ru Положение апекса. \en Position of the apex. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent a copying by default + MbFloatApex3D( const MbFloatApex3D & init ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbFloatApex3D( const MbFloatApex3D & init, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbFloatApex3D() : MbApex3D(), vertex() {} + /// \ru Конструктор по точке. \en Constructor by point. + MbFloatApex3D( const MbFloatPoint3D & vert ) : MbApex3D(), vertex( vert ) {} + /// \ru Конструктор по точке. \en Constructor by point. + MbFloatApex3D( const MbCartPoint3D & vert ) : MbApex3D(), vertex( vert.x, vert.y, vert.z ) {} + /// \ru Деструктор \en Destructor + virtual ~MbFloatApex3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbFloatApex3D & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D & to ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D & axis, double angle ); // \ru Повернуть вокруг оси на угол. \en Rotate about an axis by an angle. + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + + /** \ru \name Функции апекса. + \en \name Functions of the apex. + \{ */ + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbCartPoint3D & vert ); + /// \ru Инициализировать апекс по точке. \en Initialize apex by a point. + virtual void Init( const MbFloatPoint3D & vert ); + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbCartPoint3D & p ) const { p.Init( vertex.x, vertex.y, vertex.z ); } + /// \ru Инициализировать точку по апексу. \en Initialize point by an apex. + virtual void GetPoint( MbFloatPoint3D & p ) const { p = vertex; } + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbApex3D & init, double eps ) const; + /// \ru Инициировать по другому объекту. \en Init by other apex. + virtual void Init( const MbApex3D & other ); + + /** \} */ +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbFloatApex3D & init ); + + DECLARE_NEW_DELETE_CLASS( MbFloatApex3D ) + DECLARE_NEW_DELETE_CLASS_EX( MbFloatApex3D ) + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbFloatApex3D, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbFloatApex3D, MATH_FUNC_EX ); +}; // MbFloatApex3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Полигон. + \en Polygon. \~ + \details \ru Полигон представляет собой упорядоченное множество точек в пространстве, + последовательное соединение которых даёт ломаную линию, аппроксимирующую некоторый объект или часть объекта. \n + \en Polygon is an ordered set of points in space, + sequential connection of these points produces polyline that approximates an object or part of an object. \n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbPolygon3D : public MbPrimitive { +protected : + MbStepData stepData; ///< \ru Параметры расчета полигона (стрелка прогиба или угол отклонения). \en Parameters of polygon calculation (sag or angle of deviation). + /** \brief \ru Габаритный куб объекта (не записывается в поток и не читается). + \en Bounding box of a polygon (not read from stream and not written to stream). \~ + \details \ru Габаритный куб объекта рассчитывается только при запросе габарита объекта. Габаритный куб в конструкторе объекта и после модификации объекта принимает неопределенное значение. + \en Bounding box of object is calculated only at the request. Bounding box of object is undefined after object constructor and after object modifications \n \~ + */ + mutable MbCube cube; ///< \ru Габаритный куб полигона (не записывается в поток и не читается). \en . + +protected : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию \en Declaration without implementation of the copy-constructor to prevent copying by default + MbPolygon3D( const MbPolygon3D & ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbPolygon3D( const MbPolygon3D &, MbRegDuplicate * ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbPolygon3D(); + /// \ru Деструктор \en Destructor + virtual ~MbPolygon3D(); + +public: + + // \ru Общие функции примитива. \en Common functions of the primitive. + virtual MbePrimitiveType Type() const; // \ru Вернуть тип объекта \en Get the object type. + virtual MbePrimitiveType IsA() const = 0; // \ru Вернуть тип объекта \en Get the object type. + virtual MbPolygon3D & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; // \ru Создать копию объекта \en Create a copy of the object + virtual void Transform( const MbMatrix3D & ) = 0; // \ru Преобразовать полигон согласно матрице \en Transform polygon according to the matrix + virtual void Move ( const MbVector3D & ) = 0; // \ru Сдвиг полигона \en Translation of the polygon. + virtual void Rotate ( const MbAxis3D &, double angle ) = 0; // \ru Поворот полигона вокруг оси \en Rotation of the polygon around an axis + virtual void AddYourGabaritTo( MbCube & ) const = 0; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & ) const = 0; // \ru Вычислить расстояние до точки. \en Calculate distance to the point. + virtual double DistanceToLine( const MbAxis3D &, double maxDistance, double & t ) const = 0; // \ru Вычислить расстояние до оси. \en Calculate the distance to the axis. + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + + /** \ru \name Функции полигона. + \en \name Functions of polygon. + \{ */ + /// \ru Выдать размер занимаемой памяти. \en Get the size of taken memory. + virtual size_t SizeOf() const = 0; + /// \ru Зарезервировать место для полигона. \en Reserve memory for polygon. + virtual void Reserve( size_t cnt ) = 0; + /// \ru Удалить лишнюю память. \en Free the unnecessary memory. + virtual void Adjust() = 0; + /// \ru Очистить полигон удалив все точки. \en Clear the polygon by deleting all the points. + virtual void Flush() = 0; + /// \ru Выдать количество точек. \en Get count of points. + virtual size_t Count() const = 0; + /// \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbCartPoint3D & dpnt ) = 0; + /// \ru Добавить точку в конец полигона. \en Add point to the end of the polygon. + virtual void AddPoint( const MbFloatPoint3D & fpnt ) = 0; + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbCartPoint3D & dp ) const = 0; + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint( size_t i, MbFloatPoint3D & fp ) const = 0; + + /// \ru Установить точку с номером. \en Set point by index. + virtual void SetPoint( size_t i, MbCartPoint3D & pnt ) = 0; + + /**\ru Проверить, лежат ли точки полигона в одной плоскости c заданной точностью metricAccuracy. + Если да, то инициализировать плоскость plane. + \en Check whether all points of polygon lie on the same plane with the given metricAccuracy accuracy. + if so, then initialize 'plane' plane. \~ + */ + virtual bool IsPlanar( MbPlacement3D & plane, double metricAccuracy = Math::metricRegion ) const = 0; + /// \ru Если точки полигона лежат в одной плоскости, то инициализировать plane и заполнить полигон poly. \en If points of polygon lie on the same plane, then initialize 'plane' and fill the 'poly' polygon. + virtual bool GetPlanePolygon( MbPlacement3D & plane, MbPolygon & poly ) const = 0; + /// \ru Проверить наличие точек в объекте. \en Check existence of points in object. + virtual bool IsComplete() const = 0; + + /// \ru Выдать параметр расчета триангуляции (стрелку прогиба или угол отклонения). \en Get the parameter of triangulation calculation. + const MbStepData & GetStepData() const { return stepData; } + /// \ru Установить параметр расчета триангуляции (стрелку прогиба или угол отклонения). \en Set the parameter of triangulation calculation. + void SetStepData( const MbStepData & stData ) { stepData = stData; } + /// \ru Установить параметр расчета полигона (стрелку прогиба или угол отклонения). \en Set the parameter of polygon calculation (sag or angle of deviation). + void SetStepBySag( double s ) { stepData.InitStepBySag( s ); } + + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void AddPolygon( const MbPolygon3D & other ) = 0; + /// \ru Добавить к полигону полигон с удалением совпадающих точек стыка. \en Add a polygon to the polygon with removing the coincident points of joint. + virtual void operator += ( const MbPolygon3D & other ) = 0; + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbPolygon3D & other, double eps ) const = 0; + /// \ru Инициировать по другому полигону. \en Init by other polygon. + virtual void Init( const MbPolygon3D & other ) = 0; + + /// \ru Создать ломаную по полигону. \en Create a polyline on the base of the polygon. + virtual MbPolyline3D * CreatePolyline() const = 0; + + /** \} */ + + /// \ru Выдать все точки полигона. \en Get all the points of the polygon. + void GetPoints( std::vector & pnts ) const; + /// \ru Выдать все точки полигона. \en Get all the points of the polygon. + void GetPoints( std::vector & pnts ) const; + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbPolygon3D & ); + +}; // MbPolygon3D + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Триангуляция. + \en Triangulation. \~ + \details \ru Триангуляция представляет собой набор треугольных и четырёхугольных пластин, + стыкующихся друг с другом по общим сторонам.\n + В простейшем случае триангуляция состоит из набора точек и набора треугольников. + Треугольник - это три номера из набора точек, определяющих вершины треугольника. + Триангуляция используется для аппроксимации криволинейных поверхностей. + В определенных случаях использование плоских пластин значительно упрощает работу с криволинейными поверхностями. + Триангуляция описывает геометрическую форму объектов с определённой степенью точности.\n + Триангуляция используется для получения точечных изображений, вычисления + масс-инерционных характеристик, проверки столкновений объектов, проведения численных + экспериментов над моделями. Для одного и того же объекта триангуляция может + иметь разное наполнение данных, в зависимости от назначения.\n + \en Triangulation represents a set of triangular and quadrangular plates + which are joined to each other by their common sides.\n + In simple case triangulation consists of a set of points and a set of triangles. + Triangle is represented as three numbers from the set of points defining vertices of triangle. + Triangulation is used for approximation of curved surfaces. + In certain cases use of flat plates significantly simplifies work + with curved surfaces. Triangulation describes geometric form of objects + with the specified accuracy.\n + Triangulation is used for obtaining point-images, for calculating + mass-inertial properties, for collision detection, for numerical + experiments with models. For the same object triangulation can + have different data depending on its purpose.\n \~ + \par \ru Назначения триангуляции + От назначения триангуляции зависит наполнение данных:\n + Если триангуляция предназначена для визуализации геометрической формы, + то заполняются множества points и normals, + шаг движения вдоль кривых и поверхностей вычисляется по стрелке прогиба, работают функции Step, StepU, StepV.\n + Если триангуляция предназначена для аппроксимации геометрической формы с привязкой к параметрам поверхности, + то заполняются множества params, points и normals, + шаг движения вдоль кривых и поверхностей вычисляется по стрелке прогиба.\n + Если триангуляция предназначена для вычисления инерционных характеристик, + то заполняется множество params, шаг движения вдоль кривых и поверхностей вычисляется по углу отклонения нормали, + работают функции DeviationStep, DeviationStepU, DeviationStepV.\n + Если триангуляция предназначена для определения столкновений элементов модели, + то заполняются множества params и points, шаг движения вдоль кривых и поверхностей + вычисляется по стрелке прогиба, работают функции Step, StepU, StepV.\n + Если триангуляция предназначена для разбивки на элементы, + то заполняются множества points и normals, шаг движения вдоль кривых и поверхностей + вычисляется с ограничением длины сторон треугольников, может быть добавлено ограничение по стрелке прогиба и углу отклонения нормали. + (работают функции MetricStep, MetricStepU, MetricStepV).\n + \en Purposes of triangulation + Data depends on purposes of triangulation:\n + If triangulation is intended for visualization of a geometric form, + then 'points' and 'normals' sets are filled (in case of planes 'normals' contains one + element), spacing of sample along the curves and the surfaces is calculated by stepData + (Step, StepU, StepV functions work).\n + If triangulation is intended for visualization of geometric form and + texture, then 'params', 'points' and 'normals' sets are filled, spacing of sample along + curves and surfaces is calculated by stepData.\n + If triangulation is intended for calculation of mass-inertial properties, + then 'params' set is filled, spacing of sample along curves and surfaces + is calculated by angle of deviation (DeviationStep, DeviationStepU, + DeviationStepV functions work).\n + If triangulation is intended for collision detection between elements of model, + then 'params' and 'points' sets are filled, spacing of sample along curves and surfaces + is calculated by stepData (Step, StepU, StepV functions work).\n + If triangulation is intended for splitting into elements, + then 'normals' and 'points' sets are filled, spacing of sampling along curves and surfaces + is calculated by angle of deviation with limiting of length + (MetricStep, MetricStepU, MetricStepV functions work).\n \~ + \ingroup Polygonal_Objects +*/ +//////////////////////////////////////////////////////////////////////////////// +class MATH_CLASS MbGrid : public MbPrimitive { +protected: + std::vector triangles; ///< \ru Индексное множество треугольных пластин содержит номера элементов множества params и/или множеств points и normals. \en Set of triangular plates contains numbers of elements of 'params' set and/or of 'points' and 'normals' sets. + std::vector quadrangles; ///< \ru Индексное множество четырёхугольных пластин содержит номера элементов множества params и/или множеств points и normals. \en Set of quadrangular plates contains numbers of elements of 'params' set and/or of 'points' and 'normals' sets. + std::vector loops; ///< \ru Индексное множество граничных циклов триангуляции содержит номера элементов множества points и/или params. Объект владеет элементами множества. \en Set of bounding loops contains numbers of elements of 'points' set and/or of 'params' set. Ownership of elements of set. + MbStepData stepData; ///< \ru Параметр расчета триангуляции. \en Parameter of triangulation calculation. + /** \brief \ru Габаритный куб объекта. + \en Bounding box of object. \~ + \details \ru Габаритный куб объекта рассчитывается только при запросе габарита объекта. Габаритный куб в конструкторе объекта и после модификации объекта принимает неопределенное значение. + \en Bounding box of object is calculated only at the request. Bounding box of object is undefined after object constructor and after object modifications \n \~ + */ + mutable MbCube cube; + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbGrid( const MbGrid & init ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbGrid( const MbGrid & init, MbRegDuplicate * iReg ); + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbGrid(); +public: + /// \ru Деструктор. \en Destructor. + virtual ~MbGrid(); + +public: + + /** \ru \name Общие функции примитива. + \en \name Common functions of primitive. + \{ */ + virtual MbePrimitiveType Type() const; // \ru Тип объекта. \en A type of an object. + virtual MbePrimitiveType IsA() const = 0;; // \ru Тип объекта. \en A type of an object. + virtual MbGrid & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; // \ru Создать копию объекта. \en Create a copy of the object. + virtual void Transform( const MbMatrix3D & matr ) = 0; // \ru Преобразовать сетку согласно матрице. \en Transform mesh according to the matrix. + virtual void Move ( const MbVector3D & to ) = 0; // \ru Сдвиг сетки. \en Move mesh. + virtual void Rotate ( const MbAxis3D & axis, double angle ) = 0; // \ru Поворот сетки вокруг оси. \en Rotation of mesh about an axis. + virtual void AddYourGabaritTo( MbCube & r ) const = 0; // \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual double DistanceToPoint( const MbCartPoint3D & pnt ) const = 0; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual double DistanceToLine( const MbAxis3D & axis, double maxDistance, double & t ) const = 0; // \ru Вычислить расстояние до оси. \en Calculate the distance to an axis. + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + + /** \} */ + /** \ru \name Функции триангуляции. + \en \name Functions of triangulation. + \{ */ + /// \ru Проверить наличие данных. \en Check data availability. + bool IsComplete() const { return (triangles.size() > 0) || (quadrangles.size() > 0) || (loops.size() > 0); } + /// \ru Выдать количество точек. \en Get the number of points. + virtual size_t PointsCount() const = 0; + /// \ru Выдать количество нормалей. \en Get the number of normals. + virtual size_t NormalsCount() const = 0; + /// \ru Выдать количество параметров. \en Get the number of parameters. + virtual size_t ParamsCount() const = 0; + /// \ru Выдать количество значений. \en Get count of values. + virtual size_t EscortsCount() const = 0; + /// \ru Выдать количество точек минус 1 (максимальный индекс). \en Get the number of points minus one (maximal index). + virtual ptrdiff_t PointsMaxIndex() const = 0; + /// \ru Выдать количество нормалей минус 1 (максимальный индекс). \en Get the number of normals minus one (maximal index). + virtual ptrdiff_t NormalsMaxIndex() const = 0; + /// \ru Выдать количество параметров минус 1 (максимальный индекс). \en Get the number of parameters minus one (maximal index). + virtual ptrdiff_t ParamsMaxIndex() const = 0; + + // \ru Выдать количество треугольников. \en Get the number of triangles. + size_t TrianglesCount() const { return triangles.size(); } + // \ru Выдать количество четырёхугольников. \en Get the number of quadrangles. + size_t QuadranglesCount() const { return quadrangles.size(); } + // \ru Выдать количество полигонов. \en Get the number of loops. + size_t LoopsCount() const { return loops.size(); } + + /// \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D, const MbVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbCartPoint & p2D, const MbCartPoint3D & p3D ) = 0; + /// \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D, const MbVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint ( const MbCartPoint3D & p3D ) = 0; + /// \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam ( const MbCartPoint & p2D ) = 0; + + /// \ru Добавить в триангуляцию параметры, точку и нормаль триангулируемой поверхности в точке. \en Add parameters, point and normal of triangulated surface at point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию параметры и точку. \en Add parameters and a point to triangulation. + virtual void AddPoint ( const MbFloatPoint & p2D, const MbFloatPoint3D & p3D ) = 0; + /// \ru Добавить в триангуляцию точку и нормаль в точке. \en Add a point and normal at the point to triangulation. + virtual void AddPoint ( const MbFloatPoint3D & p3D, const MbFloatVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию точку. \en Add a point to triangulation. + virtual void AddPoint( const MbFloatPoint3D & p3D ) = 0; + /// \ru Добавить в триангуляцию нормаль. \en Add a normal to triangulation. + virtual void AddNormal( const MbFloatVector3D & n3D ) = 0; + /// \ru Добавить в триангуляцию параметры триангулируемой поверхности. \en Add parameters of triangulated surface to triangulation. + virtual void AddParam( const MbFloatPoint & p2D ) = 0; + + /// \ru Добавить в триангуляцию объекты. \en Add objects to triangulation. + template + void AddTriangles ( const TrianglesVector & trngs ) { + size_t addCnt = trngs.size(); + triangles.reserve( triangles.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + triangles.push_back( trngs[k] ); + } + /// \ru Добавить в триангуляцию объекты. \en Add objects to triangulation. + template + void AddQuadrangles ( const QuadranglesVector & qrngs ) { + size_t addCnt = qrngs.size(); + quadrangles.reserve( quadrangles.size() + addCnt ); + for ( size_t k = 0; k < addCnt; k++ ) + quadrangles.push_back( qrngs[k] ); + } + + /// \ru Добавить в коллекцию данных. \en Add scores to collection. + virtual void AddEscorts( const std::vector & scores ) = 0; + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbCartPoint3D & p ) const = 0; + /// \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbVector3D & n ) const = 0; + /// \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbCartPoint & p ) const = 0; + /// \ru Выдать дополнительную информацию по её номеру. \en Get additional information by its index. + virtual const uint32 & GetEscort( size_t i ) const = 0; + + /// \ru Выдать точку по её номеру. \en Get point by its index. + virtual void GetPoint ( size_t i, MbFloatPoint3D & p ) const = 0; + /// \ru Выдать нормаль по её номеру. \en Get normal by its index. + virtual void GetNormal( size_t i, MbFloatVector3D & n ) const = 0; + /// \ru Выдать параметр по его номеру. \en Get parameter by its index. + virtual void GetParam ( size_t i, MbFloatPoint & p ) const = 0; + + /// \ru Установить точку с заданным номером. \en Set point by the given index. + virtual void SetPoint ( size_t i, const MbCartPoint3D & p ) = 0; + /// \ru Установить нормаль с заданным номером. \en Set normal by the given index. + virtual void SetNormal( size_t i, const MbVector3D & n ) = 0; + /// \ru Установить параметр с заданным номером. \en Set parameter by the given index. + virtual void SetParam ( size_t i, const MbCartPoint & p ) = 0; + /// \ru Установить дополнительную информацию по её номеру. \en Set additional information by its index. + virtual void SetEscort( size_t i, const uint32 & e ) = 0; + + /// \ru Удалить точку с заданным номером. \en Delete point by the given index. + virtual void PointRemove ( size_t i ) = 0; + /// \ru Удалить нормаль с заданным номером. \en Delete normal by the given index. + virtual void NormalRemove( size_t i ) = 0; + /// \ru Удалить параметры поверхности с заданным номером. \en Delete parameters of surface by the given index. + virtual void ParamRemove ( size_t i ) = 0; + /// \ru Удалить треугольник по его индексу. \en Delete triangle by its index. + void TriangleRemove ( size_t k ); + /// \ru Удалить четырёхугольник по его индексу. \en Delete quadrangle by its index. + void QuadrangleRemove( size_t k ); + /// \ru Удалить полигон по его индексу. \en Delete polygon by its index. + void LoopRemove ( size_t k ); + + /// \ru Удалить точки. \en Delete points. + virtual void PointsDelete() = 0; + /// \ru Удалить нормали. \en Delete normal. + virtual void NormalsDelete() = 0; + /// \ru Удалить параметры. \en Delete params. + virtual void PapamsDelete() = 0; + /// \ru Удалить дополнительную информацию. \en Delete additional information. + virtual void EscortsDelete() = 0; + /// \ru Удалить все треугольники. \en Delete all triangles. + void TrianglesDelete(); + /// \ru Удалить все четырёхугольники. \en Delete all quadrangles. + void QuadranglesDelete(); + /// \ru Удалить все полигоны. \en Delete all polygons. + void LoopsDelete(); + + /// \ru Инвертировать нормали. \en Invert normals. + virtual void NormalsInvert() = 0; + + // \ru Добавить треугольник. \en Add a triangle. + void AddTriangle ( const MbTriangle & triangle ) { triangles.push_back( triangle ); } + // \ru Добавить треугольник с заданными номерами вершин. \en Add a triangle by the given indices of vertices + void AddTriangle ( uint j0, uint j1, uint j2, bool o ) { MbTriangle t(j0,j1,j2,o); triangles.push_back( t ); } + + // \ru Добавить четырёхугольник. \en Add a quadrangle. + void AddQuadrangle( const MbQuadrangle & quadrangle ) { quadrangles.push_back( quadrangle ); } + // \ru Добавить четырёхугольник с заданными номерами вершин. \en Add a quadrangle by the given indices of vertices. + void AddQuadrangle( uint j0, uint j1, uint j2, uint j3, bool o ) { MbQuadrangle t(j0,j1,j2,j3,o); quadrangles.push_back( t ); } + + // \ru Добавить полигон. \en Add a polygon. + void AddGridLoop ( MbGridLoop & poly ) { loops.push_back( &poly ); } + // \ru Собрать внешние полигоны. \en Collect outer loops. + void CollectEdges( std::vector & edges ) const; + + /// \ru Выдать индексы точек в массиве points для i-го треугольника (связанного или несвязанного). \en Get indices of points in 'points' array for i-th triangle (adjacent or non-adjacent). + bool GetTrianglePointIndex ( size_t i, uint & ind0, uint & ind1, uint & ind2 ) const; + /// \ru Выдать индексы точек в массиве points для i-го четырехугольника (связанного или несвязанного). \en Get indices of points in 'points' array for i-th quadrangle (adjacent or non-adjacent). + bool GetQuadranglePointIndex( size_t i, uint & ind0, uint & ind1, uint & ind2, uint & ind3 ) const; + + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th triangle in general numbering (with strips). + virtual bool GetTriangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2 ) const = 0; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2 ) const = 0; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th triangle in general numbering (with strips). + virtual bool GetTrianglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2 ) const = 0; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D & n2 ) const = 0; + // \ru Выдать для треугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th triangle in general numbering (with strips). + virtual bool GetTriangleNormals ( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2 ) const = 0; + + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) параметры поверхности. \en Get parameters of surface for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleParams ( size_t i, MbCartPoint & r0, MbCartPoint & r1, MbCartPoint & r2, MbCartPoint & r3 ) const = 0; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbCartPoint3D & p0, MbCartPoint3D & p1, MbCartPoint3D & p2, MbCartPoint3D & p3 ) const = 0; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) точки вершин. \en Get points of vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadranglePoints ( size_t i, MbFloatPoint3D & p0, MbFloatPoint3D & p1, MbFloatPoint3D & p2, MbFloatPoint3D & n3 ) const = 0; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbVector3D & n0, MbVector3D & n1, MbVector3D &n2, MbVector3D & n3 ) const = 0; + // \ru Выдать для четырёхугольника с номером i в общей нумерации (с полосами) нормали в вершинах. \en Get normals at vertices for i-th quadrangle in general numbering (with strips). + virtual bool GetQuadrangleNormals( size_t i, MbFloatVector3D & n0, MbFloatVector3D & n1, MbFloatVector3D & n2, MbFloatVector3D & n3 ) const = 0; + + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbVector3D & ) const = 0; + // \ru Выдать первую нормаль для плоской триангуляции, если количество точек больше количества нормалей (только для плоской триангуляции). \en Get first normal for flat triangulation if count of points is greater than count of normals (only for planar triangulation). + virtual bool GetSingleNormal ( MbFloatVector3D & ) const = 0; + /// \ru Если количество точек больше количества нормалей, то добавить недостающие нормали (только для плоской триангуляции). \en If count of points is greater than count of normals, then add missing normals (only for planar triangulation). + virtual void SynchronizNormals () = 0; + + // \ru Выдать треугольник с номером i. \en Get i-th triangle. + const MbTriangle & GetTriangle ( size_t i ) const { return triangles[i]; } + // \ru Выдать четырёхугольник с номером i. \en Get i-th quadrangle. + const MbQuadrangle & GetQuadrangle( size_t i ) const { return quadrangles[i]; } + // \ru Выдать полигон с номером i. \en Get i-th polygon. + const MbGridLoop & GetGridLoop ( size_t i ) const { return *loops[i]; } + + // \ru Выдать для треугольника с номером i номера точек вершин. \en Get indices of vertex points for i-th triangle. + bool GetTriangleIndex ( size_t i, uint & i0, uint & i1, uint & i2 ) const; + // \ru Выдать для четырёхугольника с номером i номера точек вершин. \en Get indices of points of vertices for i-th quadrangle. + bool GetQuadrangleIndex ( size_t i, uint & i0, uint & i1, uint & i2, uint & i3 ) const; + + // \ru Выдать контейнер треугольников. \en Get the container of triangles. + template + void GetTriangles( TrianglesVector & tVector ) const { + tVector.reserve( tVector.size() + triangles.size() ); + for ( size_t i = 0, iCount = triangles.size(); i < iCount; i++ ) + tVector.push_back( triangles[i] ); + } + // \ru Выдать контейнер четырёхугольников. \en Get the container of quadrangles. + template + void GetQuadrangles( QuadranglesVector & qVector ) const { + qVector.reserve( qVector.size() + quadrangles.size() ); + for ( size_t i = 0, iCount = quadrangles.size(); i < iCount; i++ ) + qVector.push_back( quadrangles[i] ); + } + + /// \ru Преобразовать четырёхугольники в треугольники. \en Convert quadrangles to triangles. + void ConvertQuadranglesToTriangles(); + /// \ru Преобразовать все объекты в треугольники и уравнять число точек и нормалей. \en Convert all objects to triangles and equalize count of points and count of normals. + void ConvertAllToTriangles(); + + /// \ru Определить, пересекается ли проекция на глобальную плоскость XY треугольника с заданным номером с присланным прямоугольником. \en Determine whether the projection of triangle with a given index to the global XY-plane intersects the given rectangle. + virtual bool TriangleIntersectRect( size_t i, MbRect & rect ) const = 0; + /// \ru Рассчитать габаритный прямоугольник проекции на глобальную плоскость XY треугольника с заданным номером. \en Determine bounding box of the projection of triangle with given index to the global XY-plane. + virtual void TriangleGetGabRect ( size_t i, MbRect & rect ) const = 0; + + /// \ru Определить, пересекается ли проекция на глобальную плоскость XY четырёхугольника с заданным номером с присланным прямоугольником. \en Determine whether the projection of quadrangle with given index to the global XY-plane intersects the given rectangle. + virtual bool QuadrangleIntersectRect( size_t i, MbRect & rect ) const = 0; + /// \ru Рассчитать габаритный прямоугольник проекции на глобальную плоскость XY четырёхугольника с заданным номером. \en Determine bounding box of the projection of quadrangle with given index to the global XY-plane. + virtual void QuadrangleGetGabRect ( size_t i, MbRect & rect ) const = 0; + + /// \ru Расширить присланный габаритный прямоугольник так, чтобы он включал в себя проекцию данного объекта на глобальную плоскость XY. \en Extend given bounding box so that it enclose projection of this object to the global XY-plane. + virtual void AddRect( MbRect & rect ) const = 0; + /// \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. \en Extend given bounding box so that it encloses the given object. + virtual void AddCube( MbCube & r ) const = 0; + + /// \ru Удалить дублирующие с заданной точностью друг друга точки. \en Remove redundant points with a given tolerance (duplicates). + virtual bool RemoveRedundantPoints( bool deleteNormals, double epsilon = LENGTH_EPSILON ) = 0; + + /** + \brief \ru Определить положение объекта относительно плоскости. + \en Define the object position relative to the plane. \~ + \details \ru Определить положение объекта относительно плоскости XY локальной системы координат. + \en Determine the object position relative to the XY-plane of a local coordinate system. \~ + \param[in] pl - \ru Локальная система координат, задающая плоскость. + \en A local coordinate system which defines a plane. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \param[in] onlyInItem - \ru Интересует только положение объекта над плоскостью XY локальной системы координат. + \en Whether the object position relative to the XY-plane of a local coordinate system is interested only. \~ + \return \ru iloc_OnItem - объект пересекает плоскость XY локальной системы координат,\n + iloc_InItem - объект расположен над плоскостью XY локальной системы координат,\n + iloc_OutOfItem - объект расположен под плоскостью XY локальной системы координат. + \en Iloc_OnItem - object intersects the XY plane of a local coordinate system,\n + iloc_InItem - object is located over the XY plane of a local coordinate system,\n + iloc_OutOfItem - object is located under the XY plane of a local coordinate system. \~ + */ + virtual MbeItemLocation GetLocation( const MbPlacement3D & pl, double eps, bool onlyInItem = false ) const = 0; + + /** + \brief \ru Определить положение объекта относительно трубы. + \en Determine the object position relative to the tube. \~ + \details \ru Определить, расположен ли объект внутри трубы прямоугольного сечения, + заданного прямоугольником в плоскости XY локальной системы координат. + \en Determine whether the object is inside the tube of rectangular section + given by a rectangle in the XY plane of a local coordinate system. \~ + \param[in] place - \ru Локальная система координат, в в плоскости XY которой лежит сечение трубы. + \en A local coordinate system in the XY plane of which a tube section is located. \~ + \param[in] rect - \ru Прямоугольник, задающая сечение трубы. + \en A rectangle which defines a tube section. \~ + \param[in] eps - \ru Метрическая точность. + \en A metric tolerance. \~ + \param[in] onlyInItem - \ru Интересует только положение объекта внутри трубы. + \en Whether the object position relative to the tube is interested only. \~ + \return \ru true, если объект расположен внутри трубы. + \en True if the object is inside the tube. \~ + */ + virtual bool InsideLocation( const MbPlacement3D & place, MbRect & rect, double eps ) const = 0; + /// \ru Преобразовать триангуляцию так, чтобы её параллельная проекция выглядела как центральная проекция, наблюдаемая из заданной точки vista. \en Transform triangulation so that its parallel projection looks as the central projection observed from the given 'vista' point. + virtual void SetVista ( const MbCartPoint3D & vista ) = 0; + /// \ru Отменить преобразование триангуляцию для центральной проекции, наблюдаемой из заданной точки vista. \en Undo the transformation of triangulation for central projection observed from given 'vista' point. + virtual void DeleteVista( const MbCartPoint3D & vista ) = 0; + + /// \ru Зарезервировать память для контейнера параметров. \en Reserve memory for container of elements. + virtual void ParamsReserve ( size_t n ) = 0; + /// \ru Зарезервировать память для контейнера точек. \en Reserve memory for container of points. + virtual void PointsReserve ( size_t n ) = 0; + /// \ru Зарезервировать память для контейнера нормалей. \en Reserve memory for container of normals. + virtual void NormalsReserve ( size_t n ) = 0; + /// \ru Зарезервировать память для контейнера параметров. \en Reserve memory for container of elements. + virtual void EscordsReserve ( size_t n ) = 0; + + /// \ru Зарезервировать память для контейнера треугольников. \en Reserve memory for container of triangles. + void TrianglesReserve ( size_t n ) { triangles.reserve( triangles.size() + n ); } + /// \ru Зарезервировать память для контейнера четырёхугольников. \en Reserve memory for container of quadrangles. + void QuadranglesReserve( size_t n ) { quadrangles.reserve( quadrangles.size() + n ); } + /// \ru Зарезервировать память для контейнера полигонов. \en Reserve memory for container of loops. + void LoopsReserve ( size_t n ) { loops.reserve( loops.size() + n ); } + + /// \ru Зарезервировать память для контейнеров. \en Reserve memory for some containers. + virtual void ReserveParamsPoints( size_t n ) = 0; + /// \ru Зарезервировать память для контейнеров. \en Reserve memory for some containers. + virtual void ReservePointsNormals( size_t n ) = 0; + /// \ru Зарезервировать память для контейнеров. \en Reserve memory for some containers. + virtual void ReserveParamsPointsNormals( size_t n ) = 0; + + /// \ru Удалить всю триангуляцию без освобождения памяти, занятую контейнерами. \en Delete all triangulation without freeing the memory occupied by containers. + virtual void Flush() = 0; + /// \ru Удалить всю триангуляцию и освободить память. \en Delete all triangulation and free the memory. + virtual void HardFlush() = 0; + /// \ru Освободить лишнюю память. \en Free the unnecessary memory. + virtual void Adjust() = 0; + + /// \ru Выдать размер занимаемой памяти. \en Get the size of taken memory. + virtual size_t SizeOf() const = 0; + /// \ru Инвертировать последовательность вершин треугольников и четырехугольников. \en Reverse the sequence of vertices of triangles and quadrilaterals. + virtual void Reverse() = 0; + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbGrid & init, double eps ) const = 0; + + /// \ru Выдать параметр расчета триангуляции (стрелку прогиба или угол отклонения). \en Get the parameter of triangulation calculation. + const MbStepData & GetStepData() const { return stepData; } + /// \ru Установить параметр расчета триангуляции (стрелку прогиба или угол отклонения). \en Set the parameter of triangulation calculation. + void SetStepData( const MbStepData & stData ) { stepData = stData; } + /// \ru Вернуть габаритный куб. \en Return bounding box. + const MbCube & Cube() const { return cube; } + + // \ru Инициировать по другой триангуляции. \en Init by other triangulation. + virtual void Init( const MbGrid & grid ) = 0; + + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const MbTriangle * GetTrianglesAddr() const { return (!triangles.empty() ? &(triangles[0]) : NULL); } + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const MbQuadrangle * GetQuadranglesAddr() const { return (!quadrangles.empty() ? &(quadrangles[0]) : NULL); } + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbCartPoint3D * GetExactPointsAddr() const = 0; + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbVector3D * GetExactNormalsAddr() const = 0; + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbCartPoint * GetExactParamsAddr() const = 0; + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbFloatPoint3D * GetFloatPointsAddr() const = 0; + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbFloatVector3D * GetFloatNormalsAddr() const = 0; + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + virtual const MbFloatPoint * GetFloatParamsAddr() const = 0; + + /** \} */ + + /// \ru Выдать все точки триангуляции. \en Get all the points of the grid. + void GetPoints( std::vector & pnts ) const; + /// \ru Выдать все точки триангуляции. \en Get all the points of the grid. + void GetPoints( std::vector & pnts ) const; + /// \ru Выдать все нормали триангуляции. \en Get all the normals of the grid. + void GetNormals( std::vector & vecs ) const; + /// \ru Выдать все нормали триангуляции. \en Get all the normals of the grid. + void GetNormals( std::vector & vecs ) const; + /// \ru Выдать все параметрические точки триангуляции. \en Get all the params of the grid. + void GetParams( std::vector & pnts ) const; + /// \ru Выдать все параметрические точки триангуляции. \en Get all the params of the grid. + void GetParams( std::vector & pnts ) const; + + /// \ru Дать объекты, содержащие указанный индекс точки. \ en Get all triangles with point index ind. + bool FindTrianglesByPoint( uint ind, std::vector & objs ); + /// \ru Дать объекты, содержащие указанный индекс точки. \ en Get all quadrangles with point index ind. + bool FindQuadranglesByPoint( uint ind, std::vector & objs ); + /// \ru Сделать триангуляцию односвязной. \ en Make simply connected triangulation (make cuts from outer loop to iner loops with duplicated points of cuts). + bool MakeSimplyConnected(); + +private : + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbGrid & ); + +}; // MbGrid + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от прямой линии до сегмента полигона. + \en Calculate squared distance from straight line to segment of polygon. \~ + \details \ru Вычислить квадрат расстояния от прямой линии до сегмента полигона, заданного начальной и конечной точками. \n + Возвращает значение параметра ближайшей точки на линии tRes и квадрат расстояния от этой точки до сегмента. \n + Возвращает значение параметра ближайшей точки на линии tRes и квадрат расстояния от этой точки до сегмента. \n + \en Calculate squared distance from straight line to segment of polygon defined by start and end points. \n + Returns value of parameter of nearest point on tRes line and squared distance from this point to the segment. \n + Returns value of parameter of nearest point on tRes line and squared distance from this point to the segment. \n \~ + \param[in] seg_base - \ru Начальная точка сегмента. + \en Start point of the segment. \~ + \param[in] seg_end - \ru Начальная точка сегмента. + \en Start point of the segment. \~ + \param[in] line - \ru Прямая линия, до которой вычисляется расстояние. + \en Straight line to calculate the distance to. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки на линии. + \en Value of the nearest point parameter on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToSegmentDistanceSquared( const MbFloatPoint3D & seg_base, + const MbFloatPoint3D & seg_end, + const MbFloatAxis3D & line, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от прямой линии до сегмента полигона. + \en Calculate squared distance from straight line to segment of polygon. \~ + \details \ru Вычислить квадрат расстояния от прямой линии до сегмента полигона, заданного начальной и конечной точками. \n + Возвращает значение параметра ближайшей точки на линии tRes, вектор между ближайшими точками + и квадрат расстояния от этой точки до сегмента. \n + \en Calculate squared distance from straight line to segment of polygon defined by start and end points. \n + Returns the value of parameter of nearest point on the line, the vector between the nearest points + and the squared distance from this point to the segment. \n \~ + \param[in] seg_base - \ru Начальная точка сегмента. + \en Start point of the segment. \~ + \param[in] seg_end - \ru Начальная точка сегмента. + \en Start point of the segment. \~ + \param[in] line - \ru Прямая линия, до которой вычисляется расстояние. + \en Straight line to calculate the distance to. \~ + \param[out] vRes - \ru Вектор от ближайшей точки на линии до ближайшей точки на сегменте. + \en Vector from the nearest point on the line to the nearest point on the segment. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки на линии. + \en Value of the nearest point parameter on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToSegmentDistanceSquared( const MbFloatPoint3D & seg_base, + const MbFloatPoint3D & seg_end, + const MbFloatAxis3D & line, + MbFloatVector3D & vRes, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от линии до полигона. + \en Calculate squared distance from a line to a polygon. \~ + \details \ru При вычислении квадрата расстояния от линии до полигона проверяется расстояние от каждого + сегмента полигона до первого попадания в окрестность delta. + Возвращается значение параметра ближайшей точки на линии tRes и квадрат расстояния + от этой точки до сегмента полигона. \n + \en During calculation of squared distance from a line to a polygon the distance from each + segment of the polygon is checked until the first getting to 'delta' neighborhood. + Returns the value of the nearest point parameter on tRes line and the squared distance + from this point to a segment of the polygon. \n \~ + \param[in] poly - \ru Тестируемый полигон. + \en Polygon to check. \~ + \param[in] line - \ru Линия, до которой вычисляется расстояние. + \en Line to calculate the distance to. \~ + \param[in] delta - \ru Радиус окрестности вокруг линии. + \en Neighborhood radius around the line. \~ + \param[out] nearestPoint - \ru Ближайшая к лучу точка. + \en The nearest point of the polygon. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToPolyDistanceSquared( const MbPolygon3D & poly, + const MbFloatAxis3D & line, + float delta, + MbFloatPoint3D & nearestPoint, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от линии до полигона. + \en Calculate squared distance from a line to a polygon. \~ + \details \ru При вычислении квадрата расстояния от линии до полигона проверяется расстояние от каждого + сегмента полигона до первого попадания в окрестность delta. + Возвращается значение параметра ближайшей точки на линии tRes и квадрат расстояния + от этой точки до сегмента полигона. \n + \en During calculation of squared distance from a line to a polygon the distance from each + segment of the polygon is checked until the first getting to 'delta' neighborhood. + Returns the value of the nearest point parameter on tRes line and the squared distance + from this point to a segment of the polygon. \n \~ + \param[in] poly - \ru Тестируемый полигон. + \en Polygon to check. \~ + \param[in] line - \ru Линия, до которой вычисляется расстояние. + \en Line to calculate the distance to. \~ + \param[in] delta - \ru Радиус окрестности вокруг линии. + \en Neighborhood radius around the line. \~ + \param[in] cutPlace - \ru Отсекающая плоскость. + \en Cutting plane. \~ + \param[out] nearestPoint - \ru Ближайшая к лучу точка. + \en The nearest point of the polygon. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToPolyDistanceSquared( const MbPolygon3D & poly, + const MbFloatAxis3D & line, + float delta, + const MbPlacement3D & cutPlace, + MbFloatPoint3D & nearestPoint, + float & tRes ); + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить квадрат расстояния от линии до полигона. + \en Calculate squared distance from a line to a polygon. \~ + \details \ru При вычислении квадрата расстояния от линии до полигона проверяется расстояние от каждого + сегмента полигона до первого попадания в окрестность delta. + Возвращается значение параметра ближайшей точки на линии tRes и квадрат расстояния + от этой точки до сегмента полигона. \n + \en During calculation of squared distance from a line to a polygon the distance from each + segment of the polygon is checked until the first getting to 'delta' neighborhood. + Returns the value of the nearest point parameter on tRes line and the squared distance + from this point to a segment of the polygon. \n \~ + \param[in] poly - \ru Тестируемый полигон. + \en Polygon to check. \~ + \param[in] line - \ru Линия, до которой вычисляется расстояние. + \en Line to calculate the distance to. \~ + \param[in] delta - \ru Радиус окрестности вокруг линии. + \en Neighborhood radius around the line. \~ + \param[in] cutPlaces - \ru Отсекающая плоскости. + \en Cutting planes. \~ + \param[out] nearestPoint - \ru Ближайшая к лучу точка. + \en The nearest point of the polygon. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Квадрат расстояния ближайшей точки до линии. + \en Squared distance between the nearest point and the line. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC(float) LineToPolyDistanceSquared( const MbPolygon3D & poly, + const MbFloatAxis3D & line, + float delta, + const std::vector & cutPlaces, + MbFloatPoint3D & nearestPoint, + float & tRes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить расстояние от линии до точки. + \en Calculate the distance from a line to a point. \~ + \details \ru Для корректного вычисления расстояния от линии до точки вектор направления линии должен быть нормализован. \n + \en For correct calculating of the distance from a line to a point the line direction vector must be normalized. \n \~ + \param[in] line - \ru Линия. + \en Line. \~ + \param[in] to - \ru Точка. + \en Point. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Расстояние от точки до линии. + \en The distance from a point to a line. \~ + \ingroup Algorithms_3D +*/ +// --- +template +Double LineToPointDistance( const Axis & line, + const Point & to, + Double & tRes ) +{ + C3D_ASSERT( ::fabs(line.GetAxisZ().Length() - 1.0) < METRIC_ACCURACY ); + + Vector vect( line.GetOrigin(), to ); + tRes = vect * line.GetAxisZ(); + return ( line.GetAxisZ() | vect ).Length(); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить расстояние от линии до точки. + \en Calculate the distance from a line to a point. \~ + \details \ru Для корректного вычисления расстояния от линии до точки вектор направления линии должен быть нормализован. \n + \en For correct calculating of the distance from a line to a point the line direction vector must be normalized. \n \~ + \param[in] line - \ru Линия. + \en Line. \~ + \param[in] to - \ru Точка. + \en Point. \~ + \param[in] cutPlace - \ru Отсекающая плоскость. + \en Cutting plane. \~ + \param[out] tRes - \ru Значение параметра ближайшей точки линии. + \en The value of parameter of the nearest point on the line. \~ + \return \ru Расстояние от точки до линии. + \en The distance from a point to a line. \~ + \ingroup Algorithms_3D +*/ +// --- +template +Double LineToPointDistance( const Axis & line, + const Point & to, + const Placement & cutPlace, + Double & tRes ) +{ + C3D_ASSERT( ::fabs(line.GetAxisZ().Length() - 1.0) < METRIC_ACCURACY ); + C3D_ASSERT( cutPlace.IsNormal() ); + + if ( cutPlace.PointRelative( to, METRIC_EPSILON ) != iloc_InItem ) { // Под плоскостью или на плоскости (Below plane or on plane) + Vector vect( line.GetOrigin(), to ); + tRes = vect * line.GetAxisZ(); + return ( line.GetAxisZ() | vect ).Length(); + } + + tRes = FLT_MAX; + return FLT_MAX; +} + + +#endif // __MESH_PRIMITIVE_H diff --git a/C3d/Include/mesh_triangle.h b/C3d/Include/mesh_triangle.h new file mode 100644 index 0000000..f3fccde --- /dev/null +++ b/C3d/Include/mesh_triangle.h @@ -0,0 +1,483 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Структуры данных триангуляции. + \en Triangulation data structures. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MESH_TRIANGLE_H +#define __MESH_TRIANGLE_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/// \ru Направление движения \en Motion direction +/** + \ingroup Polygonal_Objects +*/ +// --- +enum MbeMoveType { + mt_Forward = 0, ///< \ru Вперед. \en Forward. + mt_Backward = 1, ///< \ru Назад. \en Backward. +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Tреугольник. + \en Triangle. \~ + \details \ru Tреугольник определен, как тройка точек, заданных индексами + вершин триангуляции MbGrid. \n + \en Triangle is defined as a triple of points defined by indices + of vertices of MbGrid triangulation. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbTriangle { +protected : + uint pIndex[3]; ///< \ru Номера вершин треугольника в массиве точек. \en Indices of triangle vertices in the array of points. + +public : + /// \ru Конструктор. \en Constructor. + MbTriangle() { pIndex[0] = pIndex[1] = pIndex[2] = SYS_MAX_UINT; } + /// \ru Конструктор. \en Constructor. + MbTriangle( uint j0, uint j1, uint j2, bool orientation ); + /// \ru Конструктор копирования. \en The copy-constructor. + MbTriangle( const MbTriangle & init ) { + pIndex[0] = init.pIndex[0]; + pIndex[1] = init.pIndex[1]; + pIndex[2] = init.pIndex[2]; + } + /// \ru Деструктор. \en Destructor. + ~MbTriangle(); + /// \ru Оператора присваивания. \en The assignment operator. + MbTriangle & operator = ( const MbTriangle & init ) { + pIndex[0] = init.pIndex[0]; + pIndex[1] = init.pIndex[1]; + pIndex[2] = init.pIndex[2]; + return *this; + } +public : + + /// \ru Инициализация. \en Initialization. + void Init( uint j0, uint j1, uint j2, bool orientation ); + /// \ru Выдать номера вершин треугольника в массиве точек. \en Get indices of triangle vertices in the array of points. + bool GetTriangle ( uint & i0, uint & i1, uint & i2 ) const; + /// \ru Выдать номер вершины n треугольника в массиве точек. \en Get index of n-th triangle vertex in the array of points. + uint GetIndex( size_t n ) const { return pIndex[n % 3]; } + /// \ru Инвертировать последовательность вершин. \en Reverse the sequence of vertices. + void Reverse(); + + /// \ru Определить, пересекается ли проекция на глобальную плоскость XY треугольника с присланным прямоугольником. \en Determine whether the projection of the triangle to the global XY-plane intersects the given rectangle. + template + bool IntersectRect( const MbRect & rect, const ParamPoints & points ) const + { + if ( points.size() < 3 ) + return false; + + double x1 = std_min( points[pIndex[0]].x, std_min( points[pIndex[1]].x, points[pIndex[2]].x ) ); + double x2 = std_max( points[pIndex[0]].x, std_max( points[pIndex[1]].x, points[pIndex[2]].x ) ); + + double y1 = std_min( points[pIndex[0]].y, std_min( points[pIndex[1]].y, points[pIndex[2]].y ) ); + double y2 = std_max( points[pIndex[0]].y, std_max( points[pIndex[1]].y, points[pIndex[2]].y ) ); + + return std_max( x1, rect.left ) <= std_min( x2, rect.right ) && + std_max( y1, rect.bottom ) <= std_min( y2, rect.top ); + } + + /// \ru Рассчитать габаритный прямоугольник проекции на глобальную плоскость XY треугольника. \en Calculate bounding rectangle of the projection of the triangle to the global XY-plane. + template + void GetGabRect ( MbRect & rect, const ParamPoints & points ) const + { + if ( points.size() < 3 ) + return; + + rect.left = std_min( points[pIndex[0]].x, std_min( points[pIndex[1]].x, points[pIndex[2]].x ) ); + rect.right = std_max( points[pIndex[0]].x, std_max( points[pIndex[1]].x, points[pIndex[2]].x ) ); + + rect.bottom = std_min( points[pIndex[0]].y, std_min( points[pIndex[1]].y, points[pIndex[2]].y ) ); + rect.top = std_max( points[pIndex[0]].y, std_max( points[pIndex[1]].y, points[pIndex[2]].y ) ); + } + + /// \ru Принадлежит ли ребро треугольнику. \en Is triangle's edge? + bool IsTriangleEdge( uint k0, uint k1, size_t & eInd ) const + { + eInd = SYS_MAX_T; + + if ( k0 == pIndex[0] && k1 == pIndex[1] ) + eInd = 0; + else if ( k0 == pIndex[1] && k1 == pIndex[2] ) + eInd = 1; + else if ( k0 == pIndex[2] && k1 == pIndex[0] ) + eInd = 2; + + return (eInd != SYS_MAX_T); + } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & properties ); + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbTriangle, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbTriangle, MATH_FUNC_EX ); +}; // MbTriangle + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbTriangle::Init( uint j0, uint j1, uint j2, bool orientation ) +{ + if ( orientation ) { // \ru Совпадает направление обхода \en Traverse direction coincides + pIndex[0] = j0; + pIndex[1] = j1; + pIndex[2] = j2; + } + else { + pIndex[1] = j1; + pIndex[2] = j0; + pIndex[0] = j2; + } +} + + +//------------------------------------------------------------------------------ +// \ru Получить индексы треугольной пластины \en Get indices of triangle plate +// --- +inline bool MbTriangle::GetTriangle ( uint & i0, uint & i1, uint & i2 ) const +{ + i0 = pIndex[0]; + i1 = pIndex[1]; + i2 = pIndex[2]; + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Инвертировать последовательность вершин. \en Reverse the sequence of vertices. +// --- +inline void MbTriangle::Reverse() +{ + uint ind = pIndex[1]; + pIndex[1] = pIndex[2]; + pIndex[2] = ind; +} + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Четырёхугольник. + \en Quadrangle. \~ + \details \ru Четырёхугольник задан, как четверка индексов элементов из массива + вершин триангуляции MbGrid. \n + \en Quadrangle defined as a quadruple of elements' indices form the array + of vertices of MbGrid triangulation. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbQuadrangle { +protected : + uint pIndex[4]; ///< \ru Номера вершин четырёхугольника в массиве точек. //-V112 \en Indices of quadrangle vertices in the array of points. //-V112 + +public : + /// \ru Конструктор. \en Constructor. + MbQuadrangle(); + /// \ru Конструктор. \en Constructor. + MbQuadrangle( uint j0, uint j1, uint j2, uint j3, bool orientation ); + /// \ru Конструктор копирования. \en The copy-constructor. + MbQuadrangle( const MbQuadrangle & init ) { + pIndex[0] = init.pIndex[0]; + pIndex[1] = init.pIndex[1]; + pIndex[2] = init.pIndex[2]; + pIndex[3] = init.pIndex[3]; + } + /// \ru Деструктор. \en Destructor. + ~MbQuadrangle(); + /// \ru Оператора присваивания. \en The assignment operator. + MbQuadrangle & operator = ( const MbQuadrangle & init ) { + pIndex[0] = init.pIndex[0]; + pIndex[1] = init.pIndex[1]; + pIndex[2] = init.pIndex[2]; + pIndex[3] = init.pIndex[3]; + return *this; + } +public : + + /// \ru Инициализация. \en Initialization. + void Init( uint j0, uint j1, uint j2, uint j3, bool orientation ); + /// \ru Выдать номера вершин четырёхугольника в массиве точек. \en Get indices of quadrangle vertices in the array of points. + bool GetQuadrangle ( uint & i0, uint & i1, uint & i2, uint & i3 ) const; + /// \ru Выдать номер вершины n четырёхугольника в массиве точек. \en Get index of n-th quadrangle vertex in the array of points. + uint GetIndex( size_t n ) const { return pIndex[n % 4]; } //-V112 + /// \ru Инвертировать последовательность вершин. \en Reverse the sequence of vertices. + void Reverse(); + + /// \ru Определить, пересекается ли проекция на глобальную плоскость XY четырёхугольника с присланным прямоугольником. \en Determine whether the projection of the quadrangle to the global XY-plane intersects the given rectangle. + template + bool IntersectRect( const MbRect & rect, const ParamPoints & points ) const + { + if ( points.size() < 4 ) //-V112 + return false; + + double x1 = std_min( points[pIndex[0]].x, std_min( points[pIndex[1]].x, std_min( points[pIndex[2]].x, points[pIndex[3]].x ) ) ); + double x2 = std_max( points[pIndex[0]].x, std_max( points[pIndex[1]].x, std_max( points[pIndex[2]].x, points[pIndex[3]].x ) ) ); + + double y1 = std_min( points[pIndex[0]].y, std_min( points[pIndex[1]].y, std_min( points[pIndex[2]].y, points[pIndex[3]].y ) ) ); + double y2 = std_max( points[pIndex[0]].y, std_max( points[pIndex[1]].y, std_max( points[pIndex[2]].y, points[pIndex[3]].y ) ) ); + + return std_max( x1, rect.left ) <= std_min( x2, rect.right ) && + std_max( y1, rect.bottom ) <= std_min( y2, rect.top ); + } + + /// \ru Рассчитать габаритный прямоугольник проекции на глобальную плоскость XY четырёхугольника. \en Calculate bounding rectangle of the projection of quadrangle to the global XY-plane. + template + void GetGabRect ( MbRect & rect, const ParamPoints & points ) const + { + if ( points.size() < 4 ) //-V112 + return; + + rect.left = std_min( points[pIndex[0]].x, std_min( points[pIndex[1]].x, std_min( points[pIndex[2]].x, points[pIndex[3]].x ) ) ); + rect.right = std_max( points[pIndex[0]].x, std_max( points[pIndex[1]].x, std_max( points[pIndex[2]].x, points[pIndex[3]].x ) ) ); + + rect.bottom = std_min( points[pIndex[0]].y, std_min( points[pIndex[1]].y, std_min( points[pIndex[2]].y, points[pIndex[3]].y ) ) ); + rect.top = std_max( points[pIndex[0]].y, std_max( points[pIndex[1]].y, std_max( points[pIndex[2]].y, points[pIndex[3]].y ) ) ); + } + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbQuadrangle, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbQuadrangle, MATH_FUNC_EX ); +}; // MbQuadrangle + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbQuadrangle::Init( uint j0, uint j1, uint j2, uint j3, bool orientation ) +{ + if ( orientation ) { // \ru Совпадает направление обхода \en Traverse direction coincides + pIndex[0] = j0; + pIndex[1] = j1; + pIndex[2] = j2; + pIndex[3] = j3; + } + else { + pIndex[2] = j1; + pIndex[3] = j0; + pIndex[0] = j3; + pIndex[1] = j2; + } +} + + +//------------------------------------------------------------------------------ +/// \ru Получить индексы четырехугольной пластины \en Get indices of quadrangle plate +// --- +inline bool MbQuadrangle::GetQuadrangle ( uint & i0, uint & i1, uint & i2, uint & i3 ) const +{ + i0 = pIndex[0]; + i1 = pIndex[1]; + i2 = pIndex[2]; + i3 = pIndex[3]; + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Инвертировать последовательность вершин. \en Reverse the sequence of vertices. +// --- +inline void MbQuadrangle::Reverse() +{ + uint ind = pIndex[1]; + pIndex[1] = pIndex[3]; + pIndex[3] = ind; +} + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Объемный элемент. + \en Element of tesselation of solid volume. \~ + \details \ru Элемент задан, как восемь индексов точек из массива вершин объекта MbGrid. \n + \en Element defined as an elements' indices form the array of vertices of MbGrid. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbElement { +protected : + uint pIndex[8]; ///< \ru Номера вершин елемента в массиве точек. \en Indices of element vertices in the array of points. + size_t estate; ///< \ru Свойство элемента. \en Estate of element. + double props; ///< \ru Характеристика элемента. \en Property of element. + +public : + /// \ru Конструктор. \en Constructor. + MbElement(); + /// \ru Конструктор. \en Constructor. + MbElement( uint j0, uint j1, uint j2, uint j3, uint j4, uint j5, uint j6, uint j7 ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbElement( const MbElement & ); + /// \ru Деструктор. \en Destructor. + ~MbElement(); + // \ru Оператор присваивания. \en Assignment operator. + MbElement & operator = ( const MbElement & ); + +public : + + /// \ru Инициализация. \en Initialization. + void Init( uint j0, uint j1, uint j2, uint j3, uint j4, uint j5, uint j6, uint j7 ); + /// \ru Выдать номера вершин четырёхугольника в массиве точек. \en Get indices of quadrangle vertices in the array of points. + bool GetElement ( uint & i0, uint & i1, uint & i2, uint & i3, uint & i4, uint & i5, uint & i6, uint & i7 ) const; + /// \ru Выдать номер вершины n четырёхугольника в массиве точек. \en Get index of n-th quadrangle vertex in the array of points. + uint GetIndex( size_t n ) const { return pIndex[n % 8]; } + /// \ru Дать свойство элемента. \en Get estate of element. + size_t GetEstate() const { return estate; } + /// \ru Изменить свойство элемента. \en Set estate of element. + void SetEstate( uint32 e ) { estate = e; } + /// \ru Дать характеристику элемента. \en Get property of element. + double GetProps() const { return props; } + /// \ru Изменить характеристику элемента. \en Get property of element. + void SetProps( double p ) { props = p; } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties &properties ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties &properties ); + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbElement, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbElement, MATH_FUNC_EX ); +}; // MbElement + + +//------------------------------------------------------------------------------ +// \ru Инициализация \en Initialization +// --- +inline void MbElement::Init( uint j0, uint j1, uint j2, uint j3, uint j4, uint j5, uint j6, uint j7 ) +{ + pIndex[0] = j0; + pIndex[1] = j1; + pIndex[2] = j2; + pIndex[3] = j3; + pIndex[4] = j4; + pIndex[5] = j5; + pIndex[6] = j6; + pIndex[7] = j7; +} + + +//------------------------------------------------------------------------------ +/// \ru Получить индексы четырехугольной пластины \en Get indices of quadrangle plate +// --- +inline bool MbElement::GetElement ( uint & i0, uint & i1, uint & i2, uint & i3, uint & i4, uint & i5, uint & i6, uint & i7 ) const +{ + i0 = pIndex[0]; + i1 = pIndex[1]; + i2 = pIndex[2]; + i3 = pIndex[3]; + i4 = pIndex[4]; + i5 = pIndex[5]; + i6 = pIndex[6]; + i7 = pIndex[7]; + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Граница триангуляции. + \en Border of triangulation. \~ + \details \ru Граница триангуляции используется для описания набора ребер грани оболочки. \n + Граница триангуляции содержит номера последовательности вершины. + \en Border of triangulation is used to describe edge sequence of shell's face. \n + Border of triangulation contains indices of vertex sequence. \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbGridLoop { +private: + std::vector pIndices; ///< \ru Номера вершин в массиве точек. \en Indices of vertices in the array of points. + +public: + /// \ru Конструктор. \en Constructor. + MbGridLoop( size_t n = 0 ) : pIndices() { if ( n > 0 ) pIndices.reserve( n ); } + /// \ru Конструктор. \en Constructor. + template + explicit MbGridLoop( const UintVector & init ) : pIndices() { + pIndices.reserve( init.size() ); + for ( size_t i = 0, iCount = init.size(); i < iCount; i++ ) + pIndices.push_back( init[i] ); + } + /// \ru Деструктор. \en Destructor. + ~MbGridLoop() {} + +public: + /// \ru Инициализация. \en Initialization. + template + void Init( const UintVector & init ) { + pIndices.clear(); pIndices.reserve( init.size() ); + for ( size_t i = 0, iCount = init.size(); i < iCount; i++ ) + pIndices.push_back( init[i] ); + } + /// \ru Выдать количество вершин полосы. \en Get the count of strip vertices. + size_t Count() const { return pIndices.size(); } + /// \ru Добавить номер вершины. \en Add vertex number. + void Add( uint n ) { pIndices.push_back(n); } + /// \ru Выдать количество вершин полосы. \en Get the count of strip vertices. + uint GetIndex( size_t i ) const { return pIndices[i]; } + /// \ru Выдать количество вершин полосы. \en Get the count of strip vertices. + uint & SetIndex( size_t i ) { return pIndices[i]; } + /// \ru Очистить полосу. \en Clear the strip. + void Flush() { pIndices.clear(); } + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const uint * GetIndicesAddr() const { return &(pIndices[0]); } + /// \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const std::vector & GetIndices() const { return pIndices; } + /// \ru Выдать контейнер номеров вершин. \en Get the container of vertex numbers. + template + void GetIndices( IndicesVector & iVector ) const { + iVector.reserve( iVector.size() + pIndices.size() ); + for ( size_t i = 0, iCount = pIndices.size(); i < iCount; i++ ) + iVector.push_back( pIndices[i] ); + } + /// \ru Есть ли такой индекс в цикле? \en Is exist index n in the loop? + bool IsExist( uint n ) const { return ( std::find(pIndices.begin(), pIndices.end(), n) != pIndices.end() ); } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbGridLoop, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbGridLoop, MATH_FUNC_EX ); + OBVIOUS_PRIVATE_COPY( MbGridLoop ) +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** \brief \ru Сегмент(результат сегментации) полигональной сетки. + \en A polygonal mesh segment (segmentation result). \~ + \details \ru Сегмент определен множеством треугольников полигональной сетки. \n + \en Segment is defined as a set of triangles of polygonal mesh. \n \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbGridSegment { +private: + std::vector faces; ///< \ru Вектор индексов треугольников сегмента. \en A vector of segment triangles indicies. + +public: + /// \ru Конструктор. \en Constructor. + MbGridSegment() : faces() {} + /// \ru Конструктор. \en Constructor. + MbGridSegment( const std::vector & initFaces ) : faces( initFaces ) {} + /// \ru Выдать вектор индексов треугольников сегмента. \en Get the vector of segment triangles indicies. + const std::vector & GetFaces() const { return faces; } + /// \ru Выдать количество треугольников сегмента. \en Get the count of of segment triangles. + size_t GetFaceCount() const { return faces.size(); } + /// \ru Выдать индекс треугольника сегмента. \en Get the index of segment triangle. + size_t GetFace( size_t idx ) const { return faces[idx]; } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbGridSegment, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbGridSegment, MATH_FUNC_EX ); +}; + +#endif // __MESH_TRIANGLE_H diff --git a/C3d/Include/mip_curve_properties.h b/C3d/Include/mip_curve_properties.h new file mode 100644 index 0000000..c7dded8 --- /dev/null +++ b/C3d/Include/mip_curve_properties.h @@ -0,0 +1,301 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Массо-центровочные характеристики. + \en Mass-inertial properties. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MIP_CURVE_PROPERTIES_H +#define __MIP_CURVE_PROPERTIES_H + + +#include +#include +#include + + +class MATH_CLASS MbCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Массо-центровочные характеристики кривой. + \en Mass-inertial properties of curve. \~ + \details \ru Массо-центровочные характеристики кривой.\n + \en Mass-inertial properties of curve.\n \~ + \ingroup Inertia_Computation +*/ +// --- +class MATH_CLASS MIProperties { +public: + double xc; ///< \ru Координата х центра тяжести. \en X-coordinate of center of gravity. + double yc; ///< \ru Координата y центра тяжести. \en Y-coordinate of center of gravity. + double f; ///< \ru Площадь. \en Area. + double lxx; ///< \ru Осевой момент инерции относительно оси координат x. \en Centroidal moment of inertia relative to x coordinate axis. + double lyy; ///< \ru Осевой момент инерции относительно оси координат y. \en Centroidal moment of inertia relative to y coordinate axis. + double lxy; ///< \ru Центробежный момент инерции относительно исходных осей координат x и y. \en Product of inertia relative to source coordinate axes x and y. + double mxx; ///< \ru Осевой момент инерции относительно оси координат x (относительно оси, параллельной исходной оси и проходящей через центр тяжести). \en Centroidal moment of inertia relative to x coordinate axis (relative to axis, that is parallel to source axis and is passed through center of gravity). + double myy; ///< \ru Осевой момент инерции относительно оси координат y (относительно оси, параллельной исходной оси и проходящей через центр тяжести). \en Centroidal moment of inertia relative to y coordinate axis (relative to axis, that is parallel to source axis and is passed through center of gravity). + double mxy; ///< \ru Центробежный момент инерции относительно центральных осей (относительно осей, параллельных исходных осям и проходящих через центр тяжести). \en Centroidal moment of inertia relative to central coordinate axes (relative to axes, that are parallel to source axes and are passed through center of gravity). + double mxx0; ///< \ru Главные центральные моменты инерции относительно оси координат x. \en Principal central moments of inertia relative to x coordinate axis. + double myy0; ///< \ru Главные центральные моменты инерции относительно оси координат y. \en Principal central moments of inertia relative to y coordinate axis. + double a; ///< \ru Угол между первой главной осью и осью x. \en Angle between first principal axis and x-axis. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор массо-центровочных характеристик кривой.\n + Создает объект с нулевыми полями. + \en Constructor by mass-inertial properties of curve.\n + Creates an object with the zero fields. \~ + */ + MIProperties() { Init(); } + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация массо-центровочных характеристик кривой.\n + Обнуляет поля объекта. + \en Initialize mass-inertial properties of curve.\n + Reset fields of an object to zero. \~ + */ + void Init(); + + /// \ru Расчет главных моментов инерции. \en Calculate principal moments of inertia. + bool CalculateGeneral(); + + /// \ru Добавить к полям объекта полей другого объекта. \en Add fields of other object to current. + void operator += ( const MIProperties & other ); + + /// \ru Вычесть из полей объекта полей другого объекта. \en Subtract fields of other object from corresponding fields of current one. + void operator -= ( const MIProperties & other ); +}; + + +//------------------------------------------------------------------------------ +// \ru инициализация \en initialization +// --- +inline void MIProperties::Init() { + xc = yc = f = 0.0; + mxx = myy = mxy = 0.0; + mxx0 = myy0 = a = 0.0; + lxx = lyy = lxy = 0.0; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение массо-центровочных характеристик. + \en Determination of mass-inertial properties. \~ + \details \ru Определение массо-центровочных характеристик кривой.\n + x0, y0 - координаты центра тяжести,\n + f - площадь,\n + mxx, myy - моменты инерции относительно осей, параллельных осям x и y + и проходящих через центр тяжести,\n + mxy - центробежный момент инерции относительно осей, параллельных осям x и y + и проходящих через центр тяжести,\n + mxx0, myy0 - главные центральные моменты инерции,\n + a - угол между первой главной осью и осью x. + \en Determination of mass-inertial properties of curve.\n + x0, y0 - center of gravity coordinates,\n + f - area,\n + mxx, myy - moments of inertia relative axes parallel to x and y axes + and passes through center of gravity,\n + mxy - product of inertia relative to axes parallel to x and y axes + and passes through center of gravity,\n + mxx0, myy0 - principal central moments of inertia,\n + a - angle between first principal axis and x-axis. \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[out]mp - \ru Результат - массоцентровочные характеристики кривой. + \en Mass-inertial properties of curve as result. \~ + \param[in] deviateAngle - \ru Угловое отклонение касательных кривой в соседних точках на участке численного интегрирования. + \en The angular deviation of the curve in the neighboring points on the region of numerical integration. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const MbCurve * curve, + MIProperties & mp, + double deviateAngle = Math::deviateSag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение массо-центровочных характеристик. + \en Determination of mass-inertial properties. \~ + \details \ru Определение массо-центровочных характеристик кривых. + \en Determine mass-inertial properties of curves. \~ + \param[in] curves - \ru Набор кривых. + \en A set of curves. \~ + \param[in] bodies - \ru Набор флагов для каждой кривой:\n + если true - массо-центровочные характеристики кривой прибавляются к общему результату,\n + если false - массо-центровочные характеристики кривой вычитаются из общего результата.\n + Количество флагов должно совпадать с количеством кривых. + \en Set of flags for each curve:\n + if true then mass-inertial properties of curve are added to total result,\n + if false then mass-inertial properties of curve are subtracted from total result.\n + Count of flags must be equal to count of curves. \~ + \param[out] mp - \ru Результат - суммарные массо-центровочные характеристики. + \en Total mass-inertial properties as result. \~ + \param[in] deviateAngle - \ru Угловое отклонение касательных кривой в соседних точках на участке численного интегрирования. + \en The angular deviation of the curve in the neighboring points on the region of numerical integration. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const RPArray & curves, + const SArray & bodies, + MIProperties & mp, + double deviateAngle = Math::deviateSag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Oбъемные массо-центровочные характеристки. + \en Volume mass-inertial properties. \~ + \details \ru Oбъемные массо-центровочные характеристки. \n + \en Volume mass-inertial properties. \n \~ + \ingroup Inertia_Computation +*/ +// --- +class MATH_CLASS MI3DProperties { +public : + double r; ///< \ru Плотность. \en Density. + double m; ///< \ru Масса. \en Mass. + double v; ///< \ru Объем. \en Volume. + double xc; ///< \ru Статический момент относительно плоскости YOZ (после CalculateGeneral - координата X центра тяжести). \en Static moment relative to YOZ plane (after CalculateGeneral - X-coordinate of center of gravity). + double yc; ///< \ru Статический момент относительно плоскости XOZ (после CalculateGeneral - координата Y центра тяжести). \en Static moment relative to XOZ plane (after CalculateGeneral - Y-coordinate of center of gravity). + double zc; ///< \ru Статический момент относительно плоскости XOY (после CalculateGeneral - координата Z центра тяжести). \en Static moment relative to XOY plane (after CalculateGeneral - Z-coordinate of center of gravity). + double lx; ///< \ru Осевой момент инерции относительно оси координат x. \en Centroidal moment of inertia relative to x coordinate axis. + double ly; ///< \ru Осевой момент инерции относительно оси координат y. \en Centroidal moment of inertia relative to y coordinate axis. + double lz; ///< \ru Осевой момент инерции относительно оси координат z. \en Centroidal moment of inertia relative to z coordinate axis. + double lxy; ///< \ru Центробежный момент инерции в плоскости XOY. \en Product of inertia in XOY plane. + double lxz; ///< \ru Центробежный момент инерции в плоскости XOZ. \en Product of inertia in XOZ plane. + double lyz; ///< \ru Центробежный момент инерции в плоскости YOZ. \en Product of inertia in YOZ plane. + double jxx; ///< \ru Плоскостной момент инерции (интегралы инерции) относительно оси координат x. \en Planar moment of inertia (integrals of inertia) relative to x coordinate axis. + double jyy; ///< \ru Плоскостной момент инерции (интегралы инерции) относительно оси координат y. \en Planar moment of inertia (integrals of inertia) relative to y coordinate axis. + double jzz; ///< \ru Плоскостной момент инерции (интегралы инерции) относительно оси координат z. \en Planar moment of inertia (integrals of inertia) relative to z coordinate axis. + double jx; ///< \ru Осевой момент инерции относительно оси координат x. \en Centroidal moment of inertia relative to x coordinate axis. + double jy; ///< \ru Осевой момент инерции относительно оси координат y. \en Centroidal moment of inertia relative to y coordinate axis. + double jz; ///< \ru Осевой момент инерции относительно оси координат z. \en Centroidal moment of inertia relative to z coordinate axis. + double jxy; ///< \ru Центробежный момент инерции в плоскости XOY. \en Product of inertia in XOY plane. + double jxz; ///< \ru Центробежный момент инерции в плоскости XOZ. \en Product of inertia in XOZ plane. + double jyz; ///< \ru Центробежный момент инерции в плоскости YOZ. \en Product of inertia in YOZ plane. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор объемных массо-центровочных характеристик.\n + Создает объект с нулевыми полями. + \en Constructor of mass-inertial properties.\n + Creates an object with the zero fields. \~ + */ + MI3DProperties() { Init(); } + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация объемных массо-центровочных характеристик.\n + Создает объект с нулевыми полями. + \en Initialization of mass-inertial properties.\n + Creates an object with the zero fields. \~ + */ + void Init(); + + ///< \ru Расчет главных моментов инерции. \en Calculate principal moments of inertia. + void CalculateGeneral(); + + /// \ru Добавить к полям объекта полей другого объекта. \en Add fields of other object to current. + void operator += ( const MI3DProperties & other ); + /// \ru Вычесть из полей объекта полей другого объекта. \en Subtract fields of other object from corresponding fields of current one. + void operator -= ( const MI3DProperties & other ); +}; + + +//------------------------------------------------------------------------------ +// \ru инициализация \en initialization +// --- +inline void MI3DProperties::Init() { + r = 1; + m = v = 0.0; + xc = yc = zc = 0.0; // \ru центр тяжести \en center of gravity + jx = jy = jz = 0.0; // \ru осевые моменты инерции \en axial moments of inertia + jxx = jyy = jzz = 0.0; // \ru плоскостные моменты инерции \en planar moments of inertia + jxy = jxz = jyz = 0.0; // \ru центробежные моменты инерции \en product of inertia + lx = ly = lz = 0.0; // \ru осевые моменты инерции \en axial moments of inertia + lxy = lxz = lyz = 0.0; // \ru центробежные моменты инерции \en product of inertia +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Oписание формы контура. + \en Contour shape description. \~ + \details \ru Oписание формы контура. \n + \en Contour shape description. \n \~ + \ingroup Inertia_Computation +*/ +// --- +struct MATH_CLASS FormDefinition { + bool body; ///< \ru Признак тела. \en Solid attribute. + double density; ///< \ru Плотность. \en Density. + double par; ///< \ru Параметр (угол раствора или толщина). \en Parameter (apex angle or thickness). + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по признаку тела, + плотности и параметру. + \en Constructor by solid attribute, + density and parameter. \~ + \param[in] b - \ru Признак тела.\n + если true - массо-центровочные характеристики кривой прибавляются к общему результату,\n + если false - массо-центровочные характеристики кривой вычитаются из общего результата.\n + \en Solid attribute.\n + if true then mass-inertial properties of curve are added to total result,\n + if false then mass-inertial properties of curve are subtracted from total result.\n \~ + \param[in] d - \ru Плотность. + \en Density. \~ + \param[in] p - \ru Параметр (угол раствора или толщина). + \en Parameter (apex angle or thickness). \~ + */ + FormDefinition( bool b, double d, double p ) + : body( b ) + , density( d ) + , par( p ) + { + } + + /// \ru Конструктор копирования. \en Copy constructor. + FormDefinition( const FormDefinition & other ) + : body( other.body ) + , density( other.density ) + , par( other.par ) + { + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Расчет объемных массо-центровочных характеристик. + \en Calculate volume mass-inertial properties. \~ + \details \ru Расчет объемных массо-центровочных характеристик.\n + \en Calculate volume mass-inertial properties.\n \~ + \param[in] revolution - \ru Если true - параметр описания формы контура считается углом,\n + если false - толщиной. + \en If true then shape description parameter treats as angle,\n + If false then treats as thickness. \~ + \param[in] curves - \ru Набор кривых. + \en Set of curves. \~ + \param[in] formes - \ru Описание формы для каждой кривой.\n + Количество элементов должно совпадать с количеством кривых. + \en Each curve shape description.\n + Count of elements must be equal to count of curves. \~ + \param[out] mp - \ru Результат - массо-центровочные характеристики. + \en Mass-inertial properties as result. \~ + \param[in] deviateAngle - \ru Угловое отклонение касательных кривой в соседних точках на участке численного интегрирования. + \en The angular deviation of the curve in the neighboring points on the region of numerical integration. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertia3DProperties( bool revolution, + const RPArray & curves, + const SArray & formes, + MI3DProperties & mp, + double deviateAngle = Math::deviateSag ); + + +#endif // __MIP_CURVE_PROPERTIES_H diff --git a/C3d/Include/mip_solid_area_volume.h b/C3d/Include/mip_solid_area_volume.h new file mode 100644 index 0000000..7aa1a9c --- /dev/null +++ b/C3d/Include/mip_solid_area_volume.h @@ -0,0 +1,165 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Построение триангуляции тела. + \en Construction of solid triangulation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MIP_SOLID_AREA_VOLUME_H +#define __MIP_SOLID_AREA_VOLUME_H + + +#include + + +class MATH_CLASS MbFace; +class MATH_CLASS MbSurface; +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbSolid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить площадь. + \en Determine area. \~ + \details \ru Определить площадь поверхности. + \en Determine surface area. \~ + \param[in] surface - \ru Поверхность. + \en The surface. \~ + \param[in] angle - \ru Ограничение углового отклонения при аппроксимации оболочки треугольными пластинами. + \en Bounding of angular deviation during shell approximation by triangular plates. \~ + \return \ru Площадь поверхности. + \en Surface area. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateArea( const MbSurface & surface, + double angle = Math::deviateSag ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить объем. + \en Determine volume. \~ + \details \ru Определить объем тела. + \en Determine volume of solid. \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in] angle - \ru Ограничение углового отклонения при аппроксимации оболочки треугольными пластинами. + \en Bounding of angular deviation during shell approximation by triangular plates. \~ + \return \ru Значение объема тела. + \en Value of solid volume. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateVolume( const MbSolid &solid, + double angle ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить объем. + \en Determine volume. \~ + \details \ru Определить объем полигонального объекта. + \en Determine volume of polygonal object. \~ + \param[in] mesh - \ru Пполигональный объект. + \en A polygonal object. \~ + \return \ru Значение объема полигонального объекта. + \en Value of polygonal object volume. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateVolume( const MbMesh & mesh ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить площадь и центр масс. + \en Determine area and center of mass. \~ + \details \ru Определить площадь поверхности оболочки и центр масс этой поверхности. \n + В общем случае центр масс объёма объекта не совпадает с центром масс его поверхности. \n + \en Determine area of shell surface and its center of mass. \n + Center of mass of volumetric object doesn't coincide with center of mass of its surface. \n \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] angle - \ru Ограничение углового отклонения при аппроксимации оболочки треугольными пластинами. + \en Bounding of angular deviation during shell approximation by triangular plates. \~ + \param[out] centre - \ru Центр масс площади оболочки. + \en Center of mass of shell area. \~ + \result \ru Площадь поверхности оболочки. + \en Area of shell surface. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateAreaCentre( const MbFaceShell & shell, + double angle, + MbCartPoint3D & centre ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить площадь и центр масс. + \en Determine area and center of mass. \~ + \details \ru Определить площадь поверхности грани и центр масс этой поверхности. \n + В общем случае центр масс объёма объекта не совпадает с центром масс его пловерхности. \n + \en Determine area of face surface and its center of mass. \n + Center of mass of volumetric object doesn't coincide with center of mass of its surface. \n \~ + \param[in] face - \ru Грань. + \en A face. \~ + \param[in] angle - \ru Ограничение углового отклонения при аппроксимации грани треугольными пластинами. + \en Bounding of angular deviation during face approximation by triangular plates. \~ + \param[in] byOuter - \ru При true расчет выполняется только по внешней границе без учёта внутренних вырезов грани. + \en If true calculation is performed only on external boundary without taking internal cuts of face into account. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + \param[out] centre - \ru Центр масс площади грани. + \en Center of mass of face area. \~ + \result \ru Площадь поверхности грани. + \en Face surface area. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateAreaCentre( const MbFace & face, + double angle, + bool byOuter, + VERSION version, + MbCartPoint3D & centre ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение площади поверхности граней. + \en Determination of faces area. \~ + \details \ru Определение площади поверхности граней. + Определение выполняется методом вычисления масс-центровочных характеристик набора граней. + \en Determination of area of set of faces. \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode m_Items runs in parallel. \~ + \param[in] faces - \ru Набор граней. + \en A set of faces. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \return \ru Площадь граней. + \en Faces area. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateArea( const RPArray & faces, + double deviateAngle ); // (0.35 - 0.01) + + +//------------------------------------------------------------------------------ +/** \brief \ru Определение площади. + \en Determination of area. \~ + \details \ru Определение площади поверхности грани. + \en Determination of face surface area. \~ + \param[in] face - \ru Грань. + \en A face. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \return \ru Площадь грани. + \en Face area. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (double) CalculateArea( const MbFace & face, + double deviateAngle ); // (0.35 - 0.01) + + +#endif // __MIP_SOLID_AREA_VOLUME_H diff --git a/C3d/Include/mip_solid_mass_inertia.h b/C3d/Include/mip_solid_mass_inertia.h new file mode 100644 index 0000000..095d5f2 --- /dev/null +++ b/C3d/Include/mip_solid_mass_inertia.h @@ -0,0 +1,638 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Инерционные характеристики тела. + \en Inertial properties of solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MIP_SOLID_MASS_INERTIA_H +#define __MIP_SOLID_MASS_INERTIA_H + + +#include +#include +#include + + +struct IfProgressIndicator; + + +/// \ru Неинициализированное значение double. \en Uninitialized value of double. +#define NOT_INITIAL_DBL -DETERMINANT_MAX + + +//------------------------------------------------------------------------------ +/** \brief \ru Инерционные характеристики тела. + \en Inertial properties of solid. \~ + \details \ru Инерционные характеристики тела.\n + Векторы direction дают направления главных осей инерции. \n + Если все главные моменты инерции general[i] i=1,2,3 разные, + то все векторы direction[i] i=1,2,3 не равны нулю. \n + Если все главные моменты инерции general[i] i=1,2,3 одинаковые, + то все векторы direction[i] i=1,2,3 равны нулю и + главными направлениями могут служить любые три взаимно ортогональных вектора. \n + Если два из трех главных моментов инерции равны, например general[j]==general[k], + то два из трёх векторов равны нулю direction[j]=direction[k]=0, + а не равный нулю вектор direction[i] определяет направление главной оси инерции, + момент general[i] относительно которой отличается от других, + двумя другими главными направлениями могут служить любые два взаимно ортогональных + и ортогональных не равному нулю вектору direction[i] вектора. + \en Inertial properties of solid. + Vectors direction give directions of the principal axes of inertia.\n + If all principal moments of inertia (general[i] i=1,2,3) different, + all vectors (direction[i] i=1,2,3) not zero.\n + If all principal moments of inertia (general[i] i=1,2,3) are the same, + all vectors (direction[i] i=1,2,3) zero and + principal directions can be any three mutually orthogonal vectors.\n + If two of the three principal moments of inertia are equal, for example (general[j]==general[k]), + then two of the three vectors are zero (direction[j]=direction[k]=0), + a non-zero vector (direction[i]) defines the direction of the principal axis of inertia, + time general[i] with respect to which differs from other. + \n \~ + \ingroup Inertia_Computation +*/ +// --- +class MATH_CLASS InertiaProperties { +public : + double area; ///< \ru Площадь поверхности. \en Surface area. + double volume; ///< \ru Объем. \en Volume. + double mass; ///< \ru Масса. \en Mass. + double inertia[c3d::SPACE_DIM]; ///< \ru Статические моменты. \en Static moments. + double initial[c3d::SPACE_DIM][c3d::SPACE_DIM]; ///< \ru Моменты инерции относительно исходных осей координат. \en Moments of inertia relative to source coordinate axes. + double moments[c3d::SPACE_DIM][c3d::SPACE_DIM]; ///< \ru Моменты инерции относительно центральных осей координат. \en Moments of inertia relative to central coordinate axes. + double general[c3d::SPACE_DIM]; ///< \ru Главные центральные моменты инерции. \en Principal central moments of inertia. + + MbCartPoint3D center; ///< \ru Центр тяжести. \en Center of gravity. + MbVector3D direction[c3d::SPACE_DIM]; ///< \ru Векторы направлений главных центральных осей инерции. \en Direction vectors of the principal central axes of inertia. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор инерционных характеристик с умолчательными значениями полей.\n + Умолчательные значения означают, что параметры не заданы. + \en Constructor of inertial properties with default fields values.\n + Default values mean that the parameters are not set. \~ + */ + InertiaProperties() { Init(); } + /// \ru Конструктор копирования. \en Copy constructor. + InertiaProperties( const InertiaProperties & other ) { operator = ( other ); } + /// \ru Деструктор. \en Destructor. + ~InertiaProperties() {} + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация инерционных характеристик умолчательными значениями полей.\n + Умолчательные значения означают, что параметры не заданы. + \en Initialization of inertial properties with default fields values.\n + Default values mean that the parameters are not set. \~ + */ + void Init(); + + /** \brief \ru Проверить данные. + \en Check data. \~ + \details \ru Проверить данные на корректность.\n + \en Check data for correctness.\n \~ + \return \ru true, если данные корректны,\n + данные могут быть некорректны в случае нулевой площади поверхности. + \en True if the data is correct,\n + data may be incorrect in case of zero surface area. \~ + */ + bool CheckData(); + + /** \brief \ru Определить массо-центровочных характеристики. + \en Determine mass-inertial properties. \~ + \details \ru Определить массо-центровочных характеристики набора граней.\n + Каждое тело представлено совокупностью граней, описывающих его поверхность. + Определение объёма, центра масс и моментов инерции тела приводит к вычислению объёмных интегралов. + С помощью формулы Остроградского-Гаусса интегралы по объёму тела сводятся к + интегралам по поверхностям граней тела.\n + При численном интегрировании по поверхности область определения параметров грани + разбивается на небольшие четырёхугольные или треугольные подобласти. + От размеров подобластей зависит точность вычисления. + В качестве управляющего параметра разбиения области интегрирования используется + угловое отклонение нормали поверхности в подобласти deviateAngle. + Размер каждой подобласти определён условием: + угловое изменение нормали поверхности в подобласти не должно превышать deviateAngle.\n + Для четырёхугольных подобластей по каждому параметру поверхности + интегрирование выполняется с помощью квадратурных формул Гаусса. + Для треугольных областей удобно перейти от координат u и v к + трём барицентрическим координатам a, b, c, построенным по точкам pa, pb, pc. + Координаты произвольной точки p=(u,v) через барицентрические координаты a, b, c выражаются с помощью формул\n + u = a ua + b ub + c uc,\n + v = a va + b vb + c vc.\n + Барицентрические координаты удовлетворяют равенству: a + b + c = 1.\n + Во всех случаях каждый поверхностный интеграл вычисляется как взвешенная сумма + значений интегрируемой функции внутри области интегрирования. + Для каждого отдельного тела расчёт выполняется в местной системе координат. + Затем характеристики тела переводятся в глобальную систему координат и суммируются. + Результатом являются характеристики сборки тел в глобальной, + центральной и главной центральной системе координат. + \en Determine mass-inertial properties of set of faces.\n + Each solid is represented by a set of faces, describing its surface. + Determination of volume, center of mass and moments of inertia of the solid leads to the calculation of the volume integrals. + By means of the divergence (Gauss-Ostrogradsky) theorem volume integrals of the solid are reduced to the + integrals over the surfaces of the solid faces.\n + Numerical integration over the surface involves face parametric domain + subdivision into small rectangular or triangular subdomains. + Computational accuracy depends on sizes of subdomains. + As driving parameter of integration domain partitioning used + angular deviation of surface normal in 'deviateAngle' subdomain. + Size of each subdomain is defined by condition: + angular deviation of surface normal in subdomain shouldn't exceed deviateAngle.\n + For quadrangular subdomains + integration by each surface parameter is performed using the Gauss quadratures. + For triangular subdomains it is handy to transform u and v coordinates to + three barycentric coordinates a, b, c, constructed by points pa, pb, pc. + Coordinates of arbitrary point p=(u,v) has corresponding barycentric notation:\n + u = a ua + b ub + c uc,\n + v = a va + b vb + c vc.\n + Barycentric coordinates satisfy the equation: a + b + c = 1.\n + In all cases each surface integral is calculated as weighted summ + of integrable function values inside integration domain. + Calculation is performed in local coordinate system for each particular solid. + Then solid properties are transformed to global coordinate system and summarized. + Result is solids assembly properties in global, + central and principal central coordinate system. \~ + \note \ru В многопоточном режиме выполняется параллельно + (временно: многопоточность работает, только если IfProgressIndicator не определен). + \en In multithreaded mode m_Items runs in parallel + (temporarily: multithreading is working only if IfProgressIndicator is not defined). \~ + \param[in] faces - \ru Набор граней. + \en A set of faces. \~ + \param[in] closed - \ru Замкнутость набора граней. + \en Closing of set of faces. \~ + \param[in] density - \ru Плотность (closed == true) или удельная масса на единицу площади (closed == false). + \en Density (closed == true) or mass per unit square (closed == false). \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормпли поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + */ + void CalculateIntegrals ( const RPArray & faces, bool closed, double density, + double deviateAngle, IfProgressIndicator * progress ); + + /** \brief \ru Определить масс-центровочных характеристики. + \en Determine mass-inertial properties. \~ + \details \ru Определить масс-центровочных характеристики набора граней.\n + \en Determine mass-inertial properties of set of faces.\n \~ + \param[in] faces - \ru Набор граней. + \en A set of faces. \~ + \param[in] closed - \ru Замкнутость набора граней. + \en Closing of set of faces. \~ + \param[in] density - \ru Плотность (closed == true) или удельная масса на единицу площади (closed == false). + \en Density (closed == true) or mass per unit square (closed == false). \~ + \param[in] calculateAll - \ru Если false, проводится расчет интегралов инерции,\n + если true, то еще проводится расчет центра масс, центральных моментов инерции, главных центральных моментов инерции. + \en If false, then performs integrals of inertia calculation,\n + if true, then performs also calculation of center of mass, central moments of inertia, principal central moments of inertia. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + */ + void CalculateProperties( const RPArray & faces, bool closed, double density, + bool calculateAll, double deviateAngle, + IfProgressIndicator * progress ); + + /** \brief \ru Определить масс-центровочных характеристики. + \en Determine mass-inertial properties. \~ + \details \ru Определить масс-центровочных характеристики полигонального объекта.\n + \en Determine mass-inertial properties of polygonal object.\n \~ + \param[in] mesh - \ru Полигональный объект. + \en A polygonal object. \~ + \param[in] density - \ru Плотность (closed == true) или удельная масса на единицу площади (closed == false). + \en Density (closed == true) or mass per unit square (closed == false). \~ + */ + void CalculateIntegrals( const MbMesh & mesh, double density ); + + /** \brief \ru Определить масс-центровочных характеристики. + \en Determine mass-inertial properties. \~ + \details \ru Определить масс-центровочных характеристики полигонального объекта.\n + \en Determine mass-inertial properties of polygonal object.\n \~ + \param[in] mesh - \ru Полигональный объект. + \en A polygonal object. \~ + \param[in] density - \ru Плотность или удельная масса на единицу площади. + \en Density or mass per unit square. \~ + \param[in] calculateAll - \ru Если false, проводится расчет интегралов инерции,\n + если true, то еще проводится расчет центра масс, центральных моментов инерции, главных центральных моментов инерции. + \en If false, then performs integrals of inertia calculation,\n + if true, then performs also calculation of center of mass, central moments of inertia, principal central moments of inertia. \~ + */ + void CalculateProperties( const MbMesh & mesh, double density, bool calculateAll ); + + /** \brief \ru Вычислить интегралы инерции. + \en Calculate integrals of inertia. \~ + \details \ru Вычислить интегралы инерции по заданным пользователем моментам инерции.\n + Присваивает себе значение площади, объема, массы, центра масс эталона, + пересчитывает моменты инерции относительно центральных осей координат по заданным + моментам инерции эталона. + \en Calculate integrals of inertia by user-given moments of inertia.\n + Assigns the values of area, volume, mass, reference center of mass, + recalculates moments of inertia relative to central coordinate axes by given + reference moments of inertia. \~ + \param[in] etalon - \ru Эталон. + \en Reference. \~ + */ + void GetIntegrals( const InertiaProperties & etalon ); + + /** \brief \ru Учесть частично заданных характеристик. + \en Consider partially defined properties. \~ + \details \ru Пересчитать интегралы инерции с учётом частично заданных пользователем моментов инерции.\n + Присваивает себе значение площади, объема, массы, центра масс эталона, моментов инерции, + если эти величины у эталона заданы.\n + Площадь, объем, масса, центр масс, моменты инерции объекта не изменяются, + если соответствующая величина у эталона не задана. + \en Recalculate integrals of inertia with user-given partially defined moments of inertia.\n + Assigns the values of area, volume, mass, reference center of mass, moments of inertia, + if reference values are defined.\n + Area, volume, mass, center of mass, moments of inertia of an object are not changed + if corresponding reference values are not defined. \~ + \param[in] prop - \ru Частично заданные инерционные характеристики. + \en Partially defined inertial properties. \~ + */ + void CrossIntegrals( const InertiaProperties & prop ); + + /** \brief \ru Рассчитать главную центральную систему. + \en Calculate principal central coordinate system. \~ + \details \ru Расчёт главной центральной системы координат и проверка.\n + Входит: расчет центра масс и центральных моментов инерции, + расчет главных центральных моментов инерции. + \en Calculation and checking of principal central coordinate system.\n + Included: calculation of center of mass and central moments of inertia, + calculation of principal central moments of inertia. \~ + \return \ru true в случае корректных данных. + \en True if data is correct. \~ + */ + bool Calculate(); + + /** \brief \ru Рассчитать центр масс и центральные моменты инерции. + \en Calculate center of mass and central moments of inertia. \~ + \details \ru Рассчитать центр масс и центральные моменты инерции.\n + \en Calculate center of mass and central moments of inertia.\n \~ + \return \ru true в случае корректных данных. + \en True if data is correct. \~ + */ + bool CalculateCenter(); + + /** \brief \ru Рассчитать главные центральные моменты инерции. + \en Calculate principal central moments of inertia. \~ + \details \ru Рассчитать главные центральные моменты инерции.\n + \en Calculate principal central moments of inertia.\n \~ + \return \ru true в случае корректных данных. + \en True if data is correct. \~ + */ + bool CalculateGeneral(); + + /** \brief \ru Трансформировать. + \en Transform. \~ + \details \ru Трансформировать данные по матрице.\n + \en Transform data by matrix.\n \~ + \param[in] m - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform( const MbMatrix3D & m ); + + /** \brief \ru Трансформировать. + \en Transform. \~ + \details \ru Трансформировать интегралы инерции в соответствии с матрицей.\n + \en Transform integrals of inertia according to matrix.\n \~ + \param[in] m - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void IntegralsTransform( const MbMatrix3D & m ); + + /// \ru Добавить к полям объекта полей другого объекта. \en Add fields of other object to current. + void Add( const InertiaProperties & ); + /// \ru Изменить плотность. \en Change density. + void ChangeDensity( double density ); + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + bool IsSame( const InertiaProperties & other, double accuracy ) const; + + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const InertiaProperties & ); + +}; // InertiaProperties + + +typedef InertiaProperties SolidMIProperties; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тело, его характеристики и матрицы преобразования копий тела. + \en Solid, its properties and transformation matrices of solid duplicates. \~ + \details \ru Тело, его характеристики и матрицы преобразования копий тела.\n + \en Solid, its properties and transformation matrices of solid duplicates.\n \~ + \ingroup Inertia_Computation +*/ +// --- +class MATH_CLASS SolidMIAttire { +private : + const MbSolid & solid; ///< \ru Тело. \en A solid. + double density; ///< \ru Плотность или удельная масса на единицу площади. \en Density or mass per unit square. + MbMatrix3D matrix; ///< \ru Матрица преобразования тела в систему ближайшей сборки (хозяина). \en A matrix of solid transformation to the coordinate system of nearest assembly (owner). + InertiaProperties * properties; ///< \ru Характеристики тела (может быть NULL). \en Solid properties (can be NULL). + bool ready; ///< \ru Флаг, показывающий, что характеристики не требуется считать. \en Flag of already calculated properties. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор объекта с нулевыми характеристиками тела.\n + \en Constructor of object with zero solid properties.\n \~ + \param[in] s - \ru Тело. + \en A solid. \~ + \param[in] d - \ru Плотность (s.IsClosed()) или удельная масса на единицу площади (!s.IsClosed()). + \en Density (s.IsClosed()) or mass per unit square (!s.IsClosed()). \~ + \param[in] d - \ru Плотность. + \en Density. \~ + \param[in] m - \ru Матрица преобразования. + \en A transform matrix. \~ + */ + SolidMIAttire( const MbSolid & s, double d, const MbMatrix3D & m ); + /// \ru Деструктор. \en Destructor. + ~SolidMIAttire(); + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Тело. \en A solid. + const MbSolid & GetSolid() const { return solid; } + /// \ru Плотность тела. \en A solid density. + double GetDensity() const { return density; } + /// \ru Матрица преобразования. \en A transform matrix. + const MbMatrix3D & GetMatrix() const { return matrix; } + /// \ru Инерционные характеристики тела. \en Inertial properties of solid. + const InertiaProperties * GetProperties() const { return properties; } + /// \ru Флаг, показывающий, что характеристики посчитаны. \en Flag of already calculated properties. + bool IsReady() const { return ready; } + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Установить характеристики тела. \en Set solid properties. + void SetProperties( InertiaProperties & p ); + /// \ru Установить флаг, показывающий, что характеристики посчитаны. \en Set flag of already calculated properties. + void SetReady( bool r = true ) { ready = r; } + + /** \} */ + /**\ru \name Функции расчета данных. + \en \name Functions for calculating data. + \{ */ + + /** \brief \ru Расчёт аддитивных характеристик тела. + \en Calculation of additive solid properties. \~ + \details \ru Расчёт аддитивных характеристик тела.\n + \en Calculation of additive solid properties.\n \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики с учётом пользовательских данных. + \en Inertial properties calculated with user-defined data. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. Для прекращения долгих вычислений. + \en A run progress indicator. For termination of slow computations. \~ + */ + void CalculateAdditiveValues( double deviateAngle, InertiaProperties & mp, + IfProgressIndicator * progress = NULL ) const; + /** \} */ + + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without Implementation of the copy constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( SolidMIAttire ) +}; // SolidMIAttire + + +//------------------------------------------------------------------------------ +/** \brief \ru Сборка. + \en Assembly. \~ + \details \ru Сборка, её подсборки, тела и характеристики.\n + \en Assembly, its subassembly, solids and properties.\n \~ + \ingroup Inertia_Computation +*/ +// --- +class MATH_CLASS AssemblyMIAttire { +private : + RPArray assemblies; ///< \ru Подсборки. \en Subassemblies. + RPArray solids; ///< \ru Тела сборки. \en Solids in an assembly. + MbMatrix3D matrix; ///< \ru Матрица преобразования сборки в систему ближайшей сборки (хозяина). \en A matrix of assembly transformation to the coordinate system of nearest assembly (owner). + InertiaProperties * properties; ///< \ru Характеристики сборки (может быть NULL). \en Assembly properties (can be NULL). + bool ready; ///< \ru Характеристики не требуется считать. \en Properties already calculated. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор объекта с нулевыми характеристиками тела.\n + Данные массивов перекладываются в массивы класса, + где будут уничтожены при деструктурировании. + \en Constructor of object with zero solid properties.\n + Arrays data are moved to arrays of class + and will be deleted at destruction. \~ + \param[in] a - \ru Набор подсборок. + \en A set of subassemblies. \~ + \param[in] s - \ru Набор тел. + \en A set of solids. \~ + \param[in] m - \ru Матрица преобразования. + \en A transform matrix. \~ + */ + AssemblyMIAttire( RPArray & a, RPArray & s, + const MbMatrix3D & m = MbMatrix3D::identity ); + + /// \ru Деструктор. \en Destructor. + ~AssemblyMIAttire(); + + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Набор подсборок. \en A set of subassemblies. + const RPArray & GetAssemblies() const { return assemblies; } + /// \ru Набор тел. \en A set of solids. + const RPArray & GetSolids() const { return solids; } + /// \ru Матрица преобразования. \en A transform matrix. + const MbMatrix3D & GetMatrix() const { return matrix; } + /// \ru Инерционные характеристики. \en Inertial properties. + const InertiaProperties * GetProperties() const { return properties; } + /// \ru Готовы ли инерционные характеристики? \en Properties already calculated. + bool IsReady() const { return ready; } + /// \ru Вычислить количество граней. \en Calculate faces count. + size_t GetFacesCount() const; + + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data. + \{ */ + + /// \ru Установить инерционные характеристики. \en Set inertial properties. + void SetProperties( InertiaProperties & p ); + /// \ru Флаг готовых инерционных характеристик. \en Flag of already calculated properties. + void SetReady( bool r = true ) { ready = r; } + + /** \} */ + /**\ru \name Функции расчета данных. + \en \name Functions for calculating data. + \{ */ + + /** \brief \ru Расчёт аддитивных характеристик тела. + \en Calculation of additive solid properties. \~ + \details \ru Расчёт аддитивных характеристик тела.\n + \en Calculation of additive solid properties.\n \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode runs in parallel. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики с учётом пользовательских данных. + \en Inertial properties calculated with user-defined data. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. Для прекращения долгих вычислений. + \en A run progress indicator. For termination of slow computations. \~ + */ + void CalculateAdditiveValues( double deviateAngle, InertiaProperties & mp, + IfProgressIndicator * progress = NULL ) const; + /** \} */ + + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without Implementation of the copy constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( AssemblyMIAttire ) +}; // AssemblyMIAttire + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление масс-центровочных характеристик. + \en Calculation of mass-inertial properties. \~ + \details \ru Вычисление масс-центровочных характеристик тела. + \en Calculation of solid mass-inertial properties. \~ + \note \ru В многопоточном режиме mtm_Items выполняется параллельно. + \en In multithreaded mode mtm_Items runs in parallel. \~ + \param[in] solid - \ru Тело. + \en A solid. \~ + \param[in] density - \ru Плотность (solid->IsClosed()) или удельная масса на единицу площади (!solid->IsClosed()). + \en Density (solid->IsClosed()) or mass per unit square (!solid->IsClosed()). \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики. + \en Calculated inertial properties. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const MbSolid * solid, + double density, + double deviateAngle, // (0.35 - 0.01) + InertiaProperties & mp, + IfProgressIndicator * progress = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление масс-центровочных характеристик. + \en Calculation of mass-inertial properties. \~ + \details \ru Вычисление масс-центровочных характеристик тел. + \en Calculation of mass-inertial properties of solids. \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode runs in parallel. \~ + \param[in] solids - \ru Тела. + \en Solids. \~ + \param[in] densities - \ru Плотности тел или удельная масса на единицу площади.\n + Количество элементов в массиве должно совпадать с количеством тел. + \en Density of solids or mass per unit square of solids.\n + Count of elements in array must be equal to count of solids. \~ + \param[in] matrs - \ru Матрицы преобразования тел в глобальную систему координат.\n + Количество элементов в массиве должно совпадать с количеством тел. + \en Matrices of solids transformation to global coordinate system.\n + Count of elements in array must be equal to count of solids. \~ + \param[in] mpSolids - \ru Имеющиеся характеристики тел. Может содержать NULL.\n + Количество элементов в массиве должно совпадать с количеством тел. + \en Calculated properties of solids. Can contain NULL.\n + Count of elements in array must be equal to count of solids. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики. + \en Calculated inertial properties. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const RPArray & solids, + const SArray & densities, + const SArray & matrs, + const RPArray & mpSolids, + double deviateAngle, // (0.35 - 0.01) + InertiaProperties & mp, + IfProgressIndicator * progress = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление масс-центровочных характеристик. + \en Calculation of mass-inertial properties. \~ + \details \ru Вычисление масс-центровочных характеристик сборки. + \en Calculation of mass-inertial properties of assembly. \~ + \note \ru В многопоточном режиме m_Items выполняется параллельно. + \en In multithreaded mode m_Items runs in parallel. \~ + \param[in] assembly - \ru Сборка. + \en Assembly. \~ + \param[in] deviateAngle - \ru Параметр управления точностью расчёта - угловое отклонение нормали поверхности или касательных кривой на участке численного интегрирования. + \en Tolerance - the angular deviation of surface or curve in the neighboring points on the region of numerical integration. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики. + \en Calculated inertial properties. \~ + \param[in] progress - \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const AssemblyMIAttire & assembly, + double deviateAngle, // (0.35 - 0.01) + InertiaProperties & mp, + IfProgressIndicator * progress = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление масс-центровочных характеристик. + \en Calculation of mass-inertial properties. \~ + \details \ru Вычисление масс-центровочных характеристик полигонального объекта. + \en Calculation mass-inertial properties of polygonal object. \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode runs in parallel. \~ + \param[in] solid - \ru Полигональный объект. + \en A polygonal object. \~ + \param[in] density - \ru Плотность или удельная масса на единицу площади. + \en Density or mass per unit square. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики. + \en Calculated inertial properties. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const MbMesh * mesh, + double density, + InertiaProperties & mp ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычисление масс-центровочных характеристик. + \en Calculation of mass-inertial properties. \~ + \details \ru Вычисление масс-центровочных характеристик множества полигональных объектов. + \en Calculation of mass-inertial properties of polygonal objects. \~ + \note \ru В многопоточном режиме выполняется параллельно. + \en In multithreaded mode runs in parallel. \~ + \param[in] solids - \ru Множество полигональных объектов. + \en Set of polygonal objects. \~ + \param[in] densities - \ru Плотности объектов или удельная масса на единицу площади.\n + Количество элементов в массиве должно совпадать с количеством объектов. + \en Density of solids or mass per unit square of polygonal objects.\n + Count of elements in array must be equal to count of polygonal objects. \~ + \param[in] matrs - \ru Матрицы преобразования полигональных объектов в глобальную систему координат.\n + Количество элементов в массиве должно совпадать с количеством объектов. + \en Matrices of solids transformation to global coordinate system.\n + Count of elements in array must be equal to count of polygonal objects. \~ + \param[out] mp - \ru Рассчитанные инерционные характеристики. + \en Calculated inertial properties. \~ + \ingroup Inertia_Computation +*/ +// --- +MATH_FUNC (void) MassInertiaProperties( const std::vector & solids, + const std::vector & densities, + const std::vector & matrix, + InertiaProperties & mp ); + + +#endif // __MIP_SOLID_MASS_INERTIA_H diff --git a/C3d/Include/model.h b/C3d/Include/model.h new file mode 100644 index 0000000..cda4e12 --- /dev/null +++ b/C3d/Include/model.h @@ -0,0 +1,669 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** \file + \brief \ru Геометрическая модель. + \en Geometric model. \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MODEL_H +#define __MODEL_H + + +#include +#include + +struct ItModelVisitor; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Геометрическая модель. + \en Geometric model. \~ + \details \ru Геометрическая модель - контейнер геометрических объектов. \n + Модель состоит из массивов указателей на объекты геометрической модели MbItem. + Модель может содержать вспомогательные объекты MbAssistingItem, + точки MbPointFrame, каркасы MbWireFrame, + твердые тела MbSolid, полигональные объекты MbMesh, + объекты MbSpaceInstance и MbPlaneInstance.\n + Модель используется для описания геометрических свойств реальных и + воображаемых объектов, визуализации моделируемых объектов, + вычисления геометрических характеристик моделируемых объектов.\n + Имя объекта геометрической модели представляет собой контейнер простых имён. + В начале контейнера содержится простое имя SimpleName, + которое совпадает с первым полем std::multimap геометрической модели. \n + Если объект не держит в себе других объектов, то контейнер содержит одно простое имя SimpleName. + Ели объект держит в себе другие объекты (MbAssembly или MbInstance), + то имя внутренних объектов представляет собой контейнер, содержащий как минимум два простых имени. + Количество элементов имени объекта отражают количество уровней вложенности объект относительно модели. + \en Geometric model is a container of geometric objects. \n + The model consists of arrays of pointers to geometric model objects MbItem. + The model can contain MbAssistingItem assisting items, + MbPointFrame points, MbWireFrame frames, + MbSolid solids, polygonal objects MbMesh, + MbSpaceInstance and MbPlaneInstance objects.\n + Model is used to describe geometric properties of real and + imaginary objects, to visualize modeled objects, + to calculate geometric properties of modeled objects.\n + The name of an object of a geometric model is represented as a container of simple names. + In the beginning of the container there is a SimpleName simple name + which coincides with the first field std::multimap of the geometric model. \n + If the object doesn't contain other objects, then the container contains one SimpleName simple name. + If the object contains other objects (MbAssembly or MbInstance), + then the internal objects name is represented as a container with at least two simple names. + Number of the elements of an object's name corresponds to the number of levels of objects inclusion relative to the model. \~ + \ingroup Model +*/ +//--- +class MATH_CLASS MbModel : public TapeBase, + public MbRefItem, + public MbTransactions, + public MbAttributeContainer +{ +public: + typedef std::map NameItemArray; + +private: + NameItemArray modelItems; ///< \ru Множество объектов модели. \en Set of the model objects. + SimpleName name; ///< \ru Имя объекта. \en A name of an object. + +protected: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbModel( const MbModel &, MbRegDuplicate * ); + +public: + /// \ru Конструктор по имени объекта. \en Constructor by object's name. + MbModel( SimpleName n = 0 ); + /// \ru Деструктор \en Destructor + virtual ~MbModel(); + +public : + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + /// \ru Тип контейнера атрибутов - классификатор наследников. \en Type of an attribute container is a classifier of inheritors. + virtual MbeImplicationType ImplicationType() const; + + /// \ru Создать копию. \en Create a copy. + MbModel & Duplicate( MbRegDuplicate * = NULL ) const; + /// \ru Преобразовать согласно матрице. \en Transform according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * iReg = NULL ); + /// \ru Сдвинуть вдоль вектора. \en Translate along a vector. + void Move ( const MbVector3D &, MbRegTransform * iReg = NULL ); + /// \ru Повернуть вокруг оси. \en Rotate about an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * iReg = NULL ); + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + double DistanceToPoint ( const MbCartPoint3D & ) const; + /// \ru Добавь свой габарит в габаритный куб. \en Include your own bounding box into bounding box. + void AddYourGabaritTo( MbCube & ) const; + + /// \ru Создать собственное свойство с заданием его имени. \en Create your own property with specified name. + MbProperty & CreateProperty( MbePrompt ) const; + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /** \} */ + + /// \ru Выдать имя модели. \en Get name of a model. + SimpleName GetModelName() const { return name; } + /// \ru Установить имя модели. \en Set name of a model. + void SetModelName( SimpleName n ) { name = n; } + + /** \brief \ru Добавить объект в модель. + \en Add object to the model. \~ + \details \ru Добавить объект в модель с указанным именем. + \en Add object to the model with a given name. \~ + \param[in] item - \ru Объект модели. + \en A model object. \~ + \param[in] n - \ru Имя объекта. Если указанное имя равно нулю, то модель именует объект своим уникальным именем. + \en A name of an object. If a given name is equal to zero, then the model names an object with its unique name. \~ + \return \ru Добавленный объект. + \en Added object. \~ + */ + MbItem * AddItem( MbItem & item, SimpleName n = UNDEFINED_SNAME ); + /// \ru Добавить объекты модели item в модель. \en Add item objects of to the model. \~ + bool AddModel( const MbModel & ); + + // \ru Выдать объект модели по индексу. \en Get item of model by index. + const MbItem * GetItem( size_t ind ) const; + // \ru Выдать непосредственный объект модели по идентификатору. \en Get the immediate item of model by identifier. + const MbItem * SubItem( SimpleName n ) const; + + /** \brief \ru Заменить объект. + \en Replace the object. \~ + \details \ru Заменить объект новым. + \en Replace the object by a new one. \~ + \param[in] item - \ru Заменяемый объект. + \en An object to replace. \~ + \param[in] newItem - \ru Новый объект. + \en A new object. \~ + \return \ru Возвращает true, если замена была выполнена. + \en Returns true if the replacement has been done. \~ + */ + bool ReplaceItem( const MbItem & item, MbItem & newItem, bool saveName = false ); + + /// \ru Дать все объекты. \en Get all the objects. + template + void GetItems( Items & ) const; + /// \ru Отцепить объект, если он есть в модели. \en Detach an object if it is in the model. + bool DetachItem ( MbItem *, bool resetName = true ); + /// \ru Отцепить все объекты. \en Detach all the objects. + template + void DetachItems( Items & ); + + /// \ru Удалить объект, если он есть в модели. \en Delete an object if it is in the model. + bool DeleteItem ( MbItem *, bool resetName = true ); + /// \ru Удалить все объекты модели. \en Delete all the model objects. + void DeleteItems(); + + /// \ru Разрушить сборки с подсборками на составляющие. \en Decompose assemblies with subassemblies into components. + bool DecomposeAssemblies(); + + /** \brief \ru Наполнить присланную модель полигональными копиями объектов модели. + \en Fill the given model with polygonal copies of the model objects. \~ + \details \ru Наполнить присланную модель полигональными копиями объектов оригинальной модели. + Присланная модель опустошается и наполняется полигональными копиями объектов оригинальной модели. + Присланная модель заполняется аналогично оригинальной модели с той разницей, что вместо + тел, проволочных каркасов, точечных каркасов и других конечных объектов модели + присланную модель заполняют соответствующие полигональные копии объектов (MbMesh). + Сборки и вставки в присланной модели сохраняются аналогичными оригинальной модели. + Присланная модель может использоваться для визуализации модели и расчетов. + \en Fill the given model with polygonal copies of the original model objects. + Given model is being cleared and filled with polygonal copies of objects of the original model. + Given model is to be filled similarly to original model, but instead of + solids, wire-frames, point-frames and other finite objects of model + the given model is filled by the corresponding polygonal copies of objects (MbMesh). + Assemblies and instances in the given model remains similar to the original model. + Given model can be used for calculations and visualization of the model. \~ + \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. \~ + + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[out] meshModel - \ru Присланная модель для наполнения. + \en Given model to be filled. \~ + \return \ru Не было ошибок во время построения - true, были ошибки - false. + \en If there were no errors during construction, then true, otherwise false. \~ + */ + bool FillMeshModel( const MbStepData & stepData, const MbFormNote & note, MbModel & meshModel ) const; + + /** \brief \ru Добавить полигональный объект. + \en Add polygonal object. \~ + \details \ru Добавить полигональную копию модели в присланный полигональный объект (MbMesh). + Все объекты модели, её сборки и вставки помещаются в единый плоскогранный полигональный объект. + Один и тот же объект, вставленный несколько раз в сборки и вставки модели, получает несколько копий, + так как каждая копия трансформируется по матрице локальной системы координат cjjndtncnde.otq сборки и вставки. + \en Add polygonal copy of the model to the given polygonal object (MbMesh). + All the objects, assemblies and instances of the model are placed in a unified planar polygonal object. + The same object inserted several times in assemblies and instances of the model gets several copies + because each copy is transformed by the matrix of local coordinate system of the corresponding assembly and instance. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[out] mesh - \ru Присланный полигональный объект. + \en Given polygonal object. \~ + \return \ru Добавлен ли объект. + \en Whether the object is added. \~ + */ + bool AddYourMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + /** \brief \ru Разрезать модель полигональных объектов одной или двумя параллельными плоскостями. + \en Cut model of polygonal objects by one or two parallel planes. \~ + \details \ru Создать новую модель полигональных объектов и наполнить её частями исходной модели, + лежащими под плоскостью XY локальной системы координат на заданном расстоянии.\n + Функция "режет" только модель полигональных объектов MbMesh. + Функция "режет" модель двумя плоскостями: + плоскостью XY локальной системы координат place и плоскостью, параллельной ей и + расположенной на расстоянии distance ниже неё. + Если distance<=0, то функция "режет" объект только одной плоскостью XY локальной системы.\n + Содержимое исходных полигональных объектов, + необходимое для построения разрезанного объекта и не затронутое режущими плоскостями, + добавляется в возвращаемый разрезанный объект без копирования.\n + \en Create new model of polygonal objects and fill it by the source model parts + lying under XY plane of the local coordinate system at the given distance.\n + Function "cuts" only MbMesh model of polygonal objects. + Function "cuts" the model by two planes: + XY plane of 'place' local coordinate system and plane parallel to it and + located at 'distance' distance below it. + If 'distance' is less than or equal to zero, then the function "cuts" an object only by one XY plane of local coordinate system.\n + Contents of the source polygonal objects + that are necessary for creation of cut object and not affected by cutting planes + are added to returned cut object without copying.\n \~ + \param[in] place - \ru Локальная система координат, плоскость XY которой задаёт режущую плоскость. + \en A local coordinate system which XY plane defines a cutting plane. \~ + \param[in] distance - \ru Расстояние до параллельной режущей плоскости откладывается в отрицательную сторону оси Z локальной системы. + \en Distance to a parallel cutting plane is measured in negative direction of Z-axis of local coordinate system. \~ + \result \ru Возвращает новую модель полигональных объектов, лежащую под плоскость XY локальной системы координат на заданном расстоянии. + \en Returns a new model of polygonal objects that lies under XY plane of local coordinate system at given distance. \~ + */ + MbModel * CutMeshModel( const MbPlacement3D & cutPlace, double distance ) const; + + /** \brief \ru Найти ближайший объект или имя ближайшего объекта. + \en Find the nearest object or name of the nearest object. \~ + \details \ru Найти ближайший трехмерный объект или его имя по типу объекта и + составляющий элемент искомого объекта или его имя по топологическому или двумерному типу элемента (по требованию) + на расстоянии от прямой, не превышающем заданной величины. + Функция предназначена для идентификации геометрического объекта, породившего полигональный объект. + Реальный поиск выполняется для элементов MbPrimitive полигонального объекта MbMesh, + у которых берётся информация о породившем примитив геометрическом объекте. + \en Find the nearest three-dimensional object or its name by type of object and + component of the required object or its name by topological or two-dimensional type of the element (on demand) + at distance from line less than or equal to the given value. + Function is intended for identification of a geometric object which is begetter of a polygonal object. + The real search is performed for MbMesh polygonal object's MbPrimitive elements + from which the information is taken about geometric object which is begetter of the primitive. \~ + \note \ru В многопоточном режиме выполняется параллельно. \en In multithreaded mode runs in parallel. \~ + \param[in] sType - \ru Тип искомого объекта. + \en Type of required object. \~ + \param[in] tType - \ru Топологический тип составляющего элемента искомого объекта. + \en Topological type of the required object's component. \~ + \param[in] pType - \ru Двумерный тип составляющего элемента искомого объекта. + \en Two-dimensional type of the required object's component. \~ + \param[in] axis - \ru Прямая поиска. + \en Line of search. \~ + \param[in] maxDistance - \ru Расстояние от прямой, на котором ищется объект. + \en Distance from the line on which the object is looked for. \~ + \param[in] gridPriority - \ru Повышенный приоритет триангуляционной сетки при поиске. + \en Increased priority triangulation grid when searching. \~ + \param[out] find - \ru Найденный объект. + \en Found object. \~ + \param[out] findName - \ru Имя найденного объекта. + \en Name of the found object. \~ + \param[out] element - \ru Найденный составляющий элемент объекта. + \en Found component of the object. \~ + \param[out] elementName - \ru Имя найденного составляющего элемента объекта. + \en Name of found component of the object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to the object in model. \~ + \param[out] from - \ru Матрица преобразования найденного объекта в глобальную систему координат. + \en Transformation matrix of the found object to the global coordinate system. \~ + \return \ru Найден ли объект или его имя. + \en Whether the object or its name is found. \~ + */ + bool NearestMesh( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType, + const MbAxis3D & axis, double maxDistance, bool gridPriority, + MbItem *& find, SimpleName & findName, + MbRefItem *& element, SimpleName & elementName, + MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Дать все объекты указанного типа. + \en Get all objects by type. \~ + \details \ru Дать все объекты указанного типа, + а также матрицы преобразования их в глобальную систему координат. \n + \en Get all objects by type + and get transformation matrix to the global coordinate system. \n \~ + \param[in] type - \ru Тип объекта. + \en Object's type. \~ + \param[out] items - \ru Множество найденных объектов. + \en Found objects. \~ + \param[out] matrs - \ru Матрицы преобразования найденных объектов в глобальную систему координат. + \en Transformation matrix of found objects to the global coordinate system. \~ + \ingroup Model_Items + */ + virtual void GetItems( MbeSpaceType type, RPArray & items, SArray & matrs ); + + /** \brief \ru Дать все объекты указанного типа. + \en Get all objects by type. \~ + \details \ru Дать все объекты указанного типа, + а также матрицы преобразования их в глобальную систему координат. \n + \en Get all objects by type + and get transformation matrix to the global coordinate system. \n \~ + \param[in] type - \ru Тип объекта. + \en Object's type. \~ + \param[out] items - \ru Множество найденных объектов. + \en Found objects. \~ + \param[out] matrs - \ru Матрицы преобразования найденных объектов в глобальную систему координат. + \en Transformation matrix of found objects to the global coordinate system. \~ + \ingroup Model_Items + */ + virtual void GetItems( MbeSpaceType type, RPArray & items, SArray & matrs ) const; + + /** \brief \ru Дать все уникальные объекты указанного типа. + \en Get all unique objects by type. \~ + \details \ru Дать все уникальные объекты указанного типа. \n + \en Get all unique objects by type. \n \~ + \param[in] type - \ru Тип объекта. + \en Object's type. \~ + \param[out] items - \ru Множество найденных объектов. + \en Found objects. \~ + \ingroup Model_Items + */ + virtual void GetUniqItems( MbeSpaceType type, CSSArray & items ) const; + + /** \brief \ru Построить путь положения объекта. + \en Create path of object's position. \~ + \details \ru Построить путь положения объекта в модели и + дать матрицу преобразования объекта в глобальную систему координат. + Объект может содержаться в другом объекте (в сборке или вставке). + \en Create path of object's position in the model and + get transformation matrix of the object to the global coordinate system. + Object can be contained in other object (in assembly or in instance). \~ + \param[in] obj - \ru Объект. + \en Object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to the object in model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + bool MakePath( const MbItem & obj, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Дать объект по его пути. + \en Get the object by its path. \~ + \details \ru Дать объект по его пути положения в модели и + дать матрицу преобразования объекта в глобальную систему координат. + Объект может содержаться в другом объекте (в сборке или вставке). + \en Get the object by path of its position in the model and + get transformation matrix of the object to the global coordinate system. + Object can be contained in other object (in assembly or in instance). \~ + \param[in] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + const MbItem * GetItemByPath( const MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по геометрическому объекту. + \en Find object by geometric object. \~ + \details \ru Найти объект по геометрическому объекту, а также получить путь к + объекту в модели и матрицу преобразования в глобальную систему координат. + \en Find object by geometric object and also get the path to the + object in model and get transformation matrix to the global coordinate system. \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + const MbItem * FindItem( const MbSpaceItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по геометрическому объекту. + \en Find object by geometric object. \~ + \details \ru Найти объект по геометрическому объекту, + а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by geometric object + and also get the path to the object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + const MbItem * FindItem( const MbPlaneItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по объекту геометрической модели. + \en Find object by object of geometric model \~ + \details \ru Найти объект по объекту геометрической модели. + а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by object of geometric model + and also get the path to the object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + const MbItem * FindItem( const MbItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по имени. + \en Find object by name. \~ + \details \ru Найти объект по имени, а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by name and also get path to object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] n - \ru Имя объекта. + \en A name of an object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + const MbItem * GetItemByName( SimpleName n, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по имени для редактирования. + \en Find object by name for editing. \~ + \details \ru Найти объект по имени для редактирования, а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by name for editing and also get path to object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] n - \ru Имя объекта. + \en A name of an object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + */ + MbItem * SetItemByName( SimpleName n, MbPath & path, MbMatrix3D & from ); + /** \brief \ru Алгоритм общего назначения для обхода дерева модели в глубину. + \en General-purpose algorithm traversing the model graph in depth. */ + void Traverse( ItModelVisitor & ) const; + /// \ru Преобразовать селектирование объекты по матрице. \en Transform selected objects by matrix. + void TransformSelected( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Сдвинуть выбранные объекты. \en Move selected objects. + void MoveSelected( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Повернуть выбранные объекты вокруг оси. \en Rotate selected objects around an axis. + void RotateSelected( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + + /** \brief \ru Отцепить все выбранные объекты. + \en Detach all selected objects. \~ + \details \ru Отцепить все выбранные объекты модели, в том числе и + содержащиеся в сложных составных объектах, таких как сборка. \n + \en Detach all selected objects of model including ones + contained in complex composite objects such as assembly. \n \~ + \param[out] items - \ru Отцепленные объекты. + \en Detach the objects. \~ + \param[out] matrs - \ru Матрицы преобразования отцепленных объектов в глобальную систему координат. + \en Transformation matrices of detached objects to global coordinate system. \~ + */ + void DetachSelected( RPArray & , SArray & , bool selected, bool resetName = true ); + /// \ru Отцепить все видимые или невидимые объекты. \en Detach all visible or invisible objects. \~ + void DetachInvisible( RPArray & , SArray & , bool invisible, bool resetName = true ); + + /// \ru Выдать количество объектов модели. \en Get the count of objects of model. + size_t ItemsCount() const { return modelItems.size(); } + + /// \ru Содержится ли объект в модели? \en Whether the object is contained in model. + bool ContainsItem( const MbItem * ) const; + /// \ru Добавить в модель объекты другой модели. \en Add objects of other model to the model. + bool AddModelItems( const MbModel & ); + /// \ru Добавить в массив выбранные объекты модели без поиска в сложных составных объектах. \en Add selected objects of model to array without search in complex composite objects. + size_t GetSelected( RPArray & ) const; + + /// \ru Вычислить габарит по всем объектам модели. \en Calculate bounding box for all the objects of model. + void CalculateGabarit( MbCube & ) const; + + private: + // Отдать все объекты с указанным свойством. + void DetachByAttribute( RPArray & items, SArray & matrs, int attribute, bool resetName ); + +public: + /// \ru Простой итератор по объектам модели. \en Simple iterator on objects of model. + class ItemIterator { + private: + NameItemArray::iterator currIter; + + private: + ItemIterator( const NameItemArray::iterator & iter ) : currIter( iter ) {} + + public: + MbItem * operator * () { return currIter->second; } + MbItem * operator -> () { return currIter->second; } + ItemIterator & operator ++ () { ++currIter; return *this; } + ItemIterator operator ++ ( int ) { return ItemIterator(currIter++); } + + bool operator == ( const ItemIterator & other) const { return currIter == other.currIter; } + bool operator != ( const ItemIterator & other) const { return currIter != other.currIter; } + + friend class MbModel; + }; // ItemIterator + + + /// \ru Константный итератор по объектам модели. \en Constant iterator on objects of the model. + class ItemConstIterator { + private: + NameItemArray::const_iterator currIter; + + private: + ItemConstIterator( const NameItemArray::const_iterator & iter ) : currIter( iter ) {} + +// public: +// ItemConstIterator( const ItemIterator& iIter ) : currIter( iIter.currIter ) {} + + public: + const MbItem * operator * () const { return currIter->second; } + const MbItem * operator -> () const { return currIter->second; } + ItemConstIterator & operator ++ () { ++currIter; return *this; } + ItemConstIterator operator ++ ( int ) { return ItemConstIterator(currIter++); } + + bool operator == ( const ItemConstIterator & other) const { return currIter == other.currIter; } + bool operator != ( const ItemConstIterator & other) const { return currIter != other.currIter; } + + friend class MbModel; + }; // ItemConstIterator + +public: + /// \ru Выдать константный итератор по всем объектам с указанием на начало. \en Get constant iterator on all objects pointing to the first element. + ItemConstIterator CBegin() const { return ItemConstIterator( modelItems.begin() ); } + /// \ru Выдать константный итератор по всем объектам с указанием за конец. \en Get constant iterator on all objects pointing to the past-the-end element. + ItemConstIterator CEnd() const { return ItemConstIterator( modelItems.end() ); } + /// \ru Выдать константный итератор для указанного имени с указанием на начало. \en Get constant iterator by the given name pointing to the first element. + ItemConstIterator CBegin( SimpleName n ) const { return ItemConstIterator( modelItems.lower_bound(n) ); } + /// \ru Выдать константный итератор для указанного имени с указанием на конец. \en Get constant iterator by the given name pointing to the past-the-end element. + ItemConstIterator CEnd( SimpleName n ) const { return ItemConstIterator( modelItems.upper_bound(n) ); } + /// \ru Выдать не константный итератор по всем объектам с указанием на начало. \en Get non-constant iterator on all the objects pointing to the first element. + ItemIterator Begin() { return ItemIterator( modelItems.begin() ); } + /// \ru Выдать не константный итератор по всем объектам с указанием за конец. \en Get non-constant iterator on all the objects pointing to the past-the-end element. + ItemIterator End() { return ItemIterator( modelItems.end() ); } + /// \ru Выдать не константный итератор для указанного имени с указанием на начало. \en Get non-constant iterator by the given name pointing to the first element. + ItemIterator Begin( SimpleName n ) { return ItemIterator( modelItems.lower_bound(n) ); } + /// \ru Выдать не константный итератор для указанного имени с указанием на конец. \en Get non-constant iterator by the given name pointing to the past-the-end element. + ItemIterator End( SimpleName n ) { return ItemIterator( modelItems.upper_bound(n) ); } + +private: + void CreateItemsMeshes( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * ) const; + + +private: // Устаревшие методы. // Deprecated methods (it will be deleted in future revisions) + /// \ru Установить первое простое имя существующему объекту модели. \en Set the first simple name for existing object of model. + bool SetItemMainName( MbItem *, SimpleName ); + // The function is deprecated. Use ItemIterator instead indexed access. + const MbItem * GetModelItem( size_t i ) const; + +private: // \ru Закрытые методы. // \en Internal use methods. + // \ru Выдать имя последнего объекта в контейнере. \en Get name of the last object in container. + SimpleName _LastItemName() const { return modelItems.empty() ? 0 : modelItems.rbegin()->first; } + // \ru Выдать имя для следующего за последним объекта. \en Get name of past-the-end object (next object to the last one). + SimpleName _NextItemName() const; + // \ru Генерация имени для нового элемента. \en Generate identifier for a new item. + SimpleName _NewItemName( SimpleName & startName ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbModel ); + OBVIOUS_PRIVATE_COPY( MbModel ); +}; // MbModel + +IMPL_PERSISTENT_OPS( MbModel ) + +//---------------------------------------------------------------------------------------- +// \ru Дать все объекты. \en Get all the objects. +// --- +template +void MbModel::GetItems( Items & items ) const +{ + items.reserve( modelItems.size() ); + for ( NameItemArray::const_iterator iter = modelItems.begin(); iter != modelItems.end(); ++iter ) { + if ( iter->second != NULL ) + items.push_back( iter->second ); + } +} + +//---------------------------------------------------------------------------------------- +// \ru Отцепить все объекты. \en Detach all the objects. +// --- +template +void MbModel::DetachItems( Items & items ) +{ + items.reserve( modelItems.size() ); + NameItemArray::iterator iter = modelItems.begin(); + NameItemArray::const_iterator endItem = modelItems.end(); + for ( ; iter != endItem; ++iter ) { + MbItem * item = iter->second; + if ( item != NULL ) { + item->DecRef(); + items.push_back( item ); + } + } + modelItems.clear(); + AttributesChange(); +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Чтение модели MbModel из потока #reader. + \en Read MbModel model from #reader stream. \~ + \details \ru Чтение модели MbModel из потока #reader. \n + \en Read MbModel model from #reader stream. \n \~ + \ingroup Model +*/ +// --- +MATH_FUNC (bool) ReadModelItems( reader &, MbModel & ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Чтение из потока объектов, определенных в данном дереве модели. + \en Read items, defined in the given model tree, from a stream. + \details \ru Чтение из потока всех объектов, определенных в данном дереве модели, включая его корень (корни). + \en Read items, defined in the given model tree including its root(s), from a stream. + \param[in] in - \ru Поток для чтения. \en Stream to read from. \~ + \param[in] tree - \ru Дерево модели. \en Model tree. \~ + \param[out] items - \ru Прочитанные объекты. \en Read objects. \~ +*/ +// --- +MATH_FUNC (void) ReadModelItemsFromTree( reader & in, const c3d::IModelTree * tree, std::vector< SPtr > & items ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Чтение из потока объектов, определенных в поддереве с корнем в данном узле. + \en Read items, defined in a subtree with a root at the given node, from a stream. + \details \ru Чтение из потока объектов, определенных в поддереве с корнем в данном узле, исключая сам узел. + Если определено флагом (addAttr == true), то из объекта, определенного заданным узлом, читаются атрибуты и добавляются в модель. + \en Read items, defined in a subtree with a root at the given node, from a stream, excluding the node itself. + If defined by the flag (addAttr == true), attributes are read from an object defined by the given node and added to the model. + \param[in] in - \ru Поток для чтения. \en Stream to read from. \~ + \param[in] node - \ru Узел дерева модели. \en Node of Model tree. \~ + \param[out] model - \ru Модель, куда добавлять прочитанные объекты. \en Model where to add read objects. \~ + \param[in] addAttr - \ru Флаг чтения атрибутов. \en Attributes read flag. \~ +*/ +// --- +MATH_FUNC (void) ReadModelItemsFromTree( reader & in, const c3d::IModelTreeNode * node, MbModel & model, bool addAttr = false ); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Запись модели MbModel в поток #writer. + \en Write MbModel model to #writer stream. \~ + \details \ru Запись модели MbModel в поток #writer. \n + \en Write MbModel model to #writer stream. \n \~ + \ingroup Model +*/ +// --- +MATH_FUNC (void) WriteModelItems( writer &, const MbModel & ); + + +#endif // __MODEL_H diff --git a/C3d/Include/model_item.h b/C3d/Include/model_item.h new file mode 100644 index 0000000..908bfae --- /dev/null +++ b/C3d/Include/model_item.h @@ -0,0 +1,545 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Объект геометрической модели. + \en A model geometric object. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MODEL_ITEM_H +#define __MODEL_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbItem; +namespace c3d // namespace C3D +{ +typedef SPtr ItemSPtr; +typedef SPtr ConstItemSPtr; + +typedef std::vector ItemsVector; +typedef std::vector ConstItemsVector; + +typedef std::vector ItemsSPtrVector; +typedef std::vector ConstItemsSPtrVector; + +typedef std::set ItemsSet; +typedef ItemsSet::iterator ItemsSetIt; +typedef ItemsSet::const_iterator ItemsSetConstIt; +typedef std::pair ItemsSetRet; + +typedef std::set ConstItemsSet; +typedef ConstItemsSet::iterator ConstItemsSetIt; +typedef ConstItemsSet::const_iterator ConstItemsSetConstIt; +typedef std::pair ConstItemsSetRet; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Объект геометрической модели. + \en A model geometric object. \~ + \details \ru Родительский класс объектов геометрической модели. \n + Наследниками являются: \n + локальная система координат MbAssistingItem,\n + точечный каркас MbPointFrame,\n + проволочный каркас MbWireFrame,\n + твёрдое тело MbSolid,\n + полигональный объект MbMesh,\n + вставка объекта в локальной системе координат MbInstance,\n + сборка объектов в локальной системе координат MbAssembly,\n + вставка трехмерного объекта MbSpaceInstance,\n + вставка двумерного объекта MbPlaneInstance в плоскости XY локальной системы координат.\n + Объект содержит последовательность и способы своего построения MbTransactions.\n + Объект содержит не геометрические свойства в виде контейнера атрибутов MbAttributeContainer.\n + Имя объекта геометрической модели представляет собой контейнер простых имён. + В начале контейнера содержится простое имя SimpleName, присвоенное объекту геометрической моделью MbModel. \n + Если объект не держит в себе других объектов, то контейнер содержит одно простое имя SimpleName. + Ели объект держит в себе другие объекты (MbAssembly или MbInstance), + то имя внутренних объектов представляет собой контейнер, содержащий как минимум два простых имени. + Количество элементов имени объекта отражают количество уровней вложенности объект относительно модели. + \en Parent class of model geometric objects. \n + Inheritors are: \n + local coordinate system of MbAssistingItem,\n + MbPointFrame point-frame,\n + MbWireFrame wireframe,\n + MbSolid solid,\n + MbMesh polygonal planar object,\n + MbInstance instance of object in the local coordinate system,\n + MbAssembly assembly of objects in the local coordinate system,\n + MbSpaceInstance instance of three-dimensional object,\n + MbPlaneInstance instance of a two-dimensional object in the XY-plane of a local coordinate system.\n + Object contains MbTransactions sequence and ways to construct itself.\n + Object contains non-geometric properties as MbAttributeContainer attribute container.\n + The name of an object of a geometric model is represented as a container of simple names. + In the beginning of the container there is a SimpleName simple name assigned to object by MbModel geometric model. \n + If the object doesn't contain other objects, then the container contains one SimpleName simple name. + If the object contains other objects (MbAssembly or MbInstance), + then the internal objects name is represented as a container with at least two simple names. + Number of the elements of an object's name corresponds to the number of levels of objects inclusion relative to the model. \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbItem : public MbSpaceItem, + public MbTransactions, + public MbAttributeContainer, + public MbSyncItem { + +private: + SimpleName name; ///< \ru Имя объекта геометрической модели. \en Name of a geometric model object. + +protected: + /// \ru Конструктор копирования с регистратором дублирования. \en Copy-constructor with duplication registrator. + explicit MbItem( const MbItem &, MbRegDuplicate * ); +public: + /// \ru Конструктор. \en Constructor. + MbItem(); + /// \ru Деструктор. \en Destructor. + virtual ~MbItem(); + +public : + VISITING_CLASS( MbItem ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const = 0; // \ru Тип объекта. \en A type of an object. + virtual MbeSpaceType Type() const; // \ru Групповой тип объекта. \en Group type of object. + virtual MbeSpaceType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbeImplicationType ImplicationType() const; // \ru Тип контейнера атрибутов - классификатор наследников. \en Type of an attribute container is a classifier of inheritors. + virtual MbSpaceItem & Duplicate ( MbRegDuplicate * = NULL ) const = 0; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool SetEqual ( const MbSpaceItem & init ) = 0; // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const = 0; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const = 0; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const = 0; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** + \brief \ru Получить систему координат объекта, если она есть. + \en Get the coordinate system of an item if it is exist. + \return \ru Функция вернет true, если объект имеет собственную подсистему координат, + иначе считается, что ЛСК объекта всегда "стандартная" (MbPlacement3D::global). + \en The function returns true, if the object have its own local coordinate system, + otherwise it is considered that the object LCS is always "standard" (MbPlacement3D :: global). + */ + virtual bool GetPlacement( MbPlacement3D & p ) const { p = MbPlacement3D::global; return false; } + /// \ru Установить систему координат объекта, если возможно. \en Set the coordinate system of an item if it is possible. + virtual bool SetPlacement( const MbPlacement3D & ) { return false; } + + /** \brief \ru Построить полигональную копию mesh. + \en Build polygonal copy mesh. \~ + \details \ru Построить полигональную копию данного объекта, представленную полигонами, или/и плоскими пластинами. + \en Build a polygonal copy of the object that is represented by polygons or/and fasets. \~ + \param[in] stepData - \ru Данные для вычисления шага при построении полигонального. + \en Data for еру step calculation for polygonal object. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[in, out] mesh - \ru Построенный полигональный объект. + \en The builded polygonal object. + */ + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const = 0; + /** \} */ + + /** \ru \name Общие функции объекта геометрической модели + \en \name Common functions of object of geometric model. + \{ */ + + /** \brief \ru Перестроить объект по журналу построения. + \en Reconstruct object according to the history tree. \~ + \details \ru Создать заново объект по журналу построения. + \en Create object by the history tree. \~ + \param[in] sameShell - \ru Полнота копирования элементов. + \en Whether to perform complete copying of elements while constructing. \~ + \param[out] items - \ru Контейнер для складывания элементов невыполненных построений (может быть NULL). + \en Container for the elements of not performed constructions (can be NULL). \~ + \return \ru Перестроен ли объект. + \en Whether an object is constructed. \~ + \ingroup Model_Items + */ + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + + /** \brief \ru Создать полигональный объект. + \en Create polygonal object. \~ + \details \ru Создать полигональный объект - упрощенную копию данного объекта. + \en Create a polygonal object - a polygonal copy of the given object. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \return \ru Построенный полигональный объект. + \en Created polygonal object. \~ + \ingroup Model_Items + */ + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const = 0; + + /** \brief \ru Добавить полигональный объект. + \en Add polygonal object. \~ + \details \ru Добавить свою полигональную копию в присланный полигональный объект. + \en Add your own polygonal copy to the given polygonal object. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[out] mesh - \ru Присланный полигональный объект. + \en Given polygonal object. \~ + \return \ru Добавлен ли объект. + \en Whether the object is added. \~ + \ingroup Model_Items + */ + virtual bool AddYourMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + /** \brief \ru Разрезать полигональный объект одной или двумя параллельными плоскостями. + \en Cut the polygonal object by one or two parallel planes. \~ + \details \ru Построить полигональный объект из части исходного полигонального объекта, + лежащей под плоскостью XY локальной системы координат на заданном расстоянии.\n + Функция "режет" только полигональный объект MbMesh. + Функция "режет" объект двумя плоскостями: + плоскостью XY локальной системы координат place и плоскостью, параллельной ей и + расположенной на расстоянии distance ниже неё. + Если distance<=0, то функция "режет" объект только одной плоскостью XY локальной системы.\n + Содержимое объекта, необходимое для построения разрезанного объекта и не затронутое режущими плоскостями, + добавляется в возвращаемый разрезанный объект без копирования.\n + \en Create polygonal object from a part of source polygonal object + which located under XY-plane of local coordinate system at given distance.\n + Function 'cuts' only MbMesh polygonal object. + Function 'cuts' the object by two planes: + XY plane of 'place' local coordinate system and plane parallel to it and + located at 'distance' distance below it. + If 'distance' is less than or equal to zero, then the function "cuts" an object only by one XY plane of local coordinate system.\n + Contents of an object that are necessary for creation of cut object and not affected by cutting planes + are added to returned cut object without copying.\n \~ + \param[in] place - \ru Локальная система координат, плоскость XY которой задаёт режущую плоскость. + \en A local coordinate system which XY plane defines a cutting plane. \~ + \param[in] distance - \ru Расстояние до параллельной режущей плоскости откладывается в отрицательную сторону оси Z локальной системы. + \en Distance to a parallel cutting plane is measured in negative direction of Z-axis of local coordinate system. \~ + \result \ru Возвращает новый полигональный объект, лежащий под плоскость XY локальной системы координат на заданном расстоянии. + \en Returns new polygonal object that located under XY-plane of local coordinate system at given distance. \~ + \ingroup Model_Items + */ + virtual MbItem * CutMesh( const MbPlacement3D & cutPlace, double distance ) const; + + /** \brief \ru Найти ближайший объект или имя ближайшего объекта. + \en Find the nearest object or name of the nearest object. \~ + \details \ru Найти ближайший трехмерный объект или его имя по типу объекта и + составляющий элемент искомого объекта или его имя по топологическому или двумерному типу элемента (по требованию) + на расстоянии от прямой, не превышающем заданной величины. + Функция предназначена для идентификации геометрического объекта, породившего полигональный объект. + Реальный поиск выполняется для элементов MbPrimitive полигонального объекта MbMesh, + у которых берётся информация о породившем примитив геометрическом объекте. + \en Find the nearest three-dimensional object or its name by type of object and + component of the required object or its name by topological or two-dimensional type of the element (on demand) + at distance from line less than or equal to the given value. + Function is intended for identification of a geometric object which is begetter of a polygonal object. + The real search is performed for MbMesh polygonal object's MbPrimitive elements + from which the information is taken about geometric object which is begetter of the primitive. \~ + \param[in] sType - \ru Тип искомого объекта. + \en Type of required object. \~ + \param[in] tType - \ru Топологический тип составляющего элемента искомого объекта. + \en Topological type of the required object's component. \~ + \param[in] pType - \ru Двумерный тип составляющего элемента искомого объекта. + \en Two-dimensional type of the required object's component. \~ + \param[in] axis - \ru Прямая поиска. + \en Line of search. \~ + \param[in] maxDistance - \ru Расстояние от прямой, на котором ищется объект. + \en Distance from the line on which the object is looked for. \~ + \param[in] gridPriority - \ru Повышенный приоритет триангуляционной сетки при поиске. + \en Increased priority triangulation grid when searching. \~ + \param[out] t - \ru Параметр прямой для найденной точки. + \en Parameter of found point on line. \~ + \param[out] dMin - \ru Найденное расстояние объекта от прямой. + \en Found distance from line to an object. \~ + \param[out] find - \ru Найденный объект. + \en Found object. \~ + \param[out] findName - \ru Имя найденного объекта. + \en Name of the found object. \~ + \param[out] element - \ru Найденный составляющий элемент объекта. + \en Found component of the object. \~ + \param[out] elementName - \ru Имя найденного составляющего элемента объекта. + \en Name of found component of the object. \~ + \param[out] path - \ru Путь положения объекта в модели. + \en Object's path in the model. \~ + \param[out] from - \ru Матрица преобразования найденного объекта в глобальную систему координат. + \en Transformation matrix of the found object to the global coordinate system. \~ + \return \ru Найден ли объект или его имя. + \en Whether the object or its name is found. \~ + \ingroup Model_Items + */ + virtual bool NearestMesh( MbeSpaceType sType, MbeTopologyType tType, MbePlaneType pType, + const MbAxis3D & axis, double maxDistance, bool gridPriority, double & t, double & dMin, + MbItem *& find, SimpleName & findName, + MbRefItem *& element, SimpleName & elementName, + MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Дать все объекты указанного типа. + \en Get all objects by type. \~ + \details \ru Дать все объекты указанного типа, + а также матрицы преобразования их в глобальную систему координат. \n + \en Get all objects by type + and get transformation matrix to the global coordinate system. \n \~ + \param[in] type - \ru Тип объекта. + \en Object's type. \~ + \param[in] from - \ru Исходная матрица преобразования в глобальную систему координат. + \en Initial transformation matrix to the global coordinate system. \~ + \param[out] items - \ru Множество найденных объектов. + \en Found objects. \~ + \param[out] matrs - \ru Матрицы преобразования найденных объектов в глобальную систему координат. + \en Transformation matrix of found objects to the global coordinate system. \~ + \return \ru Добавлен ли данный объект. + \en Whether add this object. \~ + \ingroup Model_Items + */ + virtual bool GetItems( MbeSpaceType type, const MbMatrix3D & from, + RPArray & items, SArray & matrs ); + /** \brief \ru Дать все уникальные объекты указанного типа. + \en Get all unique objects by type. \~ + \details \ru Дать все уникальные объекты указанного типа. \n + \en Get all unique objects by type. \n \~ + \param[in] type - \ru Тип объекта. + \en Object's type. \~ + \param[out] items - \ru Множество найденных объектов. + \en Found objects. \~ + \return \ru Добавлен ли данный объект. + \en Whether add this object. \~ + \ingroup Model_Items + */ + virtual bool GetUniqItems( MbeSpaceType type, CSSArray & items ) const; + + /** \brief \ru Дать объект по его пути. + \en Get the object by its path. \~ + \details \ru Дать объект по его пути положения в модели и + дать матрицу преобразования объекта в глобальную систему координат. + Объект может содержаться в другом объекте (в сборке или вставке). + \en Get the object by path of its position in the model and + get transformation matrix of the object to the global coordinate system. + Object can be contained in other object (in assembly or in instance). \~ + \param[in] path - \ru Путь объекта. + \en Path of object. \~ + \param[in] ind - \ru Индекс требуемого объекта в path. + \en Index of the desired object in 'path'. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \param[in] currInd - \ru Индекс текущего объекта в path. + \en Index of current object in path. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual const MbItem * GetItemByPath( const MbPath & path, size_t ind, MbMatrix3D & from, size_t currInd = 0 ) const; + + /** \brief \ru Найти объект по геометрическому объекту. + \en Find object by geometric object. \~ + \details \ru Найти объект по геометрическому объекту, + а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by geometric object + and also get the path to the object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual const MbItem * FindItem( const MbSpaceItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по геометрическому объекту. + \en Find object by geometric object. \~ + \details \ru Найти объект по геометрическому объекту, + а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by geometric object + and also get the path to the object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual const MbItem * FindItem( const MbPlaneItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по объекту геометрической модели. + \en Find object by object of geometric model \~ + \details \ru Найти объект по объекту геометрической модели. + а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by object of geometric model + and also get the path to the object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] s - \ru Геометрический объект. + \en Geometric object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual const MbItem * FindItem( const MbItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Найти объект по имени. + \en Find object by name. \~ + \details \ru Найти объект по имени, а также получить путь к объекту в модели + и матрицу преобразования в глобальную систему координат. \n + \en Find object by name and also get path to object in model + and get transformation matrix to the global coordinate system. \n \~ + \param[in] n - \ru Имя объекта. + \en A name of an object. \~ + \param[out] path - \ru Путь к объекту в модели. + \en Path to object in the model. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual const MbItem * GetItemByName( SimpleName n, MbPath & path, MbMatrix3D & from ) const; + + /** \brief \ru Преобразовать выбранный объект согласно матрице. + \en Transform selected object according to the matrix. \~ + \details \ru Преобразовать выбранный простой объект согласно матрице c использованием регистратора. + Если объект содержит другие объекты геометрической модели, то преобразуется выбранное содержимое. + \en Transform selected simple object according to the matrix using the registrator. + If object contains other objects of geometric model then selected contents will be transformed. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Model_Items + */ + virtual void TransformSelected( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + + /** \brief \ru Сдвинуть выбранный объект вдоль вектора. + \en Move selected object along a vector. \~ + \details \ru Сдвинуть вдоль вектора с использованием регистратора выбранный простой объект. + Если объект содержит другие объекты геометрической модели, то преобразуется выбранное содержимое. + \en Move selected simple object along the vector using the registrator. + If object contains other objects of geometric model then selected contents will be transformed. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Model_Items + */ + virtual void MoveSelected( const MbVector3D & to, MbRegTransform * iReg = NULL ); + + /** \brief \ru Повернуть выбранный объект вокруг оси на заданный угол. + \en Rotate selected object by a given angle about an axis. \~ + \details \ru Повернуть вокруг оси на заданный угол с использованием регистратора выбранный простой объект. + Если объект содержит другие объекты геометрической модели, то преобразуется выбранное содержимое. + \en Rotate selected simple object about the axis by the given angle using the registrator. + If object contains other objects of geometric model then selected contents will be transformed. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Model_Items + */ + virtual void RotateSelected( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + + /// \ru Дать матрицу преобразования из локальной системы объекта. \en Get transform matrix from local coordinate system of object. + virtual bool GetMatrixFrom( MbMatrix3D & from ) const; + /// \ru Дать матрицу преобразования в локальную систему объекта. \en Get transform matrix into local coordinate system of object. + virtual bool GetMatrixInto( MbMatrix3D & into ) const; + + /// \ru Копировать строители и атрибуты. \en Copy creators and attributes. + void Assign( const MbItem & other ); + /// \ru Копировать имя объекта. \en Copy the name of an object. + void CopyItemName( const MbItem & other ) { name = other.GetItemName(); } + /// \ru Выдать имя объекта. \en Get name of object. + SimpleName GetItemName() const { return name; } + /// \ru Установить имя объекта. \en Set name of the object. + void SetItemName( SimpleName n ) { name = n; } + /// \ru Соответствует ли знаковый атрибут объекту? \en Whether a sign attribute matches an object? + bool IsAttributeEqual( int attribute ); + + /** \} */ + +protected: + /// \ru Захватить объект, если ядро работает в многопоточном режиме. \en Catch object if multithreading mode is on. + void LockItem() const; + /// \ru Освободить объект, если ядро работает в многопоточном режиме. \en Release object if multithreading mode is on. + void UnlockItem() const; + +private: + /** \brief \ru Построить путь положения объекта. + \en Create path of object's position. \~ + \details \ru Построить путь положения объекта в модели и + дать матрицу преобразования объекта в глобальную систему координат. + Объект может содержаться в другом объекте (в сборке или вставке). + \en Create path of object's position in the model and + get transformation matrix of the object to the global coordinate system. + Object can be contained in other object (in assembly or in instance). \~ + \param[in] obj - \ru Объект. + \en Object. \~ + \param[out] path - \ru Путь объекта. + \en Path of object. \~ + \param[out] from - \ru Матрица преобразования объекта в глобальную систему координат. + \en Transformation matrix of object to the global coordinate system. \~ + \return \ru Найден ли путь и матрица объекта. + \en Whether the path and the matrix of object are found. \~ + \ingroup Model_Items + */ + virtual bool MakePath( const MbItem & obj, MbPath & path, MbMatrix3D & from ) const; + +public: + DECLARE_PERSISTENT_CLASS( MbItem ); + OBVIOUS_PRIVATE_COPY( MbItem ); +}; // MbItem + +IMPL_PERSISTENT_OPS( MbItem ) + + +//---------------------------------------------------------------------------------------- +// The functor implementing less operator of two model objects. +//--- +struct LessName +{ + bool operator()( const MbItem * _Left, const MbItem * _Right ) const + { + return (_Left->GetItemName() < _Right->GetItemName()); + } + bool operator()( const MbItem * _Left, SimpleName _Right ) const + { + return _Left->GetItemName() < _Right; + } + bool operator()( SimpleName _Left, const MbItem * _Right ) const + { + return _Left < _Right->GetItemName(); + } +}; + + +#endif // __MODEL_ITEM_H diff --git a/C3d/Include/model_tree.h b/C3d/Include/model_tree.h new file mode 100644 index 0000000..eadb623 --- /dev/null +++ b/C3d/Include/model_tree.h @@ -0,0 +1,309 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** \file + \brief \ru Реализация дерева модели + \en Implementation of Model Tree classes \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MODEL_TREE_H +#define __MODEL_TREE_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------- +// \ru Реализация интерфейсов дерева модели. \en Implementation of Model Tree interfaces. +//---------------------------------------------------------------------------------------- + +namespace c3d // namespace C3D +{ +//---------------------------------------------------------------------------------------- +/** \brief \ru Узел дерева. + \en Tree node. \~ + \details \ru Узел дерева (может иметь несколько потомков). \n + \en Tree node (can have several children). \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS MbTreeNode : public IModelTreeNode +{ + // \ru Временное хранилище для индексов потомков узла (используется при чтении узла). + // \en Temporary storage for indices of child nodes (used while reading the node). + std::vector m_childrenIndices; + // \ru Данные узла \en The node data. + MbItemData m_data; + // \ru Флаг, указывающий, открыт ли узел при проходе вглубь по дереву. + // \en Flag which indicates whether the node is entered during traversing into depth over the tree. + mutable bool m_open; + // \ru Флаг, указывающий, читать ли только часть узла. + // \en Flag which indicates whether to read only a part of the node. + mutable bool m_partial; +public: + MbTreeNode() : m_open(false), m_partial(false) {} + MbTreeNode ( const MbItemData& data ) : m_data(data), m_open(false), m_partial(false) {} + MbTreeNode ( const MbTreeNode& node ) : m_data(node.m_data), m_childrenIndices(node.m_childrenIndices), + m_open(node.m_open), m_partial(node.m_partial) { GetChildren() = node.GetChildren(); GetParents() = node.GetParents(); } + + ///--------- + /// \ru Методы IModelTreeNode. \en IModelTreeNode methods. + + /// \ru Доступ к данным узла. \en Access to the node data. + virtual MbItemData& GetData() { return m_data; } + virtual const MbItemData& GetData() const { return m_data; } + + /// \ru Доступ к позиции чтения/записм узла. \en Access to the node read/write position. + virtual ClusterReference& GetPosition() { return m_data.position; } + virtual const ClusterReference& GetPosition() const { return m_data.position; } + + /// \ru Узнать, читать ли только часть узла. + /// \en Check whether to read the node partially. + virtual bool PartialRead() const { return m_partial; }; + + /// \ru Установить признак частичного или полного чтения узла. + /// \en Set indication of full or partial node reading. + virtual void SetPartialRead ( bool partial ) const { m_partial = partial; }; + + /// \ru Записать узел. \en Write the node. + virtual writer & operator >> ( writer & ); + + /// \ru Прочитать узел. \en Read the node. + virtual reader & operator << ( reader & ); + + /// \ru Доступ ко все потомкам узла. \en Access to the all descendants of the node. + void GetAllDescendants ( std::set& nodes ) const; + + /// \ru Создать узел с данными текущего узла и добавить его в дерево. + /// Рекурсивно скопировать в дерево всех предков текущего узла с сохранением иерархии. + /// \en Create a node with data from the current node. + /// Copy recursively all parents of the node to the tree preserving the hierarchy. + MbTreeNode* CopyToTreeWithParents ( c3d::IModelTree* tree, bool partial ) const; + + /// \ru Создать узел с данными текущего узла и добавить его в дерево. + /// Рекурсивно скопировать в дерево всех потомков текущего узла с сохранением иерархии. + /// \en Create a node with data from the current node. + /// Copy recursively all children of the node to the tree preserving the hierarchy. + MbTreeNode* CopyToTreeWithChildren ( c3d::IModelTree* tree, bool partial ) const; + + /// \ru Доступ к флагу, который указывет, открыт ли узел при проходе вглубь по дереву + /// (false означает, что узел и его потомки уже пройдены или еще не обнаружены). + /// \en Access to the flag which indicates whether the node is entered during traversing into depth over the tree + /// (false - means that the node and its children are already leaved or are not met yet). + bool IsOpen() const { return m_open; } + void SetOpen ( bool open ) { m_open = open; } + void SetOpen ( bool open ) const { m_open = open; } + + // \ru Равенство определяется по id объекта MbItemData. + // \en Equality is defined by id field of MbItemData object. + bool operator == ( const MbTreeNode& node2 ) const + { + if ( !( GetData() == node2.GetData() ) || + GetData().id != node2.GetData().id ) + return false; + return true; + } + + // \ru Сравнение по полям объектов MbItemData. + // \en Comparison of filtering fields of MbItemData objects. + bool operator < ( const MbTreeNode& node2 ) const + { + return m_data < node2.m_data; + } + + friend class MbModelTree; + +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Узел дерева исполнений. + \en Embodiments tree node. \~ + \details \ru Узел дерева исполнений (может иметь несколько потомков). + \en Embodiments tree node (can have several children). + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS MbEmbodimentNode : public IEmbodimentNode +{ + const MbTreeNode * m_subtree; +public: + MbEmbodimentNode( const MbTreeNode* node ) : IEmbodimentNode(), m_subtree( node ) {} + ~MbEmbodimentNode() {} + + // \ru Выдать узел дерева модели, соответствующий данному исполнению. + // \en Get a model tree node which corresponds to a given embodiment. + virtual const IModelTreeNode * GetModelTreeNode() const { return m_subtree; } + + // \ru Доступ к информации об исполнении. \en Access to the embodiment info. + virtual const MbItemData& GetEmbodimentData() const { C3D_ASSERT( m_subtree != NULL ); return m_subtree->GetData(); } + + // \ru Построить дерево модели, которое содержится в данном исполнении. + // \en Build a tree of a model which is contained in a given embodiment. + virtual std_unique_ptr GetEmbodiment() const; + +private: + MbEmbodimentNode(); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Дерево геометрической модели. + \en Tree of geometric model. \~ + \details \ru Дерево геометрической модели. (может иметь несколько корней). + \en Tree of geometric model (can have several roots). \n \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS MbModelTree : public IModelTree +{ +private: + // \ru Временное хранилище для индексов корней дерева (используется при чтении дерева). + // \en Temporary storage for indices of the tree roots (used while reading the tree). + std::vector m_rootsIndices; + // \ru Все узлы дерева, упорядоченные по данным. + // \en All nodes of the tree, ordered by data. + std::set m_filteredNodes; + // \ru Стек узлов, открытых при чтении/записи дерева. + // \en Stack of nodes opened during reading/writing the tree. + std::stack m_nestedNodesStack; + // \ru Все узлы дерева, упорядоченные по ID. + // \en All nodes of the tree, ordered by ID. + std::map m_indexToNode; // \ru Вспомогательный массив. \en Auxiliary map. + VERSION m_currentVersion; + IEmbodimentTree m_embTree; // \ru Дерево исполнений. \en Embodiment tree. +public: + + // \ru Конструктор. \en Constructor. + MbModelTree(); + + // \ru Деструктор. \en Destructor. + virtual ~MbModelTree(); + + ///--------- + /// \ru Методы IModelTreeNode. \en IModelTreeNode methods. + + /// \ru Создать узел по данными и добавить в дерево. \en Create a node by data and add to the tree. + virtual void AddNode ( const TapeBase* mem, const ClusterReference& ref ); + + /// \ru Закрыть узел (удалить узел из стека, так что родительский узел станет текущим). + /// \en Close the node (remove it from the stack so that its parent becomes the current node). + virtual void CloseNode ( const TapeBase* mem ); + + // \ru Построить дерево из узлов, выбранных по фильтрам. В случае дерева исполнений, функция работает с первым исполнением. + // \en Build a tree with nodes, selected by filters. In case of embodiment tree, the function works with the first embodiment. + virtual std_unique_ptr GetFilteredTree ( const std::vector& filters ) const; + + // \ru Построить дерево по заданным узлам. Не применимо для дерева исполнений (в этом случае возвращает NULL). + // \en Build a tree for given nodes. Not applicable to embodiment tree (in this case, returns NULL). + virtual std_unique_ptr GetFilteredTree ( std::vector& nodes ) const; + + // \ru Выдать указатель на дерево исполнений. Выдает NULL, если не применимо (нет исполнений). + // \en Get pointer to embodiments tree. Return NULL if not applicable (no embodiments). + virtual const IEmbodimentTree* GetEmbodimentsTree() const { return GetType() == mtt_Embodiment ? &m_embTree : NULL; } + + /// \ru Версия дерева. \en Tree version. + virtual VERSION GetVersion() { return m_currentVersion; } + virtual void SetVersion( VERSION version ) { m_currentVersion = version; } + + /// \ru Записать дерево. \en Write the tree. + virtual writer & operator >> ( writer & ); + + /// \ru Прочитать дерево. \en Read the tree. + virtual reader & operator << ( reader & ); + + ///--------- + + /// \ru Добавить узел с данными из указанного узла, если узел с такими данными не существует. + /// \param node - узел с данными. + /// \param added - заполняется, если ненулевой (true - узел добавлен, false - узел уже существует). + /// \return - возвращает указатель на узел дерева. + /// \en Add a node with the data from the given node if a node with such data does not exist. + /// \param node - a node with data. + /// \param added - filled if non-null (true - if a node added, false - a node already exists). + /// \return - a pointer to the tree node. + MbTreeNode* AddNode ( const MbTreeNode& node, bool* added = NULL ); + + /// \ru Добавить узел с указанными данными, если узел с такими данными не существует. + /// \param node - данные. + /// \param added - заполняется, если ненулевой (true - узел добавлен, false - узел уже существует). + /// \return - возвращает указатель на узел дерева. + /// \en Add a node with the given if a node with such data does not exist. + /// \param node - a data. + /// \param added - filled if non-null (true - if a node added, false - a node already exists). + /// \return - a pointer to the tree node. + MbTreeNode* AddNode ( const MbItemData& data, bool* added = NULL ); + + /// \ru Доступ к узлам дерева, упорядоченным по данным. + /// \en Access to nodes of the tree, ordered by data. + std::set& GetFilteredNodes() { return m_filteredNodes; } + const std::set& GetFilteredNodes() const { return m_filteredNodes; } + + // \ru Добавить в корень текущего дерева указанное поддерево. \en Add a given subtree to the current tree root. + const void AddSubtree( IModelTree* tree, const IModelTreeNode* node ) const; + + /// \ru Заполнить массив корней дерева. + /// \en Fill the tree roots. + void FillRoots(); + +protected: + /// \ru Добавить ветвь в дерево: + /// \param branch - листовой узел с ветвью дерева, ведущей к нему, начиная с корневого узла дерева; + /// \param partial - определяет тип чтения листового узла (частичное или полное). + /// \en Add a branch to the tree: + /// \param branch - a leaf node with the tree branch, leading to it; + /// \param partial - defines partial or full read of the leaf node. + void AddBranch( const NodeBranch& branch, bool partial ); + + /// \ru Получить уникальные узлы для данного набора узлов. Проходятся все заданные узлы и исключаются те, + /// которые являются потомками заданных узлов (и будут прочитаны, как их часть). + /// Таким образом, результат будет содержать узлы поддеревьев, содержащих все заданные узлы. + /// \en Get unique nodes for given set of nodes. Walk through the given nodes and exclude nodes, + /// which are children of other given nodes (and will be read as a part of them). + /// Thus, the result set of nodes will represent the roots of subtrees containing all given nodes. + std::vector GetUniqueNodes ( std::vector& nodes ) const; + + + // \ru Построить дерево по заданным узлам без проверки типа. + // \en Build a tree for given nodes without type check. + const IModelTree* GetFilteredTreeEx( std::vector& nodes ) const; + + /// \ru Построить дерево по индексам (используется при чтении дерева). + /// \en Build the tree using indices (used during reading the tree). + void BuildTree(); + +private: + OBVIOUS_PRIVATE_COPY(MbModelTree) +}; + +//---------------------------------------------------------------------------------------- +/// \ru Операторы для записи дерева в xml формате. +/// \en Operators for outputing a tree to xml. +// --- + +//---------------------------------------------------------------------------------------- +/// \ru Запись узла дерева в xml формате. \en Tree node writing to xml. +// --- +MATH_FUNC( c3d::t_ofstream& ) operator << ( c3d::t_ofstream& file, const IModelTreeNode& node ); + +//---------------------------------------------------------------------------------------- +/// \ru Запись узла дерева в xml формате. \en Tree node writing to xml. +// --- +MATH_FUNC( c3d::t_ofstream& ) operator << ( c3d::t_ofstream& file, IModelTreeNode& node ); + +//---------------------------------------------------------------------------------------- +/// \ru Запись дерева в xml формате. \en Tree writing to xml. +// --- +MATH_FUNC( c3d::t_ofstream& ) operator << ( c3d::t_ofstream& file, const IModelTree& tree ); + +//---------------------------------------------------------------------------------------- +/// \ru Запись дерева в xml формате. \en Tree writing to xml. +// --- +MATH_FUNC( c3d::t_ofstream& ) operator << ( c3d::t_ofstream& file, IModelTree& tree ); + +} //namespace c3d + +#endif // __MODEL_TREE_H diff --git a/C3d/Include/model_tree_data.h b/C3d/Include/model_tree_data.h new file mode 100644 index 0000000..cfbd831 --- /dev/null +++ b/C3d/Include/model_tree_data.h @@ -0,0 +1,809 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** \file + \brief \ru Реализация данных узла дерева модели + \en Implementation of data of Model Tree node \~ +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MODEL_TREE_DATA_H +#define __MODEL_TREE_DATA_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------- +// \ru Реализация пользовательских данных узла дерева модели. +// \en Implementation of user data of the model tree node. +//---------------------------------------------------------------------------------------- + +namespace c3d // namespace C3D +{ +//---------------------------------------------------------------------------------------- +/** \brief \ru Тип пользовательских данных узла дерева модели. + \en A type of user data of the model tree node. \~ + \details \ru \ru Тип пользовательских данных узла дерева модели. + \en A type of user data of the model tree node. \~ + \ingroup Base_Tools_IO +*/ +// --- +enum MbeItemDataType +{ + idtBool, // bool + idtInteger, // int + idtDouble, // double + idtString, // c3d::string_t + + // \ru Данные атрибутов, для которых хранится тип и значение атрибута. + // \en Attributes data which keeps attribute type and value. + idtAttrBool, // MbBoolAttribute (bool) + idtAttrInt, // MbIntAttribute (int) + idtAttrDouble, // MbDoubleAttribute (double) + idtAttrString, // MbStringAttribute (c3d::string_t) + idtAttrInt64, // MbInt64Attribute (int64) + idtAttrIdentifier, // MbIdentifier (int32) + idtAttrColor, // MbColor (uint32) + idtAttrWidth, // MbWidth (int) + idtAttrStyle, // MbStyle (int) + idtAttrSelected, // MbSelected (bool) + idtAttrVisible, // MbVisible (bool) + idtAttrChanged, // MbChanged (bool) + idtAttrDencity, // MbDencity (double) + idtAttrUpdateStamp, // MbUpdateStamp (uint32) + idtAttrAnchor, // MbAnchorAttribute (uint8) + + // \ru Данные сложных атрибутов, для которых хранится только тип. + // \en Complex attributes data which keeps attribute type only. + idtAttrVisual, // MbVisual + idtAttrWireCount, // MbWireCount + idtAttrName, // MbNameAttribute + idtAttrGeom, // MbGeomAttribute + idtAttrStampRib, // MbStampRibAttribute + idtAttrModelInfo, // MbModelInfo + idtAttrPersonOrganizationInfo, // MbPersonOrganizationInfo + + // \ru Специальная обработка атрибута - хранится свойство Идентификатор (Обозначение). + // \en Special processing of attribute - keep property Identifier. + idtAttrProductInfo, // MbProductInfo + + // \ru Данные сложных атрибутов, для которых хранится только тип (продолжение). + // \en Complex attributes data which keeps attribute type only (continuation). + idtAttrSTEPTextDescription, // MbSTEPTextDescription + idtAttrSTEPReferenceHolder, // MbSTEPReferenceHolder + idtAttrBinary, // MbBinaryAttribute + + // \ru Атрибут исполнения (хранится тип и пара значений). + // \en Attribute of embodiment (keeps type and values pair). + idtAttrEmbodiment, // MbEmbodimentAttribute + + // \ru Новый тип должен добавляться непосредственно перед idtCount (после всех определенных ранее типов). + // \en New type should be added just before idtCount (after all types defined before). + idtCount // \ru Число поддерживаемых типов данных. \en Number of supported data types +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Базовый класс для пользовательских данных узла дерева. + \en A base class for user data of a tree node. \~ + \details \ru Базовый класс для пользовательских данных узла дерева. + \en A base class for user data of a tree node. \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS ItemDataBase +{ +// \ru Приведение объекта 'item' к типу данных 'Type' (тип проверен заранее). +// \en Cast object 'item' to the data type 'Type' (type already verified). +#define CAST(Type, item) dynamic_cast(const_cast(item)) + +protected: + bool m_filterByType; // \ru Фильтр только по типу (значение данных игнорируется). \en Filter by type only (ignore data value). + +public: + + ItemDataBase() : m_filterByType(false) {} + virtual ~ItemDataBase() {} + + // \ru Тип данных. \en The data type. + virtual MbeItemDataType Type() const = 0; + + // \ru Размер записи данных в поток. \en The data size in the stream. + virtual size_t Size( writer& ) const = 0; + + // \ru Создать данные заданного типа. \en Create data of the given type. + static ItemDataBase* Create( MbeItemDataType type ); + + // \ru Создать копию данных. \en Create data copy. + static ItemDataBase* Create( ItemDataBase* item ); + + // \ru Прочитать данные. \en Read data. + reader& operator << ( reader& in ); + + // \ru Записать данные. \en Write data. + writer& operator >> ( writer& out ) const; + + // \ru Сравнить данные. \en Compare data. + bool operator == ( ItemDataBase* item2 ) const; + + /// \ru Сравнить данные. \en Compare data. + bool operator < ( ItemDataBase* item2 ) const; + + // \ru Выдать/установить флаг сравнения только по типу (значение игнорируется). + // \en Get/set flag for comparing by type only (value ignored). + bool IgnoreValue() const { return m_filterByType; } + void SetIgnoreValue( bool ignore ) { m_filterByType = ignore; } +}; + + +//---------------------------------------------------------------------------------------- +/// \ru Создать объект пользовательских данных для атрибута. Возвращает NULL, если данный атрибут не поддерживается деревом модели. +/// \en Create user data object for the attribute. Return NULL if this attribute is not supported in the model tree. +//--- +MATH_FUNC( ItemDataBase* ) CreateAttributeData( MbAttribute* attr ); + +//---------------------------------------------------------------------------------------- +/// \ru Прочитать атрибуты для узла дерева. +/// \en Read attributes for the model tree node. +//--- +MATH_FUNC( std_unique_ptr ) GetTreeNodeAttributes( const IModelTreeNode * node, reader& in ); + + +//---------------------------------------------------------------------------------------- +// \ru Функции чтения и записи для пользовательских данных атрибута. +// \en Functions of reading and writing for attribute user data. +//--- +#define MTREE_PERSISTENT_DATA_OBJ(Class) \ + public: \ + static void Read(reader& in, Class* item) { in >> item->m_value; } \ + static void Write(writer& out, const Class* item) { out << item->m_value; } + +//---------------------------------------------------------------------------------------- +// \ru Определение типа для пользовательских данных атрибута. +// \en Type definition for attribute user data. +//--- +#define MTREE_DEFINE_DATA_TYPE(type) \ + public: \ + virtual MbeItemDataType Type() const { return type; } + +//---------------------------------------------------------------------------------------- +/// \ru Определение размера записи пользовательских данных атрибута в поток, как sizeof. +/// \en Definition of data size of attribute user data in the stream as sizeof. +//--- +#define MTREE_DEFINE_DATA_SIZE_STD(data) \ + public: \ + virtual size_t Size(writer&) const { return sizeof(data); } + +//---------------------------------------------------------------------------------------- +// \ru Макрос для объявления класса без данных (dataless) для атрибута. +// \en Macro for defining attribute dataless class. +//--- +#define MTREE_ATTR_DATALESS_CLASS(Class,ClassType) \ +class Class : public ItemDataBase { \ +public: \ + virtual ~Class() {} \ + virtual size_t Size( writer& ) const { return 0; } \ + virtual MbeItemDataType Type() const { return ClassType; } \ + static void Read( reader&, Class* ) {} \ + static void Write( writer&, const Class* ) {} \ +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Свойство типа bool. + \en Bool property. \~ + \details \ru Свойство типа bool. + \en Bool property. \~ + \ingroup Base_Tools_IO +*/ +// --- +class ItemDataBool : public ItemDataBase +{ +public: + bool m_value; + + ItemDataBool() : m_value( false ) {} + ItemDataBool( bool value ) : m_value( value ) {} + virtual ~ItemDataBool() {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtBool) + MTREE_PERSISTENT_DATA_OBJ(ItemDataBool) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Свойство типа integer. + \en Integer property. \~ + \details \ru Свойство типа integer. + \en Integer property. \~ + \ingroup Base_Tools_IO +*/ +// --- +class ItemDataInteger : public ItemDataBase +{ +public: + int m_value; + + ItemDataInteger() : m_value( 0 ) {} + ItemDataInteger( int value ) : m_value( value ) {} + virtual ~ItemDataInteger() {} + + MTREE_DEFINE_DATA_SIZE_STD(int32) + MTREE_DEFINE_DATA_TYPE(idtInteger) + MTREE_PERSISTENT_DATA_OBJ(ItemDataInteger) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Свойство типа double. + \en Double property. \~ + \details \ru Свойство типа double. + \en Double property. \~ + \ingroup Base_Tools_IO +*/ +// --- +class ItemDataDouble : public ItemDataBase +{ +public: + double m_value; + + ItemDataDouble() : m_value( 0 ) {} + ItemDataDouble( double value ) : m_value( value ) {} + virtual ~ItemDataDouble() {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtDouble) + MTREE_PERSISTENT_DATA_OBJ(ItemDataDouble) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Свойство типа string. + \en String property. \~ + \details \ru Свойство типа string. + \en String property. \~ + \ingroup Base_Tools_IO +*/ +// --- +class ItemDataString : public ItemDataBase +{ +public: + c3d::string_t m_value; + + ItemDataString() {} + ItemDataString( c3d::string_t value ) : m_value( value ) {} + virtual ~ItemDataString() {} + + /// \ru Размер записи данных в поток. \en The data size in the stream. + virtual size_t Size( writer& out ) const { return out.__lenWchar( m_value.c_str() ); } + + MTREE_DEFINE_DATA_TYPE(idtString) + MTREE_PERSISTENT_DATA_OBJ(ItemDataString) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута bool. + \en Data of Bool attribute. \~ + \details \ru Данные атрибута bool. + \en Data of Bool attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrBool : public ItemDataBool +{ +public: + ItemAttrBool() : ItemDataBool() {} + ItemAttrBool( bool value ) : ItemDataBool( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrBool) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrBool) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута integer. + \en Data of Integer attribute. \~ + \details \ru Данные атрибута integer. + \en Data of Integer attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrInteger : public ItemDataInteger +{ +public: + ItemAttrInteger() : ItemDataInteger() {} + ItemAttrInteger( int value ) : ItemDataInteger( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrInt) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrInteger) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута double. + \en Data of Double attribute. \~ + \details \ru Данные атрибута double. + \en Data of Double attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrDouble : public ItemDataDouble +{ +public: + ItemAttrDouble() : ItemDataDouble() {} + ItemAttrDouble( double value ) : ItemDataDouble( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrDouble) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrDouble) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута string. + \en Data of String attribute. \~ + \details \ru Данные атрибута string. + \en Data of String attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrString : public ItemDataString +{ +public: + ItemAttrString() : ItemDataString() {} + ItemAttrString( c3d::string_t value ) : ItemDataString( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrString) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrString) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута MbProductInfo. + \en Data of MbProductInfo attribute. \~ + \details \ru Данные атрибута MbProductInfo. + \en Data of MbProductInfo attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrProductInfo : public ItemDataString +{ +public: + ItemAttrProductInfo() : ItemDataString() {} + ItemAttrProductInfo( c3d::string_t value ) : ItemDataString( value ) {} + + MTREE_DEFINE_DATA_TYPE( idtAttrProductInfo ) + + static void Read( reader &, ItemAttrProductInfo * ) {} + static void Write( writer &, const ItemAttrProductInfo * ) {} +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута int64. + \en Data of int64 attribute. \~ + \details \ru Данные атрибута int64. + \en Data of int64 attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrInt64 : public ItemDataBase +{ +public: + int64 m_value; + + ItemAttrInt64() : m_value( 0 ) {} + ItemAttrInt64( int64 value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtAttrInt64) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrInt64) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Идентификатор. + \en Data of Identifier attribute. \~ + \details \ru Данные атрибута Идентификатор. + \en Data of Identifier attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrIdentifier : public ItemDataBase +{ +public: + int32 m_value; + + ItemAttrIdentifier() : m_value( 0 ) {} + ItemAttrIdentifier( int32 value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtAttrIdentifier) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrIdentifier) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Цвет. + \en Data of Color attribute. \~ + \details \ru Данные атрибута Цвет. + \en Data of Color attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrColor : public ItemDataBase +{ +public: + uint32 m_value; + + ItemAttrColor() : m_value( 0 ) {} + ItemAttrColor( uint32 value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtAttrColor) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrColor) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Толщина. + \en Data of Width attribute. \~ + \details \ru Данные атрибута Толщина. + \en Data of Width attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrWidth : public ItemDataInteger +{ +public: + ItemAttrWidth() : ItemDataInteger() {} + ItemAttrWidth( int value ) : ItemDataInteger( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrWidth) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrWidth) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Стиль. + \en Data of Style attribute. \~ + \details \ru Данные атрибута Стиль. + \en Data of Style attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrStyle : public ItemDataInteger +{ +public: + ItemAttrStyle() : ItemDataInteger() {} + ItemAttrStyle( int value ) : ItemDataInteger( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrStyle) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrStyle) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Селектированность. + \en Data of Selection attribute. \~ + \details \ru Данные атрибута Селектированность. + \en Data of Selection attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrSelected : public ItemDataBool +{ +public: + ItemAttrSelected() : ItemDataBool() {} + ItemAttrSelected( bool value ) : ItemDataBool( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrSelected) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrSelected) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Видимость. + \en Data of Visibility attribute. \~ + \details \ru Данные атрибута Видимость. + \en Data of Visibility attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrVisible : public ItemDataBool +{ +public: + ItemAttrVisible() : ItemDataBool() {} + ItemAttrVisible( bool value ) : ItemDataBool( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrVisible) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrVisible) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Изменённость. + \en Data of Modification attribute. \~ + \details \ru Данные атрибута Изменённость. + \en Data of Modification attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrChanged : public ItemDataBool +{ +public: + ItemAttrChanged() : ItemDataBool() {} + ItemAttrChanged( bool value ) : ItemDataBool( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrChanged) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrChanged) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Плотность. + \en Data of Dencity attribute. \~ + \details \ru Данные атрибута Плотность. + \en Data of Dencity attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrDencity : public ItemDataDouble +{ +public: + ItemAttrDencity() : ItemDataDouble( 0 ) {} + ItemAttrDencity( double value ) : ItemDataDouble( value ) {} + + MTREE_DEFINE_DATA_TYPE(idtAttrDencity) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrDencity) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Метка времени обновления. + \en Data of Update timestamp attribute. \~ + \details \ru Данные атрибута Метка времени обновления. + \en Data of Update timestamp attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrUpdateStamp : public ItemDataBase +{ +public: + uint32 m_value; + + ItemAttrUpdateStamp() : m_value( 0 ) {} + ItemAttrUpdateStamp( uint32 value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtAttrUpdateStamp) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrUpdateStamp) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута Якорь. + \en Data of Anchor attribute. \~ + \details \ru Данные атрибута Якорь. + \en Data of Anchor attribute. \~ +\ingroup Base_Tools_IO +*/ +// --- +class ItemAttrAnchor : public ItemDataBase +{ +public: + uint8 m_value; + + ItemAttrAnchor() : m_value( 0 ) {} + ItemAttrAnchor( uint8 value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD(m_value) + MTREE_DEFINE_DATA_TYPE(idtAttrAnchor) + MTREE_PERSISTENT_DATA_OBJ(ItemAttrAnchor) +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные атрибута исполнения. + \en Data of embodiment attribute. \~ + \details \ru Данные атрибута исполнения. + \en Data of embodiment attribute. \~ + \ingroup Base_Tools_IO +*/ +// --- +class ItemAttrEmbodiment : public ItemDataBase +{ +public: + typedef std::pair, bool> EmbData; + EmbData m_value; + + ItemAttrEmbodiment() : m_value( std::pair(0, 0),false ) {} + ItemAttrEmbodiment( const EmbData& value ) : m_value( value ) {} + + MTREE_DEFINE_DATA_SIZE_STD( m_value ) + MTREE_DEFINE_DATA_TYPE( idtAttrEmbodiment ) + static void Read( reader& in, ItemAttrEmbodiment* item ) { + in >> item->m_value.first.first; + in >> item->m_value.first.second; + if ( in.MathVersion() >= 0x13000010L ) + in >> item->m_value.second; + } + static void Write( writer& out, const ItemAttrEmbodiment* item ) { + out << item->m_value.first.first; + out << item->m_value.first.second; + if ( out.MathVersion() >= 0x13000010L ) + out << item->m_value.second; + } +}; + +//---------------------------------------------------------------------------------------- +/// \ru Объявление классов без данных для атрибутов. +/// \en Definition of attribute dataless classes. +//--- +MTREE_ATTR_DATALESS_CLASS(ItemAttrVisual, idtAttrVisual); +MTREE_ATTR_DATALESS_CLASS(ItemAttrWireCount, idtAttrWireCount); +MTREE_ATTR_DATALESS_CLASS(ItemAttrName, idtAttrName); +MTREE_ATTR_DATALESS_CLASS(ItemAttrGeom, idtAttrGeom); +MTREE_ATTR_DATALESS_CLASS(ItemAttrStampRib, idtAttrStampRib); +MTREE_ATTR_DATALESS_CLASS(ItemAttrModelInfo, idtAttrModelInfo); +MTREE_ATTR_DATALESS_CLASS(ItemAttrPersonOrganizationInfo, idtAttrPersonOrganizationInfo); +MTREE_ATTR_DATALESS_CLASS(ItemAttrSTEPTextDescription, idtAttrSTEPTextDescription); +MTREE_ATTR_DATALESS_CLASS(ItemAttrSTEPReferenceHolder, idtAttrSTEPReferenceHolder); +MTREE_ATTR_DATALESS_CLASS(ItemAttrBinary, idtAttrBinary); + +//---------------------------------------------------------------------------------------- +/** \brief \ru Контейнер для пользовательских данных узла дерева. + \en A container for user data of a tree node. \~ + \details \ru Контейнер для пользовательских данных узла дерева (владеет данными). + \en A container for user data of a tree node (owns the data). \~ + \ingroup Base_Tools_IO +*/ +// --- +class MATH_CLASS UserDataMap : public MultiMap +{ +public: + UserDataMap() {} + UserDataMap( const UserDataMap& other ); + + ~UserDataMap(); // \ru Владеет данными. \en Owns the data. + + /// \ru Оператор ==. \en Operator ==. + bool operator == ( const UserDataMap& other ) const; + + /// \ru Оператор <. \en Operator <. + bool operator < ( const UserDataMap& other ) const; + + /// \ru Оператор =. \en Operator =. + UserDataMap& operator = ( const UserDataMap& other ); +}; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Данные узла дерева. +\en Tree node data. \~ +\details \ru Данные узла дерева. \n +\en Tree node data. \n \~ +\ingroup Base_Tools_IO +*/ +// --- +struct MATH_CLASS MbItemData +{ + // \ru Признак наличия локальной системы координат. + // \en Token of local coordinate system presence. + enum PlacementPresenceToken + { + ppt_No = 0x01, + ppt_Yes = 0x02 + }; + + // \ru Уникальный ID узла в дереве модели. \en Unique id in the model tree. + // \ru Не учитывается при сравнении. \en Not considered during comparison. + mutable size_t id; + // \ru Тип объекта. \en Object type. + // \ru type==st_Undefined означает, что фильтр по типу не определен. + // \en type==st_Undefined means that filter is undefined. + MbeSpaceType type; + // \ru иИмя объекта. \en Object name. + // \ru name==SYS_MAX_UINT32 означает, что фильтр по имени не определен. + // \en name==SYS_MAX_UINT32 means that filter is undefined. + SimpleName name; + // \ru gabarit.IsEmpty()==true означает, что фильтр по габариту не определен. + // \en gabarit.IsEmpty()==true means that filter is undefined. + MbCube gabarit; + // \ru Позиция записи/чтения узла. \en Position for the node writing/reading. + // \ru position.IsValid()==false означает, что это поле не учитывается при сравнении. + // \en position.IsValid()==false means that this field is not considered during comparison. + ClusterReference position; + // \ru Локальная система координат объекта. \en Local coordinate system for the object. + // \ru Не учитывается при сравнении. \en Not considered during comparison. + MbPlacement3D placement; + + // \ru Кроме обязательных данных узла, описанных выше, можно задать пользовательские данные, + // которые содержатся в контейнере 'properties'. + // \en In addition to the mandatory node data, described above, it is possible to define user data, + // which is kept in the 'properties' container. + // \ru Контейнер для пользовательских данных узла. + // \en Container for user data of a node. + UserDataMap properties; + + + // \ru Конструкторы. \en Constructors. + MbItemData() : id( SYS_MAX_T ), type( st_Undefined ), name( SYS_MAX_UINT32 ) {} + MbItemData( MbeSpaceType t, SimpleName n, const MbCube& c, ClusterReference& pos ) : id( SYS_MAX_T ), type( t ), name( n ), gabarit( c ), position( pos ) {} + MbItemData( MbeSpaceType t, SimpleName n, const MbCube& c, ClusterReference& pos, const UserDataMap& prop ) : + id( SYS_MAX_T ), type( t ), name( n ), gabarit( c ), position( pos ), properties( prop ) {} + MbItemData( const MbItemData& data ) : id( data.id ), type( data.type ), + name( data.name ), gabarit( data.gabarit ), position( data.position ), + placement( data.placement ), properties( data.properties ) {} + + // \ru Признак пустых (неинициализированных) данных. \en Indicator of empty (uninitialized) data. + bool IsEmpty() const; + + // \ru Идентичность полей-фильтров (id не важен). + // \en Equality of filtering fields (id is irrelevant). + bool operator == ( const MbItemData& rt ) const; + + // \ru Сравнение полей-фильтров (id не важен). + // \en Comparison of filtering fields (id is irrelevant). + bool operator < ( const MbItemData& rt ) const; + + // \ru Специальное сравнение габаритов для сортировки объектов. + // \en Special comparison of bounding boxes for object sorting. + static bool CompareGabarits( const MbCube& a, const MbCube& b ); + + // \ru Запись и чтение. + // \en Writing and reading. + writer& operator >> ( writer & out ); + reader& operator << ( reader & out ); +}; + +//---------------------------------------------------------------------------------------- +/// \ru Чтение UserDataMap. \en UserDataMap reading. +// --- +inline reader& operator >> ( reader & in, UserDataMap& itemmap ) +{ + size_t typeCount = ::ReadCOUNT( in ); // \ru Количество типов данных в наборе. \en A number of types in the map. + + if ( in.good() ) { + for ( size_t i = 0; i < typeCount; i++ ) { + int t; + in >> t; + size_t typeSize = ::ReadCOUNT( in ); + C3D_ASSERT( t < (int)idtCount ); + if ( t < (int)idtCount ) { + MbeItemDataType type = (MbeItemDataType)t; // \ru Тип данных. \en A data type. + ItemDataBase* item = ItemDataBase::Create( type ); + *item << in; + itemmap.Associate( type, item ); + } + else { // skip unknown data + char* buff = new char[typeSize]; + in.readBytes( buff, typeSize ); + delete[] buff; + } + + if ( !in.good() ) { + in.setState( io::fail ); + break; + } + } + } + return in; +} + +//---------------------------------------------------------------------------------------- +/// \ru Запись UserDataMap. \en UserDataMap writing. +// --- +inline writer& operator << ( writer & out, const UserDataMap& itemmap ) +{ + size_t mapCount = itemmap.Count(); + ::WriteCOUNT( out, mapCount ); // \ru Количество типов данных в наборе. \en A number of types in the map. + + if ( out.good() && mapCount ) { + UserDataMap::Iterator curIter = itemmap.First(); + while ( !curIter.Empty() ) { + MbeItemDataType type = curIter.Key(); + ItemDataBase* item = curIter.Value(); + C3D_ASSERT( type < idtCount && item != NULL ); + if ( type < idtCount && item != NULL ) { + out << (int)type; // \ru Тип данных. \en A data type. + size_t dataSize = item->Size( out ); + ::WriteCOUNT( out, dataSize );// \ru Размер данных. \en Data size. + *item >> out; + } + if ( !out.good() ) { + out.setState( io::fail ); + break; + } + curIter++; + } + } + return out; +} + +} //namespace c3d + +#endif // __MODEL_TREE_DATA_H diff --git a/C3d/Include/mt_ref_item.h b/C3d/Include/mt_ref_item.h new file mode 100644 index 0000000..543dcd4 --- /dev/null +++ b/C3d/Include/mt_ref_item.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Надкласс для объектов, время жизни которых автоматически регулируется счетчиком ссылок. + \en Superclass for objects their lifetime is automatically regulated by reference counter. +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __MT_REF_ITEM_H +#define __MT_REF_ITEM_H + +#include + + +////////////////////////////////////////////////////////////////////////////////////////// +/** + \brief \ru Базовый класс для объектов с подсчетом ссылок. + \en Base class for objects with reference counting. \~ + \ingroup Base_Items + \sa #MbRefItem, #SPtr +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +class MtRefItem +{ + mutable refcount_t useCount; + +protected: + MtRefItem() : useCount(0) {} + virtual ~MtRefItem() {} + +public: + /// \ru Добавить одну ссылку на объект. \en Adds a reference to this object. + refcount_t AddRef() const { return ++useCount; } + /// \ru Освободить одну ссылку на объект. \en Releases a reference to this object. + refcount_t Release() const; + +public: + /// \ru Вернуть количество объектов, ссылающихся на данный. \en Returns a number of objects referring to this. + refcount_t GetUseCount() const { return useCount; } + +private: + MtRefItem( const MtRefItem & ); + MtRefItem & operator = ( const MtRefItem & ); +}; + +//---------------------------------------------------------------------------------------- +// +//--- +inline refcount_t MtRefItem::Release() const +{ + if ( !useCount || (--useCount == 0) ) + { + delete this; // \ru Вызов виртуального деструктора \en Call of virtual destructor + return 0; + } + + return useCount; +} + +#endif // __MT_REF_ITEM_H + +// eof \ No newline at end of file diff --git a/C3d/Include/multiline.h b/C3d/Include/multiline.h new file mode 100644 index 0000000..f2b55f5 --- /dev/null +++ b/C3d/Include/multiline.h @@ -0,0 +1,1816 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Мультилиния. + \en Multiline. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// \ru Заголовочный файл мультилинии cодержит следующие разделы. \en Header file of multiline contains the following sections. +// \ru _1_ EnMLVertexTracingType - тип обхода углов в вершине мультилинии \en _1_ EnMLVertexTracingType - type of traverse of corners at a vertex of multiline +// \ru _2_ EnMLInnerTipType - тип внутренней законцовки мультилинии \en _2_ EnMLInnerTipType - type of inner tip of multiline +// \ru _3_ EnMLTipType - тип законцовки мультилинии \en _3_ EnMLTipType - type of tip of multiline +// \ru _4_ StMLTipParams - структура параметров законцовки мультилинии \en _4_ StMLTipParams - tip of multiline parameters structure +// \ru _5_ StVertexOfMultilineInfo - информация о вершине мультилинии \en _5_ StVertexOfMultilineInfo - information about vertex of multiline +// \ru _6_ MbMultiline - класс мультилиния \en _6_ MbMultiline - multiline class +// \ru _7_ Функция построения скругления базовой кривой мультилинии \en _7_ Function for multiline base curve fillet construction +// \ru _8_ Функция построения фаски базовой кривой мультилинии \en _8_ Function for multiline base curve chamfer construction +// \ru _9_ Внеклассные функции расчета/учета радиусов кривизны \en _9_ Out-of-class functions for curvature radii calculation/consideration +// \ru _10_ Внеклассная функция гладкого стыка двух последовательных кривых \en _10_ Out-of-class function for smooth joint of two consecutive curves +// \ru _11_ Разбить мультилинию на две части \en _11_ Split multiline into two pieces +// \ru _12_ Разбить мультилинию на N равных частей \en _12_ Split multiline into N equal pieces +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MULTILINE_H +#define __MULTILINE_H + + +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +// _1_ +/** \brief \ru Тип обхода углов. + \en Type of traverse of corners. \~ + \details \ru Тип обхода углов в вершине мультилинии.\n + \en Type of traverse of corners at a vertex of multiline.\n \~ + \ingroup Algorithms_2D +*/ // --- +enum EnMLVertexTracingType { + mvt_ShearType, ///< \ru Обход срезом. \en Traverse by shear. + mvt_FilletType, ///< \ru Обход со скруглением. \en Traverse by fillet. + mvt_SpecFilletType, ///< \ru Обход со скруглением заданным радиусом. \en Traverse by fillet with a given radius. + // \ru ДОБАВЛЕНИЕ ТОЛЬКО В КОНЕЦ!!! \en ADDITION ONLY TO THE END!!! +}; + + +//------------------------------------------------------------------------------ +// _2_ +/** \brief \ru Тип внутренней законцовки. + \en Type of inner tip. \~ + \details \ru Тип внутренней законцовки мультилинии.\n + \en Type of inner tip of multiline.\n \~ + \ingroup Algorithms_2D +*/ // --- +enum EnMLInnerTipType { + mit_UndefTip, ///< \ru Законцовки нет. \en No tip. + mit_VerticesTip, ///< \ru Законцовка между соответствующими вершинами. \en Tip between corresponding vertices. + mit_LinearTip, ///< \ru Линейная законцовка. \en Linear tip. + mit_ArcTip, ///< \ru Дуговая законцовка. \en Arc tip. + // \ru ДОБАВЛЕНИЕ ТОЛЬКО В КОНЕЦ!!! \en ADDITION ONLY TO THE END!!! +}; + + +//------------------------------------------------------------------------------ +// _3_ +/** \brief \ru Тип законцовки. + \en Type of tip. \~ + \details \ru Тип законцовки мультилинии.\n + \en Type of tip of multiline.\n \~ + \ingroup Algorithms_2D +*/ // --- +enum EnMLTipType { + mtt_UndefTip, ///< \ru Законцовки нет. \en No tip. + mtt_LinearTip, ///< \ru Линейная законцовка. \en Linear tip. + mtt_ArcTip, ///< \ru Дуговая законцовка. \en Arc tip. + mtt_PolylineTip, ///< \ru Ломаная законцовка. \en Polyline tip. + mtt_ObliqueTip, ///< \ru Наклонная законцовка. \en Inclined tip. + // \ru ДОБАВЛЕНИЕ ТОЛЬКО В КОНЕЦ!!! \en ADDITION ONLY TO THE END!!! +}; + + +//------------------------------------------------------------------------------ +// _4_ +/** \brief \ru Cтруктура параметров законцовки. + \en Tip parameters structure. \~ + \details \ru Cтруктура параметров законцовки мультилинии.\n + Изменять данные объекта можно только из MbMultiline. + \en Multiline tip parameters structure.\n + Object data can be changed only from MbMultiline. \~ + \ingroup Algorithms_2D +*/ +struct MATH_CLASS StMLTipParams { +friend class MbMultiline; +private: + EnMLTipType tipType; ///< \ru Тип законцовки. \en Type of tip. + + /** \brief \ru Параметр законцовки. + \en Parameter of tip. \~ + \details \ru Для mtt_UndefTip неопределен,\n + для mtt_LinearTip - расстояние от конца ЛМ до законцовки,\n + для mtt_ArcTip - расстояние от конца ЛМ до вершины дуги законцовки,\n + для mtt_PolylineTip - расстояние от конца ЛМ до вершины угла законцовки,\n + для mtt_ObliqueTip - угол поворота нормали от конца мультилинии (в радианах). + \en Undefined for mtt_UndefTip,\n + for mtt_LinearTip - distance from the end of multiline to the tip,\n + for mtt_ArcTip - distance from the end of multiline to the vertex of arc of tip,\n + for mtt_PolylineTip - distance from the end of multiline to the vertex of corner of tip,\n + for mtt_ObliqueTip - angle of rotation of normal from the end of multiline (in radians).\~ + */ + double tipParam; + +public: + StMLTipParams(); ///< \ru Умолчательный конструктор. \en Default constructor. + StMLTipParams( const StMLTipParams & other ); ///< \ru Копирующий конструктор. \en Copy-constructor. + + /** \brief \ru Конструктор по типу законцовки и параметру законцовки. + \en Constructor by type of tip and parameter of tip. \~ + \details \ru Конструктор по типу законцовки и параметру законцовки.\n + \en Constructor by type of tip and parameter of tip.\n \~ + \param[in] _tipType - \ru Тип законцовки. + \en Type of tip. \~ + \param[in] _tipParam - \ru Параметр законцовки, зависит от типа законцовки:\n + для mtt_UndefTip неопределен,\n + для mtt_LinearTip - расстояние от конца ЛМ до законцовки,\n + для mtt_ArcTip - расстояние от конца ЛМ до вершины дуги законцовки,\n + для mtt_PolylineTip - расстояние от конца ЛМ до вершины угла законцовки,\n + для mtt_ObliqueTip - угол поворота нормали от конца мультилинии (в радианах). + \en Parameter of tip, depends on type of tip:\n + for mtt_UndefTip is undefined,\n + for mtt_LinearTip - distance from the end of multiline to the tip,\n + for mtt_ArcTip - distance from the end of multiline to the vertex of arc of tip,\n + for mtt_PolylineTip - distance from the end of multiline to the vertex of corner of tip,\n + for mtt_ObliqueTip - angle of rotation of normal from the end of multiline (in radians). \~ + */ + StMLTipParams( EnMLTipType _tipType, double _tipParam ); + +public: + + /**\ru \name Функции доступа к данным + \en \name Functions for access to data + \{ */ + /// \ru Тип законцовки. \en Type of tip. + EnMLTipType GetTipType () const { return tipType; } + /// \ru Параметр законцовки. \en Parameter of tip. + double GetTipParam() const { return tipParam; } + /** \} */ + /**\ru \name Операторы сравнения + \en \name Comparison operators + \{ */ + /// \ru Оператор сравнения. \en Comparison operator. + bool operator ==( const StMLTipParams & ) const; + /// \ru Оператор сравнения. \en Comparison operator. + bool operator !=( const StMLTipParams & ) const; + /** \} */ + +protected: + + /**\ru \name Функции инициализации + \en \name Initialization functions + \{ */ + + /// \ru Инициализация по структуре параметров законцовки. \en Initialization by tip parameters structure. + void Init ( const StMLTipParams & other ); + + /** \brief \ru Инициализация по типу законцовки и параметру законцовки. + \en Initialization by type of tip and parameter of tip. \~ + \details \ru Инициализация по типу законцовки и параметру законцовки.\n + \en Initialization by type of tip and parameter of tip.\n \~ + \param[in] _tipType - \ru Тип законцовки. + \en Type of tip. \~ + \param[in] _tipParam - \ru Параметр законцовки, зависит от типа законцовки:\n + для mtt_UndefTip неопределен,\n + для mtt_LinearTip - расстояние от конца ЛМ до законцовки,\n + для mtt_ArcTip - расстояние от конца ЛМ до вершины дуги законцовки,\n + для mtt_PolylineTip - расстояние от конца ЛМ до вершины угла законцовки,\n + для mtt_ObliqueTip - угол поворота нормали от конца мультилинии (в радианах). + \en Parameter of tip, depends on type of tip:\n + for mtt_UndefTip is undefined,\n + for mtt_LinearTip - distance from the end of multiline to the tip,\n + for mtt_ArcTip - distance from the end of multiline to the vertex of arc of tip,\n + for mtt_PolylineTip - distance from the end of multiline to the vertex of corner of tip,\n + for mtt_ObliqueTip - angle of rotation of normal from the end of multiline (in radians). \~ + */ + void Init ( EnMLTipType _tipType, double _tipParam ); + + /** \} */ + /**\ru \name Функции изменения данных + \en \name Functions for changing data + \{ */ + + /** \brief \ru Изменить тип законцовки. + \en Change type of tip. \~ + \details \ru Изменить тип законцовки мультилинии.\ n + \en Change type of tip of multiline.\n \~ + \param[in] othTipType - \ru Новый тип законцовки. + \en New type of tip. \~ + \return \ru false, если старое значение типа совпадает со значением othTipType. + \en False if the old value of type coincides with the value of othTipType. \~ + */ + bool ChangeTipType ( EnMLTipType othTipType ); + + /** \brief \ru Изменить параметр законцовки. + \en Change parameter of tip. \~ + \details \ru Изменить параметр законцовки мультилинии.\n + \en Change parameter of tip of multiline.\n \~ + \param[in] othTipParam - \ru Новый параметр законцовки. + \en New parameter of tip. \~ + \return \ru false, если старое значение параметра совпадает со значением othTipParam. + \en False if the old value of parameter coincides with the value of othTipParam. \~ + */ + bool ChangeTipParam( double othTipParam ); + + /** \brief \ru Трансформация. + \en Transformation. \~ + \details \ru Преобразование объекта согласно матрице.\n + \en Transform object according to the matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform ( const MbMatrix & matr ); + /** \} */ + +private: + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const StMLTipParams & ); + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( StMLTipParams, MATH_FUNC_EX ) +}; // StMLTipParams + + +//------------------------------------------------------------------------------ +// _5_ +/** \brief \ru Информация о вершине. + \en Information about a vertex. \~ + \details \ru Информация о вершине мультилинии.\n + Изменять данные объекта можно только из MbMultiline. + \en Information about a vertex of multiline.\n + Object data can be changed only from MbMultiline. \~ + \ingroup Algorithms_2D +*/ +struct MATH_CLASS StVertexOfMultilineInfo { +friend class MbMultiline; +private: + bool smoothJoint; ///< \ru Флаг гладкого стыка в вершине сегментов базовой линии мультилинии \en Flag of multiline base line segments smooth joint at a vertex + ///< \ru (только для сплайнов). \en (only for splines). + EnMLVertexTracingType tracingType; ///< \ru Тип обхода углов в вершине мультилинии. \en Type of traverse of corners at a vertex of multiline. + double specFilletRad; ///< \ru Радиус особого скругления на линии мультилинии (если tracingType == mvt_SpecFilletType). \en Radius of a special fillet on a line of multiline (if tracingType == mvt_SpecFilletType). + // \ru Параметры законцовки в вершине (внутренней) \en Parameters of (inner) tip at a vertex + EnMLInnerTipType tipType; ///< \ru Тип внутренней законцовки. \en Type of inner tip. + bool firstSegTip; ///< \ru Законцовка для первого сегмента вершины. \en Tip for the first segment of a vertex. + +public: + StVertexOfMultilineInfo(); ///< \ru Умолчательный конструктор. \en Default constructor. + StVertexOfMultilineInfo( const StVertexOfMultilineInfo & other ); ///< \ru Копирующий конструктор. \en Copy-constructor. + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] _smoothJoint - \ru Флаг гладкого стыка в вершине сегментов базовой линии мультилинии,\n + используется только для сплайнов. + \en Flag of multiline base line segments smooth joint at a vertex,\n + used only for splines. \~ + \param[in] _tracingType - \ru Тип обхода углов в вершине мультилинии. + \en Type of traverse of corners at a vertex of multiline. \~ + \param[in] _specFilletRad - \ru Радиус особого скругления на линии мультилинии,\n + если tracingType == mvt_SpecFilletType. + \en Radius of a special fillet on line of multiline,\n + if tracingType == mvt_SpecFilletType. \~ + \param[in] _tipType - \ru Тип внутренней законцовки. + \en Type of inner tip. \~ + \param[in] _firstSegTip - \ru Законцовка для первого сегмента вершины. + \en Tip for the first segment of a vertex. \~ + */ + StVertexOfMultilineInfo( bool _smoothJoint, EnMLVertexTracingType _tracingType, + double _specFilletRad, EnMLInnerTipType _tipType, bool _firstSegTip ); + +public: + + /**\ru \name Функции доступа к данным + \en \name Functions for access to data + \{ */ + /// \ru Тип обхода углов в вершине мультилинии. \en Type of traverse of corners at a vertex of multiline. + EnMLVertexTracingType GetTracingType () const { return tracingType; } + /// \ru Флаг гладкого стыка в вершине сегментов базовой линии мультилинии. \en Flag of multiline base line segments smooth joint at a vertex. + bool IsSmoothJoint () const { return smoothJoint; } + /// \ru Радиус особого скругления на линии мультилинии. \en Radius of special fillet on base line of multiline. + double GetSpecFilletRad() const { return specFilletRad; } + /// \ru Тип внутренней законцовки. \en Type of inner tip. + EnMLInnerTipType GetTipType () const { return tipType; } + /// \ru Законцовка для первого сегмента вершины. \en Tip for the first segment of a vertex. + bool IsFirstSegTip () const { return firstSegTip; } + /// \ru Обход скруглением. \en Traverse by fillet. + bool IsFilletTracing () const; + +public: + + /** \} */ + /**\ru \name Операторы сравнения и присваивания + \en \name Comparison operators and assignment + \{ */ + /// \ru Оператор сравнения. \en Comparison operator. + bool operator == ( const StVertexOfMultilineInfo & ) const; + /// \ru Оператор сравнения. \en Comparison operator. + bool operator != ( const StVertexOfMultilineInfo & ) const; + /// \ru Оператор присваивания. \en Assignment operator. + StVertexOfMultilineInfo & operator = ( const StVertexOfMultilineInfo & other ) + { + Init( other ); + return *this; + } + + /** \} */ + + +protected: + + /**\ru \name Функции инициализации + \en \name Initialization functions + \{ */ + + /// \ru Инициализация по информации о вершине мультилинии. \en Initialization by an information about a vertex of multiline. + void Init( const StVertexOfMultilineInfo & other ); + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация.\n + \en Initialization.\n \~ + \param[in] _smoothJoint - \ru Флаг гладкого стыка в вершине сегментов базовой линии мультилинии,\n + используется только для сплайнов. + \en Flag of multiline base line segments smooth joint at a vertex,\n + used only for splines. \~ + \param[in] _tracingType - \ru Тип обхода углов в вершине мультилинии. + \en Type of traverse of corners at a vertex of multiline. \~ + \param[in] _specFilletRad - \ru Радиус особого скругления на линии мультилинии,\n + если tracingType == mvt_SpecFilletType. + \en Radius of a special fillet on line of multiline,\n + if tracingType == mvt_SpecFilletType. \~ + \param[in] _tipType - \ru Тип внутренней законцовки. + \en Type of inner tip. \~ + \param[in] _firstSegTip - \ru Законцовка для первого сегмента вершины. + \en Tip for the first segment of a vertex. \~ + */ + void Init ( bool _smoothJoint, EnMLVertexTracingType _tracingType, + double _specFilletRad, EnMLInnerTipType _tipType, + bool _firstSegTip ); + /** \} */ + /**\ru \name Функции изменения данных + \en \name Functions for changing data + \{ */ + /// \ru Изменить флаг гладкого стыка в вершине сегментов базовой линии мультилинии. \en Change flag of multiline base line segments smooth joint at a vertex. + bool ChangeSmoothJoint ( bool othSmoothJoint ); + /// \ru Изменить тип обхода углов в вершине мультилинии. \en Change type of traverse of corners at a vertex of multiline. + bool ChangeTracingType ( EnMLVertexTracingType othTracingType ); + /// \ru Изменить радиус особого скругления на линии мультилинии. \en Change radius of special fillet on base line of multiline. + bool ChangeSpecFilletRad( double othSpecFilletRad ); + /// \ru Изменить тип внутренней законцовки. \en Change type of inner tip. + bool ChangeTipType ( EnMLInnerTipType othTipType ); + /// \ru Изменить флаг законцовки для первого сегмента вершины. \en Change flag of tip for the first segment of a vertex. + bool ChangeFirstSegTip ( bool othFirstSegTip ); + + /** \brief \ru Трансформация. + \en Transformation. \~ + \details \ru Преобразование объекта согласно матрице.\n + \en Transform object according to the matrix.\n \~ + \param[in] matr - \ru Матрица трансформации. + \en Transformation matrix. \~ + */ + void Transform ( const MbMatrix & matr ); + /** \} */ + +private: + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( StVertexOfMultilineInfo, MATH_FUNC_EX ) +}; // StVertexOfMultilineInfo + + +//------------------------------------------------------------------------------ +/** \brief \ru Класс для перестроения разрывов. + \en Class for breaks rebuilding. \~ + \details \ru Класс для перестроения разрывов. Содержит номера сегментов базовой кривой.\n + \en Class for breaks rebuilding. Contains indices of the base curve segments.\n \~ + \ingroup Algorithms_2D +*/ +// --- +class MATH_CLASS MbBreaksRebuild { + +public: + SArray baseNumbers; ///< \ru Номера сегментов базовой кривой для сегментов линии мультилинии. \en Indices of the base curve segments for line segments of multiline. + +public: + /// \ru Конструктор по массиву номеров. \en Constructor by array of indices. + MbBreaksRebuild( const SArray & bNumbers ) + :baseNumbers( bNumbers ) + { + } + ~MbBreaksRebuild() {} +}; + + +//------------------------------------------------------------------------------ +// _6_ +/** \brief \ru Мультилиния. + \en Multiline. \~ + \details \ru Мультилиния - составной геометрический объект, состоящий из\n + 1) кривых curves, построенных эквидистантно к базовой кривой мультилинии basisCurve + с радиусами equidRadii. При этом способ обхода углов для каждой вершины + basisCurve определяется отдельно (с помощью vertices.tracingType и vertices.specFilletRad).\n + 2) массива законцовок tipCurves в вершинах мультилинии, тип которых определяется + соответствующим vertices[i].tipParams.tipType.\n + 3) законцовок begTipCurve и endTipCurve на концах мультилинии, тип которых определяется + с помощью begTipParams и endTipParams.\n + При создании линии мультилинии (добавлении радиуса эквидистанты) создается контур, + который будет жить (меняться только внутри) до того момента, пока в массиве equidRadii + есть соответствующий ему в начале элемент.\n + Контур законцовки живет до тех пор, пока соответствующий тип законцовки не равен m_t_UndefTip.\n + За существованием и удалением законцовок должны следить функции SetTipType.\n + При построении кривых мультилинии вырожденные участки исключаются только в вершинах (перехлесты). + \en Multiline is a composite geometric object consisting of\n + 1) 'curves' curves constructed to be equidistant to base line 'basisCurve' of the multiline + with 'equidRadii' radii. The method of traverse of corners for each vertex of + 'basisCurve' is defined separately (with the help of vertices.tracingType and vertices.specFilletRad).\n + 2) 'tipCurves' array of tips at vertices of multiline, which type is defined + by corresponding vertices[i].tipParams.tipType.\n + 3) 'begTipCurve' and 'endTipCurve' tips at the ends of multiline, which type is defined + with the help of 'begTipParams' and 'endTipParams'.\n + While creating line of multiline (adding equidistance radius) the contour is created + which will be alive (can be changed only internally) while the 'equidRadii' array + contains element at the beginning corresponding to it.\n + The contour of a tip will be alive while the corresponding type of the tip isn't equal to m_t_UndefTip.\n + SetTipType functions care about the existence and removal of tips.\n + Degenerated regions are excluded only at vertices (overlaps) while constructing the curves of a multiline. \~ + \ingroup Region_2D +*/ +// --- +class MATH_CLASS MbMultiline : public MbPlaneItem { +private: + MbContour * basisCurve; ///< \ru Базовая кривая (БК) (всегда не NULL). \en Base curve (BC) (always not NULL). + SArray vertices; ///< \ru Массив вершин мультилинии (согласован с вершинами БК). \en Array of vertices of a multiline (agreed with the vertices of the base curve). + CSSArray equidRadii; ///< \ru Сортированный массив радиусов эквидистантных кривых. \en Sorted array of radii of equidistant curves. + StMLTipParams begTipParams; ///< \ru Параметры законцовки в начале мультилинии (начале БК). \en Parameters of a tip at the beginning of a multiline ( the beginning of base curve). + StMLTipParams endTipParams; ///< \ru Параметры законцовки в конце мультилинии (конце БК). \en Parameters of a tip at the end of a multiline (end of the base curve). + bool processClosed; ///< \ru Обрабатывать ли замкнутость БК (доп. вершина). \en Whether to process the closedness of the base curve (additional vertex). + bool isTransparent; ///< \ru "Прозрачная" ли мультилиния. \en Whether the multiline is "transparent". + // \ru Объекты, которые составляют мультилинию (рекомендовали не делать их mutable, а писать и читать) \en Objects which constitute a multiline (recommended to read and write and not to make them mutable) + // \ru ЭТИ ОБЪЕКТЫ НЕЛЬЗЯ МЕНЯТЬ СНАРУЖИ!!! \en THESE OBJECTS CAN'T BE CHANGED OUTSIDE!!! + PArray curves; ///< \ru Кривые мультилинии (согласован с equidRadii) (всегда не NULL). \en Curves of a multiline (agreed with the 'equidRadii') (always not NULL). + PArray tipCurves; ///< \ru Законцовки в вершинах мультилинии (согласован с vertices). \en Tips at vertices of a multiline (agreed with 'vertices'). + MbContour * begTipCurve; ///< \ru Законцовка в начале мультилинии (начале БК). \en Tip at the beginning of a multiline (beginning of the base curve). + MbContour * endTipCurve; ///< \ru Законцовка в конце мультилинии (конце БК). \en Tip at the end of a multiline (end of the base curve). + + mutable double maxPosRadius; ///< \ru Максимально возможный для невывернутого построения положительный радиус. \en Maximum possible positive radius for non-everted construction. + mutable double minNegRadius; ///< \ru Минимально возможный для невывернутого построения отрицательный радиус. \en Minimum possible negative radius for non-everted construction. + mutable size_t minNotDegInd; ///< \ru Индекс невырожденного элемента curves с минимальным радиусом. \en Index of non-everted element of 'curves' with minimal radius. + mutable size_t maxNotDegInd; ///< \ru Индекс невырожденного элемента curves с максимальным радиусом. \en Index of non-everted element of 'curves' with maximal radius. + +public: + MbMultiline(); ///< \ru Конструктор пустой мультилинии. \en Constructor of an empty multiline. + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] _basisCurve - \ru Базовая кривая. + \en Base curve. \~ + \param[in] vertInfo - \ru Информация о вершине мультилинии (применяется ко всем вершинам). + \en Information about a vertex of the multiline (applied to all vertices). \~ + \param[in] _equidRadii - \ru Сортированный массив радиусов эквидистантных кривых. + \en Sorted array of radii of equidistant curves. \~ + \param[in] _begTipParams - \ru Параметры законцовки в начале мультилинии. + \en Parameters of tip at the beginning of multiline. \~ + \param[in] _endTipParams - \ru Параметры законцовки в конце мультилинии. + \en Parameters of a tip at the end of a multiline. \~ + \param[in] _processClosed - \ru Обрабатывать ли замкнутость базовой кривой. + \en Whether to process the closedness of the base curve. \~ + \param[in] _isTransparent - \ru "Прозрачная" ли мультилиния\n + параметр не используется, мультилиния считается прозрачной. + \en Whether the multiline is "transparent"\n + parameter isn't used, multiline is considered to be transparent. \~ + */ + MbMultiline( const MbContour & _basisCurve, const StVertexOfMultilineInfo & vertInfo, + const SArray & _equidRadii, + const StMLTipParams & _begTipParams, const StMLTipParams & _endTipParams, + bool _processClosed, bool _isTransparent ); + +protected: + /// \ru Копирующий конструктор. \en Copy-constructor. + MbMultiline( const MbMultiline & ); + +private: + MbMultiline( const MbContour & _basisCurve, const SArray & _vertices, + const SArray & _equidRadii, + const StMLTipParams & _begTipParams, const StMLTipParams & _endTipParams, + bool _processClosed, bool _isTransparent, bool & error ); + +public: + virtual ~MbMultiline(); + +public: + + /**\ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbePlaneType IsA () const; // \ru Тип объекта. \en A type of an object. + virtual MbePlaneType Type () const; // \ru Групповой тип объекта. \en Group type of an object. + virtual MbePlaneType Family () const; // \ru Семейство объекта. \en Family of an object. + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool IsSimilar ( const MbPlaneItem & item ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual bool SetEqual ( const MbPlaneItem & item ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual void Transform ( const MbMatrix & matr, MbRegTransform * = NULL, const MbSurface * newSurface = NULL );// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + virtual void Move ( const MbVector & to, MbRegTransform * = NULL, const MbSurface * newSurface = NULL );// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Rotate ( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = NULL, const MbSurface * newSurface = NULL ); // \ru Повернуть вокруг точки на угол. \en Rotate at angle around a point. + virtual MbPlaneItem & Duplicate ( MbRegDuplicate * = NULL ) const; // \ru Сделать копию объекта. \en Create a copy of the object. + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the given bounding box. + + virtual bool IsVisibleInRect ( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прям-ке. \en Whether the object is visible in the given rectangle. + virtual double DistanceToPoint ( const MbCartPoint & toP ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual bool DistanceToPointIfLess( const MbCartPoint & to, double &distance) const; // \ru Вычислить расстояние до точки, если оно меньше d. \en Calculate the distance to the point if it is less than d. + + virtual MbProperty& CreateProperty( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /**\ru \name Функции доступа к данным + \en \name Functions for access to data + \{ */ + + /// \ru Базовая кривая. \en Base curve. + const MbContour & GetBasisCurve () const { return *basisCurve; } + /// \ru Дать базовую кривую для изменения. \en Get base curve for editing. + MbContour & SetBasisCurve () { return *basisCurve; } + /// \ru Количество вершин. \en Count of vertices. + size_t GetVerticesCount () const { return vertices.Count(); } + /// \ru Вершина по номеру. Номер должен быть меньше количества вершин. \en Vertex by an index. Index must be less than count of vertices. + const StVertexOfMultilineInfo & GetVertex ( size_t i ) const { return vertices[i]; } + /// \ru Количество радиусов эквидистант. \en Count of radii of equidistant curves. + size_t GetEquidRadiiCount() const { return equidRadii.Count(); } + /// \ru Радиус эквидистанты по номеру. Номер должен быть меньше количества радиусов. \en Radius of equidistant curve by an index. Index must be less than count of radii. + double GetEquidRadius ( size_t i ) const { return equidRadii[i]; } + /// \ru Параметры законцовки в начале мультилинии. \en Parameters of tip at the beginning of multiline. + const StMLTipParams & GetBegTipParams () const { return begTipParams; } + /// \ru Параметры законцовки в конце мультилинии. \en Parameters of a tip at the end of a multiline. + const StMLTipParams & GetEndTipParams () const { return endTipParams; } + /// \ru Признак обрабатывания замкнутости базовой кривой. \en An attribute of the base curve closedness processing. + bool IsProcessClosed () const { return processClosed; } + /// \ru Прозрачность мультилинии. \en Transparency of multiline. + bool IsTransparent () const { return isTransparent; } + // \ru Функции доступа к объектам мультилинии \en Functions for access to objects of multiline + // \ru ЭТИ ОБЪЕКТЫ НЕЛЬЗЯ МЕНЯТЬ СНАРУЖИ!!! \en THESE OBJECTS CAN'T BE CHANGED OUTSIDE!!! + + /// \ru Количество кривых мультилинии. \en Count of curves of a multiline. + size_t GetCurvesCount () const { return curves.Count(); } + /// \ru Кривая мультилинии по номеру. Номер должен быть меньше количества кривых. \en Curve of multiline by an index. Index must be less than count of curves. + const MbContourWithBreaks* GetCurve ( size_t i ) const { return curves[i]; } + + /// \ru Количество кривых - законцовок в вершинах мультилинии. \en Count of tip-curves at vertices of multiline. + size_t GetTipCurvesCount () const { return tipCurves.Count(); } + /// \ru Кривая - законцовка по номеру. Номер должен быть меньше количества законцовок. \en Tip-curve by an index. Index must be less than the count of tips. + const MbContour * GetTipCurve ( size_t i ) const { return tipCurves[i]; } + + /// \ru Законцовка в начале мультилинии. \en Tip at the beginning of a multiline. + const MbContour * GetBegTipCurve () const { return begTipCurve; } + /// \ru Законцовка в конце мультилинии. \en Tip at the end of a multiline. + const MbContour * GetEndTipCurve () const { return endTipCurve; } + + /// \ru Максимально возможный для невывернутого построения положительный радиус. \en Maximum possible positive radius for non-everted construction. + double GetMaxPosRadius () const { return maxPosRadius; } + /// \ru Минимально возможный для невывернутого построения отрицательный радиус. \en Minimum possible negative radius for non-everted construction. + double GetMinNegRadius () const { return minNegRadius; } + + /// \ru Индекс невырожденной кривой мультилинии с минимальным радиусом \en Index of non-degenerated curve of a multiline with minimal radius + size_t GetMinNotDegInd () const { return minNotDegInd; } + /// \ru Индекс невырожденной кривой мультилинии с максимальным радиусом \en Index of non-degenerated curve of a multiline with maximal radius + size_t GetMaxNotDegInd () const { return maxNotDegInd; } + + /** \} */ + /**\ru \name Функции изменения данных: изменение базовой кривой мультилинии + \en \name Functions for changing data: changing the base curve of a multiline + \{ */ + + /// \ru Очистить базовую кривую. \en Clear the base curve. + void ClearBasisCurve (); + + /** \brief \ru Заменить базовую кривую. + \en Replace the base curve. \~ + \details \ru Заменить базовую кривую.\n + При замене базовой кривой мультилинии в ней удаляются все разрывы. + \en Replace the base curve.\n + When replacing the base curve of multiline all of its breaks are removed. \~ + \param[in] _basisCurve - \ru Новая базовая кривая. + \en New base curve. \~ + \param[in] vertInfo - \ru Новая информация о вершинах мультилинии. + \en New information about vertices of multiline. \~ + */ + void ReplaceBasisCurve ( const MbContour & _basisCurve, + const StVertexOfMultilineInfo & vertInfo ); + + /** \brief \ru Добавить сегмент в базовую кривую. + \en Add a segment to a base curve. \~ + \details \ru Добавить сегмент в базовую кривую.\n + \en Add a segment to a base curve.\n \~ + \param[in] segment - \ru Добавляемый сегмент,\n + если является ломаной или контуром, то в мультилинию добавляются только составляющие сегменты. + \en Segment to add,\n + if it is polyline or contour, then only component segments are added to the multiline. \~ + \param[in] vertInfo - \ru Информация присваивается всем добавленным или измененным вершинам. + \en Information is assigned to all added or changed vertices. \~ + \return \ru true, если сегмент был добавлен. + \en True if a segment has been added. \~ + */ + bool AddBasisSegment ( MbCurve * segment, + const StVertexOfMultilineInfo & vertInfo ); + + /// \ru Удалить последний сегмент базовой кривой. \en Delete the last segment of the base curve. + void DeleteLastBasisSegment (); + + /** \brief \ru Вставить вершину. + \en Insert a vertex. \~ + \details \ru Вставить вершину. Сегмент разбивается на два.\n + \en Insert a vertex. Segment is split into two segments.\n \~ + \param[in] t - \ru Параметр на базовой кривой. + \en Parameter on the base curve. \~ + \param[in] vertInfo - \ru Информация о новой вершине мультилинии. + \en Information about new vertex of a multiline. \~ + \return \ru Индекс разбитого сегмента. + \en Index of split segment. \~ + */ + size_t InsertVertex ( double t, + const StVertexOfMultilineInfo & vertInfo ); + + /** \brief \ru Удалить вершину мультилинии. + \en Delete a vertex of multiline. \~ + \details \ru Удалить вершину мультилинии.\n + Пара сегментов, примыкающих к вершине, заменяется отрезком.\n + Разрывы на прилегающих сегментах исчезают. + Разрывы, лежащие на прямолинейных прилегающих сегментах, + остаются, привязываясь к вершинам нового отрезка. + \en Delete a vertex of multiline.\n + Pair of segments adjoining the vertex is replaced by a segment.\n + Breaks on adjacent segments are disappeared. + Breaks on straight adjacent segments + are remained by binding to the vertices of a new segment. \~ + \param[in] i - \ru Индекс вершины. + \en An index of a vertex. \~ + \return \ru true, если вершина была удалена. + \en True if a vertex is deleted. \~ + */ + bool RemoveVertex ( size_t i ); + + /** \brief \ru Сместить геометрическую hot-точку. + \en Shift a geometric hot-point. \~ + \details \ru Сместить геометрическую hot-точку базовой кривой.\n + При перемещении точки разрывы контуров, соответствующих прилегающим прямолинейным + сегментам привязываются к соседним неподвижным вершинам базовой кривой. + \en Shift a geometric hot-point of the base curve.\n + While shifting point, the contour breaks corresponding to adjacent straight + segments are bound to the neighboring fixed vertices of the base curve. \~ + \param[in] segInd - \ru Номер сегмента. + \en An index of a segment. \~ + \param[in] subInd - \ru Номер точки на сегменте:\n + если subInd = 0 - общая точка между двумя сегментами (может быть задана для любого сегмента),\n + если subInd = 1 - средняя точкой отрезка, средняя точкой дуги, базовая точка сплайнов pt_Nurbs и pt_Bezier,\n + если subInd > 1 - базовая точка сплайнов pt_Nurbs и pt_Bezier. + \en An index of a point on the segment:\n + if subInd = 0 - common point between two segments (can be specified for any segment),\n + if subInd = 1 - middle point of a segment, middle point of an arc, the base point of pt_Nurbs and pt_Bezier splines,\n + if subInd > 1 - base point of pt_Nurbs and pt_Bezier splines. \~ + \param[in] newPoint - \ru Новое положение точки. + \en New position of the point. \~ + \return \ru Точка была смещена. + \en Point has been shifted. \~ + */ + bool SetBasisCurvesGeoHotPoint( size_t segInd, size_t subInd, + const MbCartPoint & newPoint ); + + /** \brief \ru Удалить геометрическую hot-точку. + \en Delete a geometric hot-point. \~ + \details \ru Удалить геометрическую hot-точку базовой кривой.\n + \en Delete a geometric hot-point of the base curve.\n \~ + \param[in] segInd - \ru Номер сегмента. + \en An index of a segment. \~ + \param[in] subInd - \ru Номер точки на сегменте:\n + если subInd = 0 - результат аналогичен удалению вершины мультилинии RemoveVertex,\n + если subInd = 1 - удаление средней точки дуги (дуга заменяется отрезком), + удаление базовой точки сплайнов pt_Nurbs и pt_Bezier (изменение формы),\n + если subInd > 1 - удаление базовой точки сплайнов pt_Nurbs и pt_Bezier (изменение формы). + \en An index of a point on the segment:\n + if subInd = 0 - result is similar to deletion of the 'RemoveVertex' vertex of a multiline,\n + if subInd = 1 - deletion of the middle point of an arc (the arc is replaced by segment), + deletion of the base point of pt_Nurbs and pt_Bezier splines (changing of shape),\n + if subInd > 1 - deletion of the base point of pt_Nurbs and pt_Bezier splines (changing of shape). \~ + \return \ru true, если hot-точка была удалена. + \en True if hot-point has been deleted. \~ + */ + bool DelBasisCurvesGeoHotPoint( size_t segInd, size_t subInd ); + + /** \} */ + /**\ru \name Функции изменения данных: скругления и фаски базовой кривой + \en \name Functions for changing data: fillet and chamfer of the base curve + \{ */ + + /** \brief \ru Скруглить два соседних сегмента. + \en Fillet two neighboring segments. \~ + \details \ru Скруглить два соседних сегмента базовой кривой.\n + \en Fillet two neighboring segments of base curve.\n \~ + \param[in] index - \ru Индекс первого скругляемого сегмента. + \en Index of the first segment to fillet. \~ + \param[in] rad - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \return \ru true в случае успеха операции. + \en Returns true if the operation succeeded. \~ + */ + bool FilletTwoBasisSegments ( ptrdiff_t & index, double rad, + const StVertexOfMultilineInfo & vertInfo ); + + /** \brief \ru Скруглить базовую кривую. + \en Fillet the base curve. \~ + \details \ru Скруглить все углы базовой кривой.\n + \en Fillet all corners of the base curve.\n \~ + \param[in] rad - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \return \ru true, если добавилось хотя бы одно скругление. + \en True if at least one fillet is added. \~ + */ + bool FilletBasisCurve ( double rad, + const StVertexOfMultilineInfo & vertInfo ); + + /** \brief \ru Вставить фаску между двумя соседними сегментами базовой кривой мультилинии. + \en Insert a chamfer between two neighboring segments of the base curve of a multiline. \~ + \details \ru Вставить фаску между двумя соседними сегментами базовой кривой мультилинии.\n + \en Insert a chamfer between two neighboring segments of the base curve of a multiline.\n \~ + \param[in] index - \ru Индекс первого скругляемого сегмента. + \en Index of the first segment to fillet. \~ + \param[in] len - \ru Длина фаски. + \en Length of chamfer. \~ + \param[in] par - \ru Параметр в зависимости от типа type:\n + если type = true, par - угол\n + если type = false, par - размер. + \en Parameter depending on 'type' type:\n + if type = true, par is a corner\n + if type = false, par is a size. \~ + \param[in] type - \ru Тип задания фаски:\n + true - фаска задана как размер + угол,\n + false - фаска задана как размер + размер. + \en The type of a chamfer specification:\n + true - chamfer specified as size + angle,\n + false - chamfer specified as size + size. \~ + \param[in] firstSeg - \ru true, если параметр par относится к первому сегменту. + \en True if 'par' parameter is related to the first segment. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \return \ru true в случае успеха операции. + \en Returns true if the operation succeeded. \~ + */ + bool ChamferTwoBasisSegments ( ptrdiff_t & index, double len, double par, + bool type, bool firstSeg, + const StVertexOfMultilineInfo & vertInfo ); + + /** \brief \ru Вставить фаску между каждыми двумя соседними сегментами базовой кривой мультилинии. + \en Insert a chamfer between each two neighboring segments of the base curve of a multiline. \~ + \details \ru Вставить фаску между каждыми двумя соседними сегментами базовой кривой мультилинии.\n + Параметр par относится к первому сегменту из каждой пары. + \en Insert a chamfer between each two neighboring segments of the base curve of a multiline.\n + 'par' parameter is related to the first segment of each pair. \~ + \param[in] len - \ru Длина фаски. + \en Length of chamfer. \~ + \param[in] par - \ru Параметр в зависимости от типа type:\n + если type = true, par - угол,\n + если type = false, par - размер. + \en Parameter depending on 'type' type:\n + if type = true, par is a corner,\n + if type = false, par is a size. \~ + \param[in] type - \ru Тип задания фаски:\n + true - фаска задана как размер + угол,\n + false - фаска задана как размер + размер. + \en The type of a chamfer specification:\n + true - chamfer specified as size + angle,\n + false - chamfer specified as size + size. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \return \ru true, если добавилась хотя бы одна фаска. + \en True if at least one chamfer is added. \~ + */ + bool ChamferBasisCurve ( double len, double par, bool type, + const StVertexOfMultilineInfo & vertInfo ); ///< \ru Вставить фаску БК \en Insert chamfer of the base curve + + /** \} */ + /**\ru \name Функции изменения данных: изменение параметров вершины мультилинии + \en \name Functions for changing data: changing the parameters of a vertex of a multiline + \{ */ + + /** \brief \ru Установить флаг гладкого стыка. + \en Set the flag of smooth joint. \~ + \details \ru Установить флаг гладкого стыка в вершине.\n + \en Set the flag of smooth joint at a vertex.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] othSmoothJoint - \ru Флаг гладкого стыка. + \en Flag of smooth joint. \~ + */ + void SetSmoothJoint ( size_t i, bool othSmoothJoint ); + + /** \brief \ru Установить тип обхода. + \en Set the type of traverse. \~ + \details \ru Установить тип обхода вершины.\n + \en Set the type of traverse of the vertex.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] othTracingType - \ru Тип обхода. + \en Type of traverse. \~ + */ + void SetTracingType ( size_t i, EnMLVertexTracingType othTracingType ); + + /** \brief \ru Установить радиус специального скругления. + \en Set the radius of a special fillet. \~ + \details \ru Установить радиус специального скругления вершины мультилинии.\n + \en Set the radius of special fillet of a vertex of the multiline.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] othSpecFilletRad - \ru Радиус. + \en Radius. \~ + */ + void SetSpecFilletRad ( size_t i, double othSpecFilletRad ); + + /** \brief \ru Установить тип законцовки. + \en Set the type of a tip. \~ + \details \ru Установить тип законцовки (разделителя) в вершине.\n + \en Set the type of tip (splitter) at the vertex.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] othTipType - \ru Тип законцовки. + \en Type of tip. \~ + */ + void SetTipType ( size_t i, EnMLInnerTipType othTipType ); + + /** \brief \ru Установить направление законцовки. + \en Set the direction of a tip. \~ + \details \ru Установить направление законцовки в вершине мультилинии.\n + \en Set the direction of a tip at a vertex of multiline.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] othFirstSegTip - \ru Направление законцовки, если true - от первого сегмента. + \en Direction of tip, if true - from the first segment. \~ + */ + void SetTipDirection ( size_t i, bool othFirstSegTip ); + + /** \brief \ru Установить информацию о вершине. + \en Set the information about a vertex. \~ + \details \ru Установить информацию о вершине мультилинии.\n + \en Set the information about a vertex of multiline.\n \~ + \param[in] i - \ru Индекс вершины мультилинии. + \en An index of a vertex of a multiline. \~ + \param[in] vertInfo - \ru Информация о вершине. + \en Information about a vertex. \~ + */ + void SetVertexOfMultilineInfo ( size_t i, + const StVertexOfMultilineInfo & vertInfo ); + + /** \} */ + /**\ru \name Функции изменения данных: изменение радиусов эквидистант + \en \name Functions for changing data: changing the radii of equidistant curves + \{ */ + + /** \brief \ru Установить значение радиуса кривой. + \en Set the value of radius of curve. \~ + \details \ru Установить значение радиуса кривой.\n + \en Set the value of radius of curve.\n \~ + \param[in] i - \ru Индекс кривой мультилинии. + \en An index of curve of multiline. \~ + \param[in] radius - \ru Новое значение радиуса. + \en New value of the radius. \~ + \param[out] newIndex - \ru Новый индекс кривой. + \en New index of curve. \~ + \return \ru true, если радиус был изменен. + \en True if a radius has been changed. \~ + */ + bool SetRadius ( size_t i, double radius, size_t & newIndex ); + + /** \brief \ru Изменение всех радиусов кривых. + \en Changing all radii of curves. \~ + \details \ru Изменение одновременно всех радиусов кривых.\n + Значения радиусов будут изменены, если их количество в newRadii совпадает с количеством кривых. + \en Simultaneous changing all radii of curves.\n + Values of radii will be changed if their count in 'newRadii' is coincident to the count of curves. \~ + \param[in] newRadii - \ru Новые значения радиусов кривых. + \en New values of radii of curves. \~ + \return \ru true, если радиусы были изменены. + \en True if radii has been changed. \~ + */ + bool SetRadii ( const CSSArray & newRadii ); + + /** \brief \ru Изменение радиуса. + \en Change the radius. \~ + \details \ru Изменение радиуса кривой мультилинии.\n + \en Change the radius of a curve of multiline.\n \~ + \param[in] oldRadius - \ru Старое значение радиуса. + \en Old value of the radius. \~ + \param[in] radius - \ru Новое значение радиуса. + \en New value of the radius. \~ + */ + void ChangeRadius ( double oldRadius, double radius ); + + /** \brief \ru Добавление радиуса кривой мультилинии. + \en Add the radius of a curve of multiline. \~ + \details \ru Добавление радиуса кривой мультилинии.\n + Фактически, добавление кривой мультилинии. + \en Add the radius of a curve of multiline.\n + Actually, addition of a curve of multiline. \~ + \param[in] radius - \ru Значение радиуса. + \en Value of radius. \~ + \return \ru Значение индекса новой кривой\n + если кривая не была добавлена, индекс равен SYS_MAX_T. + \en Value of an index of the new curve.\n + if curve was not added, then the index is equal to SYS_MAX_T. \~ + */ + size_t AddRadius ( double radius ); + + /** \brief \ru Удаление кривой. + \en Delete a curve. \~ + \details \ru Удаление кривой мультилинии.\n + \en Delete a curve of multiline.\n \~ + \param[in] i - \ru Индекс кривой. + \en A curve index. \~ + \return \ru true, если кривая была удалена. + \en True if curve has been deleted. \~ + */ + bool RemoveRadius ( size_t i ); + + /** \brief \ru Удаление кривой. + \en Delete a curve. \~ + \details \ru Удаление кривой мультилинии.\n + \en Delete a curve of multiline.\n \~ + \param[in] oldRadius - \ru Радиус кривой. + \en Radius of a curve. \~ + \return \ru true, если кривая была удалена. + \en True if curve has been deleted. \~ + */ + bool RemoveRadius ( double oldRadius ); + + /** \} */ + /**\ru \name Функции изменения данных: изменение параметров законцовок + \en \name Functions for changing data: change the parameters of tips + \{ */ + + /** \brief \ru Изменение типа законцовки в начале. + \en Change the type of a tip at the beginning. \~ + \details \ru Изменение типа законцовки мультилинии в начале.\n + \en Change the type of a tip of multiline at the beginning.\n \~ + \param[in] othTipType - \ru Новый тип законцовки. + \en New type of tip. \~ + */ + void SetBegTipType ( EnMLTipType othTipType ); + + /** \brief \ru Изменение параметра законцовки в начале. + \en Change the parameter of a tip at the beginning. \~ + \details \ru Изменение параметра законцовки мультилинии в начале.\n + \en Change the parameter of a tip of multiline at the beginning.\n \~ + \param[in] othTipParam - \ru Новый параметр законцовки. + \en New parameter of tip. \~ + */ + void SetBegTipParam ( double othTipParam ); + + /** \brief \ru Изменение типа законцовки в конце. + \en Change the type of a tip at the end. \~ + \details \ru Изменение типа законцовки мультилинии в конце.\n + \en Change the type of a tip of multiline at the end.\n \~ + \param[in] othTipType - \ru Новый тип законцовки. + \en New type of tip. \~ + */ + void SetEndTipType ( EnMLTipType othTipType ); + + /** \brief \ru Изменение параметра законцовки в конце. + \en Change the parameter of a tip at the end. \~ + \details \ru Изменение параметра законцовки мультилинии в конце.\n + \en Change the parameter of a tip of multiline at the end.\n \~ + \param[in] othTipParam - \ru Новый параметр законцовки. + \en New parameter of tip. \~ + */ + void SetEndTipParam ( double othTipParam ); + + /** \} */ + /**\ru \name Функции изменения данных + \en \name Functions for changing data + \{ */ + + /** \brief \ru Изменение обработки замкнутости. + \en Change the closedness processing. \~ + \details \ru Изменение флага обработки замкнутости.\n + \en Change the flag of the closedness processing.\n \~ + \param[in] othProcessClosed - \ru Флаг обработки замкнутости. + \en Flag of the closedness processing. \~ + */ + void SetProcessClosed ( bool othProcessClosed ); + + /** \brief \ru Изменение прозрачности мультилинии. + \en Change the transparency of multiline. \~ + \details \ru Изменение флага прозрачности мультилинии.\n + \en Change the flag of transparency of multiline.\n \~ + \param[in] othTransparent - \ru Флаг прозрачности. + \en Transparency flag. \~ + */ + void SetTransparent ( bool othTransparent ); + + /** \} */ + /**\ru \name Работа с разрывами: добавление разрывов + \en \name Working with breaks: addition of breaks + \{ */ + + /** \brief \ru Усечение части кривой мультилинии между точками. + \en Trimming of a piece of a curve of multiline between points. \~ + \details \ru Усечение части кривой мультилинии между точками.\n + Добавление разрыва. + \en Trimming of a piece of a curve of multiline between points.\n + Add a break. \~ + \param[in] contour - \ru Кривая мультилинии для добавления разрыва. + \en Curve of multiline for addition of a break. \~ + \param[in] point1 - \ru Первая граница разрыва. + \en The first boundary of the break. \~ + \param[in] point2 - \ru Вторая граница разрыва. + \en The second boundary of the break. \~ + \param[in] point3 - \ru Точка, которая показывает удаляемую часть замкнутого контура,\n + в случае разомкнутого контура она игнорируется. + \en The point indicating the piece of a closed contour to be deleted,\n + ignored in case of the opened contour. \~ + \param[in] invertBreak - \ru Если true, то разрыв накладывается на противоположную часть контура. + \en If 'true', then the break is applied to the opposite piece of the contour. \~ + \return \ru true, если разрыв был добавлен. + \en True if a break has been added. \~ + */ + bool DeletePartP1P2 ( MbContourWithBreaks * contour, + const MbCartPoint & point1, + const MbCartPoint & point2, + const MbCartPoint & point3, + bool invertBreak = false ); + + /** \brief \ru Усечение части кривой мультилинии между точками. + \en Trimming of a piece of a curve of multiline between points. \~ + \details \ru Усечение части кривой мультилинии между точками.\n + Добавление разрыва. + \en Trimming of a piece of a curve of multiline between points.\n + Add a break. \~ + \param[in] cNumber - \ru Номер кривой мультилинии для добавления разрыва. + \en Index of curve of multiline for addition of a break. \~ + \param[in] point1 - \ru Первая граница разрыва. + \en The first boundary of the break. \~ + \param[in] point2 - \ru Вторая граница разрыва. + \en The second boundary of the break. \~ + \param[in] point3 - \ru Точка, которая показывает удаляемую часть замкнутого контура,\n + в случае разомкнутого контура она игнорируется. + \en The point indicating the piece of a closed contour to be deleted,\n + ignored in case of the opened contour. \~ + \param[in] invertBreak - \ru Если true, то разрыв накладывается на противоположную часть контура. + \en If 'true', then the break is applied to the opposite piece of the contour. \~ + \return \ru true, если разрыв был добавлен. + \en True if a break has been added. \~ + */ + bool DeletePartP1P2 ( size_t cNumber, + const MbCartPoint & point1, + const MbCartPoint & point2, + const MbCartPoint & point3, + bool invertBreak = false ); + + /** \brief \ru Усечение части кривой мультилинии между параметрами контура. + \en Trimming of a piece of a curve of multiline between parameters of contour. \~ + \details \ru Усечение части кривой мультилинии между параметрами контура.\n + Добавление разрыва. + \en Trimming of a piece of a curve of multiline between parameters of contour.\n + Add a break. \~ + \param[in] cNumber - \ru Номер кривой мультилинии для добавления разрыва. + \en Index of curve of multiline for addition of a break. \~ + \param[in] t1 - \ru Первая граница разрыва. + \en The first boundary of the break. \~ + \param[in] t2 - \ru Вторая граница разрыва. + \en The second boundary of the break. \~ + \param[in] t3 - \ru Параметр, который показывает удаляемую часть замкнутого контура,\n + в случае разомкнутого контура он игнорируется. + \en A parameter which indicates a removable part of the closed contour, \n + ignored in case of opened contour. \~ + \param[in] invertBreak - \ru Если true, то разрыв накладывается на противоположную часть контура. + \en If 'true', then the break is applied to the opposite piece of the contour. \~ + \return \ru true, если разрыв был добавлен. + \en True if a break has been added. \~ + */ + bool DeletePartP1P2 ( size_t cNumber, + double t1, double t2, double t3, + bool invertBreak = false ); + + /** \} */ + /**\ru \name Работа с разрывами: удаление разрывов + \en \name Working with breaks: deletion of breaks + \{ */ + + /** \brief \ru Удалить разрывы. + \en Remove breaks. \~ + \details \ru Удалить все разрывы мультилинии.\n + \en Delete all breaks of multiline.\n \~ + \return \ru true, если хотя бы один разрыв был удален. + \en true, if at least one break has been deleted. \~ + */ + bool DeleteBreaks ( ); + + /** \brief \ru Удалить разрывы кривой. + \en Remove breaks of curve. \~ + \details \ru Удалить все разрывы кривой мультилинии.\n + \en Delete all breaks of curve of multiline.\n \~ + \param[in] cNumber - \ru Номер кривой. + \en Index of curve. \~ + \return \ru true, если хотя бы один разрыв был удален. + \en true, if at least one break has been deleted. \~ + */ + bool DeleteBreaks ( size_t cNumber ); + + /** \brief \ru Удалить разрыв кривой. + \en Delete a break of curve. \~ + \details \ru Удалить разрыв по параметру на кривой.\n + \en Delete a break by a parameter on the curve.\n \~ + \param[in] cNumber - \ru Номер кривой. + \en Index of curve. \~ + \param[in] t - \ru Параметр на кривой. + \en A parameter on the curve. \~ + \return \ru true, если разрыв был удален. + \en True if a break has been deleted. \~ + */ + bool DeleteBreak ( size_t cNumber, double t ); + + /** \brief \ru Удалить разрыв. + \en Delete a break. \~ + \details \ru Удалить разрыв по номеру.\n + \en Delete a break by an index.\n \~ + \param[in] cNumber - \ru Номер кривой. + \en Index of curve. \~ + \param[in] brNumber - \ru Номер разрыва на кривой. + \en Index of a break on the curve. \~ + \return \ru true, если разрыв был удален. + \en True if a break has been deleted. \~ + */ + bool DeleteBreakAtNumber ( size_t cNumber, size_t brNumber ); + + /** \brief \ru Удалить разрывы малой длины. + \en Delete breaks of small length. \~ + \details \ru Удалить разрывы малой метрической длины у кривой мультилинии.\n + В случае успеха линия мультилинии перестраивается соответственно разрывам. + \en Delete breaks of small length of a curve of multiline.\n + In case of success the line of multiline is rebuilt according to breaks. \~ + \param[in] cNumber - \ru Номер кривой мультилинии. + \en Index of a curve of multiline. \~ + \param[in] length - \ru Минимальная длина невидимой части. + \en Minimal length of invisible piece. \~ + \return \ru true, если хотя бы один разрыв кривой был удален. + \en True if at least one break of the curve has been deleted. \~ + */ + bool DeleteSmallBreaks ( size_t cNumber, double length ); + + /** \brief \ru Удалить малые видимые части. + \en Delete small visible pieces. \~ + \details \ru Удалить видимые части малой метрической длины у кривой мультилинии.\n + Соответствует объединению близких разрывов в один. + В случае успеха видимые контуры кривой перестраиваются соответственно разрывам. + \en Delete small visible pieces of a curve of multiline with small metric length.\n + Corresponds to union of close breaks into one. + In case of success the visible contours of the line is rebuilt according to breaks. \~ + \param[in] cNumber - \ru Номер кривой мультилинии. + \en Index of a curve of multiline. \~ + \param[in] length - \ru Минимальная длина видимой части. + \en Minimal length of visible piece. \~ + \return \ru true, если разрывы кривой были изменены. + \en True if breaks has been changed. \~ + */ + bool DeleteSmallVisContours ( size_t cNumber, double length ); + + /** \} */ + /**\ru \name Работа с разрывами + \en \name Working with breaks + \{ */ + + /** \brief \ru Находится ли интервал на разрыве. + \en Whether the interval is on a break. \~ + \details \ru Находится ли интервал параметров на разрыве кривой.\n + \en Whether the interval of parameters is on a break of a curve.\n \~ + \param[in] cNumber - \ru Номер кривой мультилинии. + \en Index of a curve of multiline. \~ + \param[in] rect - \ru Интервал для проверки. + \en Interval to check. \~ + \return \ru true, если интервал полностью находится на разрыве или совпадает с ним. + \en True if interval entirely is on the break or coincides with it. \~ + */ + bool IsRectInBreak ( size_t cNumber, const MbRect1D & rect ); + + /** \brief \ru Запомнить разрывы. + \en Memorize the breaks. \~ + \details \ru Запомнить разрывы невидимыми контурами.\n + Для использования в паре с AddBreaksByInvisContours.\n + Удаляет все разрывы мультилинии.\n + Все контуры invisContours имеют счетчик ссылок = 1 (вызван AddRef()). + \en Memorize the breaks as invisible contours.\n + For using together with AddBreaksByInvisContours.\n + Deletes all breaks of multiline.\n + All 'invisContours' contours has a reference counter = 1 (called AddRef()). \~ + \param[out] invisContours - \ru Набор невидимых контуров всех кривых мультилинии. + \en Set of invisible contours of all curves of multiline. \~ + */ + void GetBreaksInInvisContours( RPArray & invisContours ); + + /** \brief \ru Добавить разрывы. + \en Add breaks. \~ + \details \ru Добавить разрывы невидимыми контурами.\n + Для использования в паре с GetBreaksInInvisContours.\n + Контуры invisContours удаляются (вызывается Release()).\n + Данной функцией можно наложить разрывы на мультилинию, + если они были получены методом GetBreaksInInvisContours у этой мультилинии + и форма мультилинии не была изменена. + \en Add the breaks as invisible contours.\n + For using together with GetBreaksInInvisContours.\n + 'invisContours' contours are deleted (called Release()).\n + It is possible to apply breaks to multiline by this function, + if they were obtained by GetBreaksInInvisContours method from this multiline + and shape of multiline wasn't changed. \~ + \param[in] invisContours - \ru Набор невидимых контуров всех кривых мультилинии. + \en Set of invisible contours of all curves of multiline. \~ + */ + void AddBreaksByInvisContours( RPArray & invisContours ); + + /** \brief \ru Номера контуров, пересекаемых отрезком. + \en Indices of contours intersected with a segment. \~ + \details \ru Номера контуров, которые пересекаются с отрезком по двум точкам.\n + \en Indices of contours which are intersected with segment by two points.\n \~ + \param[in] p1 - \ru Первая точка отрезка. + \en The first point of a segment. \~ + \param[in] p2 - \ru Вторая точка отрезка. + \en The second point of a segment. \~ + \param[out] cNumbers - \ru Номера контуров. + \en Indices of contours. \~ + */ + void CurvesIntersectNumbers ( const MbCartPoint & p1, const MbCartPoint & p2, SArray & cNumbers ) const; + + /** \} */ + /**\ru \name Информация о мультилинии + \en \name Information about multiline. + \{ */ + + /// \ru Вырождена ли мультилиния. \en Whether the multiline is degenerate. + bool IsDegenerate( double lenEps = Math::LengthEps ) const; + /// \ru Замкнутая ли мультилиния. \en Whether the multiline is closed. + bool IsClosed () const; + /// \ru Получить ширину мультилинии. \en Get width of multiline. + double GetWidth () const; + /// \ru Лежит ли данная точка на мультилинии. \en Whether the given point is on multiline. + bool IsPointOn ( const MbCartPoint & point ) const; + + /** \brief \ru Найти индекс кривой мультилинии. + \en Find an index of a curve of multiline. \~ + \details \ru Найти индекс кривой мультилинии.\n + \en Find an index of a curve of multiline.\n \~ + \param[in] radius - \ru Радиус нужной кривой. + \en Radius of the required curve. \~ + \return \ru Индекс кривой. + \en A curve index. \~ + */ + size_t FindRadius ( double radius ); + + /** \} */ + /**\ru \name Операции с мультилинией + \en \name Operations with multiline + \{ */ + + /** \brief \ru Усечь мультилинию. + \en Truncate multiline. \~ + \details \ru Усечь мультилинию.\n + Вернуть мультилинию, базовая кривая которой - + копия участка между параметрами t1 и t2 базовой данной мультилинии. + \en Truncate multiline.\n + Return multiline which base curve is + a copy of piece between parameters t1 and t2 of the base curve of a given multiline. \~ + \param[in] t1 - \ru Начальный параметр усечения. + \en Start parameter of trimming. \~ + \param[in] t2 - \ru Конечный параметр усечения. + \en End parameter of trimming. \~ + \param[in] sense - \ru Направление усеченной базовой кривой. + \en Direction of the trimmed base curve. \~ + \return \ru Новую мультилинию. + \en New multiline. \~ + */ + MbMultiline * Trimmed( double t1, double t2, int sense ) const; + + /** \} */ +private: + /**\ru \name Внутренние функции мультилинии + \en \name Internal functions of multiline + \{ */ + + // \ru Все внутренние функции реализованы в MltLine_.cpp (кроме тех, для которых указан другой файл) \en All internal functions implemented in MltLine_.cpp (except ones for which the other file is specified) + // \ru Насчет объектов \en Calculation of objects + /// \ru Насчитать кривую мультилинии c радиусом эквидистанты rad. \en Calculate curve of multiline with 'rad' equidistant radius. + void CalculateCurve ( double rad, MbContourWithBreaks & contour ); + /// \ru Насчитать кривую мультилинии c радиусом эквидистанты rad c заполнением информации. \en Calculate curve of multiline with equidistant radius 'rad' and filling the information. + void CalculateCurveWithInfo ( double rad, MbContourWithBreaks & contour, + SArray & baseIndexes ); + /// \ru Насчитать все кривые (с определением minNotDegInd и maxNotDegInd). \en Calculate all the curves (with determination of minNotDegInd and maxNotDegInd). + void CalculateCurves (); + /// \ru Насчитать все кривые с информацией для граничных невырожденных кривых. \en Calculate all the curves with information for non-degenerate boundary curves. + bool CalculateCurvesWithInfo ( SArray & minInfo, SArray & maxInfo ); + /// \ru Насчитать все законцовки в вершинах. \en Calculate all tips at vertices. + void CalculateTipCurves ( const SArray & minInfo, const SArray & maxInfo ); + /// \ru Насчитать все законцовки в вершинах. \en Calculate all tips at vertices. + void CalculateTipCurves (); + /// \ru Насчитать все кривые и все законцовки в вершинах. \en Calculate all curves and all tips at vertices. + void CalculateCurvesAndTipCurves(); + /// \ru Насчитать законцовку в начале. \en Calculate tip at the beginning. + void CalculateBegTipCurve ( SArray * changeCurvesNumbers = NULL ); + /// \ru Насчитать законцовку в конце. \en Calculate tip at the end. + void CalculateEndTipCurve (); + + // \ru Отцепление объектов \en Detach the objects + + /// \ru Отцепить все кривые. \en Detach all curves. + void DeleteCurves (); + /// \ru Отцепить кривую с индексом i. \en Detach i-th curve. + void DeleteCurve ( size_t i ); + /// \ru Отцепить все законцовки в вершинах. \en Detach all tips at vertices. + void DeleteTipCurves (); + /// \ru Отцепить законцовку в вершине с индексом i. \en Detach i-th tip at vertex. + void DeleteTipCurve ( size_t i ); + /// \ru Отцепить законцовку в начале. \en Detach tip at the beginning. + void DeleteBegTipCurve (); + /// \ru Отцепить законцовку в конце. \en Detach tip at the end. + void DeleteEndTipCurve (); + /// \ru Отцепить все объекты. \en Detach all the objects. + void DeleteAllObjects (); + + // \ru Пересчет объектов \en Recalculation of objects + + /// \ru Перестроить все объекты. \en Rebuild all objects. + void RebuildAllObjects (); + + // \ru Обработки изменения vertices (без перестроения) \en Processing of 'vertices' changing (without rebuilding) + void AddVert ( const StVertexOfMultilineInfo & vertInfo ); + void InsertVert ( size_t i, const StVertexOfMultilineInfo & vertInfo ); + void ChangeVert ( size_t i, const StVertexOfMultilineInfo & vertInfo ); + void RemoveVert ( size_t i ); + + // \ru Вспомогательные функции \en Auxiliary functions + + /// \ru Обработать изменение i-ого сегмента БК. \en Process change of i-th segment of base curve. + void CalculateChangeOfSegment ( size_t i ); + /// \ru Продлить кривую до законцовок. \en Extend curve to the tips. + void ProlongCurveToTips ( size_t i ); + /// \ru Рассчитать удаление i-ой кривой (обработка). \en Calculate removal of i-th curve (processing). + void CalculateRemovalOfCurve ( size_t i ); + + // \ru Скругление/фаска двух соседних сегментов БК (реализация в MLOper.cpp) \en Fillet/chamfer of two neighboring segments of the base curve (implementation in MLOper.cpp) + bool FilletOrChamferTwoBasisSegs( ptrdiff_t & index, const StVertexOfMultilineInfo & vertInfo, + bool fillet, bool recalcCrvRadii, + double param, + double par = 0.0, bool type = false, bool firstSeg = true ); + + // \ru Работа с разрывами \en Working with breaks + // \ru Работа с разрывами при редактировании (сохранение фиксированной точки и длины) \en Working with breaks while editing (preserving of fixed point and length) + void SetBreaksFixedVars ( size_t segInd, size_t subInd, const MbCartPoint & newPoint ); + void TransformBreaks ( const MbMatrix & matr ); + + // \ru Удалить разрывы на сегментах контура, с соотв. базовым номером \en Delete breaks on segments of contour with corresponding base index + void DeleteBreaksAtBaseNumber ( size_t baseNumber, bool delTracingBreaks, bool delEquidBreaks, + bool delInLineSeg = true/*\ru Удалять ли разрывы с прямолинейных сегментов + \en Whether to remove breaks from straight segments \~*/ ); + + // \ru Функции восстановления разрывов по невидимым контурам \en Functions for recovering breaks by invisible contours + void GetBreaksInInvisContours( bool allBreaks, // \ru Удалять все разырвы \en Delete all breaks + size_t i, // \ru Номер вершины, специально для изменения типа обхода \en Index of vertex, specially for changing the type of traverse \~ + bool addContWbr, // \ru Набирать контуры с разрывами \en Collect contours with breaks + RPArray & breaksContours, + RPArray & invisContours ); + void AddBreaksByInvisContours( RPArray & breaksContours, + RPArray & invisContours ); + // \ru Для перестроения разрывов \en For breaks rebuilding + void GetBreaks ( RPArray & baseNumbers ); + void RebuildBreaks ( RPArray & baseNumbers ); + + /** \} */ +private: + void operator =( const MbMultiline & ); ///< \ru Не реализован \en Not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMultiline ) +}; // MbMultiline + +IMPL_PERSISTENT_OPS( MbMultiline ) + +//------------------------------------------------------------------------------ +// _7_ +/** \brief \ru Построить скругления мультилинии. + \en Construct a fillet of multiline. \~ + \details \ru Построить скругления базовой кривой мультилинии.\n + \en Construct a fillet of the base curve of multiline.\n \~ + \param[in] multiline - \ru Изменяемая мультилиния. + \en A multiline to be modified. \~ + \param[in] rad - \ru Радиус скругления. + \en The radius of fillet. \~ + \param[in] nodeFlag - \ru Флаг выбора скругляемых вершин:\n + true - скругление всех вершин мультилинии,\n + false - скругление ближайшей вершины к точке pnt. + \en Flag of selection of vertices to fillet:\n + true - fillet of all vertices of multiline,\n + false - fillet of the vertex nearest to 'pnt' point. \~ + \param[in] pnt - \ru Точка для указания нужной вершины. + \en Point for indication the required vertex. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \ingroup Algorithms_2D +*/ // --- +MATH_FUNC (bool) FilletMultiline ( MbMultiline & multiline, double rad, + bool nodeFlag, MbCartPoint & pnt, + const StVertexOfMultilineInfo & vertInfo ); + + +//------------------------------------------------------------------------------ +// _8_ +/** \brief \ru Построить фаски мультилинии. + \en Construct a chamfer of multiline. \~ + \details \ru Построить фаски базовой кривой мультилинии.\n + \en Construct a chamfer of the base curve of multiline.\n \~ + \param[in] multiline - \ru Изменяема мультилиния. + \en A multiline to be modified. \~ + \param[in] len - \ru Длина фаски. + \en Length of chamfer. \~ + \param[in] par - \ru Параметр в зависимости от типа type:\n + если type = true, par - угол,\n + если type = false, par - размер. + \en Parameter depending on 'type' type:\n + if type = true, par is a corner,\n + if type = false, par is a size. \~ + \param[in] type - \ru Тип задания фаски:\n + true - фаска задана как размер + угол,\n + false - фаска задана как размер + размер. + \en The type of a chamfer specification:\n + true - chamfer specified as size + angle,\n + false - chamfer specified as size + size. \~ + \param[in] nodeFlag - \ru Флаг выбора обрабатываемых вершин:\n + true - фаска между каждыми двумя соседними сегментами мультилинии,\n + false - фаска между двумя соседними сегментами мультилинии, примыкающими к ближайшей к точке pnt вершине. + \en Flag of selection of vertices to process:\n + true - chamfer between each two neighboring segments of multiline,\n + false - chamfer between two neighboring multiline segments joining at the vertex nearest to 'pnt' point. \~ + \param[in] pnt - \ru Точка для указания нужной пары сегментов. + \en Point for indication the required pair of segments. \~ + \param[in] vertInfo - \ru Информация для новых вершин мультилинии. + \en Information for new vertices of a multiline. \~ + \ingroup Algorithms_2D +*/ // --- +MATH_FUNC (bool) ChamferMultiline( MbMultiline & multiline, double len, double par, bool type, + bool nodeFlag, MbCartPoint & pnt, + const StVertexOfMultilineInfo & vertInfo ); + + +//////////////////////////////////////////////////////////////////////////////// +// +// _9_ +/// \ru Внеклассные функции расчета/учета радиусов кривизны (реализация в MltLine.cpp) \en Out-of-class functions for curvature radii calculation/consideration (implementation in MltLine.cpp) +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Учесть радиусы кривизны кривой. + \en Consider the curve curvature radii. \~ + \details \ru Учесть минимальный положительный и максимальный отрицательный радиусы кривизны кривой.\n + Для внутреннего использования. + \en Consider the curve curvature minimum positive and maximum negative radii.\n + For internal use only. \~ + \param[in] curve - \ru Кривая мультилинии. + \en A curve of multiline. \~ + \param[in] angle - \ru Угловая толерантность. + \en An angular tolerance. \~ + \param[in, out] minPos - \ru Радиус кривой, если он меньше текущего значения переменной minPos. + \en Curve radius if it is less than current value of 'minPos' variable. \~ + \param[in, out] maxNeg - \ru Радиус кривой, если он больше текущего значения переменной minPos. + \en Curve radius if it is greater than current value of 'minPos' variable. \~ + \ingroup Algorithms_2D +*/ // --- +void ToTakeIntoCurvesCrvRadii( MbCurve & curve, double angle, double & minPos, double & maxNeg ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Получить радиусы кривизны контура. + \en Get the contour curvatures radii. \~ + \details \ru Получить минимальный положительный и максимальный отрицательный радиусы кривизны контура.\n + Для внутреннего использования. + \en Get the contour curvature minimum positive and maximum negative radii.\n + For internal use only. \~ + \param[in] contour - \ru Контур. + \en A contour. \~ + \param[in] angle - \ru Угловая толерантность. + \en An angular tolerance. \~ + \param[out] minPos - \ru Минимальный радиус сегмента контура. + \en Minimal contour segment radius. \~ + \param[out] maxNeg - \ru Максимальный радиус сегмента контура. + \en Maximal contour segment radius. \~ + \ingroup Algorithms_2D +*/ // --- +void GetContoursCrvRadii( MbContour & contour, double angle, double & minPos, double & maxNeg ); + + +//------------------------------------------------------------------------------ +// _10_ +/** \brief \ru Состыковать две кривые. + \en Join two curves. \~ + \details \ru Гладко состыковать две последовательные кривые.\n + Для внутреннего использования. + \en Smoothly join two consecutive curves.\n + For internal use only. \~ + \param[in] curve1 - \ru Первая кривая. + \en The first curve. \~ + \param[in] curve2 - \ru Вторая кривая. + \en The second curve. \~ + \return \ru true, если хотя бы одна кривая была изменена. + \en True if at least one curve has been changed. \~ + \ingroup Algorithms_2D +*/ // --- +bool SmoothJointSuccessiveCurves( MbCurve & curve1, MbCurve & curve2 ); + + +//------------------------------------------------------------------------------ +// _11_ +/** \brief \ru Разбить мультилинию. + \en Split multiline. \~ + \details \ru Разбить мультилинию на две части. + \en Split multiline into two pieces. \~ + \param[in] multiline - \ru Разбиваемая мультилиния. + \en A multiline to be split. \~ + \param[in] p1 - \ru Точка разбиения или, если мультилиния замкнута, начальная точка для новой мультилинии. + \en Splitting point or start point of a new multiline if the multiline is closed. \~ + \param[in] p2 - \ru Если мультилиния замкнута, то конечная точка для новой мультилинии. + \en End point of a new multiline if the multiline is closed. \~ + \param[out] parts - \ru Массив полученных участков (2 элемента). + \en The array of obtained pieces (two elements). \~ + \ingroup Algorithms_2D +*/ // --- +MATH_FUNC (bool) BreakMultiline( const MbMultiline & multiline, + const MbCartPoint & p1, const MbCartPoint & p2, + PArray & parts ); + + +//------------------------------------------------------------------------------ +// _12_ +/** \brief \ru Разбить мультилинию. + \en Split multiline. \~ + \details \ru Разбить мультилинию на N равных частей. + \en Split multiline into N equal pieces. \~ + \param[in] multiline - \ru Разбиваемая мультилиния. + \en A multiline to be split. \~ + \param[in] partsCount - \ru Количество частей. + \en The count of pieces. \~ + \param[in] point - \ru Ограничивающая точка для замкнутой мультилинии. + \en Bounding point for closed multiline. \~ + \param[out] parts - \ru Массив полученных участков (partsCount элементов). + \en The array of obtained pieces (partsCount elements). \~ + \ingroup Algorithms_2D +*/ // --- +MATH_FUNC (bool) BreakMultilineNParts( const MbMultiline & multiline, size_t partsCount, + const MbCartPoint & point, PArray & parts ); + +// \ru LF-Linux: inline-функции следует помещать в заголовочный файл, а не cpp! \en LF-Linux: inline-functions should be placed in the header file instead of cpp! +//------------------------------------------------------------------------------- +/// \ru Вырождена ли мультилиния \en Whether the multiline is degenerate +// --- +inline bool MbMultiline::IsDegenerate( double lenEps ) const { + return ( (minNotDegInd == SYS_MAX_T) || // \ru Значит, и maxNotDegInd == SYS_MAX_T \en So maxNotDegInd == SYS_MAX_T + (basisCurve != NULL && basisCurve->IsDegenerate(lenEps)) ); +} + + +//------------------------------------------------------------------------------- +/// \ru Замкнутая ли мультилиния \en Whether the multiline is closed +// --- +inline bool MbMultiline::IsClosed() const { + return ( basisCurve->IsClosed() && processClosed && basisCurve->GetSegmentsCount() > 1 ); +} + + +//------------------------------------------------------------------------------- +/// \ru Получить ширину мультилинии \en Get width of multiline +// --- +inline double MbMultiline::GetWidth() const +{ + if ( minNotDegInd == maxNotDegInd ) + return 0.0; + else + return ( equidRadii[maxNotDegInd] - equidRadii[minNotDegInd] ); +} + +//------------------------------------------------------------------------------- +/// \ru Обход скруглением (одним из) \en Traverse by fillet (one of) +// --- +inline bool StVertexOfMultilineInfo::IsFilletTracing() const +{ + return ( tracingType == mvt_FilletType || tracingType == mvt_SpecFilletType ); +} + + +//------------------------------------------------------------------------------- +/// +// --- +inline bool StVertexOfMultilineInfo::operator ==( const StVertexOfMultilineInfo & with ) const +{ + return smoothJoint == with.smoothJoint && + tracingType == with.tracingType && + ::fabs(specFilletRad - with.specFilletRad) < EXTENT_REGION && + tipType == with.tipType && + firstSegTip == with.firstSegTip; +} + + +//------------------------------------------------------------------------------- +/// +// --- +inline bool StVertexOfMultilineInfo::operator !=( const StVertexOfMultilineInfo & with ) const +{ + return !(*this == with); +} + + +//------------------------------------------------------------------------------- +/// \ru Инициализация по объекту \en Initialization by object +// --- +inline void StVertexOfMultilineInfo::Init( const StVertexOfMultilineInfo & other ) +{ + smoothJoint = other.smoothJoint; + tracingType = other.tracingType; + specFilletRad = other.specFilletRad; + tipType = other.tipType; + firstSegTip = other.firstSegTip; +} + + +//------------------------------------------------------------------------------- +/// \ru Инициализация по параметрам \en Initialize by parameters +// --- +inline void StVertexOfMultilineInfo::Init( bool _smoothJoint, EnMLVertexTracingType _tracingType, + double _specFilletRad, EnMLInnerTipType _tipType, + bool _firstSegTip ) +{ + smoothJoint = _smoothJoint; + tracingType = _tracingType; + specFilletRad = _specFilletRad; + tipType = _tipType; + firstSegTip = _firstSegTip; +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить флаг "гладкий стык" (smoothJoint) \en Change flag "smooth joint" (smoothJoint) +// --- +inline bool StVertexOfMultilineInfo::ChangeSmoothJoint( bool othSmoothJoint ) +{ + if ( smoothJoint == othSmoothJoint ) + return false; + else { + smoothJoint = othSmoothJoint; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить тип обхода углов в вершине (tracingType) \en Change type of traverse of corners at a vertex (tracingType) +// --- +inline bool StVertexOfMultilineInfo::ChangeTracingType( EnMLVertexTracingType othTracingType ) +{ + if ( tracingType == othTracingType ) + return false; + else { + tracingType = othTracingType; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить радиус особого скругления (specFilletRad) \en Change radius of special fillet (specFilletRad) +// --- +inline bool StVertexOfMultilineInfo::ChangeSpecFilletRad( double othSpecFilletRad ) +{ + if ( ::fabs(specFilletRad - othSpecFilletRad) < Math::LengthEps ) + return false; + else { + specFilletRad = othSpecFilletRad; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить тип законцовки (tipType) \en Change type of tip (tipType) +// --- +inline bool StVertexOfMultilineInfo::ChangeTipType( EnMLInnerTipType othTipType ) +{ + if ( tipType == othTipType ) + return false; + else { + tipType = othTipType; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить флаг сегмента законцовки (isFirstSegTip) \en Change flag of segment of tip (isFirstSegTip) +// --- +inline bool StVertexOfMultilineInfo::ChangeFirstSegTip( bool othFirstSegTip ) +{ + if ( firstSegTip == othFirstSegTip ) + return false; + else { + firstSegTip = othFirstSegTip; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Преобразовать объект согласно матрице \en Transform an object according to the matrix +// --- +inline void StVertexOfMultilineInfo::Transform( const MbMatrix & matr ) +{ + matr.TransformScalarX( specFilletRad ); // \ru Преобразовать радиус \en Transform radius +} + + +//------------------------------------------------------------------------------- +/// +// --- +inline bool StMLTipParams::operator ==( const StMLTipParams & with ) const +{ + return (tipType == with.tipType ) && + ::fabs(tipParam - with.tipParam) < EXTENT_REGION; +} + + +//------------------------------------------------------------------------------- +/// +// --- +inline bool StMLTipParams::operator !=( const StMLTipParams & with ) const +{ + return !(*this == with); +} + + +//------------------------------------------------------------------------------- +/// \ru Инициализация \en Initialization +// --- +inline void StMLTipParams::Init( const StMLTipParams & other ) +{ + tipType = other.tipType; + tipParam = other.tipParam; +} + + +//------------------------------------------------------------------------------- +/// \ru Инициализация \en Initialization +// --- +inline void StMLTipParams::Init( EnMLTipType _tipType, double _tipParam ) +{ + tipType = _tipType; + tipParam = _tipParam; +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить тип законцовки (tipType) \en Change type of tip (tipType) +// --- +inline bool StMLTipParams::ChangeTipType( EnMLTipType othTipType ) +{ + if ( tipType == othTipType ) + return false; + else { + tipType = othTipType; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Изменить параметр законцовки (tipParam) \en Change parameter of tip (tipParam) +// --- +inline bool StMLTipParams::ChangeTipParam( double othTipParam ) +{ + if ( ::fabs(tipParam - othTipParam) < Math::LengthEps ) + return false; + else { + tipParam = othTipParam; + return true; + } +} + + +//------------------------------------------------------------------------------- +/// \ru Преобразовать объект согласно матрице \en Transform an object according to the matrix +// --- +inline void StMLTipParams::Transform( const MbMatrix & matr ) +{ + matr.TransformScalarX( tipParam ); // \ru Преобразовать расстояние \en Transform distance +} + + +#endif // __MULTILINE_H diff --git a/C3d/Include/name_check.h b/C3d/Include/name_check.h new file mode 100644 index 0000000..ce45618 --- /dev/null +++ b/C3d/Include/name_check.h @@ -0,0 +1,180 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Работа с топологическими именами объекта. + \en Treatment of object's topological names. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __NAME_CEHCK_H +#define __NAME_CEHCK_H + + +#include +#include +#include + + +class MATH_CLASS MbSNameMaker; + + +//------------------------------------------------------------------------------ +/** \brief \ru Сравнение точек в пространстве. + \en Points comparison in space. \~ + \details \ru Сравнение точек в пространстве с точностью Math::region: + по первой координате, по второй координате, по третьей координате. + \en Points comparison with precision Math::region: + in the first coordinate, in the second coordinate, in the third coordinate. \~ + \param[in] p1 - \ru Первая точка. + \en An first point. \~ + \param[in] p2 - \ru Множество граней. + \en Вторая точка. \~ + \return \ru Возвращает: -1, если p1 < p2; +1, если p1 > p2; 0, если p1 == p2. + \en Returns: -1 -if p1 < p2; +1 -if p1 > p2; 0 -if p1 == p2. \~ + \ingroup Names +*/ +// --- +inline int PointCompare3D ( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ) +{ + if ( p2.x + Math::region < p1.x ) // по X + return 1; + else if ( p1.x + Math::region < p2.x ) + return -1; + else { + if ( p2.y + Math::region < p1.y ) // по Y + return 1; + else if ( p1.y + Math::region < p2.y ) + return -1; + else { + if ( p2.z + Math::region < p1.z ) // по Z + return 1; + else if ( p1.z + Math::region < p2.z ) + return -1; + } + } + + return 0; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить имена элементам оболочки. + \en Set names for elements of shell. \~ + \details \ru Установить имена элементам оболочки: граням, ребрам, вершинам. + \en Set names for elements of shell: for faces, edges, vertices. \~ + \param[in] edges - \ru Множество ребер. + \en An array of edges. \~ + \param[in] faces - \ru Множество граней. + \en An array of faces. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] processVertexes - \ru Устанавливать ли имена вершинам. + \en Whether to set names to vertices. \~ + \ingroup Names +*/ +// --- +MATH_FUNC (void) SetShellNames( RPArray & edges, + const RPArray & faces, + const MbSNameMaker & nameMaker, + bool processVertexes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить имена элементам оболочки. + \en Set names for elements of shell. \~ + \details \ru Установить имена граням оболочки. + \en Set names for faces of shell. \~ + \param[in] faces - \ru Множество граней. + \en An array of faces. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \param[in] processVertexes - \ru Устанавливать ли имена вершинам. + \en Whether to set names to vertices. \~ + \ingroup Names +*/ +// --- +MATH_FUNC (void) SetFacesNames( const RPArray & faces, + const MbSNameMaker & nameMaker, + bool processVertexes ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить имена элементам оболочки. + \en Set names for elements of shell. \~ + \details \ru Установить имена элементам оболочки: граням, ребрам, вершинам. + \en Set names for elements of shell: for faces, edges, vertices. \~ + \param[in] shell - \ru Оболочка. + \en A shell. \~ + \param[in] nameMaker - \ru Именователь. + \en An object for naming the new objects. \~ + \ingroup Names +*/ +// --- +inline +void SetShellNames( MbFaceShell & shell, + const MbSNameMaker & nameMaker ) +{ + RPArray edges( 0, 1 ); + RPArray faces( 0, 1 ); + + shell.GetEdges( edges ); // \ru Получение массива ребер \en Get an array of edges + shell.GetFaces( faces ); + + ::SetShellNames( edges, faces, nameMaker, true ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Имя со счётчиком совпадений. + \en Name with hits counter. \~ + \details \ru Имя со счётчиком совпадений. \n + \en Name with hits counter. \n \~ + \ingroup Names +*/ +// --- +struct NameIntersectionInfo { + const MbName * name; ///< \ru Имя объектов. \en A name of objects. + size_t intersections; ///< \ru Количество совпадений. \en The count of coincidences. + + NameIntersectionInfo() : name( NULL ), intersections( 0 ) {} +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить имена на совпадение. + \en Check names for coincidence. \~ + \details \ru Проверить имена составляющих элементов оболочке на совпадение. \n + \en Check names of shell's components for coincidence. \n \~ + \param[in] shells - \ru Множество проверяемых оболочек. + \en An array of checked shells. \~ + \param[out] infos - \ru Множество совпадающих имен со счетчиком совпадений. + \en Array of coincident names with hits counter. \~ + \return \ru Возвращает true, если совпадающих имен не найдено. + \en Returns true if no coincident names found. \~ + \ingroup Names +*/ +// --- +MATH_FUNC (bool) CheckShellNames( const RPArray & shells, SArray & infos ); + + +//----------------------------------------------------------------------------- +/** \brief \ru Выбрать имя объединяемых ребер. + \en Select name for united edges. \~ + \details \ru Выбрать наиболее подходящее имя при объединении двух ребер, \n + новое имя будет установленно первому ребру. \n + \en Select the most suitable name while uniting two edges, \n + the new name will be set to the first edge. \n \~ + \param[in,out] edge1 - \ru Первое ребро. + \en The first edge. \~ + \param[in] edge2 - \ru Второе ребро. + \en The second edge. \~ + \param[in] version - \ru Версия исполнения. + \en The version. \~ + \ingroup Names +*/ +//--- +MATH_FUNC (void) CombineNames( MbCurveEdge & edge1, const MbCurveEdge & edge2, VERSION version ); + + +#endif // __NAME_CEHCK_H diff --git a/C3d/Include/name_contour_tree.h b/C3d/Include/name_contour_tree.h new file mode 100644 index 0000000..d1d835f --- /dev/null +++ b/C3d/Include/name_contour_tree.h @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Дерево именованых контуров. + \en The tree of named contours. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __NAME_CONTOUR_TREE_H +#define __NAME_CONTOUR_TREE_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Дерево именованных контуров. + \en The tree of named contours. \~ + \details \ru Дерево именованных контуров.\n + \en The tree of named contours.\n \~ + \ingroup Names +*/ +// --- +class MATH_CLASS MbNamedContoursTree { +private: + const MbContour * contour; // \ru Самый внешний контур \en The most external contour + bool own; // \ru Владение контуром \en Ownership of contour + PArray children; // \ru Внутренние контуры \en All inner contours + bool intersectChildren; // \ru Пересекаются ли внутренние контуры \en Are inner contours intersect +public: + /// \ru Конструктор. \en Constructor. + MbNamedContoursTree( const MbContour * con = NULL, bool o = true ); + /// \ru Деструктор. \en Destructor. + ~MbNamedContoursTree(); +public: + /// \ru Сформировать дерево. \en Form the tree. + void FillTree ( RPArray & comContours, double eps, VERSION version ); + /// \ru Получить количество деревьев. \en Get count of trees. + size_t GetChildrenCount() const { return children.Count(); } + /// \ru Получить дерево контуров по индексу. \en Get contour tree by an index. + const MbNamedContoursTree * GetTreeContour( size_t index ) const { return (GetChildrenCount() >= index) ? children[index] : NULL; } + /// \ru Проверить группы контуров на не пересечение. \en Check groups of contours for absence of intersection. + MbResultType CheckProfiles( bool base ) const; + /// \ru Получить указатель на внешний контур. \en Get the pointer to the external contour. + const MbContour * GetContour() const { return contour; } + // \ru Пересекаются ли внутренние контуры \en Are inner contours intersect + bool AreChildrenIntersect() const { return intersectChildren; } + +private: + void FillItem( const RPArray & sortContours, double eps, bool contoursEqual ); + void AddChild( const MbContour &, const RPArray &, size_t, double eps, bool contoursEqual ); // \ru добавить элемент в дерево \en add element to the tree + bool IsExistContour( const MbContour & ) const; // \ru существует в дереве такой контур \en whether there is such a contour in the tree + void GetCountInOneNode( const MbNamedContoursTree & tCont, size_t & countTmp ) const; +private: + MbNamedContoursTree( const MbNamedContoursTree & ); // \ru не реализовано \en not implemented + void operator = ( const MbNamedContoursTree & ); // \ru не реализовано \en not implemented +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать самый большой контур. + \en Get the biggest contour. \~ + \details \ru Выдать самый большой контур по длине диагонали габарита. + \en Get the biggest contour by bounding box diagonal length. \~ + \return \ru Возвращает указатель на найденный контур или NULL. + \en Returns pointer to the found contour or NULL. \~ + \ingroup Names +*/ +// --- +MATH_FUNC (MbContour *) FindBigContour( const RPArray & contours ); + + +#endif // __NAME_CONTOUR_TREE_H diff --git a/C3d/Include/name_flags.h b/C3d/Include/name_flags.h new file mode 100644 index 0000000..c196596 --- /dev/null +++ b/C3d/Include/name_flags.h @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Общий интерфейс для работы с битовыми флагами. + \en Common interface for bit-flags treatment. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __NAME_FLAGS_H +#define __NAME_FLAGS_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Предоставляет общий интерфейс для работы с битовыми флагами. + \en Provides the common interface for bit-flags treatment. \~ + \details \ru Это почти копия ItFlags, но весь inline и без виртуальных функций. \n + \en It is almost the copy of 'ItFlags' but is 'inline' and without virtual functions. \n \~ + \ingroup Base_Items +*/ +// --- +class MATH_CLASS MbFlags { + uint8 flags; + +public: + /// \ru Конструктор. \en Constructor. + MbFlags( uint8 f = 0 ) : flags(f) {} + /// \ru Установить битовые флаги. \en Set the bit-flags. + void SetFlagValue( uint8 mask, bool set = true ) { set ? flags |= mask : flags &= (uint8)(~mask); } + /// \ru Получить битовые флаги. \en Get the bit-flags. + uint8 GetFlagValue( uint8 mask = 0xff ) const { return flags & mask; } + /// \ru Установить все битовые флаги. \en Set all bit-flags. + void InitFlags( uint8 f = 0 ) { flags = f; } + /// \ru Получить все битовые флаги. \en Get all bit-flags. + uint8 GetFlags() const { return flags; } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbFlags ) +}; + + +#endif // __NAME_FLAGS_H diff --git a/C3d/Include/name_item.h b/C3d/Include/name_item.h new file mode 100644 index 0000000..49becf6 --- /dev/null +++ b/C3d/Include/name_item.h @@ -0,0 +1,1350 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Имя топологического объекта. + \en A name of a topological object. \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __NAME_ITEM_H +#define __NAME_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbProperties; +class MATH_CLASS MbName; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Поменять местами. + \en Swap. \~ + \details \ru Поменять местами. \n + \en Swap. \n \~ + \ingroup Names +*/ +// --- +template +inline void SwapIT( IntegralType & a, IntegralType & b ) { a^=b; b^=a; a^=b; } + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Размер SimpleName. + \en Size of SimpleName. \~ + \details \ru Размер SimpleName. \n + \en Size of SimpleName. \n \~ + \ingroup Names +*/ +// --- +const size_t sizeofSimpleName = sizeof( SimpleName ); + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Множество простых имен. \en Set of simple names. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Множество простых имен. + \en Set of simple names. \~ + \details \ru Множество содержит контейнер простых имен. \n + \en The set contains the container of simple names. \n \~ + \ingroup Names +*/ +// --- +class SimpleNameArray { +private: + SArray m_array; ///< \ru Множество простых имен. \en Array of simple names. + +public: + /// \ru Конструктор. \en Constructor. + SimpleNameArray( size_t i_max = 0, uint16 i_delta = 1 ) : m_array( i_max, i_delta ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + SimpleNameArray( const SimpleNameArray & other ) : m_array( other.m_array ) {} + +public: + /// \ru Установить приращение по количеству элементов при выделении дополнительной памяти (1 - автоприращение). \en Set an increment by the number of elements while allocating additional memory (1 - autoincrement). + void Delta( uint16 newDelta ) { m_array.Delta( newDelta ); } + /// \ru Установить максимальное из приращений. \en Set maximum of increments. + void SetMaxDelta( uint16 newDelta ) { m_array.SetMaxDelta( newDelta ); } + /// \ru Количество элементов в массиве. \en Count of elements in array. + size_t Count() const { return m_array.Count(); } + /// \ru Индекс последнего элемента. \en The last element index. + ptrdiff_t MaxIndex() const { return m_array.MaxIndex(); } + + /// \ru Зарезервировать память под указанное количество элементов. \en Reserve memory for the specified number of elements. + void Reserve( size_t additionalSpace ) { m_array.Reserve( additionalSpace ); } + /// \ru Удалить все элементы в массиве без освобождения памяти. \en Delete all elements from the array without freeing memory. + void Flush() { m_array.Flush(); } + /// \ru Освободить неиспользуемую память. \en Free unused memory. + void Adjust() { m_array.Adjust(); } + + /// \ru Получить адрес начала массива. \en Get address of the beginning of the array. + const SimpleName * GetAddr() const { return (SimpleName *)m_array.GetAddr(); } + + /// \ru Получить элемент по индексу. \en Get element by an index. + SimpleName & operator []( size_t loc ) const { return m_array[loc]; } + + /// \ru Вставить элемент по индексу. \en Insert element by an index. + SimpleName * AddAt( const SimpleName & ent, size_t index ) { return m_array.AddAt( ent, index ); } + /// \ru Вставить хэш имени по индексу. \en Insert name hash by an index. + SimpleName * AddAt( const MbName & ent, size_t index ); + /// \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + SimpleName * Add ( const SimpleName & ent ) { return m_array.Add( ent ); } + /// \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + SimpleName * Add ( const MbName & ent ); + + /// \ru Удалить элемент по индексу. \en Delete element by an index. + void RemoveInd( size_t delIndex ) { m_array.RemoveInd(delIndex); } + /// \ru Удалить элементы начиная с индекса firstIdx до lastIdx-1 включительно. \en Delete elements in range from firstIdx to lastIdx-1 inclusive. + void RemoveInd( size_t firstIdx, size_t lastIdx ) { m_array.RemoveInd(firstIdx, lastIdx); } + + /// \ru Вставить элемент по индексу. \en Insert element by an index. + SimpleName * InsertInd( size_t index, const SimpleName & ent ) { return m_array.InsertInd( index, ent ); } + /// \ru Вставить хэш имени по индексу. \en Insert name hash by an index. + SimpleName * InsertInd( size_t index, const MbName & ent ); + + /// \ru Найти объект среди элементов массива. \en Find object among elements of the array. + size_t FindIt( const SimpleName & ent ) const { return m_array.FindIt( ent ); } + + /// \ru Оператор добавления. \en Operator for adding. + SimpleNameArray & operator += ( const SimpleNameArray & other ) { m_array += other.m_array; return *this; } + /// \ru Оператор добавления. \en Operator for adding. + friend SArray & operator += ( SArray &, const SimpleNameArray & ); + + /// \ru Оператор чтения. \en Read operator. + friend reader & operator >> ( reader &, SimpleNameArray *& ); + /// \ru Оператор чтения. \en Read operator. + friend reader & operator >> ( reader &, SimpleNameArray & ); + /// \ru Оператор записи. \en Write operator. + friend writer & operator << ( writer &, const SimpleNameArray & ); +}; + +//---------------------------------------------------------------------------------------- +/// \ru Чтение с выделением памяти: nArr = new SimpleNameArray(); \en Reading with memory allocation: nArr = new SimpleNameArray(); +// --- +reader & operator >> ( reader & in, SimpleNameArray *& nArr ); + +//---------------------------------------------------------------------------------------- +/// \ru Чтение. \en Reading. +// --- +inline reader & operator >> ( reader & in, SimpleNameArray & ref ) +{ + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + if ( in.good() && count ) { + ref.m_array.SetSize( count, true/*clear*/ ); + for ( size_t i = 0; i < count && in.good(); ++i ) { + SimpleName item( ReadSimpleName( in ) ); + ref.Add( item ); + } + } + return in; +} + +//---------------------------------------------------------------------------------------- +/// \ru Запись. \en Writing. +// --- +inline writer & operator << ( writer & out, const SimpleNameArray & ref ) +{ + size_t count = ref.Count(); + ::WriteCOUNT( out, count ); + for ( size_t i = 0; i < count && out.good(); ++i ) + ::WriteSimpleName( out, ref.m_array[i] ); + return out; +} + +//---------------------------------------------------------------------------------------- +/// Hash32 +// --- +inline SimpleName Hash32( const SimpleNameArray & snArr ) { + return (SimpleName)::Hash32( (uint8 *)snArr.GetAddr(), snArr.Count() * sizeofSimpleName ); +} + +//---------------------------------------------------------------------------------------- +/// \ru Оператор конкатенации. \en Concatenation operator. +// --- +inline SArray & operator += ( SArray & array, const SimpleNameArray & other ) +{ + array += other.m_array; + return array; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Укороченное множество простых имен. \en Truncated set of simple names. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Укороченное множество простых имен. + \en Truncated set of simple names. \~ + \details \ru Укороченное множество простых имен состоит из базовых и обычных элементов. \n + \en Truncated set of simple names consists of basic and ordinary elements. \n \~ + \ingroup Names +*/ +// --- +struct MATH_CLASS MbIdArr : private LiSArray +{ + friend class MbName; +private: + uint16 countBase; ///< \ru Количество элементов в базовой части. \en The count of elements in base part. + mutable SimpleName hash; ///< \ru Хэш множества простых имен. \en The hash of simple names` set. +protected://public: + MbFlags flags; ///< \ru Флаги. \en Flags. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbIdArr() : LiSArray(), countBase(0), hash(SIMPLENAME_MAX), flags() {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbIdArr( const MbIdArr & o ) : LiSArray(o), countBase(o.countBase), hash( o.hash ), flags(o.flags) {} + +public: + SimpleName Hash() const; ///< \ru Вычислить хэш себя. \en Calculate hash of itself. + void FlashHash() { hash = SIMPLENAME_MAX; } ///< \ru Сбросить свой хэш. \en Reset hash value. + + size_t CountAll() const { return Count(); } ///< \ru Дать количество элементов массива. \en Get the number of elements in the array. + size_t CountBase() const { return countBase; } ///< \ru Дать количество элементов массива в базовой части. \en Get the number of elements in base part. + + /// \ru Обнулить количество элементов \en Set the number of elements to null + void Flush () { LiSArray::Flush(); countBase = 0; hash = SIMPLENAME_MAX; } + + bool IsEmpty () const; ///< \ru Множество пуст? \en Is the array empty? + bool GetCut ( SimpleName & cutIndex ) const; ///< \ru Получение индекса разрезки. \en Get an index of a cutaway. + void SetCopyIndex( SimpleName ci ); ///< \ru Установка индекса копирования. \en Set an index of copying. + bool GetCopyIndex( SimpleName & ci ) const; ///< \ru Получение индекса копирования. \en Get an index of copying. + size_t SizeOf() const; ///< \ru Размер в памяти. \en Size in memory. + + /// \ru Добавить основной элемент в конец массива. \en Add main element to the end of the array. + SimpleName * AddBase ( const SimpleName & ent ) { FlashHash(); return InsertInd( countBase++, ent ); } + /// \ru Добавить дополнительный элемент в конец массива. \en Add additional element to the end of the array. + SimpleName * AddExtra ( const SimpleName & ent ) { FlashHash(); return Add( ent ); } + /// \ru Удалить основное элемент из массива. \en Delete main element from the array. + void RemoveIndBase ( size_t delIndex ) { C3D_ASSERT(delIndex < countBase); RemoveInd( delIndex ); countBase--; FlashHash(); } + /// \ru Удалить дополнительный элемент из массива. \en Delete additional element from the array. + void RemoveIndExtra( size_t delIndex ) { C3D_ASSERT(delIndex >= countBase); RemoveInd( delIndex ); FlashHash(); } + /// \ru Получить основное простое имя по индексу. \en Get main simple name by an index. + const SimpleName & GetValueBase( size_t index ) const { C3D_ASSERT(index=countBase && index=countBase && index::operator = ( other ); countBase = other.countBase; hash = other.hash; flags = other.flags; } + /// \ru Функция присваивания (без копирования флагов). \en Assignment function (without copying of flags). + void Assign( const MbIdArr & other ) { LiSArray::operator = ( other ); countBase = other.countBase; hash = other.hash; } + + /// \ru Получить адрес массива. \en Get address of the array. + using LiSArray::GetAddr; + +KNOWN_OBJECTS_RW_REF_OPERATORS( MbIdArr ) +}; + +//---------------------------------------------------------------------------------------- +// \ru Вычислить хэш себя. \en Calculate hash of itself. +// --- +inline SimpleName MbIdArr::Hash() const +{ + if ( hash == SIMPLENAME_MAX ) + hash = ::Hash32( (uint8*)parr, count * sizeofSimpleName/*4*/ ); + return hash; +} + +//---------------------------------------------------------------------------------------- +// \ru Размер в памяти \en Size in memory +// --- +inline size_t MbIdArr::SizeOf() const +{ + size_t size = sizeof(MbFlags); + size += sizeof(LiSArray) + Count() * sizeofSimpleName; //-V119 + size += sizeofSimpleName; + return size; +} + +//---------------------------------------------------------------------------------------- +// +// --- +inline void MbIdArr::operator += ( const MbIdArr & other ) +{ + C3D_ASSERT( CountAll() == CountBase() ); + if ( CountAll() == CountBase() ) { + LiSArray::operator += ( other ); + flags = other.flags; + + C3D_ASSERT( (countBase + other.countBase) <= SYS_MAX_UINT16 ); // \ru Превышение размерности uint16 \en Exceeding of size of uint16 + countBase = (uint16)(countBase + other.countBase); + FlashHash(); + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Имя объекта. \en A name of an object. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Имя объекта. + \en A name of an object. \~ + \details \ru Имя топологического объекта (автоматически генерируемый атрибут). \n + Не используйте главные имена из диапазона MbName::ReservedMainNames (исключение - MbName::ReservedMainNames::rmn_DefaultName). \n + \en A name of a topological object (automatically generated attribute). \n + Do not use the main names from the range MbName::ReservedMainNames (exception - MbName::ReservedMainNames::rmn_DefaultName). \n \~ + \ingroup Names +*/ // --- +class MATH_CLASS MbName { +public: + typedef std_unique_ptr UniqueNamePtr; + +public : + /// \ru Индекс имени. \en A name index. + enum EIndexes + { // v e f + // i_Main, // * * * + // i_First, // * * * + // i_Cut, // - + + + // i_Copy, // - - + + // i_Extra, // - - + + i_Main, ///< \ru Индекс главного имени. \en Main name index. + i_First, ///< \ru Индекс уникального имени, содержащего в себе hash, построенный по жестким правилам. \en Index of unique name which includes hash constructed by strict rules. + i_Cut, ///< \ru Индекс индекса разрезанности. \en Index of index of cutaway. + i_Copy, ///< \ru Индекс индекса копирования. \en Index of index of copying. + i_Extra, ///< \ru Индекс предыдущего hash'a копирования. \en Index of previous hash of copying. + i_PseudoCopy = -1, ///< \ru Индекс псевдо копирования. \en Index of pseudo copying. + }; + /// \ru Основной индекс имени. \en Main index of name. + enum BaseNameIndex + { // v e f + // bni_Main, // * * * + // bni_First, // * * * + // bni_Cut, // - + + + bni_Main, ///< \ru Индекс главного имени. \en Main name index. + bni_First, ///< \ru Индекс уникального имени, содержащего в себе hash, построенный по жестким правилам. \en Index of unique name which includes hash constructed by strict rules. + bni_Cut, ///< \ru Индекс индекса разрезанности (может нести признак разрезанности). \en Index of index of cutaway (can indicate to cutaway). + bni_Total, ///< \ru Максимальное размер базовой части имени. \en Maximum size of base part of name. + }; + /// \ru Дополнительный индекс имени. \en Additional index of name. + enum ExtraNameIndex + { // v e f + // eni_Copy, // - - + + // eni_Extra, // - - + + eni_Copy, ///< \ru Индекс индекса копирования. \en Index of index of copying. + eni_Extra, ///< \ru Индекс предыдущего hash'a копирования. \en Index of previous hash of copying. + eni_Total, ///< \ru Периодичность структуры индексов. \en Periodicity of structure of indices. + }; + /// \ru Зарезервированные главные имена. \en Reserved main names. + enum ReservedMainNames + { + rmn_EmergencyName = -5, ///< \ru Системное аварийное имя для замены. \en Emergency name for replacing. + rmn_DummyFaceName = -4, ///< \ru Системное имя фиктивной грани. \en Default name of dummy face. + rmn_ReservedName = -3, ///< \ru Системное имя резервное. \en Reserved name. + rmn_SectionItemName = -2, ///< \ru Системное имя секущего объекта. \en Section item name. + rmn_DefaultName = -1, ///< \ru Системное имя по умолчанию (= SIMPLENAME_MAX). \en Default name (= SIMPLENAME_MAX). + }; + // The name -2 is also reserved for system names in the Kompas CAD. + +protected: + /// \ru Флаги. \en Flags. + enum EFlags { + f_Cut = 0x01, ///< \ru Примитив разрезан. \en Primitive is cut. + f_Sheet = 0x02, ///< \ru Примитив является листовым. (Действителен только для граней) \en Primitive is sheet. (Valid only for faces) + f_InnerBend = 0x04, ///< \ru Примитив является внутренней гранью сгиба. (Действителен только для граней) //-V112 \en Primitive is an internal face of bend. (Valid only for faces) //-V112 + f_OuterBend = 0x08, ///< \ru Примитив является внешней гранью сгиба. (Действителен только для граней) \en Primitive is an external face of bend. (Valid only for faces) + f_SideBend = 0x10, ///< \ru Примитив является боковой гранью сгиба. (Действителен только для граней) \en Primitive is a side face of bend. (Valid only for faces) + f_RibBend = 0x20, ///< \ru Примитив является гранью ребра жесткости листового тела. (Действителен только для граней) \en Primitive is a face of reinforcement rib of sheet solid. (Valid only for faces) + }; + +protected: + MbIdArr defNames; ///< \ru Множество идентификаторов. \en An array of identifiers. + +public: + static const UniqueNamePtr uniqueFaceName; ///< \ru Уникальное имя фиктивной грани. \en Unique name of dummy face. + +public : + /// \ru Конструктор по умолчанию \en Default constructor + MbName() : defNames() {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbName( const MbName & other ) : defNames( other.defNames ) {} + /// \ru Деструктор. \en Destructor. + virtual ~MbName(); +public: + + /// \ru Получить главное имя. \en Get main name. + SimpleName GetMainName() const; + /// \ru Установить главное имя. \en Set main name. + bool SetMainName( SimpleName n ); + /// \ru Установить имя. \en Set name. + void SetName ( const MbName &, bool setFlags = true ); + + /// \ru Пуст ли массив идентификаторов имени. \en Whether the array of name identifiers is empty. + bool IsEmpty () const { return defNames.IsEmpty(); } + ///< \ru Очистить массив идентификаторов имени. \en Clear array of name identifiers. + void SetEmpty () { defNames.Flush(); } + + /// \ru Дать количество элементов массива. \en Get the number of elements in array. + size_t CountAll () const { return defNames.CountAll(); } + /// \ru Дать количество элементов массива в базовой части. \en Get the number of array elements in base part. + size_t CountBase () const { return defNames.CountBase(); } + + /// \ru Извлечь имена в массив. \en Extract names into array. + void AddNamesBase( SimpleNameArray & to ) const; + + /// \ru Дать или сгенерировать основное имя. \en Get or generate the main name. + SimpleName GetNameBase ( size_t i ) const; + /// \ru Дать или сгенерировать дополнительное имя. \en Get or generate the additional name. + SimpleName GetNameExtra( size_t i ) const; + + ///< \ru Получение индекса разрезки. \en Get an index of a cutaway. + bool IsCutIndex() const; + /// \ru Получение индекса разрезки. \en Get an index of a cutaway. + bool GetCutIndex( SimpleName & cutIndex ) const { return defNames.GetCut( cutIndex ); } + /// \ru Установка индекса разрезки. \en Set an index of cutaway. + void SetCutIndex( SimpleName cutIndex ); + /// \ru Удаление индекса разрезки. \en Delete an index of cutaway. + bool RemoveCutIndex(); + + /// \ru Получить первое имя. \en Get first name. + SimpleName GetFirstName() const { return (defNames.CountBase() > (size_t)i_First) ? defNames.GetValueBase((size_t)i_First) : -1; } + /// \ru Прямой доступ к первому имени. \en Direct access to the first name. + SimpleName GetFirstNameDirect() const { C3D_ASSERT(defNames.CountBase() > (size_t)i_First); return defNames.GetValueBase((size_t)i_First); } + /// \ru Прямой доступ к первому имени. \en Direct access to the first name. + void SetFirstNameDirect( SimpleName fi ) { C3D_ASSERT(defNames.CountBase() > (size_t)i_First); defNames.SetValueBase(fi, (size_t)i_First); } + + /// \ru Получение значения флага порезанности. \en Get flag of cutaway. + bool IsCutFlag() const; + /// \ru Установление значения флага порезанности. \en Set flag of cutaway. + void SetCutFlag( bool s = true ); + + /// \ru Установление значения флага листового примитива. \en Set flag of sheet primitive. + void SetSheet( bool s ); + /// \ru Установка значения флага внутренней части сгиба. \en Set flag of internal part of bend. + void SetInnerBend( bool s ); + /// \ru Установка значения флага внешней части сгиба. \en Set flag of external part of bend. + void SetOuterBend( bool s ); + /// \ru Установка значения флага боковой грани сгиба. \en Set flag of side part of bend. + void SetSideBend( bool s ); + /// \ru Установка значения флага грани ребра жесткости листового тела. \en Set flag of reinforcement rib part of sheet solid. + void SetStampRibBend( bool s ); + /// \ru Получение значения флага листового примитива. \en Get flag of sheet primitive. + bool IsSheet() const; + /// \ru Получение значения флага внутренней части сгиба. \en Get flag of internal part of bend. + bool IsInnerBend() const; + /// \ru Получение значения флага внешней части сгиба. \en Get flag of external part of bend. + bool IsOuterBend() const; + /// \ru Получение значения флага боковой грани сгиба. \en Get flag of side part of bend. + bool IsSideBend() const; + /// \ru Получение значения флага грани ребра жесткости листового тела. \en Get flag of reinforcement rib part of sheet solid. + bool IsStampRibBend() const; + + /// \ru Установка индекса копирования. \en Set an index of copying. + void SetCopyIndex( SimpleName ci ) { defNames.SetCopyIndex( ci ); } + /// \ru Получение индекса копирования. \en Get an index of copying. + bool GetCopyIndex( SimpleName & ci ) const { return defNames.GetCopyIndex( ci ); } + + /** \brief \ru Установить положение в сетке копирования. + \en Set a position in grid of copying. \~ + \details \ru Установить положение копии в сетке копирования при размножении объекта по прямоугольной или концентрической сетке. \n + \en Set a copy position in the copy grid when the object is reproduced on a rectangular or concentric grid. \n \~ + \param[in] row - \ru Индекс ряда. + \en Index of row. \~ + \param[in] col - \ru Индекс солонки. + \en Index of column. \~ + \return \ru true - если индекс установлен, иначе - false. + \en true, if the copy position was set, otherwise false. \~ */ + bool SetCopyPosition( size_t row, size_t col ); + + /** \brief \ru Выдать положение в сетке копирования. + \en Get position in grid of copying. \~ + \details \ru Выдать положение копии в сетке копирования при размножении объекта по прямоугольной или концентрической сетке. \n + \en Get a copy position in the copy grid when the object is reproduced on a rectangular or concentric grid. \n \~ + \param[out] row - \ru Индекс ряда. + \en Index of row. \~ + \param[out] col - \ru Индекс солонки. + \en Index of column. \~ + \return \ru true - если положение копии было найдено, иначе - false. + \en true, if the copy position was find, otherwise false. \~ */ + bool GetCopyPosition( ptrdiff_t & row, ptrdiff_t & col ); + + /// \ru Можно ли получить индексы копирования. \en Whether the indices of copying can be obtained. + bool IsCopied() const { return defNames.CountAll() > defNames.CountBase(); } + + /// \ru Выдать главное имя источника для копирования, вызывать только после проверки - IsCopied(); \en Get the main name of source for copying, to be called only after check by IsCopied(); + SimpleName GetCopySourceName() const { return defNames.GetValueExtra( CountAll() - 1 ); } + /** \brief \ru Получить массив индексов копирования. + \en Get array of copying indices. \~ + \details \ru Получить заданное количество индексов копирования в обратном порядке. + Если запросить больше чем есть - не даст ничего. \n + \en Get the given count of copying indices in reverse order. + If requested more than exist, then nothing will be returned. \n \~ + \param[out] indexes - \ru Множество индексов копирования. + \en Array of copying indices. \~ + \param[in,out] count - \ru Количество запрашиваемых индексов [in], количество полученных индексов [out]. + \en Count of the requested indices [in], count of the obtained indices [out]. \~ + */ + void GetCopyIndices( SArray & indexes , size_t & count ) const; + + /// \ru Вычислить хэш себя. \en Calculate hash of itself. + SimpleName Hash() const { return defNames.Hash(); } + /// \ru Оператор равенства. \en An equality operator. + bool operator == ( const MbName & ) const; + /// \ru Оператор сравнения. \en Comparison operator. + bool operator < ( const MbName & ) const; + /// \ru Оператор неравенства. \en Inequality operator. + bool operator != ( const MbName & n ) const { return !( operator == (n) ); } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + /// \ru Преобразовать имя в строку. \en Convert name to string. + void ToString( c3d::string_t & strName ) const; + /// \ru Преобразовать в имя из строки. \en Convert name from string. + void FromString( const c3d::string_t & strName ); + /// \ru Размер в памяти. \en Size in memory. + size_t SizeOf() const { return defNames.SizeOf(); } + +//private: + /// \ru Оператор присваивания. \en An assignment operator. + void operator = ( const MbName & other ) { defNames = other.defNames; } + +public: + /// \ru Функция присваивания (без копирования флагов). \en Assignment function (without copying of flags). + void Assign( const MbName & other ) { defNames.Assign( other.defNames ); } + + /// \ru Сделать из имени шаблон. \en Create template from name. + void MakeTemplate() { + C3D_ASSERT( defNames.CountBase() ); + if ( defNames.CountBase() > (size_t)i_First ) { + SetFirstNameDirect( 0 ); + if ( defNames.CountBase() > (size_t)i_Cut ) SetCutIndex( 0 ); + } + else + defNames.AddBase( 0 ); + C3D_ASSERT( *this != *uniqueFaceName ); + } + + /// \ru Уникальное имя фиктивной грани. \en Unique name of dummy face. + static UniqueNamePtr UniqueFaceName() + { + UniqueNamePtr name( new MbName ); + name->defNames.AddBase( static_cast(rmn_DummyFaceName) ); // i_Main + name->defNames.AddBase( 0 ); // i_First + return name; + } + + friend class MATH_CLASS MbNameMaker; + friend class MATH_CLASS MbSNameMaker; + friend MATH_FUNC (int) MbDefNameCompare ( const MbName & n1, const MbName & n2 ); + friend MATH_FUNC (int) MbMemDefNameCompare( const MbName & n1, const MbName & n2 ); + +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbName, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//---------------------------------------------------------------------------------------- +// +// --- +inline bool MbIdArr::IsEmpty() const { + // \ru IsEmpty проверять parr[MbName::i_Main] только для count == 1 \en IsEmpty check parr[MbName::i_Main] only for count == 1 + // \ru Если count > 1 - считать не пустым \en If count > 1, then it is considered as non-empty + return ( Count() > (size_t)MbName::i_Main ) ? ( (Count() - 1) == (size_t)MbName::i_Main ? !parr[(size_t)MbName::i_Main] : false ) : true; +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение индекса разрезки \en Get an index of a cutaway +// --- +inline bool MbIdArr::GetCut( SimpleName & cutIndex ) const +{ + if ( Count() > (size_t)MbName::i_Cut ) { + cutIndex = parr[(size_t)MbName::i_Cut]; + return true; + } + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение индекса копирования \en Get an index of copying +// --- +inline bool MbIdArr::GetCopyIndex( SimpleName & ci ) const +{ + if ( Count() > (size_t)MbName::i_Copy ) { + ci = parr[(size_t)MbName::i_Copy]; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Получить главное имя. \en Get main name. +// --- +inline SimpleName MbName::GetMainName() const +{ + if ( defNames.CountBase() > (size_t)i_Main ) + return defNames.GetValueBase( (size_t)i_Main ); + return 0; +} + + +//------------------------------------------------------------------------------ +// \ru Установить главное имя. \en Set main name. +// --- +inline bool MbName::SetMainName( SimpleName n ) +{ + bool res = true; + if ( static_cast(rmn_DummyFaceName) == n ) { // Reserved for unique name of dummy face (-1 = SIMPLENAME_MAX, -2 is already used for Kompas CAD and It's the error on their side) + n = static_cast(rmn_EmergencyName); + C3D_ASSERT_UNCONDITIONAL( false ); + res = false; + } + + if ( defNames.CountBase() > 0 ) + defNames.SetValueBase( n, 0 ); + else + defNames.AddBase( n ); + + return res; +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка на равенство. \en Check for equality. +// --- +inline bool MbName::operator == ( const MbName & n ) const +{ + if ( defNames.CountAll() == n.defNames.CountAll() ) { + if ( defNames.CountAll() ) { + // C3D-510 return (::memcmp( defNames.GetAddr(), n.defNames.GetAddr(), defNames.CountAll() * sizeofSimpleName ) == 0); + return (defNames.Hash() == n.defNames.Hash()); + } + return true; + } + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Проверка не неравенство. \en Check for inequality. +// --- +inline bool MbName::operator < ( const MbName & n ) const +{ + if ( defNames.CountAll() == n.defNames.CountAll() ) { + if ( defNames.CountAll() ) { + if ( defNames.Hash() != n.defNames.Hash() ) // C3D-510 + return (::memcmp( defNames.GetAddr(), n.defNames.GetAddr(), defNames.CountAll() * sizeofSimpleName ) < 0); + } + return false; + } + else if ( defNames.CountAll() < n.defNames.CountAll() ) + return true; + + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение индекса разрезки. \en Get an index of a cutaway. +// --- +inline bool MbName::IsCutIndex() const +{ + SimpleName cutIndex = 0; + if ( GetCutIndex( cutIndex ) ) + return ::IsGoodSimpleName( cutIndex ); + return false; +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага порезанности. \en Get flag of cutaway. +// --- +inline bool MbName::IsCutFlag() const { + return !!defNames.flags.GetFlagValue( f_Cut ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага порезанности. \en Set flag of cutaway. +// --- +inline void MbName::SetCutFlag( bool s ) { + defNames.flags.SetFlagValue( f_Cut, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага листового примитива. \en Set flag of sheet primitive. +// --- +inline void MbName::SetSheet( bool s ) { + defNames.flags.SetFlagValue( f_Sheet, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага листового примитива. \en Get flag of sheet primitive. +// --- +inline bool MbName::IsSheet() const { + return !!defNames.flags.GetFlagValue( f_Sheet ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага внутренней части сгиба. \en Set flag of internal part of bend. +// --- +inline void MbName::SetInnerBend( bool s ) { + defNames.flags.SetFlagValue( f_InnerBend, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага внутренней части сгиба. \en Get flag of internal part of bend. +// --- +inline bool MbName::IsInnerBend() const { + return !!defNames.flags.GetFlagValue( f_InnerBend ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага внешней части сгиба. \en Set flag of external part of bend. +// --- +inline void MbName::SetOuterBend( bool s ) { + defNames.flags.SetFlagValue( f_OuterBend, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага внешней части сгиба. \en Get flag of external part of bend. +// --- +inline bool MbName::IsOuterBend() const { + return !!defNames.flags.GetFlagValue( f_OuterBend ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага боковой грани сгиба. \en Set flag of side part of bend. +// --- +inline void MbName::SetSideBend( bool s ) { + defNames.flags.SetFlagValue( f_SideBend, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага боковой грани сгиба. \en Get flag of side part of bend. +// --- +inline bool MbName::IsSideBend() const { + return !!defNames.flags.GetFlagValue( f_SideBend ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установление значения флага грани ребра жесткости листового тела. \en Set flag of reinforcement rib part of sheet solid. +// --- +inline void MbName::SetStampRibBend( bool s ) { + defNames.flags.SetFlagValue( f_RibBend, s ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Получение значения флага грани ребра жесткости листового тела. \en Get flag of reinforcement rib part of sheet solid. +// --- +inline bool MbName::IsStampRibBend() const { + return !!defNames.flags.GetFlagValue( f_RibBend ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Имя объекта и его копии. \en Name of object and its duplicate. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +#define ORIGINAL_MAIN_NAME // \ru Используется для работы с массивами. \en Used for arrays treatment. + + +#ifdef ORIGINAL_MAIN_NAME +//---------------------------------------------------------------------------------------- +/** \brief \ru Имя объекта и его копии. + \en Name of object and its duplicate. \~ + \details \ru Имя топологического объекта и его копии. \n + \en Name of topological object and its duplicate. \n \~ + \ingroup Names +*/ +// --- +class MATH_CLASS MbNamePair { +private: + MbName * gageName; // \ru Имя оригинала. \en A name of original. + MbName * copyName; // \ru Имя копии. \en A name of duplicate. + + // могут использоваться для самостоятельного поиска + mutable SimpleName copyHash; // \ru Кэш хеша имени оригинала. \en + +public: + /// \ru Конструктор. \en Constructor. + MbNamePair( MbName * orig, MbName * copy ) : gageName( orig ), copyName( copy ), copyHash( SIMPLENAME_MAX ) {} + /// \ru Конструктор для поиска по имени копии. \en Constructor for find by copy name. + MbNamePair( MbName * copy ) : gageName( NULL ), copyName( copy ), copyHash( SIMPLENAME_MAX ) {} + /// \ru Конструктор для поиска по хешу копии. \en Constructor for find by copy hash. + MbNamePair( SimpleName copy ) : gageName( NULL ), copyName( NULL ), copyHash( copy ) {} + /// \ru Деструктор. \en Destructor. + ~MbNamePair() {} + +public: + /// \ru Обнулить имя оригинала и имя копии. \en Set name of original and of its duplicate to null. + void SetNull() { gageName = NULL; copyName = NULL; copyHash = SIMPLENAME_MAX; } + /// \ru Оператор сравнения. \en Comparison operator. + bool operator == ( const MbNamePair & other ) const; + /// \ru Оператор меньше. \en "Less than" operator. + bool operator < ( const MbNamePair & other ) const; + /// \ru Расчет хеша имени оригинала для сравнения. \en Original hash calculation + SimpleName CopyNameHash() const + { + if ( copyName ) + copyHash = Prepare(*copyName).Hash(); + return copyHash; + } + /// \ru Правило приготовления имен. \en Names prepare rules. + static MbName Prepare( const MbName & name ); + + friend class MATH_CLASS MbNamePairList; +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Таблица соответствия имён размноженных объектов. \en Table of names correspondence of duplicated objects. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Таблица соответствия имён. + \en Table of names correspondence. \~ + \details \ru Таблица соответствия имён оригиналов и их размноженных копий в массивах. \n + \en Table of names correspondence of originals and its duplicates in arrays. \n \~ + \ingroup Names +*/ +// --- +class MATH_CLASS MbNamePairList { +private: + CSSArray checkList; ///< \ru Имена объектов и их копий. \en Names of objects and of its duplicates. + +public: + /// \ru Конструктор. \en Constructor. + MbNamePairList( size_t count = 0 ) : checkList( count, 1 ) {} + /// \ru Деструктор. \en Destructor. + ~MbNamePairList() { DeleteNames(); } + +public: + /// \ru Добавить имя объекта и имя его копии, имя оригинала и копии должно быть создано по new. \en Store names of object and its duplicate, which are created by new. + void AddNameData( MbName * orig, MbName * copy ) + { + C3D_ASSERT( (orig != NULL) && (copy != NULL) ); + if ( (orig != NULL) && (copy != NULL) ) { + checkList.Add( MbNamePair( orig, copy ) ); + } + } + /// \ru Выделить память под элементы. \en Allocate memory for elements. + void Reserve( size_t count ) { checkList.Reserve( count ); } + /// \ru Очистить массив не удаляя память под элементы. \en Erase array without deleting memory for elements. + void Erase() { DeleteNames(); checkList.Flush(); } + /// \ru Удалить память под элементы. \en Delete memory for elements. + void Free() { DeleteNames(); checkList.HardFlush(); } + /// \ru Удалить ненужные элементы по именам копий. \en Clean up unnecessary pairs by name copies. + bool Clean( const std::vector & delNamesCopies ); + /// \ru Заменить имена копий. \en Replace names copies. + bool Replace( const MbName & newNameCopies, const std::vector & oldNamesCopies ); + + /// \ru Найти имя объекта по имени его копии. \en Find name of object by name of its duplicate. + const MbName * FindOriginalByCopy( const MbName * copy ); + /// \ru Найти имя копии объекта по имени его оригинала. \en Find name of duplicate object by name of its original. + const MbName * FindCopyByOriginal( const MbName & original ) const; + /// \ru Найти имя объекта по хешу его копии. \en Find name of object by hash of its duplicate. + const MbName * FindOriginalByCopy( const SimpleName & originalHash ); + + const CSSArray & GetCheckList() const { return checkList; } + + friend class MATH_CLASS MbNameMaker; + friend class MATH_CLASS MbSNameMaker; + +private: + /// \ru Удалить имена в каждом элементе. \en Delete names in each element. + void DeleteNames(); + /// \ru Обнулить имя оригинала и имя копии в каждом элементе. \en Set name of original and of its duplicate to null in each element. + void SetNull(); +}; +#endif // ORIGINAL_MAIN_NAME + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Генератор имен. \en Name generator. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Генератор имен. + \en Name generator. \~ + \details \ru Генератор имен топологических объектов по заданному шаблону. \n + Не используйте главные имена из диапазона MbName::ReservedMainNames (исключение - MbName::ReservedMainNames::rmn_DefaultName). \n + \en Generator of names of topological objects by the given template. \n + Do not use the main names from the range MbName::ReservedMainNames (exception - MbName::ReservedMainNames::rmn_DefaultName). \n \~ + \internal +\ru Надо добиться того, чтобы имена не могли создаваться в обход определенных правил + и одновременно предусмотреть возможность создания новых правил!!! + Задача противоречивая - попробуем вот так. + Если надо создать новое правило генерации имени, то сделайте наследника от этого класса + напишите новое правило создающее MbIdArr (LiSArray) (или просто SimpleName) + и отдайте на вход MakeName +\en It is necessary to achieve that names can't be created passing over certain rules + and at the same time to provide possibility for creating new rules!!! + Task is inconsistent - try so. + If it is necessary to create a new rule for generating name, then inherit from this class, + write a new rule that creates MbIdArr (LiSArray) (or simply SimpleName) + and set it as input to MakeName \~ + \endinternal + \ingroup Names +*/ +//--- +class MATH_CLASS MbNameMaker { + +protected: + MbName defName; ///< \ru Шаблон имени. \en Name template. + MbNameVersion version; ///< \ru Версия изготовления. \en Version of manufacture. +#ifdef ORIGINAL_MAIN_NAME + SimpleName original; ///< \ru Исходное главное имя. \en Source main name. + mutable MbNamePairList * nameList; ///< \ru Таблица соответствия имён оригиналов и их копий. \en Table of correspondence of names of originals and its duplicates. +#endif // ORIGINAL_MAIN_NAME + +public: + /// \ru Конструктор по главному имени. \en Constructor by main name. + MbNameMaker( SimpleName mn ); + /// \ru Конструктор по имени. \en Constructor by name. + MbNameMaker( const MbName & _name ); + /// \ru Конструктор другому генератору имен. \en Constructor by another generator of names. + MbNameMaker ( const MbNameMaker & o ); + /// \ru Деструктор. \en Destructor. + ~MbNameMaker() {} + +public: + /// \ru Доступ к главному имени. \en Access to main name. + SimpleName GetMainName () const { return defName.GetMainName(); } + /// \ru Установка главного имени. \en Set main name. + void SetMainName ( SimpleName n ) { defName.SetMainName( n ); } + /// \ru Версия изготовления. \en Version of manufacture. + const VersionContainer & GetVersionContainer() const { return version.GetVersionContainer(); } + /// \ru Версия изготовления. \en Version of manufacture. + const MbNameVersion & GetMbNameVersion() const { return version; } + /// \ru Версия изготовления. \en Version of manufacture. + void SetVersion( const MbNameVersion & v ) { version = v; } + + /// \ru Получить версию математического ядра. \en Get version of the mathematical kernel. + VERSION GetMathVersion() const { return version.GetVersionContainer().GetMathVersion(); } + /// \ru Установить версию математического ребра. \en Set version of the mathematical kernel. + void SetMathVersion( VERSION v ) { version.SetVersion( 0, v ); } + +protected: + /// \ru Генерация имени name по шаблону и двум простым именам. \en Generate 'name' name by template and two simple names. + void MakeNameBy( SimpleName snFirst, SimpleName snCut, MbName & name ) const; + /// \ru Генерация имени name шаблону и источнику для грани скругления. \en Generate 'name' name by template and by source for fillet face. + void MakeNameBy( const MbName & source, MbName & name ) const; +public: + /// \ru Генерация имени name по шаблону и простому имени. \en Generate 'name' name by template and by simple name. + void MakeNameBy( SimpleName sn, MbName & name ) const; + /// \ru Генерация имени name по двум простым именам SimpleName. \en Generate 'name' name by two SimpleName simple names. + void MakeName( SimpleName sn1, SimpleName sn2, MbName & name ) const; + /// \ru Генерация имени name по простому имени SimpleName. \en Generate 'name' name by SimpleName simple name. + void MakeName( SimpleName sn, MbName & name ) const; + /// \ru Генерация имени name для грани скругления. \en Generate 'name' name for fillet face. + void MakeFilletFaceName( const MbName &, MbName & name ) const; + +#ifdef ORIGINAL_MAIN_NAME + /// \ru Установить исходное главное имя и таблицу соответствия имён. \en Set original main name and table of name correspondence. + void SetOriginalMainName( SimpleName orig, MbNamePairList * list ) { original = orig; nameList = list; } + /// \ru Исходное главное имя. \en Source main name. + SimpleName GetOriginalMainName() const { return original; } + /// \ru Таблица соответствия имён оригиналов и их копий. \en Table of correspondence of names of originals and of its duplicates. + MbNamePairList * GetNameList() const { return nameList; } + /// \ru Получить генератор имен оригинала, считая, что это именователь копии. \en Get original name maker. + MbNameMaker GetOriginalNameMaker() const; + /// \ru Удалить ненужные элементы по именам копий. \en Clean up unnecessary pairs by name copies. + bool CleanNameList( std::vector & delNamesCopies ) const; + /// \ru Заменить имена копий. \en Replace names copies. + bool ReplaceNameList( const MbName & newNameCopies, const std::vector & oldNamesCopies ) const; +#endif // ORIGINAL_MAIN_NAME + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbNameMaker & ) const; + +protected: + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader &) operator >> ( reader & in, MbNameMaker & ref ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, const MbNameMaker & ref ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, MbNameMaker & ref ) { return operator << ( out, static_cast(ref) ); } + +private: + void operator = ( const MbNameMaker & ); // \ru Не реализовано. \en Not implemented. +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Генератор имен c добавлением информации об источниках. \en Generator of names with addition of information about sources. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Генератор имен c добавками к имени. + \en Generator of names with additions to name. \~ + \details \ru Генератор имен (именователь) топологических объектов c добавлением информации об источниках. \n + Делает имена граням. Не используйте главные имена из диапазона MbName::ReservedMainNames (исключение - MbName::ReservedMainNames::rmn_DefaultName). + \en Generator of names (name-maker) of topological objects with addition of information about sources. \n + Makes names for faces. Do not use the main names from the range MbName::ReservedMainNames (exception - MbName::ReservedMainNames::rmn_DefaultName). \~ + \ingroup Names +*/ //--- +class MATH_CLASS MbSNameMaker : public SimpleNameArray, public MbNameMaker { + +public: + /// \ru Типы добавок к имени. \en Types of additions to name. + enum ESides { + i_SideNone = 0, ///< \ru Никакое. \en None. + i_SidePlus = 1, ///< \ru Положительное. \en Positive. + i_SideMinus = -1, ///< \ru Отрицательное. \en Negative. + }; + +protected: + ESides sideAdd; ///< \ru Добавка к имени боковой грани. \en Addition to name of a side face. + SimpleName buttAdd; ///< \ru Добавка к имени торцевой грани. \en Addition to name of a butt face. + bool cpyHist; ///< \ru Добавлять индексы копирования и старые имена в конец (не записываем). \en Whether to add indices of copying and old names to the end (don't write). +private: + bool addParentNamesAttributes; ///< \ru Добавлять атрибуты типа имя в объединенные грани. \en Whether to add name attributes to united faces. + +public: + /// \ru Конструктор. \en Constructor. + explicit MbSNameMaker ( SimpleName _mainName = UNDEFINED_SNAME, ESides _sideAdd = MbSNameMaker::i_SideNone, SimpleName _buttAdd = 0 ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSNameMaker ( const MbSNameMaker & other ); + + /// \ru Инициализировать по другому именователю. \en Initialize by another name-maker. + void SetName( const MbSNameMaker & other, bool setVersion = false ); + /// \ru Получить простое имя из массива с контролем выхода за границы \en Get simple name from array with control of overruning + SimpleName GetName( size_t i ) const; + /// \ru Инверсия. \en Inversion. + void Inverse(); + + /// \ru Выдать имя в виде условного положения в сетке копирования (для массивов). \en Get name in form of conditional position in grid of copying (for arrays). + bool GetNameAsPosition( size_t i, ptrdiff_t & row, ptrdiff_t & col ) const; + + /// \ru Добавка к имени боковой грани. \en Addition to name of a side face. + void SetSideAdd ( ESides s ) { sideAdd = s; } + /// \ru Добавка к имени торцевой грани. \en Addition to name of a butt face. + void SetButtAdd ( SimpleName b ) { buttAdd = b; } + /// \ru Установить состояние флага работы с индексами копирования. \en Set flag state of working with indices of copying. + void SetCopyHist( bool setHist ) { cpyHist = setHist; } + /// \ru Получить состояние флага работы с индексами копирования. \en Get flag state of working with indices of copying. + bool GetCopyHist() const { return cpyHist; } + /// \ru Установить состояние флага добавки атрибутов типа имя в объединенные грани и ребра. \en Set flag state of addition of name attributes to united faces and edges. + void SetParentNamesAttributes( bool addPNA ) { addParentNamesAttributes = addPNA; } + /// \ru Получить состояние флага добавки атрибутов типа имя в объединенные грани и ребра. \en Get flag state of addition of name attributes to united faces and edges. + bool GetParentNamesAttributes() const { return addParentNamesAttributes; } + /// \ru Установить количество имен. \en Set count of names. + void SetNamesCount( size_t newCount ); + + /// \ru Генерация имени name торцевой грани: mainName, +/-defName, знак определяется направлением. \en Generate 'name' name for butt face: mainName, +/-defName, sign is defined by direction. + void SetButtFaceName( MbName & name, MbSNameMaker::ESides side ) const; + /// \ru Генерация имени name грани: mainName, hash( sideName, add ). \en Generate 'name' name for face: mainName, hash( sideName, add ). + void SetFaceName( MbName & name, size_t i, SimpleName add ) const; + /// \ru Генерация имени name каркаса. \en Generate 'name' name for frame. + void SetWireName( MbName & name, size_t i ) const; + /// \ru Генерация имени name ребра из имен граней (sense - направление ребра по отношению к подлежащей кривой). \en Generate 'name' name for edge from names of faces ('sense' is a direction of edge relative to underlined curve). + void CompileEdgeName( MbName & name, + const MbName * f1, + const MbName * f2, + size_t ind, + bool sameSense ) const; + /// \ru Генерация имени name по другому имени, полное совпадение. \en Generate 'name' name by other name, full coincidence. + void CompileEdgeName( MbName & name, const MbName & other ) const; + + /// \ru Добавить генератор имен. \en Add name generator. + void AddSNameMaker( const MbSNameMaker & other ); + /// \ru Создать с именем индекса iFrom. \en Create with name of iForm index. + MbSNameMaker * GetSNameMakerFrom( size_t iFrom, size_t iTo ); +#ifdef ORIGINAL_MAIN_NAME + /// \ru Получить генератор имен оригинала, считая, что это именователь копии. \en Get original name maker. + MbSNameMaker GetOriginalSNameMaker() const; +#endif // ORIGINAL_MAIN_NAME + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSNameMaker & ) const; + +protected: + /// \ru Оператор чтения. \en Read operator. + friend MATH_FUNC (reader &) operator >> ( reader & in, MbSNameMaker & ref ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, const MbSNameMaker & ref ); + /// \ru Оператор записи. \en Write operator. + friend MATH_FUNC (writer &) operator << ( writer & out, MbSNameMaker & ref ) { return operator << ( out, static_cast(ref) ); } + +private: + /// \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbSNameMaker & ); +}; + + +//---------------------------------------------------------------------------------------- +// \ru Конструктор. \en Constructor. +//--- +inline MbSNameMaker::MbSNameMaker ( SimpleName _mainName, // =-1 + MbSNameMaker::ESides _sideAdd, // = 0 + SimpleName _buttAdd ) // = 0 + : SimpleNameArray( 0, 2 ) + , MbNameMaker ( _mainName ) + , sideAdd ( _sideAdd ) + , buttAdd ( _buttAdd ) + , cpyHist ( true ) + , addParentNamesAttributes( false ) +{} + + +//---------------------------------------------------------------------------------------- +// \ru Конструктор по другому именователю. \en Constructor by other name-maker. +// --- +inline MbSNameMaker::MbSNameMaker ( const MbSNameMaker & other ) + : SimpleNameArray( other.Count(), 2 ) + , MbNameMaker ( other ) + , sideAdd ( i_SideNone ) + , buttAdd ( 0 ) + , cpyHist ( true ) + , addParentNamesAttributes( false ) +{ + SetName( other, true ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Установить имя \en Set name +// --- +inline void MbSNameMaker::SetName( const MbSNameMaker & other, bool setVersion ) +{ + SetMainName( other.GetMainName() ); + SimpleNameArray::operator = ( (SimpleNameArray&)other ); + sideAdd = other.sideAdd; + buttAdd = other.buttAdd; + cpyHist = other.cpyHist; + addParentNamesAttributes = other.addParentNamesAttributes; + if ( setVersion ) + SetVersion( other.GetMbNameVersion() ); +#ifdef ORIGINAL_MAIN_NAME + original = other.original; + nameList = other.nameList; +#endif // ORIGINAL_MAIN_NAME +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Неклассные функция имён. \en Out-of-class functions for names. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Функция сравнения имён. + \en Name comparison function. \~ + \details \ru Функция сравнения имён возвращает: \n + -1, если n1 < n2; \n + 0, если n1 == n2; \n + +1, если n1 > n2; \n + \en Name comparison function returns: \n + -1, if n1 < n2; \n + 0, if n1 == n2; \n + +1, if n1 > n2; \n \~ + \ingroup Names +*/ +inline MATH_FUNC (int) MbMemDefNameCompare( const MbName & n1, const MbName & n2 ) +{ + int res = -1; + size_t count1 = n1.defNames.CountAll(); + size_t count2 = n2.defNames.CountAll(); + + if ( count1 == count2 ) { + if ( count1 ) + res = ::memcmp( n1.defNames.GetAddr(), n2.defNames.GetAddr(), count1 * sizeofSimpleName ); + else + res = 0; + } + else if ( count1 > count2 ) + res = 1; + + return res; +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Функция сравнения имён. + \en Name comparison function. \~ + \details \ru Функция сравнения имён для работы в сортированных структурах. \n + \en Name comparison function for work with sorted structures. \n \~ + \ingroup Names +*/ +// --- +inline MATH_FUNC (int) MbDefNameCompare( const MbName & n1, const MbName & n2 ) +{ + SimpleName hash1 = n1.defNames.Hash(); + SimpleName hash2 = n2.defNames.Hash(); + return ::SimpleNameCompare( hash1, hash2 ); +} + + +//---------------------------------------------------------------------------------------- +// \ru часто встречающаяся комбинация - hash от SArray'a \en Frequently occurring combination - hash of SArray +// --- +inline SimpleName Hash32( const SArray & arr ) { + return Hash32( (uint8*)arr.GetAddr(), arr.Count() * sizeofSimpleName ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Расчет модификатора имени примитива \en Calculate of modifier of name of primitive +// --- +inline SimpleName CalcNameModifier( const MbName & name, const SArray & path ) +{ + return ( (path.Count()) ? ::Hash32SN(name.Hash(), Hash32(path)) : name.Hash() ); +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Сравнить пути в виде массива идентификаторов. + \en Compare paths as array of identifiers. \~ + \details \ru Сравнить пути в виде массива идентификаторов. \n + \en Compare paths as array of identifiers. \n \~ + \return \ru Возвращает true, если пути совпадают. + \en Returns true if paths is coincident. \~ + \ingroup Names +*/ +// --- +MATH_FUNC (bool) IsEqualPaths( const SArray & path1, + const SArray & path2 ); + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Путь к компоненту. \en Path to component. +// +////////////////////////////////////////////////////////////////////////////////////////// + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Путь к компоненту. + \en Path to component. \~ + \details \ru Путь в виде массива идентификаторов (путь к компоненту от верхнего компонента). \n + \en Path as array of identifiers (path to component from upper component). \n \~ + \ingroup Names +*/ // --- +class MbPath : public SArray +{ +public: + /// \ru Конструктор. \en Constructor. + MbPath() : SArray ( 0, 1 ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbPath( const MbPath & other ) : SArray ( other ) {} + /// \ru Вычислить хэш себя. \en Calculate hash of itself. + SimpleName Hash() const; + /// \ru Оператор равенства. \en An equality operator. + bool operator == ( const MbPath & ) const; + bool operator != ( const MbPath & ) const; + /// \ru Оператор присваивания. \en An assignment operator. + MbPath & operator = ( const MbPath & o ) { SArray::operator = (o); return *this; } + /// \ru Оператор чтения. \en Read operator. + friend reader & operator >> ( reader & in, MbPath & ref ); + /// \ru Оператор записи. \en Write operator. + friend writer & operator << ( writer & out, const MbPath & ref ); + /// \ru Оператор записи. \en Write operator. + friend writer & operator << ( writer & out, MbPath & ref ) { return operator << ( out, (const MbPath &)ref ); } +}; + + +//---------------------------------------------------------------------------------------- +// \ru чтение \en Reading +// --- +inline reader & operator >> ( reader & in, MbPath & ref ) +{ + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + if ( in.good() && count ) { + ref.SetSize( count, true/*clear*/ ); + + if ( (ref.GetAddr() == NULL) && (count >= SYS_MAX_UINT32) ) // We could not allocate the required amount of memory + in.setState( io::outOfMemory ); + else { + for ( size_t i = 0; i < count && in.good(); i++ ) { + SimpleName item = ReadSimpleName( in ); + ref.Add( item ); + } + } + } + return in; +} + + +//---------------------------------------------------------------------------------------- +// \ru Запись \en Writing +// --- +inline writer & operator << ( writer & out, const MbPath & ref ) +{ + size_t count = ref.Count(); + WriteCOUNT( out, count ); + for( size_t i = 0; i < count && out.good(); i++ ) + WriteSimpleName( out, (SimpleName&)ref[i] ); + + return out; +} + + +//---------------------------------------------------------------------------------------- +// +// --- +inline SimpleName MbPath::Hash() const +{ + return ::Hash32( *this ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Сравнить пути в виде массива идентификаторов \en Compare paths as array of identifiers +// --- +inline bool MbPath::operator == ( const MbPath & other ) const +{ + return IsEqualPaths( *this, other ); +} +inline bool MbPath::operator != ( const MbPath & other ) const +{ + return !IsEqualPaths( *this, other ); +} + + +#endif // __NAME_ITEM_H diff --git a/C3d/Include/name_version.h b/C3d/Include/name_version.h new file mode 100644 index 0000000..7dcfc89 --- /dev/null +++ b/C3d/Include/name_version.h @@ -0,0 +1,151 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Версия топологического имени объекта. + \en Version of an object topological name. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __NAME_VERSION_H +#define __NAME_VERSION_H + + +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +// +/** \brief \ru Версия имени. + \en Version of a name. \~ + \details \ru Версия имени. \n + \en Version of a name. \n \~ + \ingroup Names +*/ +class MATH_CLASS MbNameVersion { + VersionContainer m_ver; /// \ru Контейнер версий. \en Container of versions. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbNameVersion(); + /// \ru Конструктор копирования. \en Copy-constructor. + explicit MbNameVersion( const VersionContainer & vers ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbNameVersion( const MbNameVersion & o ); + /// \ru Установить версию имени по умолчанию. \en Set default version of a name. + void SetDefault(); + /// \ru Установить версию в контейнере версий по индексу. \en Set the version in container of versions by an index. + void SetVersion ( size_t index, VERSION ver ) { m_ver.SetVersion( index, ver ); } + /// \ru Инициализировать версию имени другим контейнером версий. \en Initialize version of a name by other container of versions. + void Init ( const VersionContainer & vers ) { m_ver = vers; } + + /// \ru Получить контейнер версий. \en Get the container of versions. + const VersionContainer & GetVersionContainer() const { return m_ver; } + /// \ru Оператор получения математической версии. \en Operator for obtaining a mathematical version. + operator VERSION () const { return m_ver.GetMathVersion(); } + /// \ru Оператор равенства. \en An equality operator. + bool operator == ( VERSION v ) const { return (v == *this); } + /// \ru Оператор неравенства. \en Inequality operator. + bool operator != ( VERSION v ) const { return (v != *this); } + /// \ru Оператор больше. \en "Greater than" operator. + bool operator > ( VERSION v ) const { return (v < *this); } + /// \ru Оператор больше или равно. \en "Greater than or equal to" operator. + bool operator >= ( VERSION v ) const { return (v <= *this); } + /// \ru Оператор меньше. \en "Less than" operator. + bool operator < ( VERSION v ) const { return (v > *this); } + /// \ru Оператор меньше или равно. \en "Less than or equal to" operator. + bool operator <= ( VERSION v ) const { return (v >= *this); } + + /// \ru Оператор равенства. \en An equality operator. + bool operator == ( int32 v ) const { return ((VERSION)v == *this); } + /// \ru Оператор неравенства. \en Inequality operator. + bool operator != ( int32 v ) const { return ((VERSION)v != *this); } + /// \ru Оператор больше. \en "Greater than" operator. + bool operator > ( int32 v ) const { return ((VERSION)v < *this); } + /// \ru Оператор больше или равно. \en "Greater than or equal to" operator. + bool operator >= ( int32 v ) const { return ((VERSION)v <= *this); } + /// \ru Оператор меньше. \en "Less than" operator. + bool operator < ( int32 v ) const { return ((VERSION)v > *this); } + /// \ru Оператор меньше или равно. \en "Less than or equal to" operator. + bool operator <= ( int32 v ) const { return ((VERSION)v >= *this); } + + /// \ru Оператор присваивания. \en An assignment operator. + void operator = ( const MbNameVersion & o ) { m_ver = o.m_ver; } +private: + static VERSION GetIOVersion( uint8 v, VERSION ver ); + static uint8 GetVersion ( VERSION iov ); + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbNameVersion ); +}; + + +//------------------------------------------------------------------------------ +// +// --- +inline MbNameVersion::MbNameVersion() +{ +} + + +//------------------------------------------------------------------------------ +// +// --- +inline MbNameVersion::MbNameVersion( const VersionContainer & iov ) + : m_ver ( iov ) +{ +} + + +//------------------------------------------------------------------------------ +// +// --- +inline MbNameVersion::MbNameVersion( const MbNameVersion & o ) + : m_ver ( o.m_ver ) +{ +} + + + +//------------------------------------------------------------------------------ +// +// --- +inline reader& CALL_DECLARATION operator >> ( reader& in, MbNameVersion& ref ) { + VERSION version = in.MathVersion(); + + if ( version < 0x0590004FL ) { + ref.m_ver.Flush(); + ref.m_ver.SetVersion( 0/*System*/, version ); + } + else if ( version < 0x07000104L ) { + uint8 v; + in >> v; + ref.m_ver.Flush(); + ref.m_ver.SetVersion( 0/*System*/, MbNameVersion::GetIOVersion( v, version ) ); + } + else { + in >> ref.m_ver; + } + + return in; +} + + +//------------------------------------------------------------------------------ +// +// --- +inline writer& CALL_DECLARATION operator << ( writer& out, const MbNameVersion& ref ) { + + VERSION version = out.MathVersion(); + if ( version < 0x07000104L ) { + out << MbNameVersion::GetVersion( version ); + } + else { + out << ref.m_ver; + } + + return out; +} + + +#endif // __NAME_VERSION_H diff --git a/C3d/Include/op_binding_data.h b/C3d/Include/op_binding_data.h new file mode 100644 index 0000000..044a3fd --- /dev/null +++ b/C3d/Include/op_binding_data.h @@ -0,0 +1,387 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Классы привязки объектов. + \en Items binding classes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __OP_BINDING_DATA_H +#define __OP_BINDING_DATA_H + +#include +#include +#include + + +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbFaceShell; + + +//------------------------------------------------------------------------------ +/** \brief \ru Индекс идентификации объекта. + \en Index of object identification. \~ + \details \ru Индекс содержит имя, номер в теле и контрольную точку и + служит для поиска объекта (грани, ребра, вершины) в оболочке. + Поиск объекта производится по имени, в случае неудаче - по номеру, + и проверяется по контрольной точке \n + \en Index contains the name, the index in the solid and the control point, it + is used to search for object (face, edge, vertex) in the shell. + Object searching is performed by name. In failure case - by index, + and checked by the control point \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbItemIndex { +protected: + size_t itemIndex; ///< \ru Номер объекта в оболочке. \en The index of object in the shell. + MbCartPoint3D point; ///< \ru Контрольная точка объекта. \en Control point of the object. + SimpleName itemName; ///< \ru Имя объекта. \en A name of an object. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbItemIndex() + : itemIndex( SYS_MAX_T ) + , point ( -DETERMINANT_MAX, -DETERMINANT_MAX, -DETERMINANT_MAX ) + , itemName ( SIMPLENAME_MAX ) + {} + + /// \ru Конструктор по индексу без точки привязки. \en Constructor by the index without anchor point. + explicit MbItemIndex( size_t i ) + : itemIndex( i ) + , point ( -DETERMINANT_MAX, -DETERMINANT_MAX, -DETERMINANT_MAX ) + , itemName ( SIMPLENAME_MAX ) + {} + + /// \ru Конструктор по индексу с точкой привязки. \en Constructor by the index with anchor point. + MbItemIndex( size_t i, const MbCartPoint3D & p, SimpleName n ) + : itemIndex( i ) + , point ( p ) + , itemName ( n ) + {} + + /// \ru Конструктор по индексу с точкой привязки. \en Constructor by the index with anchor point. + MbItemIndex( size_t i, const MbFace & face ) : itemIndex( i ), point(), itemName() { Init( face, i ); } + /// \ru Конструктор по индексу с точкой привязки. \en Constructor by the index with anchor point. + MbItemIndex( size_t i, const MbCurveEdge & edge ) : itemIndex( i ), point(), itemName() { Init( edge, i ); } + + /// \ru Конструктор копирования. \en Copy-constructor. + MbItemIndex( const MbItemIndex & other ) + : itemIndex( other.itemIndex ) + , point ( other.point ) + , itemName ( other.itemName ) + {} + /// \ru Деструктор. \en Destructor. + ~MbItemIndex(); + +public: + /// \ru Функция инициализации. \en Initialization function. + void Init( const MbItemIndex & other ) + { + itemIndex = other.itemIndex; + point = other.point; + itemName = other.itemName; + } + /// \ru Функция инициализации. \en Initialization function. + void Init( size_t ind, bool reset = true ) + { + itemIndex = ind; + if ( reset ) { + point.Init( -DETERMINANT_MAX, -DETERMINANT_MAX, -DETERMINANT_MAX ); + itemName = SIMPLENAME_MAX; + } + } + /// \ru Функция инициализации. \en Initialization function. + void Init( size_t i, const MbCartPoint3D & p, SimpleName n ) + { + itemIndex = i; + point = p; + itemName = n; + } + /// \ru Функция инициализации. \en Initialization function. + bool Init( const MbFaceShell &, size_t faceIndex ); + /// \ru Функция инициализации. \en Initialization function. + void Init( const MbFace &, size_t faceIndex ); + /// \ru Функция инициализации. \en Initialization function. + void Init( const MbCurveEdge &, size_t edgeIndex ); + + /// \ru Оператор присваивания. \en Assignment operator. + MbItemIndex & operator = ( const MbItemIndex & other ) + { + Init( other ); + return *this; + } + + /// \ru Получить индекс. \en Get index. + size_t GetIndex() const { return itemIndex; } + /// \ru Получить имя. \en Get name. + SimpleName GetName() const { return itemName; } + /// \ru Получить точку привязки. \en Get anchoring point. + const MbCartPoint3D & GetPoint() const { return point; } + + /// \ru Установить индекс. \en Set index. + void SetIndex( size_t index ) { itemIndex = index; } + /// \ru Установить имя. \en Set name. + void SetName( SimpleName name ) { itemName = name; } + /// \ru Установить точку привязки. \en Set anchoring point. + void SetPoint( const MbFace & ); + /// \ru Установить точку привязки. \en Set anchoring point. + void SetPoint( const MbCurveEdge & ); + + /// \ru Изменить индекс и точку привязки. \en Change index and anchoring point. + void ChangeIndexPoint( size_t index, const MbCartPoint3D & pnt ) { itemIndex = index; point = pnt; } + /// \ru Изменить индекс и точку привязки. \en Change index and anchoring point. + void ChangeIndexName( size_t index, const SimpleName & name ) { itemIndex = index; itemName = name; } + + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbItemIndex & other, double accuracy ) const; + + /// \ru Статический оператор меньше. \en Static operator "less". + static bool LessByItemIndex( const MbItemIndex & ind1, const MbItemIndex & ind2 ) + { + if ( ind1.GetIndex() < ind2.GetIndex() ) + return true; + return false; + } + /// \ru Статический оператор меньше. \en Static operator "less". + static bool LessByItemName( const MbItemIndex & ind1, const MbItemIndex & ind2 ) + { + if ( ind1.GetName() < ind2.GetName() ) + return true; + return false; + } + /// \ru Статический оператор отсутствия индекса. \en Static operator "no item index". + static bool NoItemIndex( const MbItemIndex & ind ) + { + if ( ind.itemIndex == SYS_MAX_T ) + return true; + return false; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbItemIndex ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( MbItemIndex ) + DECLARE_NEW_DELETE_CLASS_EX( MbItemIndex ) +}; + +namespace c3d // namespace C3D +{ +typedef std::pair ItemIndexPair; +typedef std::vector ItemIndices; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Расширенный индекс идентификации объекта. + \en Extended index of object identification. \~ + \details \ru Расширенный индекс содержит имя, номер в теле и контрольную точку и служит для поиска объекта + (например, грани а теле для построения тонкой стенки). + Поиск объекта производится по имени, в случае неудаче - по номеру, и проверяется по контрольной точке \n + \en Extended index contains the name, the index in the solid and the control point and is used to search object + (or example: face in the solid, for construction of thin wall). + Object searching is performed by name. In failure case - by index, and checked by the control point \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbItemThinValues : public MbItemIndex { +public: + double value1; ///< \ru Первое значение параметра объекта (толщина наружу). \en The first parameter value of the object (thickness of the outside). + double value2; ///< \ru Второе значение параметра объекта (толщина внутрь). \en The second parameter value of the object (thickness of the outside). + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbItemThinValues() + : MbItemIndex( ) + , value1 ( 0.0 ) + , value2 ( 0.0 ) + {} + + /// \ru Конструктор по индексу и толщинам наружу и внутрь. \en Constructor by the index and thickness to outside and inside. + MbItemThinValues( ptrdiff_t i, double d1, double d2 ) + : MbItemIndex( i ) + , value1 ( ::fabs(d1) ) + , value2 ( ::fabs(d2) ) + {} + + /// \ru Конструктор по индексу, точке привязки и толщинам наружу и внутрь. \en Constructor by the index, anchor point and thickness to outside and inside. + MbItemThinValues( ptrdiff_t i, const MbCartPoint3D & p, double d1, double d2, SimpleName n ) + : MbItemIndex( i, p, n ) + , value1 ( ::fabs(d1) ) + , value2 ( ::fabs(d2) ) + {} + + /// \ru Конструктор по индексу, точке привязки и толщинам наружу и внутрь. \en Constructor by the index, anchor point and thickness to outside and inside. + MbItemThinValues( const MbItemIndex & itemInd, double d1, double d2 ) + : MbItemIndex( itemInd ) + , value1 ( ::fabs(d1) ) + , value2 ( ::fabs(d2) ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + MbItemThinValues( const MbItemThinValues & other ) + : MbItemIndex( other.itemIndex, other.point, other.itemName ) + , value1 ( other.value1 ) + , value2 ( other.value2 ) + {} + + /// \ru Оператор присваивания. \en Assignment operator. + MbItemThinValues & operator = ( const MbItemThinValues & other ) { + MbItemIndex::Init( (const MbItemIndex &)other ); + value1 = other.value1; + value2 = other.value2; + return *this; + } + + /** \brief \ru Инициализировать по индексу идентификации. + \en Initialize by identification index. \~ + \details \ru Инициализировать по индексу идентификации и толщине наружу и внутрь. + \en Initialize by the identification index and thickness to outside and inside. \~ + \param[in] itemInd - \ru Индекс идентификации. + \en Identification index. \~ + \param[in] d1 - \ru Толщина наружу. + \en Thickness to outside. \~ + \param[in] d2 - \ru Толщина внутрь. + \en Thickness to inside. \~ + */ + void Init( const MbItemIndex & itemInd, double d1, double d2 ) + { + MbItemIndex::Init( itemInd ); + value1 = ::fabs(d1); + value2 = ::fabs(d2); + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbItemThinValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbItemThinValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( MbItemThinValues ) + DECLARE_NEW_DELETE_CLASS_EX( MbItemThinValues ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Индекс идентификации ребра. + \en Index of edge identification. \~ + \details \ru Индекс содержит имя, номер ребра, номера соединяемых ребром граней в теле + и контрольную точку и служит для поиска ребра для скругления или фаски. + Поиск ребра производится по имени, в случае неудаче - по номерам, и проверяется по контрольной точке \n + \en Index contains the name, the index of the edge, indices of faces in the solid connected by edge + and control point and is used to search the edge for fillet or chamfer. + Edge searching is performed by name. In failure case - by indices, and checked by the control point \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbEdgeFacesIndexes { +public: + size_t edgeIndex; ///< \ru Номер ребра в множестве рёбер тела. \en The index of the edge in the set of solid edges. + size_t facePIndex; ///< \ru Номер грани слева в множестве граней тела. \en The index of the face on the left in the set of solid faces. + size_t faceMIndex; ///< \ru Номер грани справа в множестве граней тела. \en The index of the face on the right in the set of solid faces. + MbCartPoint3D point; ///< \ru Контрольная точка ребра. \en Control point of the edge. + SimpleName itemName; ///< \ru Имя объекта. \en A name of an object. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbEdgeFacesIndexes() + : edgeIndex ( SYS_MAX_T ) + , facePIndex( SYS_MAX_T ) + , faceMIndex( SYS_MAX_T ) + , point ( -DETERMINANT_MAX, -DETERMINANT_MAX, -DETERMINANT_MAX ) + , itemName ( SIMPLENAME_MAX ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + MbEdgeFacesIndexes( const MbEdgeFacesIndexes & other ) + : edgeIndex ( other.edgeIndex ) + , facePIndex( other.facePIndex ) + , faceMIndex( other.faceMIndex ) + , point ( other.point ) + , itemName ( other.itemName ) + {} + + /// \ru Оператор присваивания. \en Assignment operator. + MbEdgeFacesIndexes & operator = ( const MbEdgeFacesIndexes & other ) { + edgeIndex = other.edgeIndex; + facePIndex = other.facePIndex; + faceMIndex = other.faceMIndex; + point = other.point; + itemName = other.itemName; + return *this; + } + + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbEdgeFacesIndexes & other, double accuracy ) const; + + /// \ru Установить индекс. \en Set index. + void SetIndex( size_t index, size_t indexP, size_t indexM ) { edgeIndex = index; facePIndex = indexP; faceMIndex = indexM; } + /// \ru Установить имя. \en Set name. + void SetName( SimpleName name ) { itemName = name; } + + /// \ru Статический оператор меньше. \en Static operator "less". + static bool LessByEdgeIndex( const MbEdgeFacesIndexes & ind1, const MbEdgeFacesIndexes & ind2 ) + { + if ( ind1.edgeIndex < ind2.edgeIndex ) + return true; + return false; + } + + /// \ru Функция чтения. \en Read function. + friend MATH_FUNC (reader &) operator >> ( reader & in, MbEdgeFacesIndexes & ref ); + /// \ru Функция записи. \en Write function. + friend MATH_FUNC (writer &) operator << ( writer & out, const MbEdgeFacesIndexes & ref ); + /// \ru Функция записи. \en Write function. + friend MATH_FUNC (writer &) operator << ( writer & out, MbEdgeFacesIndexes & ref ) { + return operator << ( out,(const MbEdgeFacesIndexes &)ref ); + } + + DECLARE_NEW_DELETE_CLASS( MbEdgeFacesIndexes ) + DECLARE_NEW_DELETE_CLASS_EX( MbEdgeFacesIndexes ) +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Неклассные функции. \en Out-of-class functions. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/// \ru Сортировка по возрастанию номера. \en Sorting in ascending order of index. +// --- +template // Indices - MbItemIndex vector +void SortItemIndices( Indices & indices ) +{ + if ( indices.size() > 1 ) { + std::sort( indices.begin(), indices.end(), MbItemIndex::LessByItemIndex ); + } +} + + +//------------------------------------------------------------------------------ +/// \ru Сортировка по возрастанию номера. \en Sorting in ascending order of index. +// --- +template // Indices - MbEdgeFacesIndexes vector +void SortEdgeFacesIndices( Indices & indices ) +{ + if ( indices.size() > 1 ) { + std::sort( indices.begin(), indices.end(), MbEdgeFacesIndexes::LessByEdgeIndex ); + } +} + + + +#endif // __OP_BINDING_DATA_H diff --git a/C3d/Include/op_boolean_flags.h b/C3d/Include/op_boolean_flags.h new file mode 100644 index 0000000..dc5cdaf --- /dev/null +++ b/C3d/Include/op_boolean_flags.h @@ -0,0 +1,164 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Флаги булевой операции и ее наследников. + \en Flags of a boolean operation and its heirs. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __OP_BOOLEAN_FLAGS_H +#define __OP_BOOLEAN_FLAGS_H + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Управляющие флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \details \ru Управляющие флаги слияния элементов оболочки. \n + \en Control flags of shell items merging. \n \~ +\ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbMergingFlags { +protected: + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool mergeEdges; ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbMergingFlags() : mergeFaces( true ), mergeEdges( true ) {} + /// \ru Конструктор по флагам слияния. \en Constructor by merging flags. + MbMergingFlags( bool mFs, bool mEs ) : mergeFaces( mFs ), mergeEdges( mEs ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbMergingFlags( const MbMergingFlags & f ) : mergeFaces( f.mergeFaces ), mergeEdges( f.mergeEdges ) {} +public: + bool MergeFaces() const { return mergeFaces; } ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool MergeEdges() const { return mergeEdges; } ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). +public: + MbMergingFlags & operator = ( const MbMergingFlags & f ) { mergeFaces = f.mergeFaces; mergeEdges = f.mergeEdges; return *this; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Управляющие флаги булевой операции. + \en Control flags of Boolean operations. \~ + \details \ru Управляющие флаги булевой операции. \n + \en Control flags of Boolean operations \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbBooleanFlags { +protected: + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool mergeEdges; ///< \ru Сливать подобные ребра (true). \en Whether to merge similar edges (true). + bool closed; ///< \ru Замкнутость оболочек операндов. \en Closedness of operands' shells. + bool enclosureCheck; ///< \ru Проверять оболочки на вложенность. \en Check shell on nesting. + bool allowNonIntersecting; ///< \ru Выдавать конечную оболочку, если нет пересечений. \en Allow a final result if there is no intersection. + bool cutting; ///< \ru Флаг резки оболочки при построении разрезов и сечений. \en Flag of cutting the shell in the construction of cuts and sections. + bool repairShellEdges; ///< \ru Флаг починки ребер исходных оболочек. \en Flag of input shells edges repair. +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbBooleanFlags() + : mergeFaces ( true ) + , mergeEdges ( true ) + , closed ( true ) + , enclosureCheck ( true ) + , allowNonIntersecting( false ) + , cutting ( false ) + , repairShellEdges ( false ) + {} +public: + /// \ru Конструктор копирования. \en Copy-constructor. + MbBooleanFlags( const MbBooleanFlags & flags ) + : mergeFaces ( flags.mergeFaces ) + , mergeEdges ( flags.mergeEdges ) + , closed ( flags.closed ) + , enclosureCheck ( flags.enclosureCheck ) + , allowNonIntersecting( flags.allowNonIntersecting ) + , cutting ( flags.cutting ) + , repairShellEdges ( flags.repairShellEdges ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbBooleanFlags( const MbBooleanFlags & flags, bool _closed ) + : mergeFaces ( flags.mergeFaces ) + , mergeEdges ( flags.mergeEdges ) + , closed ( _closed ) + , enclosureCheck ( flags.enclosureCheck ) + , allowNonIntersecting( flags.allowNonIntersecting ) + , cutting ( flags.cutting ) + , repairShellEdges ( flags.repairShellEdges ) + {} +protected: + /// \ru Конструктор по флагам булевой операции. \en Constructor by Boolean flags. + MbBooleanFlags( bool _mergeFaces, bool _mergeEdges, bool _closed, bool _enclosureCheck, bool _allowNonIntersecting, bool _cutting ) + : mergeFaces ( _mergeFaces ) + , mergeEdges ( _mergeEdges ) + , closed ( _closed ) + , enclosureCheck ( _enclosureCheck ) + , allowNonIntersecting( _allowNonIntersecting ) + , cutting ( _cutting ) + , repairShellEdges ( false ) + {} + +public: + /// \ru Булева операция над оболочками. \en Boolean operation of shells. + void InitBoolean( bool _closed, bool _allowNonIntersecting = false ) + { + mergeFaces = true; + mergeEdges = true; + closed = _closed; + enclosureCheck = _closed; + allowNonIntersecting = _allowNonIntersecting; + cutting = false; + } + /// \ru Сечение (или усечение) оболочки. \en The cutting (or truncation) of a shell. + void InitCutting( bool _closed, bool _allowNonIntersecting = false ) + { + mergeFaces = true; + mergeEdges = true; + closed = _closed; + enclosureCheck = _closed; + allowNonIntersecting = _allowNonIntersecting; + cutting = true; + } + + bool MergeFaces () const { return mergeFaces; } ///< \ru Сливать подобные грани (true)? \en Whether to merge similar faces (true)? + bool MergeEdges () const { return mergeEdges; } ///< \ru Сливать подобные ребра (true)? \en Whether to merge similar edges (true)? + bool DoClosed () const { return closed; } ///< \ru Замкнутость результата. \en Closedness of resulting shell. + bool CheckEnclosure () const { return enclosureCheck; } ///< \ru Проверять оболочки на вложенность. \en Check shell on nesting. + bool AllowNonIntersecting() const { return allowNonIntersecting; } ///< \ru Выдавать конечную оболочку, если нет пересечений. \en Allow a final result if there is no intersection. + bool IsCutting () const { return cutting; } ///< \ru Флаг резки оболочки при построении разрезов и сечений. \en Flag of cutting the shell in the construction of cuts and sections. + bool ShellEdgesRepair () const { return repairShellEdges; } ///< \ru Флаг починки ребер исходных оболочек. \en Flag of input shells edges repair. + + /// \ru Получить флаги слияния подобных элементов. \en Get flags of merging. + MbMergingFlags GetMerging() const { return MbMergingFlags( mergeFaces, mergeEdges ); } + + /// \ru Проверить состояние флага. \en Check the flag's state. + void CheckEnclosureState() { if ( closed ) { enclosureCheck = true; } } + /// \ru Сливать подобные элементы. \en Whether to merge similar items. + void SetMerging( const MbMergingFlags & f ) { mergeFaces = f.MergeFaces(); mergeEdges = f.MergeEdges(); } + + void SetMergingFaces( bool s ) { mergeFaces = s; } ///< \ru Сливать подобные грани. \en Whether to merge similar faces. + void SetMergingEdges( bool s ) { mergeEdges = s; } ///< \ru Сливать подобные ребра. \en Whether to merge similar edges. + void SetAllowNonIntersecting( bool s ) { allowNonIntersecting = s; } ///< \ru Выдавать конечную оболочку, если нет пересечений. \en Allow a final result if there is no intersection. + void SetEnclosureCheck( bool s ) { enclosureCheck = s; } ///< \ru Проверять оболочки на вложенность. \en Check shell on nesting. + void SetShellEdgesRepair( bool s ) { repairShellEdges = s; } ///< \ru Чинить ребера исходных оболочек. \en Repair edges of input shells. + + /// \ru Оператор присваивания. \en Assignment operator. + MbBooleanFlags & operator = ( const MbBooleanFlags & flags ) + { + mergeFaces = flags.mergeFaces; + mergeEdges = flags.mergeEdges; + closed = flags.closed; + enclosureCheck = flags.enclosureCheck; + allowNonIntersecting = flags.allowNonIntersecting; + cutting = flags.cutting; + repairShellEdges = flags.repairShellEdges; + + return *this; + } +}; + + +#endif // __OP_BOOLEAN_FLAGS_H diff --git a/C3d/Include/op_duplication_parameter.h b/C3d/Include/op_duplication_parameter.h new file mode 100644 index 0000000..a8413e2 --- /dev/null +++ b/C3d/Include/op_duplication_parameter.h @@ -0,0 +1,416 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Параметры размножения. + \en Parameters of duplication. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __OP_DUPLICATION_PARAMETERS_H +#define __OP_DUPLICATION_PARAMETERS_H + +#include +#include +#include +#include + + +class MATH_CLASS MbAxis3D; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы параметров размножения. + \en Types of parameters of duplication. \~ + \details \ru dt_Grid - Копии располагаются в узлах декартовой сетки, заданной двумя направлениями, + шагами и количеством шагов по каждому направлению, а также сдвигом относительно исходного положения.\n + Исходное тело находится в центре сетки.\n + O---O---O \n + / / / \n + O---O---O \n + / / / \n + [O]--O---O \n + dt_Polar - Копии располагаются в узлах полярной сетки, заданной вектором начального луча, + вектором оси вращения, шагом по лучу, углом поворота, числом шагов по лучу и угловых шагов, + а также сдвигом относительно исходного положения.\n + Исходное тело находится в центре сетки.\n + O O \n + \ / \n + O O \n + \ / \n + O--O-[O]-O--O \n + dt_Matrix - Параметры разложения - массив матриц. Количество копий равно количеству матриц. + Каждая копия получается из исходного тела трансформацией соответствующей матрицей. \n + \en Dt_Grid - Copies locate in the nodes of the Cartesian grid, that define by two directions, + steps and numbers of steps along of each directions, and also by a shift from the initial position.\n + The original solid locate in the center of the grid.\n + O---O---O \n + / / / \n + O---O---O \n + / / / \n + [O]--O---O \n + dt_Polar - Copies locate in the nodes of the polar grid, that define by directions of the initial ray and the axis of rotation, + steps on the ray, angle of rotation and number of steps on the ray and angular step, + and also by a shift from the initial position.\n + The original solid locate in the center of the grid.\n + O O \n + \ / \n + O O \n + \ / \n + O--O-[O]-O--O \n + dt_Matrix - Parameters of duplication is array of matrices. Number of copies equal to number of matrix. + Each copy is obtained by transformation of corresponding matrix. \n \~ + \ingroup Model_Creators + */ +// --- +enum MbeDuplicatesType +{ + dt_Grid = 0 , ///< \ru Копии располагаются в узлах декартовой сетки. \en Copies locate in nodes of Cartesian grid. + dt_Polar = 1 , ///< \ru Копии располагаются в узлах полярной сетки.\en Copies locate in nodes of a polar grid. + dt_Matrix = 2 , ///< \ru Копии трансформируются матрицами. \en Copies are transformed by matrices. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Абстрактный класс параметров размножения. + \en Abstract class of duplication parameters. \~ + \details \ru Родительский класс для всех видов параметров размножения. \n + \en Parent class for all types of parameters of duplication. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS DuplicationValues +{ +protected: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + */ + DuplicationValues() {} + +public: + /** \brief \ru Деструктор. + \en Destructor. \~ + */ + virtual ~DuplicationValues() {} + + /** \brief \ru Функция копирования. + \en Copy function. \~ + */ + virtual bool Init( const DuplicationValues & ) = 0; + + /** \brief \ru Тип параметров. + \en Type of parameters \~ + \details \ru Возвращает тип параметров размножения. \n + \en Return type of parameters of duplication. \n \~ + */ + virtual MbeDuplicatesType Type() const = 0; + + /** \brief \ru Преобразовать параметры согласно матрице. + \en Transform parameters according to the matrix. \~ + */ + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; + + /** \brief \ru Сдвинуть параметры вдоль вектора. + \en Move parameters along a vector. \~ + \details \ru Сдвинуть параметры вдоль вектора. + \en Move parameters along a vector. \n \~ + */ + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; + + /** \brief \ru Повернуть параметры вокруг оси на заданный угол. + \en Rotate parameters at a given angle around an axis. \~ + \details \ru Повернуть параметры вокруг оси на заданный угол. + \en Rotate parameters at a given angle around an axis. \n \~ + */ + virtual void Rotate ( const MbAxis3D &, double ang, MbRegTransform * = NULL ) = 0; + + /** \brief \ru Выдать свойства объекта. + \en Get properties of the object. \~ + \details \ru Выдать свойства объекта. \n + \en Get properties of the object. \n \~ + */ + virtual void GetProperties( MbProperties & ) = 0; + + /** \brief \ru Записать свойства объекта. + \en Set properties of the object. \~ + \details \ru Записать свойства объекта. \n + \en Set properties of the object. \n \~ + */ + virtual void SetProperties( const MbProperties & ) = 0; + + /** \brief \ru Являются ли объекты равными? + \en Determine whether an object is equal? \~ + \details \ru Являются ли объекты равными? \n + \en Determine whether an object is equal? \n \~ + */ + virtual bool IsSame( const DuplicationValues &, double accuracy ) const = 0; + + /** \brief \ru Построить копию объекта. + \en Create a copy of the object. \~ + \details \ru Построить копию объекта. \n + \en Create a copy of the object. \n \~ + */ + virtual DuplicationValues & Duplicate( MbRegDuplicate * = NULL ) const = 0; + + /** \brief \ru Сгенерировать матрицы трансформаций. + \en Generate matrices of transformations. \~ + \details \ru Сгенерировать матрицы трансформаций согласно параметрам. \n + \en Generate matrices of transformations according to parameters. \n \~ + */ + virtual void GenerateTransformMatrices( SArray & ) const = 0; + + /** \brief \ru Количество создаваемых копий. + \en Number of of copies. \~ + \details \ru Количество создаваемых копий. \n + \en Number of of copies. \n \~ + */ + virtual size_t Count() const = 0; + +OBVIOUS_PRIVATE_COPY( DuplicationValues ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Размножение по сетке. + \en Duplication by grid. \~ + \details \ru Параметры размножение по размножение по декартовой сетке или по полярной сетке.\n + Тип сетки определяется флагом 'isPolar':\n + false - dt_Grid, true - dt_Polar.\n + Исходное тело находится в центре сетки. \n + Вектор 'axis1' задает одно из направлений декартовой сетки или направление луча в полярной сетке. \n + Вектор 'axis2' задает другое направление декартовой сетки или ось вращения в полярной сетке, + точка оси не важна т.к. поворачиваются только вектора. \n + 'step1' и step2' задают шаги по направлениям декартовой сетки. \n + 'step1' - задает шаг по лучу полярной сетки, 'step2' задает угол поворота. \n + 'num1' и 'num2' задают кол-во шагов 'step1' и 'step2' соответственно. \n + Ориентация тел на сетке определяется флагом 'isAlongAxis'. \n + Если флаг 'isAlongAxis' = true, то тела ориентированы вдоль радиальной оси, false - параллельно исходному телу. \n + 'center' задает центр локальной системы координат. \n + ВАЖНО! У векторов 'axis1', 'axis2' учитываются только направления, при инициализации или изменении происходит нормирование. \n + \en Parameters of duplication by Cartesian grid or polar grid.\n + Type of grid is determined by flag 'isPolar':\n + false - dt_Grid, true - dt_Polar.\n + The original solid locate in the center of the grid. \n + Vector 'axis1' define one of the directions of the Cartesian grid or direction of the ray in the polar grid. \n + Vector 'axis2' define other directions of the Cartesian grid or the axis of rotation in the polar grid, + point of axis doesn't matter because only vector will be rotated. + 'step1' and 'step2' define steps along the directions. \n + 'step1' define 'step' along the ray of polar grid, step2 define angle of rotation. \n + 'num1 and 'num2' define number of steps 'step1' and 'step2'. \n + Orientation of the bodies on the grid is controlled by 'isAlongAxis' flag. \n + If 'isAlongAxis' = true, then bodies are oriented along radial axis, false - parallel to the origin body. \n + 'center' determines the origin of local coordinate system. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS DuplicationMeshValues: public DuplicationValues +{ +protected: + MbVector3D axis1; ///< \ru Направление размножения (dt_Grid и dt_Polar). \en Direction of duplication (dt_Grid and dt_Polar). + MbVector3D axis2; ///< \ru Направление размножения (dt_Grid), направление оси вращения (dt_Polar). \en Direction of duplication (dt_Grid), direction of axis of rotation (dt_Polar). + double step1; ///< \ru Шаг по направлению axis1 (dt_Grid и dt_Polar). \en Step along of axis1 (dt_Grid and dt_Polar). + double step2; ///< \ru Шаг по направлению axis2 (dt_Grid), угол поворота (dt_Polar). \en Step along of axis1 (dt_Grid), angle of rotation (dt_Polar). + uint num1; ///< \ru Кол-во шагов по направлению axis1 (dt_Grid и dt_Polar). \en Number of steps along of axis1 (dt_Grid and dt_Polar). + uint num2; ///< \ru Кол-во шагов по направлению axis2 (dt_Grid), кол-во угловых шагов (dt_Polar). \en Number of steps along of axis2 (dt_Grid), number of angular steps (dt_Polar). + bool isPolar; ///< \ru Тип сетки, false - dt_Grid, true - dt_Polar. Type of grid, false - dt_Grid, true - dt_Polar. \en . + bool isAlongAxis; ///< \ru true - тела расположены вдоль радиальной оси, false - параллельно исходному телу. \en true - along polar axis, false - parallel to initial body. + MbCartPoint3D center; ///< \ru Центр локальной системы координат (и точка приложения оси вращения в случае полярной системы). \en Origin of the coordinate system. +public: + /** \brief \ru Конструктор по типу. + \en Constructor by a type. \~ + \details \ru Конструктор размножения по сетке.\n + Вектора и значения инициализируются нулевыми, тип сетки инициализируется параметром, по умолчанию 'false'. \n + \en Constructor of duplication by grid. \n + Vectors and values are initialized to zero, type of grid is initialized by parameter, default 'false'. \n \~ + */ + DuplicationMeshValues( bool polar = false ); + + /** \brief \ru Конструктор по параметрам и типу. + \en Constructor by parameters and a type. \~ + \details \ru Конструктор размножения по сетке. \n + Тип сетки, направления осей, шаги и кол-во шагов инициализируются параметрами. \n + \en Constructor of duplication by grid. \n + Type of grid, vectors, steps and numbers of steps are initialized to parameters. \n \~ + */ + DuplicationMeshValues( bool isPolar, const MbVector3D & dir1, const double step1, const unsigned int num1, + const MbVector3D & dir2, const double step2, const unsigned int num2, + const MbCartPoint3D * center = NULL, bool isAlongAxis = false ); + + /// \ru Деструктор. \en Destructor. + virtual ~DuplicationMeshValues(); + + /// \ru Функция копирования. \en Copy function. + void Init( const DuplicationMeshValues & other ); + /// \ru Функция копирования. \en Copy function. + virtual bool Init( const DuplicationValues & other ); + /// \ru Тип параметров. \en Type of parameters. + virtual MbeDuplicatesType Type() const; + /// \ru Преобразовать сетку согласно матрице. \en Transform grid according to the matrix. + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); + /// \ru Сдвинуть сетку вдоль вектора. \en Move grid along a vector. + virtual void Move ( const MbVector3D &, MbRegTransform * ireg = NULL ); + /// \ru Повернуть сетку вокруг оси на заданный угол. \en Rotate grid at a given angle around an axis. + virtual void Rotate ( const MbAxis3D &, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Выдать свойства объекта \en Get properties of the object + virtual void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта \en Set properties of the object + virtual void SetProperties( const MbProperties & ); + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const DuplicationValues &, double accuracy ) const; + + /// \ru Построить копию объекта. \en Create a copy of the object. + virtual DuplicationValues & Duplicate( MbRegDuplicate * ireg = NULL ) const; + + /// \ru Сгенерировать матрицы трансформации. \en Generate matrix of transformation by. + virtual void GenerateTransformMatrices( SArray & tfMatr ) const; + + /// \ru Количество создаваемых копий. \en Number of copies. + virtual size_t Count() const; + + /** \brief \ru Установить одно из направлений сетки. + \en Set one of the directions of grid. \~ + \details \ru Установить одно из направлений сетки. \n + \en Set one of the directions of grid. \n \~ + */ + void SetDirection( bool first, const MbVector3D & dir ); + + /** \brief \ru Получить одно из направлений сетки. + \en Get one of the directions of grid. \~ + \details \ru Получить одно из направлений сетки. \n + \en Get one of the directions of grid. \n \~ + */ + void GetDirection( bool first, MbVector3D & dir ) const; + + /** \brief \ru Установить шаг по одному из направлений сетки. + \en Set the step along of one of the directions of grid. \~ + \details \ru Установить шаг по одному из направлений сетки. \n + \en Set the step along of one of the directions of grid. \n \~ + */ + void SetStep( bool first, const double step ); + + /** \brief \ru Получить шаг по одному из направлений сетки. + \en Get the step along of one of the directions of grid. \~ + \details \ru Получить шаг по одному из направлений сетки. \n + \en Get the step along of one of the directions of grid. \n \~ + */ + void GetStep( bool first, double & step ) const; + + /** \brief \ru Установить количество шагов по одному из направлений сетки. + \en Set the number of steps along of one of the directions of grid. \~ + \details \ru Установить количество шагов по одному из направлений сетки. \n + \en Set the number of steps along of one of the directions of grid. \n \~ + */ + void SetNumStep( bool first, const uint num ); + + /** \brief \ru Полярная ли сетка? + \en Is mesh polar? \~ + \details \ru Задана ли сетка в полярной системе координат? \n + \en Is local system of mesh polar? \n \~ + */ + bool IsPolar() const { return isPolar; } + + /** \brief \ru Задать тип сетки. + \en Set mesh type. \~ + \details \ru Задать сетку в полярной или декартовой системе координат. \n + \en Set local system of mesh. \n \~ + */ + void SetPolar( bool p ) { isPolar = p; } + + /** \brief \ru Получить количество шагов по одному из направлений сетки. + \en Get the number of steps along of one of the directions of grid. \~ + \details \ru Получить количество шагов по одному из направлений сетки. \n + \en Get the number of steps along of one of the directions of grid. \n \~ + */ + void GetNumStep( bool first, uint & num ) const; + + /** \brief \ru Тело вдоль радиальной оси? + \en Is body along radial axis? \~ + \details \ru Тело вдоль радиальной оси? \n + \en Is body along radial axis? \n \~ + */ + bool IsAlongAxis() const { return isAlongAxis; } + + /** \brief \ru Вернуть центр полярной системы. + \en Return center of the polar system. \~ + \details \ru Вернуть центр полярной системы. \n + \en Return center of the polar system. \n \~ + */ + + MbCartPoint3D GetCenter() const { return center; } + + /** \brief \ru Установить центр полярной системы. + \en Set center of the polar system. \~ + \details \ru Установить центр полярной системы. \n + \en Set center of the polar system. \n \~ + */ + + void SetCenter( MbCartPoint3D & cntr ) { center = cntr; } + +KNOWN_OBJECTS_RW_REF_OPERATORS( DuplicationMeshValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +OBVIOUS_PRIVATE_COPY( DuplicationMeshValues ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Размножение матрицами. + \en Duplication by matrices. \~ + \details \ru Размножение задается набором матриц трансформаций. Каждая копия это трансформация оригинального тела соответствующей матрицей. \n + \en Duplication is defined by set of transform matrices. Each copy is a transformation of original solid by corresponding matrix. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS DuplicationMatrixValues: public DuplicationValues +{ +public: + SArray matrices; +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + DuplicationMatrixValues(); + /// \ru Конструктор по матрице. \en Constructor by matrix. + DuplicationMatrixValues( const MbMatrix3D & matr ); + /// \ru Конструктор по набору матриц. \en Constructor by set of matrices. + DuplicationMatrixValues( const SArray & matr ); + + /// \ru Деструктор. \en Destructor. + virtual ~DuplicationMatrixValues(); + + /// \ru Функция копирования. \en Copy function. + void Init( const DuplicationMatrixValues & other ); + /// \ru Функция копирования. \en Copy function. + virtual bool Init( const DuplicationValues & other ); + /// \ru Тип параметров. \en Type of parameters. + virtual MbeDuplicatesType Type() const; + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Move ( const MbVector3D &, MbRegTransform * ireg = NULL ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + virtual void Rotate ( const MbAxis3D &, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Выдать свойства объекта \en Get properties of the object + virtual void GetProperties( MbProperties & ); + /// \ru Записать свойства объекта \en Set properties of the object + virtual void SetProperties( const MbProperties & ); + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const DuplicationValues &, double accuracy ) const; + + /// \ru Построить копию объекта. \en Create a copy of the object. + virtual DuplicationValues & Duplicate( MbRegDuplicate * ireg = NULL ) const; + + /// \ru Сгенерировать матрицы трансформации. \en Generate matrix of transformation. + virtual void GenerateTransformMatrices( SArray & tfMatr ) const; + + /// \ru Количество создаваемых копий. \en Number of copies. + virtual size_t Count() const; + +KNOWN_OBJECTS_RW_REF_OPERATORS( DuplicationMatrixValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +OBVIOUS_PRIVATE_COPY( DuplicationMatrixValues ) +}; + + +#endif // __OP_DUPLICATION_PARAMETERS_H \ No newline at end of file diff --git a/C3d/Include/op_shell_parameter.h b/C3d/Include/op_shell_parameter.h new file mode 100644 index 0000000..acb493d --- /dev/null +++ b/C3d/Include/op_shell_parameter.h @@ -0,0 +1,3103 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Параметры операций над телами. + \en Parameters of operations on the solids. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __OP_SHELL_PARAMETERS_H +#define __OP_SHELL_PARAMETERS_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPoint3D; +class MATH_CLASS MbPolyCurve3D; +class MATH_CLASS MbPolyline3D; +class MATH_CLASS MbSurface; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbPlane; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbFace; +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbSolid; +class MATH_CLASS MbSNameMaker; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры скругления или фаски ребра. + \en Parameters of fillet or chamfer of edge. \~ + \details \ru Параметры скругления или фаски ребра содержат информацию, необходимую для выполнения операции. \n + \en The parameter of fillet or chamfer of edge contain Information necessary to perform the operation. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS SmoothValues { +public: + /// \ru Способы обработки углов стыковки трёх рёбер. \en Methods of processing corners of connection by three edges. + enum CornerForm { + ec_pointed = 0, ///< \ru Обработка угла отсутствует. \en Processing of corner is missing. + ec_either = 1, ///< \ru Стыкующиеся в одной точке три ребра обрабатываются в порядке внутренней нумерации ребер без учета выпуклости и вогнутости. \en Mating at one point of three edges are processed in the order of internal indexation of edges without convexity and concavity. + ec_uniform = 2, ///< \ru Если в точке стыкуются два выпуклых (вогнутых) и одно вогнутое (выпуклое) ребро, то первым обрабатывается вогнутое (выпуклое) ребро. \en If two convex (concave) and one concave (convex) edge are mated at the point, then concave (convex) edge is processed at the first. + ec_sharp = 3, ///< \ru Если в точке стыкуются два выпуклых (вогнутых) и одно вогнутое (выпуклое) ребро, то первыми обрабатываются выпуклые (вогнутые) ребра. \en If two convex (concave) and one concave (convex) edge are mated at the point, then concave (convex) edges are processed at the first. + }; + +public: + double distance1; ///< \ru Радиус кривизны/катет на первой поверхности. \en Radius of curvature/leg on the first surface. + double distance2; ///< \ru Радиус кривизны/катет на второй поверхности. \en Radius of curvature/leg on the second surface. + double conic; ///< \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0 - дуга окружности). \en Coefficient of shape is changed from 0.05 to 0.95 (if 0 - circular arc). + double begLength; ///< \ru Расстояние от начала скругления до точки остановки (UNDEFINED_DBL - остановки нет). \en Distance from the beginning of fillet to the stop point (UNDEFINED_DBL - no stop). + double endLength; ///< \ru Расстояние от конца скругления до точки остановки (UNDEFINED_DBL - остановки нет). \en Distance from the end of fillet to the stop point (UNDEFINED_DBL - no stop). + MbeSmoothForm form; ///< \ru Тип сопряжения скругление/фаска. \en Mate type of fillet/chamfer. + CornerForm smoothCorner; ///< \ru Способ обработки углов стыковки трёх рёбер. \en Method of processing corners of connection by three edges. + bool prolong; ///< \ru Продолжить по касательной. \en Prolong along the tangent. + ThreeStates keepCant; ///< \ru Автоопределение сохранения кромки (ts_neutral), сохранение поверхности (ts_negative), сохранение кромки (ts_positive). \en Auto detection of boundary saving (ts_neutral), surface saving (ts_negative), boundary saving (ts_positive). + bool strict; ///< \ru При false скруглить хотя бы то, что возможно. \en If false - round at least what is possible. + bool equable; ///< \ru В углах сочленения вставлять тороидальную поверхность (для штамповки листового тела). \en In corners of the joint insert toroidal surface (for stamping sheet solid). + +private: + MbVector3D vector1; ///< \ru Вектор нормали к плоскости, по которой выполняется усечение скругления в начале цепочки. \en Normal vector of the plane cutting the fillet at the beginning of chain. + MbVector3D vector2; ///< \ru Вектор нормали к плоскости, по которой выполняется усечение скругления в конце цепочки. \en Normal vector of the plane cutting the fillet at the end of chain. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + SmoothValues() + : distance1 ( 1.0 ) + , distance2 ( 1.0 ) + , conic ( c3d::_ARC_ ) + , begLength (UNDEFINED_DBL) + , endLength (UNDEFINED_DBL) + , form ( st_Fillet ) + , smoothCorner ( ec_uniform ) + , prolong ( false ) + , keepCant ( ts_negative ) + , strict ( true ) + , equable ( false ) + , vector1 ( ) + , vector2 ( ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по параметрам. + \en Constructor by parameters. \~ + \param[in] d1, d2 - \ru Радиусы кривизны/катеты. + \en Radii of curvature/catheti. \~ + \param[in] f - \ru Способ построения поверхности сопряжения. + \en Method of construction of mating surface. \~ + \param[in] c - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0 - дуга окружности). + \en Coefficient of shape is changed from 0.05 to 0.95 (if 0 - circular arc). \~ + \param[in] pro - \ru Продолжить по касательной. + \en Prolong along the tangent. \~ + \param[in] cor - \ru Способ скругления "чемоданных" углов. + \en Method for bending corner of three surfaces. \~ + \param[in] autoS - \ru Автоопределение сохранения кромки/поверхности. + \en Auto detection of boundary/surface saving. \~ + \param[in] keep - \ru Сохранять кромку (true) или сохранять поверхность скругления/фаски (false). + \en Keep boundary (true) or keep surface of fillet/chamfer (false). \~ + \param[in] str - \ru Строгое скругление. Если false, скруглить хотя бы то, что возможно. + \en Strict fillet. If false - round at least what is possible. \~ + \param[in] equ - \ru В углах сочленения вставлять тороидальную поверхность. + \en In corners of the joint insert toroidal surface. \~ + */ + SmoothValues( double d1, double d2, MbeSmoothForm f, double c, bool pro, + CornerForm cor, bool autoS, bool keep, bool str, bool equ ) + : distance1 ( d1 ) + , distance2 ( d2 ) + , conic ( c ) + , begLength (UNDEFINED_DBL) + , endLength (UNDEFINED_DBL) + , form ( f ) + , smoothCorner ( cor ) + , prolong ( pro ) + , keepCant ( ts_negative ) + , strict ( str ) + , equable ( equ ) + , vector1 ( ) + , vector2 ( ) + { + keepCant = autoS ? ts_neutral : ts_negative; + if ( keep ) + keepCant = ts_positive; + + } + + /// \ru Конструктор копирования. \en Copy-constructor. + SmoothValues( const SmoothValues & other, MbRegDuplicate * iReg = NULL ); + /// \ru Деструктор. \en Destructor. + virtual ~SmoothValues(){} + + /// \ru Функция инициализации. \en Initialization function. + void Init( const SmoothValues & other ); +public: + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Move ( const MbVector3D &, MbRegTransform * /*ireg*/ = NULL ){} + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + virtual void Rotate ( const MbAxis3D &, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Установить плоскость, параллельно которой будет выполнена остановка скругления в начале цепочки. \en Set the plane by which parallel will be carry out stop of the fillet at the begin. + bool SetStopObjectAtBeg( const MbSurface * object, bool byObject = true ); + /// \ru Установить плоскость, параллельно которой будет выполнена остановка скругления в конце цепочки. \en Set the plane by which parallel will be carry out stop of the fillet at the end. + bool SetStopObjectAtEnd( const MbSurface * object, bool byObject = true ); + /// \ru Установить вектор нормали к плоскости остановки скругления в начале цепочки. \en Set normal to the bound plane at the begin. + void SetBegVector( const MbVector3D & vect ) { vector1.Init( vect ); } + /// \ru Установить вектор нормали к плоскости остановки скругления в конце цепочки. \en Set normal to the bound plane at the end. + void SetEndVector( const MbVector3D & vect ) { vector2.Init( vect ); } + /// \ru Получить вектор нормали к плоскости остановки в начале скругления. \en Get normal vector to the bound plane at the begin of the fillet. + void GetBegVector( MbVector3D & vect ) const { vect.Init( vector1 ); } + /// \ru Получить вектор нормали к плоскости остановки в конце скругления. \en Get normal vector to the bound plane at the end of the fillet. + void GetEndVector( MbVector3D & vect ) const { vect.Init( vector2 ); } + + /// \ru Оператор присваивания. \en Assignment operator. + SmoothValues & operator = ( const SmoothValues & other ) { + Init( other ); + return *this; + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const SmoothValues & other, double accuracy ) const; + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( SmoothValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры скругления грани. + \en Parameters of face fillet. \~ + \details \ru Параметры скругления грани содержат информацию, необходимую для выполнения операции. \n + \en The parameters of face fillet contain Information necessary to perform the operation. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS FullFilletValues { +public: + bool prolong; ///< \ru Продолжить по касательной. \en Prolong along the tangent. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + FullFilletValues() + : prolong ( true ) + {} + + /// \ru Конструктор по параметрам. \en Constructor by parameters. + FullFilletValues( bool prlg ) + : prolong ( prlg ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + FullFilletValues( const FullFilletValues & other, MbRegDuplicate * iReg = NULL ); + + /// \ru Деструктор. \en Destructor. + ~FullFilletValues(){} +public: + /// \ru Функция инициализации. \en Initialization function. + void Init( const FullFilletValues & other ); + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D &, MbRegTransform * /*ireg*/ = NULL ){} + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D &, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Оператор присваивания. \en Assignment operator. + FullFilletValues & operator = ( const FullFilletValues & other ) { + Init( other ); + return *this; + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const FullFilletValues & other, double accuracy ) const; + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( FullFilletValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры скругления вершины. + \en Parameters of vertex fillet. \~ + \details \ru Параметры скругления вершины, в которой стыкуются три ребра, содержат информацию, необходимую для выполнения операции. \n + \en Fillet parameters of vertex (where three edges are connected) contain information necessary to perform the operation \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS CornerValues { +public: + /// \ru Способы скругления вершины стыковки трёх рёбер. \en Methods of vertices fillet of connection by three edges. + enum CornerForm { + ef_sphere = 0, ///< \ru Скругление вершины сферической поверхностью. \en Vertex fillet by spherical surface. + ef_smart = 1, ///< \ru Скругление вершины гладкой поверхностью. \en Vertex fillet by smooth surface. + ef_delta = 3, ///< \ru Скругление вершины треугольной поверхностью. \en Vertex fillet by triangular surface. + ef_elbow1 = 4, ///< \ru Скругление вершины четырёхугольной поверхностью, четвёртую сторону располагать напротив range1. \en Vertex fillet by quadrangular surface, the fourth side is opposite the range1. + ef_elbow2 = 5, ///< \ru Скругление вершины четырёхугольной поверхностью, четвёртую сторону располагать напротив range2. \en Vertex fillet by quadrangular surface, the fourth side is opposite the range2. + ef_elbow3 = 6, ///< \ru Скругление вершины четырёхугольной поверхностью, четвёртую сторону располагать напротив range3. \en Vertex fillet by quadrangular surface, the fourth side is opposite the range3. + }; + +public: + double radius0; ///< \ru Радиус сферы в вершине. \en Radius of the sphere of the vertex. + double radius1; ///< \ru Радиус первого ребра вершины. \en Radius of the first edge of the vertex. + double radius2; ///< \ru Радиус второго ребра вершины. \en Radius of the second edge of the vertex. + double radius3; ///< \ru Радиус третьего ребра вершины. \en Radius of the third edge of the vertex. + CornerForm cornerForm; ///< \ru Способ скругления вершины стыковки трёх рёбер. \en Method of vertex fillet of connection by three edges. + uint8 additive; ///< \ru Сдвиг в нумерации рёбер вершины (добавка к номеру ребра). \en Shift in the indexation of vertex edges (addition to the index of edge). + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + CornerValues() + : radius0 ( 0.0 ) + , radius1 ( 1.0 ) + , radius2 ( 1.0 ) + , radius3 ( 1.0 ) + , cornerForm( ef_smart ) + , additive ( 0 ) + {} + /// \ru Конструктор по параметрам. \en Constructor by parameters. + CornerValues( double r0, double r1, double r2, double r3, CornerForm ck ) + : radius0 ( ::fabs(r0) ) + , radius1 ( ::fabs(r1) ) + , radius2 ( ::fabs(r2) ) + , radius3 ( ::fabs(r3) ) + , cornerForm( ck ) + , additive ( 0 ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + CornerValues( const CornerValues & other ) + : radius0 ( other.radius0 ) + , radius1 ( other.radius1 ) + , radius2 ( other.radius2 ) + , radius3 ( other.radius3 ) + , cornerForm( other.cornerForm ) + , additive ( other.additive ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~CornerValues(); + + /// \ru Функция инициализации. \en Initialization function. + void Init( const CornerValues & other ) { + radius0 = other.radius0; + radius1 = other.radius1; + radius2 = other.radius2; + radius3 = other.radius3; + cornerForm = other.cornerForm; + additive = other.additive; + } + /// \ru Циклическая перестановка параметров. \en Cyclic permutation of the parameters. + void CiclicSwap( bool increase ); + /// \ru Поменять местами радиусы (constRadius = 1,2,3). \en Swap radii (constRadius = 1,2,3). + void Swap( int constRadius ); + /// \ru Оператор присваивания. \en Assignment operator. + CornerValues & operator = ( const CornerValues & other ) { + Init( other ); + return *this; + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const CornerValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( CornerValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы выемки. + \en Types of notch. \~ + \details \ru Типы выемки. Служат для определения одного из построений: отверстий, карманов, пазов. \n + \en Types of notch. These are used to determine one from the constructions: holes, pockets, grooves. \n \~ + \ingroup Build_Parameters +*/ +// --- +enum MbeHoleType { + ht_BorerValues = 0, ///< \ru Отверстие. \en Hole. + ht_PocketValues = 1, ///< \ru Карман. \en Pocket. + ht_SlotValues = 2, ///< \ru Паз. \en Slot. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры выемки. + \en The parameters of notch. \~ + \details \ru Общие параметры построения выемки: отверстия, фигурного паза, кармана (бобышки). \n + \en The common parameters of notch construction: holes, figure slot, pocket (boss). \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS HoleValues { +public: + double placeAngle; ///< \ru Угол между осью и нормалью к поверхности (0 <= placeAngle <= M_PI_2). \en Angle between axis and normal to the surface (0 <= placeAngle <= M_PI_2). + double azimuthAngle; ///< \ru Угол поворота оси вокруг нормали поверхности (-M_PI2 <= azimuthAngle <= M_PI2). \en Angle of rotation around the surface normal (-M_PI2 <= azimuthAngle <= M_PI2). +protected: + MbSurface * surface; ///< \ru Обрабатываемая поверхность (если NULL, то считается плоской). \en Processing surface (if NULL, then is considered planar). + bool doPhantom; ///< \ru Создавать фантом результата операции. \en Create the phantom of the operation. + +protected: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров выемки с нулевыми углами и плоской поверхностью. + \en Constructor of notch parameters with zero angles and planar surfaces. \~ + */ + HoleValues(); + + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + HoleValues( const HoleValues & other ); + /// \ru Конструктор копирования. \en Copy-constructor. + HoleValues( const HoleValues & other, MbRegDuplicate * iReg ); + +public: + /// \ru Деструктор. \en Destructor. + virtual ~HoleValues(); + +public: + /// \ru Тип выемки. \en Type of notch. + virtual MbeHoleType Type() const = 0; + /// \ru Построить копию объекта. \en Create a copy of the object. + virtual HoleValues & Duplicate( MbRegDuplicate * ireg = NULL ) const = 0; + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + virtual void Transform( const MbMatrix3D &, MbRegTransform * ireg = NULL ) = 0; + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Move ( const MbVector3D &, MbRegTransform * ireg = NULL ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + virtual void Rotate ( const MbAxis3D &, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const HoleValues &, double accuracy ) const; + + /// \ru Оператор присваивания. \en Assignment operator. + virtual void operator = ( const HoleValues & other ) = 0; + /// \ru Функция копирования. \en Copy function. + void Init( const HoleValues & init ); + /// \ru Получить поверхность. \en Get the surface. + const MbSurface * GetSurface() const { return surface; } + /// \ru Заменить поверхность. \en Replace surface. + void SetSurface( MbSurface * s ); + /// \ru Установить флаг создания фантома. \en Set the phantom flag. + void SetPhantom( bool s ) { doPhantom = s; } + /// \ru Получить флаг создания фантома. \en Get the phantom flag. + bool GetPhantom() const { return doPhantom; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры отверстия. + \en The hole parameters. \~ + \details \ru Параметры для построения отверстий различных типов. \n + Законцовка отверстия управляется параметром spikeAngle. + При #spikeAngle = 0 - сферическая законцовка отверстия, \n + при #spikeAngle = M_PI - плоская законцовка отверстия, \n + в остальных случаях - коническая законцовка отверстия. \n + \en The parameters for construction of holes with different types. \n + Tip of hole is controlled by the spikeAngle parameter. + If # spikeAngle = 0 - spherical tip of hole, \n + If # spikeAngle = M - planar tip of hole, \n + in other cases - conical tip of hole. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS BorerValues : public HoleValues { +public: + /** \brief \ru Типы отверстий. + \en Types of holes. \~ + \details \ru Тип определяет форму отверстия. + \en The type determines the hole shape. \~ + \ingroup Build_Parameters + */ + enum BorerType { + // + // _______________ + // /| | + // +-+-------------+ + bt_SimpleCylinder = 0, ///< \ru Простое цилиндрическое отверстие. \en Simple cylindrical hole. + // __ + // _____________|| + // /| || + // +-+------------++ + bt_TwofoldCylinder = 1, ///< \ru Двойное цилиндрическое отверстие. \en Double cylindrical hole. + // / + // _____________/| + // /| || + // +-+------------++ + bt_ChamferCylinder = 2, ///< \ru Цилиндрическое отверстие с фаской. \en Cylindrical hole with a chamfer. + // ____ + // __________/| | + // /| || | + // +-+---------++--+ + bt_ComplexCylinder = 3, ///< \ru Двойное цилиндрическое отверстие с переходом. \en Double cylindrical hole with a transition. + // + // _______________ + // /| | + // +-+-------------+ + bt_SimpleCone = 4, ///< \ru Простое коническое отверстие. \en Simple conical hole. + // | + // ____________ /| + // /| | | + // +-+---------+---+ + bt_ArcCylinder = 5, ///< \ru Центровое отверстие формы R (дугообразное). \en Center hole of form R (arcuate). + }; + +public: + double capDiameter; ///< \ru Диаметр головки (для отверстий типа #bt_TwofoldCylinder, #bt_ChamferCylinder, #bt_ComplexCylinder). \en Diameter cap (for hole with type #bt_TwofoldCylinder, #bt_ChamferCylinder, #bt_ComplexCylinder). + double capDepth; ///< \ru Глубина под головку (для отверстий типа #bt_TwofoldCylinder, #bt_ComplexCylinder). \en Depth for cap (for hole with type #bt_TwofoldCylinder, #bt_ChamferCylinder, #bt_ComplexCylinder). + double capAngle; ///< \ru Угол фаски под головку (для отверстий типа #bt_ChamferCylinder, #bt_ComplexCylinder), capAngle <= M_PI. \en Chamfer angle for cap (for holes with type #bt_ChamferCylinder, #bt_ComplexCylinder), capAngle <= M_PI. + double diameter; ///< \ru Диаметр отверстия под резьбу (для всех типов отверстий). \en Hole diameter for thread (for all the types of holes). + double depth; ///< \ru Глубина отверстия под резьбу (для всех типов отверстий). \en Hole depth for thread (for all the types of holes). + double angle; ///< \ru Угол конусности отверстия под резьбу (для отверстия типа #bt_SimpleCone), 0 < angle < M_PI. \en Angle of hole conicity for thread (for hole with type #bt_SimpleCone), 0 < angle < M_PI. + double spikeAngle; ///< \ru Угол раствора конца отверстия (для всех типов отверстий), spikeAngle <= M_PI. \en Apex angle of the hole end (for all the types of holes), spikeAngle <= M_PI. + double arcRadius; ///< \ru Радиус дуги (для отверстия типа #bt_ArcCylinder). \en Arc radius (for hole with type #bt_ArcCylinder). + bool prolong; ///< \ru Флаг продления сверла в обратную сторону (для всех типов отверстий), по умолчанию true (есть продление). \en Flag of drill extension along the opposite direction (for all the types of holes), default true (the extension exists). + bool down; ///< \ru Направление оси отверстия: true - прямое (против оси Z локальной системы), false - обратное. \en Direction of hole axis: true - forward (opposite to the Z of the local system), false - backward. + BorerType type; ///< \ru Тип отверстия. \en Type of hole. + +private : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + BorerValues( const BorerValues & other ); + /// \ru Конструктор копирования. \en Copy-constructor. + BorerValues( const BorerValues & other, MbRegDuplicate * ireg ); +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор простого цилиндрического отверстия. + \en Constructor of simple cylindrical hole. \~ + */ + BorerValues() + : HoleValues () + , capDiameter( 20.0 ) + , capDepth ( 5.0 ) + , capAngle ( M_PI_2 ) + , diameter ( 10.0 ) + , depth ( 25.0 ) + , angle ( M_PI_2 ) + , spikeAngle ( M_PI * c3d::TWO_THIRD ) + , arcRadius ( 10. ) + , prolong ( true ) + , down ( true ) + , type ( bt_SimpleCylinder ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~BorerValues(); + +public: + virtual MbeHoleType Type() const; // \ru Тип выемки. \en Type of notch. + virtual HoleValues & Duplicate( MbRegDuplicate * ireg = NULL ) const; // \ru Построить копию. \en Create a copy. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual bool IsSame( const HoleValues &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual void operator = ( const HoleValues & other ); // \ru Оператор присваивания. \en Assignment operator. +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const BorerValues & other ); +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( BorerValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры кармана или бобышки. + \en The parameters of pocket or boss. \~ + \details \ru Параметры прямоугольного кармана или бобышки со скруглёнными углами. \n + \en The parameters of rectangular pocket or boss with rounded corners. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS PocketValues : public HoleValues { +public: + double length; ///< \ru Длина кармана или бобышки. \en The length of pocket or boss. + double width; ///< \ru Ширина кармана или бобышки. \en The width of pocket or boss. + double depth; ///< \ru Глубина кармана или бобышки. \en The depth of pocket or boss. + + /** \brief \ru Радиус скругления углов кармана или бобышки. + \en Fillet radius of corners of pocket or boss. \~ + \details \ru Радиус скругления углов кармана или бобышки, 2 * cornerRadius <= std_min( width, length ). + При length == width == 2 * cornerRadius получим карман в виде отверстия. + \en Fillet radius of corners of pocket or boss, 2 * cornerRadius <= std_min( width, length ). + If length == width == 2 * cornerRadius, then pocket as a hole. \~ + */ + double cornerRadius; + + double floorRadius; ///< \ru Радиус скругления дна кармана или верха бобышки. \en Fillet radius of bottom of pocket or top of boss. + double taperAngle; ///< \ru Угол уклона стенок кармана или верха бобышки (отклонение от вертикали в радианах). \en Draft angle of pocket walls or top of boss (vertical deviation in radians) + bool type; ///< \ru type == false - карман, type == true - бобышка. \en Type == false - pocket, type == true - boss. + +private : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + PocketValues( const PocketValues & other ); + /// \ru Конструктор копирования. \en Copy-constructor. + PocketValues( const PocketValues & other, MbRegDuplicate * ireg ); + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор кармана. + \en Constructor of pocket. \~ + */ + PocketValues() + : HoleValues () + , length ( 20.0 ) + , width ( 10.0 ) + , depth ( 5.0 ) + , cornerRadius( 2.0 ) + , floorRadius ( 1.0 ) + , taperAngle ( 0.0 ) + , type ( false ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~PocketValues(); + +public: + virtual MbeHoleType Type() const; // \ru Тип выемки. \en Type of notch. + virtual HoleValues & Duplicate( MbRegDuplicate * ireg = NULL ) const; // \ru Построить копию. \en Create a copy. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual bool IsSame( const HoleValues &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual void operator = ( const HoleValues & other ); // \ru Оператор присваивания. \en Assignment operator. +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const PocketValues & other ); +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( PocketValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры паза. + \en The parameters of slot. \~ + \details \ru Параметры фигурного паза. \n + Вид паза сверху представляет собой разрезанную пополам окружность, + половинки которой раздвинуты на длину паза, а края соединены отрезками. + \en The parameters of figure slot. \n + View of slot from above is cut in half to circle, + halves of which are spread apart by the length of slot and the edges are connected by segments. \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS SlotValues : public HoleValues { +public: + // \ru Вид паза сверху. \en View of slot from above. \~ + // -- + // / \ + // | | + // | | + // | | + // | | + // \ / + // -- + enum SlotType { + // ________ * + // | | * + // +------+ * + // \ / * + // -- * + st_BallEnd = 0, ///< \ru Цилиндрический в донной части. \en Cylindrical in the bottom part. + // ________ * + // | | * + // | | * + // | | * + // +------+ * + st_Rectangular = 1, ///< \ru Прямоугольный. \en Rectangular. + // ________ * + // | | * + // +--+------+--+ * + // | | * + // +------------+ * + st_TShaped = 2, ///< \ru T-образный. \en T-shaped. + // ________ * + // / \ * + // / \ * + // / \ * + // +--------------+ * + st_DoveTail = 3, ///< \ru Ласточкин хвост. \en Dovetail + }; + +public: + double length; ///< \ru Длина паза. \en Slot length. + double width; ///< \ru Ширина паза. \en Slot width. + double depth; ///< \ru Глубина паза. \en Slot depth. + double bottomWidth; ///< \ru Ширина донной части T-образного паза, должна превосходить ширину width. \en Width of the bottom part of T-shaped slot must be greater than the width "width". + double bottomDepth; ///< \ru Глубина донной части ласточкиного хвоста. \en Depth of the bottom part of dovetail. + + /** \brief \ru Радиус скругления дна паза. + \en Fillet radius of the slot bottom. \~ + \details \ru Радиус скругления дна паза (2 * floorRadius <= width). + При width == 2 * floorRadius получим паз типа st_BallEnd. + floorRadius = 0 для пазов типа st_TShaped и st_DoveTail. + \en Fillet radius of slot bottom (2 * floorRadius <= width). + If width == 2 * floorRadius, then slot has type st_BallEnd. + floorRadius = 0 for slots with type st_TShaped and st_DoveTail. \~ + */ + double floorRadius; + double tailAngle; ///< \ru Угол уклона стенок паза типа st_DoveTail (отклонение от вертикали в радианах). \en Draft angle of walls of slot with type st_DoveTail (vertical deviation in radians). + SlotType type; ///< \ru Тип паза. \en Type of slot. + +private : + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + SlotValues( const SlotValues & other ); + /// \ru Конструктор копирования. \en Copy-constructor. + SlotValues( const SlotValues & other, MbRegDuplicate * ireg ); + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор прямоугольного паза. + \en Constructor of rectangular slot. \~ + */ + SlotValues() + : HoleValues () + , length ( 10.0 ) + , width ( 10.0 ) + , depth ( 5.0 ) + , bottomWidth( 15.0 ) + , bottomDepth( 10.0 ) + , floorRadius( 1.0 ) + , tailAngle ( M_PI_4 ) + , type ( st_Rectangular ) + {} + + /// \ru Деструктор. \en Destructor. + virtual ~SlotValues(); + +public: + virtual MbeHoleType Type() const; // \ru Тип выемки. \en Type of notch. + virtual HoleValues & Duplicate( MbRegDuplicate * ireg = NULL ) const; // \ru Построить копию. \en Create a copy. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * ireg = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual bool IsSame( const HoleValues &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual void operator = ( const HoleValues & other ); // \ru Оператор присваивания. \en Assignment operator. +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const SlotValues & other ); +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( SlotValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры крепежа. + \en The parameters of fastener elements. \~ + \details \ru Параметры крепежных элементов. \n + \en The parameters of fastener elements. \n \~ +*/ +// --- +class MATH_CLASS FastenersValues { +public: + //------------------------------------------------------------------------------ + /** \brief \ru Типы крепежа. + \en Fastener Types. \~ + */ + // --- + enum MbeFastenerType { + ft_CountersunkHeadRivet = 0, ///< \ru Заклепка с (полу)потайной головкой. \en (semi)Countersunk head rivet. + ft_UniversalHeadRivet, ///< \ru Заклепка с универсальной головкой. \en Universal head rivet. + ft_RoundHeadRivet, ///< \ru Заклепка с полукруглой головкой. \en Round head rivet. + ft_FlatHeadRivet ///< \ru Заклепка с плоской головкой. \en Flat head rivet. + }; +private: + MbeFastenerType fastenerType; ///< \ru Тип крепежа. \en Fastener type. + double diameter; ///< \ru Диаметр крепежа. \en Fastener diameter. + double angle; ///< \ru Угол фаски. \en Countersunk angle. + double depth; ///< \ru Глубина фаски. \en Depth of chamfer. + double headDiameter; ///< \ru Диаметр основания головки. \en Diameter of the head base. + double headHeight; ///< \ru Высота головки. \en Head height. + + ThreeStates rivetAndHole; ///< \ru ts_negative - создать только отверстия (без крепежа), ts_neutral - создать только крепёж (без отверстий), ts_positive - создать крепеж и отверстия. + ///< \en ts_negative - create holes only (without rivets), ts_neutral - create rivets only (without holes), ts_positive - create rivets and holes. \~ + +public: + /** \brief \ru Конструктор крепежа по типу и диаметру. + \en Constructor of fastener based on type and diameter. \~ + \details \ru Конструктор крепежа по типу и диаметру. + \en Constructor of fastener based on type and diameter. \~ + \param[in] ft - \ru Тип крепежа. + \en Fastener type. \~ + \param[in] d - \ru Диаметр крепежа. + \en Fastener diameter. \~ + */ + FastenersValues( MbeFastenerType ft, double d ) + : fastenerType ( ft ) + , diameter ( d ) + , angle ( M_PI_4 ) + , depth ( d * c3d::ONE_HALF ) + , headDiameter ( 2 * d ) + , headHeight ( d ) + , rivetAndHole ( ts_positive ) + {} + + /** \brief \ru Конструктор крепежа по типу, диаметру, углу, катету. + \en Constructor of fastener based on type, diameter, angle and side length. \~ + \details \ru Конструктор крепежа по типу, диаметру, углу, катету. + \en Constructor of fastener based on type, diameter, angle and side length. \~ + \param[in] ft - \ru Тип крепежа. + \en Fastener type. \~ + \param[in] d - \ru Диаметр крепежа. + \en Fastener diameter. \~ + \param[in] a - \ru Угол. + \en Angle. \~ + \param[in] dd - \ru Глубина (фаски). + \en Depth. \~ + \param[in] hd - \ru Диаметр основания головки. + \en Head base diameter \~ + \param[in] hh - \ru Высота головки. + \en Head height. \~ + + \param[in] ho - \ru Создать только отверстие. + \en Create hole only. \~ + */ + FastenersValues( MbeFastenerType ft, double d, double a, double dd, double hd, double hh, ThreeStates ho ) + : fastenerType ( ft ) + , diameter ( d ) + , angle ( a ) + , depth ( dd ) + , headDiameter ( hd ) + , headHeight ( hh ) + , rivetAndHole ( ho ) + {} + + /// \ru Выдать тип крепежа. \en Return type of fastener. + MbeFastenerType GetType() const { return fastenerType; } + /// \ru Выдать значение диаметра. \en Return diameter value. + double GetDiameter() const { return diameter; } + /// \ru Установить значение диаметра. \en Set diameter value. + void SetDiameter( double d ) { diameter = d; } + /// \ru Выдать значение угла. \en Return angle value. + double GetAngle() const { return angle; } + /// \ru Установить значение угла. \en Set angle value. + void SetAngle( double a ) { angle = a; } + /// \ru Выдать значение глубины фаски. \en Return chamfer depth value. + double GetDepth() const { return depth; } + /// \ru Установить значение глубины фаски. \en Set chamfer depth value. + void SetDepth( double d ) { depth = d; } + /// \ru Выдать значение диаметра основания головки. \en Return chamfer depth value. + double GetHeadDiameter() const { return headDiameter; } + /// \ru Установить значение диаметра основания головки. \en Set chamfer depth value. + void SetHeadDiameter( double hd ) { headDiameter = hd; } + /// \ru Выдать значение высоты головки. \en Return head height value. + double GetHeadHeight() const { return headHeight; } + /// \ru Установить значение высоты головки. \en Set head height value. + void SetHeadHeight( double hh ) { headHeight = hh; } + + /// \ru Только отверстие? \en Hole only? + ThreeStates RivetAndHole() const { return rivetAndHole; } + /// \ru Функция инициализации. \en Initialization function. + void Init( const FastenersValues & other ) { + fastenerType = other.fastenerType; + diameter = other.diameter; + angle = other.angle; + depth = other.depth; + headDiameter = other.headDiameter; + headHeight = other.headHeight; + rivetAndHole = other.rivetAndHole; + } + /// \ru Оператор присваивания. \en Assignment operator. + FastenersValues & operator = ( const FastenersValues & other ) { + Init( other ); + return *this; + } + +private: + /// \ru Конструктор по умолчанию - запрещен. \en Default constructor - forbidden. + FastenersValues() + {} +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( FastenersValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры заплатки. + \en The parameters of patch. \~ + \details \ru Параметры заплатки. \n + Содержат информацию о типе заплатки и флаге проверки самопересечений. + \en The parameters of patch. \n + Contain Information about type of patch and flag of checking self-intersection. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS PatchValues { +public: + /** \brief \ru Тип заплатки. + \en Type of patch. \~ + \details \ru Флаг можно установить через вызов PatchValues::SetType(). + \en The flag can be set by calling PatchValues::SetType(). \~ + */ + enum SurfaceType { + ts_tang, ///< \ru По касательной. \en Along the tangent. + ts_norm, ///< \ru По нормали. \en Along the normal. + ts_none, ///< \ru Не определено. \en Undefined. + ts_plane ///< \ru Плоская заплатка. \en Plane patch. + }; +private: + SurfaceType type; ///< \ru Тип заплатки. \en Type of patch. + bool checkSelfInt; ///< \ru Флаг проверки самопересечений (вычислительно "тяжелыми" методами). \en Flag for checking of self-intersection (computationally by "heavy" methods). + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров заплатки не определенного типа без проверки самопересечений. + \en Constructor of parameters of patch with undefined type and without checking of self-intersection. \~ + */ + PatchValues() + : type ( ts_none ) + , checkSelfInt( false ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + PatchValues( const PatchValues & other ) + : type ( other.type ) + , checkSelfInt( other.checkSelfInt ) + {} + /// \ru Деструктор. \en Destructor. + ~PatchValues() + {} + +public: + /// \ru Выдать тип заплатки. \en Get type of patch. + SurfaceType GetType() const { return type; } + /// \ru Выдать тип заплатки для изменения. \en Get type of patch for changing. + SurfaceType & SetType() { return type; } + /// \ru Получить флаг проверки самопересечений. \en Get the flag of checking self-intersection. + bool CheckSelfInt() const { return checkSelfInt; } + /// \ru Установить флаг проверки самопересечений. \en Set the flag of checking self-intersection. + void SetCheckSelfInt( bool c ) { checkSelfInt = c; } + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const PatchValues & other ) { type = other.type; checkSelfInt = other.checkSelfInt; } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const PatchValues & obj, double ) const { return ((obj.type == type) && (obj.checkSelfInt == checkSelfInt)); } + + KNOWN_OBJECTS_RW_REF_OPERATORS( PatchValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кривая для построения заплатки. + \en Curve for the patch construction. \~ + \details \ru Кривая для построения заплатки и параметры её окружения. \n + \en Curve for the patch construction and parameters of its environment. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MbPatchCurve : public MbRefItem { +private: + MbCurve3D * curve; ///< \ru Кривая. \en A curve. + double begTolerance; ///< \ru Толерантность привязки в начале. \en Binding tolerance at the start. + double endTolerance; ///< \ru Толерантность привязки в начале. \en Binding tolerance at the start. + bool isSurfaceOne; ///< \ru В ребре есть грань с первой поверхностью из кривой пересечения. \en There is face with the first surface from the intersection curve in the edge. + bool isSurfaceTwo; ///< \ru В ребре есть грань со второй поверхностью из кривой пересечения. \en There is face with the second surface from the intersection curve in the edge. + mutable bool isUsed; ///< \ru Флаг использования. \en An using flag. + +public: + /// \ru Конструктор по кривой (копирует кривую, трансформируя по матрице). \en Constructor by a curve (copies a curve, transforms by the matrix). + MbPatchCurve( const MbCurve3D & crv, const MbMatrix3D & mtr ); + /// \ru Конструктор по ребру (копирует кривую, трансформируя по матрице). \en Constructor by an edge (copies a curve, transforms by the matrix). + MbPatchCurve( const MbCurveEdge & edge, const MbMatrix3D & mtr ); + /// \ru Деструктор. \en Destructor. + virtual ~MbPatchCurve(); + +public: + /// \ru В ребре есть грань с первой поверхностью из кривой пересечения. \en There is face with the first surface from the intersection curve in the edge. + bool IsSurfOne() const { return isSurfaceOne; } + /// \ru В ребре есть грань со второй поверхностью из кривой пересечения. \en There is face with the second surface from the intersection curve in the edge. + bool IsSurfTwo() const { return isSurfaceTwo; } + /// \ru Толерантность привязки в начале. \en Binding tolerance at the start. + double GetBegTolerance() const { return begTolerance; } + /// \ru Толерантность привязки в начале. \en Binding tolerance at the start. + double GetEndTolerance() const { return endTolerance; } + /// \ru Получить кривую. \en Get a curve. + const MbCurve3D & GetCurve() const { return *curve; } + /// \ru Получить кривую для изменения. \en Get a curve for changing. + MbCurve3D & SetCurve() { return *curve; } + /// \ru Кривая используется? \en Is curve used? + bool IsUsed() const { return isUsed; } + /// \ru Установить флаг использования кривой. \en Set flag of using curve. + void SetUsed( bool b ) const { isUsed = b; } + + OBVIOUS_PRIVATE_COPY( MbPatchCurve ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры масштабирования объекта. + \en The parameters of object scaling. \~ + \details \ru Масштабирование объекта выполняется преобразованием по матрице. \n + \en Object scaling is performed by the transformation matrix. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS TransformValues { + +protected: + MbMatrix3D matrix; ///< \ru Матрица преобразования . \en A transformation matrix. + // \ru Остальные параметры не обязательны (нужны для расчета matrix по деформации габаритного куба функцией MbCube::CalculateMatrix) \en Other parameters are optional (they are necessary for the calculation of matrix by deformation of bounding box by the function MbCube::CalculateMatrix) + MbCartPoint3D fixedPoint; ///< \ru Неподвижная точка преобразования (используется, если useFixed = true). \en A fixed point of transformation. (It is used if useFixed = true). + bool useFixed; ///< \ru Использовать неподвижную точку преобразования (если true). \en Use fixed point of transformation (if true). + bool isotropy; ///< \ru Использовать одинаковое масштабирование по осям (если true). \en Use the same axes scaling (if true). + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + TransformValues() + : matrix() + , fixedPoint() + , useFixed( false ) + , isotropy( false ) + {} + /// \ru Конструктор по матрице. \en Constructor by matrix. + TransformValues( const MbMatrix3D & m ) + : matrix( m ) + , fixedPoint() + , useFixed( false ) + , isotropy( false ) + {} + /// \ru Конструктор по матрице и неподвижной точке преобразования. \en Constructor by matrix and fixed point of transformation. + TransformValues( const MbMatrix3D & m, const MbCartPoint3D & f, bool fix = false, bool iso = false ) + : matrix( m ) + , fixedPoint( f ) + , useFixed( fix ) + , isotropy( iso ) + {} + /// \ru Конструктор по неподвижной точке преобразования и масштабам по осям. \en Constructor by fixed point of transformation and axes scale. + TransformValues( double sX, double sY, double sZ, const MbCartPoint3D & fP ); + /// \ru Конструктор. \en Constructor. + TransformValues( const TransformValues & other ) + : matrix ( other.matrix ) + , fixedPoint ( other.fixedPoint ) + , useFixed ( other.useFixed ) + , isotropy ( other.isotropy ) + {} + /// \ru Деструктор. \en Destructor. + ~TransformValues() {} +public: + /// \ru Функция инициализации. \en Initialization function. + void Init( const TransformValues & other ) { + matrix = other.matrix; + fixedPoint = other.fixedPoint; + useFixed = other.useFixed; + isotropy = other.isotropy; + } + /// \ru Оператор присваивания. \en Assignment operator. + TransformValues & operator = ( const TransformValues & other ) { + matrix = other.matrix; + fixedPoint = other.fixedPoint; + useFixed = other.useFixed; + isotropy = other.isotropy; + return *this; + } + + /// \ru Выдать матрицу преобразования для использования. \en Get a transformation matrix for use. + const MbMatrix3D & GetMatrix() const { return matrix; } + /// \ru Выдать неподвижную точку преобразования для использования. \en A fixed point of transformation for use. + const MbCartPoint3D & GetFixedPoint() const { return fixedPoint; } + /// \ru Использовать неподвижную точку преобразования?. \en Is fixed point use? + bool IsFixed() const { return useFixed; } + /// \ru Одинаковое масштабирование по осям? \en Is the isotropic scaling? + bool Isisotropy() const { return isotropy; } + + /// \ru Выдать матрицу преобразования для редактирования. \en Get a transformation matrix for modify. + MbMatrix3D & SetMatrix() { return matrix; } + /// \ru Выдать неподвижную точку преобразования для редактирования. \en A fixed point of transformation for modify. + MbCartPoint3D & SetFixedPoint() { return fixedPoint; } + /// \ru Использовать неподвижную точку преобразования. \en Use fixed point of transformation. + void SetFixed( bool b ) { useFixed = b; } + /// \ru Использовать одинаковое масштабирование по осям. \en Use the same axes scaling. + void SetIsotropy( bool b ) { isotropy = b; } + + /// \ru Используется ли неподвижная точка преобразования? \en Whether the fixed point of transformation is used? + bool IsUsingFixed() const { return useFixed; } + /// \ru Является ли преобразование изотропным? \en Whether the transformation is isotropic? + bool IsIsotropy() const { return isotropy; } + /// \ru Рассчитать неподвижную точку преобразования. \en Calculate a fixed point of transformation. + bool CalculateFixedPoint(); + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const TransformValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( TransformValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы модификации. + \en Type of modification. \~ + \details \ru Тип определяет действия при прямом моделировании. + \en Type determines direct modeling actions. \~ + \ingroup Build_Parameters +*/ +enum MbeModifyingType { + dmt_Remove = 0, ///< \ru Удаление из тела выбранных граней с окружением. \en Removal of the specified faces with the neighborhood from a solid. + dmt_Create, ///< \ru Создание тела из выбранных граней с окружением. \en Creation of a solid from the specified faces with the neighborhood. + dmt_Action, ///< \ru Перемещение выбранных граней с окружением относительно оставшихся граней тела. \en Translation of the specified faces with neighborhood relative to the other faces of the solid. + dmt_Offset, ///< \ru Замена выбранных граней тела эквидистантными гранями (перемещение по нормали, изменение радиуса). \en Replacement of the specified faces of a solid with the offset faces (translation along the normal, change of the radius). + dmt_Fillet, ///< \ru Изменение радиусов выбранных граней скругления. \en Change of radii of the specified fillet faces. + dmt_Supple, ///< \ru Замена выбранных граней тела деформируемыми гранями (превращение в NURBS для редактирования). \en Replacement of the specified faces of a solid with a deformable faces (conversion to NURBS for editing). + dmt_Purify, ///< \ru Удаление из тела выбранных скруглений. \en Removal of the specified fillets from a solid. + dmt_Merger, ///< \ru Слияние вершин ребёр и удаление рёбер. \en Merging vertices of edges and edges removal. + dmt_United, ///< \ru Замена гладко стыкующихся граней одной гранью. \en Replacing smoothly joined faces with one face. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры прямого редактирования тела. + \en Parameter for direct editing of solid. \~ + \details \ru Параметры прямого редактирования тела. \n + Параметры содержат информацию о типе модификации и векторе перемещения. + \en Parameter for direct editing of solid. \n + The parameters contain Information about modification type and movement vector. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS ModifyValues { + +public: + MbeModifyingType way; ///< \ru Тип модификации. \en Type of modification. + MbVector3D direction; ///< \ru Перемещение при модификации. \en Moving when modifying. + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров операции удаления из тела выбранных граней. + \en Constructor of operation parameters of removing the specified faces from the solid. \~ + */ + ModifyValues() + : way( dmt_Remove ) + , direction( 0.0, 0.0, 0.0 ) + {} + /// \ru Конструктор по способу модификации и вектору перемещения. \en Constructor by way of modification and movement vector. + ModifyValues( MbeModifyingType w, const MbVector3D & p ) + : way ( w ) + , direction( p ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + ModifyValues( const ModifyValues & other ) + : way ( other.way ) + , direction( other.direction ) + {} + /// \ru Деструктор. \en Destructor. + ~ModifyValues() {} +public: + /// \ru Функция копирования. \en Copy function. + void Init( const ModifyValues & other ) { + way = other.way; + direction = other.direction; + } + /// \ru Оператор присваивания. \en Assignment operator. + ModifyValues & operator = ( const ModifyValues & other ) { + way = other.way; + direction = other.direction; + return *this; + } + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const ModifyValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( ModifyValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры деформируемой грани. + \en Parameters of the deformable face. \~ + \details \ru Параметры деформируемой грани используются при замене поверхности выбранной грани тела + NURBS-поверхностью и при дальнейшем редактировании этой грани. \n + \en Parameters of the deformable face are used when replacing the surface of selected face of solid + by NURBS-surface and with further editing of this face. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS NurbsValues { +public: + MbNurbsParameters uParameters; ///< \ru Параметры u-направления NURBS-поверхности. \en Parameters of u-direction of NURBS-surface. + MbNurbsParameters vParameters; ///< \ru Параметры v-направления NURBS-поверхности. \en Parameters of v-direction of NURBS-surface. + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров деформированной грани для замены + поверхности NURBS-поверхностью 4 порядка по всей области определения по направлениям u и v. + \en Constructor of parameters of deformed face for replacement + of surface by NURBS-surface of the fourth order in the entire domain along the u and v directions. \~ + */ + NurbsValues() + : uParameters() + , vParameters() + {} + + /** \brief \ru Конструктор по параметрам. + \en Constructor by parameters. \~ + \details \ru Конструктор параметров деформированной грани. + \en Constructor of parameters of deformed face. \~ + \param[in] ud, vd - \ru Порядок NURBS-копии по u и по v. + \en Order of NURBS-copy along u and v. \~ + \param[in] uc, vc - \ru Количество контрольных точек по u и по v. + \en The count of control points along u and v. \~ + \param[in] umin, umax, vmin, vmax - \ru Диапазоны параметров по u и v для деформирования грани. + \en Parameter ranges along u and v for deforming face. \~ + \param[in] uapprox, vapprox - \ru Флаги возможного построения приближенной поверхности, а не точной. + \en Flags of the possible constructing of approximate surface, not exact. \~ + */ + NurbsValues( size_t ud, size_t uc, double umin, double umax, bool uapprox, + size_t vd, size_t vc, double vmin, double vmax, bool vapprox ) + : uParameters( ud, uc, umin, umax, uapprox ) + , vParameters( vd, vc, vmin, vmax, vapprox ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + NurbsValues( const NurbsValues & other ) + : uParameters( other.uParameters ) + , vParameters( other.vParameters ) + {} + /// \ru Деструктор. \en Destructor. + ~NurbsValues() {} + +public: + /// \ru Функция копирования. \en Copy function. + void Init( const NurbsValues & other ) { + uParameters = other.uParameters; + vParameters = other.vParameters; + } + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const NurbsValues & other, double accuracy ) const; + /// \ru Оператор присваивания. \en Assignment operator. + NurbsValues & operator = ( const NurbsValues & other ) { + uParameters = other.uParameters; + vParameters = other.vParameters; + return *this; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( NurbsValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//-------------------------------------------------------------------- +/** \brief \ru Параметры для построения NURBS-блока. + \en The parameters for construction of NURBS-block. \~ + \details \ru Параметры для построения блока из NURBS-поверхностей. \n + \en The parameters for construction of block.from NURBS-surfaces. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS NurbsBlockValues { +public: + // \ru Параметры для построения блока из nurbs-поверхностей. \en The parameters for construction of block.from nurbs-surfaces. + // + // \ru +Z (N) - номер грани *-----* \en +Z (N) - index of face *-----* + // | | | + // *--------* | (5) | + // /| /| | | + // / | / | *-----*-----*-----*-----* + // / | / | | | | | | + // *---+----* | | (2) | (3) | (4) | (1) | + // | | | | | | | | | + // | *----+---*-- +Y *-----*-----*-----*-----* + // | / | / | | + // | / | / | (0) | + // |/ |/ | | + // *--------* *-----* + // / + // \ru +X Развертка граней блока внешней стороной к наблюдателю. \en +X Unfolding the outer side of block faces to the viewer. + // + // \ru Принцип соответствия номеров и граней. \en Principle of correspondence of indices and faces. + // \ru Элементы матрицы структуры соответствуют параметрам поверхностей следующих граней блока: \en Matrix elements of the structure correspond to surfaces parameters the following blocks: + // \ru - элемент 0 - грани 0, 5 ( нижняя и верхняя грани ); \en - element 0 - faces 0, 5 ( lower and upper faces ); + // \ru - элемент 1 - грани 1, 3 ( боковые грани ); \en - element 1 - faces 1, 3 ( lateral faces ); + // \ru - элемент 2 - грани 2, 4 ( боковые грани ). \en - element 2 - faces 2, 4 ( lateral faces ). + + ptrdiff_t udeg[3]; ///< \ru Порядок nurbs-сплайнов по первому параметру для трех пар поверхностей граней блока. \en Order of nurbs-splines along the first parameter for three pairs of block faces. + ptrdiff_t vdeg[3]; ///< \ru Порядок nurbs-сплайнов по второму параметру для трех пар поверхностей граней блока. \en Order of nurbs-splines along the second parameter for three pairs of block faces. + ptrdiff_t ucnt[3]; ///< \ru Количество контрольных точек вдоль первого параметра для трех пар поверхностей граней блока. \en The count of matrix elements of control points along the first and for three pairs of block faces. + ptrdiff_t vcnt[3]; ///< \ru Количество контрольных точек вдоль второго параметра для трех пар поверхностей граней блока. \en The count of matrix elements of control points along the second and for three pairs of block faces. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры сплайновой поверхности. + \en The parameters of spline surface. \~ + \details \ru Параметры определяют контрольные точки, веса, узлы сплайновой поверхности. \n + \en The parameters determines control points, weights, knots of spline surface. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS NurbsSurfaceValues { + friend class MbNurbsSurfacesSolid; +private: + ptrdiff_t udegree; ///< \ru Порядок В-сплайна по U. \en Spline degree along U. + ptrdiff_t vdegree; ///< \ru Порядок В-сплайна по V. \en Spline degree along V. + bool uclosed; ///< \ru Признак замкнутости по U. \en Attribute of closedness along U. + bool vclosed; ///< \ru Признак замкнутости по V. \en Attribute of closedness along V. + Array2 points; ///< \ru Множество точек. \en Set of points. + double weight; ///< \ru Вес точек в случае одинаковости весов. \en Points weight in the case of equal weights. + Array2 * weights; ///< \ru Веса точек (может быть NULL). \en Weights of points (can be NULL). + bool throughPoints; ///< \ru Строить поверхность, проходящую через точки. \en Build surface passing through points. + bool pointsCloud; ///< \ru Облако точек (массив не упорядочен). \en Point cloud (disordered array). + MbPlane * cloudPlane; ///< \ru Опорная плоскость облака точек. \en Support plane of point cloud. + bool ownCloudPlane; ///< \ru Собственная опорная плоскость облака точек. \en Own support plane of point cloud. + bool checkSelfInt; ///< \ru Искать самопересечения. \en Find self-intersection. + mutable CSSArray checkLnNumbers; ///< \ru Номера проверяемых строк. \en The indices of checked rows. + mutable CSSArray checkCnNumbers; ///< \ru Номера проверяемых столбцов. \en The indices of checked columns. + mutable ptrdiff_t minCloudDegree; ///< \ru Минимально возможный порядок сплайнов по облаку точек. \en The smallest possible order of splines by point cloud. + mutable ptrdiff_t maxCloudDegree; ///< \ru Максимально возможный порядок сплайнов по облаку точек. \en The maximum possible order of splines by point cloud. + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров не замкнутой сплайновой поверхности + второго порядка по направлениям u и v. + \en Constructor of parameters of non-closed spline surface + of second order along the u and v directions. \~ + */ + NurbsSurfaceValues(); + + /// \ru Конструктор копирования. \en Copy-constructor. + NurbsSurfaceValues( const NurbsSurfaceValues & ); + /// \ru Деструктор. \en Destructor. + ~NurbsSurfaceValues(); + +public: + /** \brief \ru Инициализация по сетке точек. + \en Initialization by grid of points. \~ + \details \ru Инициализация параметров сплайновой поверхности по сетке точек. + \en Initialization of parameters of spline surface by grid of points. \~ + \param[in] uDeg, vDeg - \ru Порядок по u и по v. + \en Order along u and v. \~ + \param[in] uCls, vCls - \ru Признаки замкнутости поверхности по u и по v. + \en Attribute of surface closedness along u and v. \~ + \param[in] pnts - \ru Набор точек. + \en A point set. \~ + \param[in] checkSelfInt - \ru Признак проверки на самопересечение. + \en Attribute of check for self-intersection. \~ + \return \ru false при некорректных параметрах. + \en False if incorrect parameters. \~ + */ + bool InitMesh( ptrdiff_t uDeg, bool uCls, + ptrdiff_t vDeg, bool vCls, + const Array2 & pnts, + bool checkSelfInt ); + + /** \brief \ru Инициализация по сетке точек. + \en Initialization by grid of points. \~ + \details \ru Инициализация параметров сплайновой поверхности по сетке точек. + \en Initialization of parameters of spline surface by grid of points. \~ + \param[in] uDeg, vDeg - \ru Порядок по u и по v. + \en Order along u and v. \~ + \param[in] uCls, vCls - \ru Признаки замкнутости поверхности по u и по v. + \en Attribute of surface closedness along u and v. \~ + \param[in] pnts - \ru Набор точек. + \en A point set. \~ + \param[in] wts - \ru Веса точек. + \en Weights of points. \~ + \param[in] checkSelfInt - \ru Признак проверки на самопересечение. + \en Attribute of check for self-intersection. \~ + \return \ru false при некорректных параметрах. + \en False if incorrect parameters. \~ + */ + bool InitMesh( ptrdiff_t uDeg, bool uCls, + ptrdiff_t vDeg, bool vCls, + const Array2 & pnts, + const Array2 * wts, bool checkSelfInt ); + + /** \brief \ru Инициализация по облаку точек. + \en Initialization by point cloud. \~ + \details \ru Инициализация по облаку точек (используется оригинал плоскости).\n + Если uvDeg < 0, то будет создаваться набор треугольных пластин \n + (триангуляцией проекций точек на cloudPlace) + \en Initialization by point cloud (used the original plane).\n + If uvDeg < 0, then set of triangular plates is created \n + (by triangulation of points projections on the cloudPlace) \~ + \param[in] uvDeg - \ru Порядок по u и по v. + \en Order along u and v. \~ + \param[in] pnts - \ru Множество точек.\n + Набор точек подходит для инициализации (является облаком точек) + в случае, если это одномерный массив точек, + не лежащих на одной прямой, без совпадений. + \en Set of points.\n + Set of points is suitable for initialization (is a point cloud) + if it is one-dimensional array of points + which don't lie on a straight line without coincidence. \~ + \param[in] cloudPlace - \ru Опорная плоскость облака точек. + \en Support plane of point cloud. \~ + \param[in] checkSelfInt - \ru Признак проверки на самопересечение. + \en Attribute of check for self-intersection. \~ + \return \ru true при корректных параметрах. + \en True if correct parameters. \~ + */ + bool InitCloud( ptrdiff_t uvDeg, + const Array2 & pnts, + const MbPlacement3D * cloudPlace, + bool checkSelfInt ); + + /// \ru Оператор копирования. \en Copy-operator. + void operator = ( const NurbsSurfaceValues & ); + +public: + /// \ru Первичная проверка корректности параметров. \en Initial check of parameters correctness + bool IsValid( bool checkPoints ) const; + + /// \ru Получить порядок сплайнов по U. \en Get splines degree along U. + ptrdiff_t GetUDegree() const { return udegree; } + /// \ru Получить порядок сплайнов по V. \en Get splines degree along V. + ptrdiff_t GetVDegree() const { return vdegree; } + /// \ru Замкнутость по U. \en Closedness along U. + bool GetUClosed() const { return uclosed; } + /// \ru Замкнутость по V. \en Closedness along V. + bool GetVClosed() const { return vclosed; } + /// \ru Количество точек по U. \en A count of points along U. + size_t GetUCount() const { return points.Columns(); } + /// \ru Количество точек по V. \en A count of points along V. + size_t GetVCount() const { return points.Lines(); } + + /// \ru Установить порядок сплайна по u. \en Set spline degree along u. + bool SetUDegree( size_t uDeg ); + /// \ru Установить порядок сплайна по v. \en Set spline degree along v. + bool SetVDegree( size_t vDeg ); + /// \ru Установить замкнутость по U. \en Set closedness along U. + void SetUClosed( bool uCls ) { uclosed = uCls; } + /// \ru Установить замкнутость по V. \en Set closedness along V. + void SetVClosed( bool vCls ) { vclosed = vCls; } + + /// \ru Получить точку по позиции. \en Get point by position. + bool GetUVPoint ( size_t ui, size_t vi, MbCartPoint3D & ) const; + /// \ru Получить вес по позиции. \en Get weight by position. + bool GetUVWeight( size_t ui, size_t vi, double & ) const; + /// \ru Получить общий вес (вернет true, если вес у всех точек одинаковый). \en Get total weight (return true if all the weights are the same). + bool GetCommonWeight( double & ) const; + /// \ru Установить точки по позиции. \en Set points by position. + bool SetUVPoint ( size_t ui, size_t vi, const MbCartPoint3D & ); + /// \ru Установить вес по позиции. \en Set weight by position. + bool SetUVWeight( size_t ui, size_t vi, const double & ); + /// \ru Установить общий вес. \en Set total weight. + bool SetCommonWeight( double ); + + /// \ru Преобразовать данные согласно матрице. \en Transform data according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * ireg ); + /// \ru Сдвинуть данные вдоль вектора. \en Move data along a vector. + void Move ( const MbVector3D &, MbRegTransform * ireg ); + /// \ru Повернуть данные вокруг оси на заданный угол. \en Rotate data at a given angle around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg ); + + bool IsSame( const NurbsSurfaceValues &, double accuracy ) const; // \ru Являются ли объекты равными? \en Determine whether an object is equal? + + /// \ru Установить размерность массивов точек и весов без сохранения или с сохранением имеющихся данных. \en Set the size of arrays of points and weights without saving or with saving of existing data. + bool SetSize( size_t ucnt, size_t vcnt, bool keepData = false ); + /// \ru Установить флаг прохождения поверхности через точки. \en Set flag of surface passing through the points. + void SetThroughPoints( bool tp ); + /// \ru Будет ли поверхность проходить через точки? \en Whether the surface passes through the points? + bool IsThroughPoints() const { return throughPoints; } + /// \ru Является ли массив облаком точек? \en Whether the array is point cloud? + bool IsPointsCloud() const { return pointsCloud; } + /// \ru Используется ли собственная плоскость проецирования (в случае массива по облаку точек)? \en Whether the own plane of projection is used (in the case of array by point cloud)? + bool IsOwnCloudPlane() const { return ownCloudPlane; } + /// \ru Нужно ли проверять самопересечения? \en Whether it is necessary to check self-intersections? + bool CheckSelfInt() const { return checkSelfInt; } + /// \ru Получить массив номеров проверяемых строк. \en Get the array of indices of checked rows. + void GetCheckLines( CSSArray & checkNumbers ) const { checkNumbers = checkLnNumbers; } + /// \ru Получить массив номеров проверяемых столбцов. \en Get the array of indices of checked columns. + void GetCheckCols ( CSSArray & checkNumbers ) const { checkNumbers = checkCnNumbers; } + /// \ru Получить количество строк. \en Get the count of rows. + size_t GetPointsLines () const { return points.Lines(); } //-V524 + /// \ru Получить количество столбцов. \en Get the count of columns. + size_t GetPointsColumns() const { return points.Columns(); } //-V524 + /// \ru Получить массив точек. \en Get array of points. + bool GetPoints ( Array2 & pnts ) const { return pnts.Init( points ); } + /// \ru Если ли веса? \en Is there weights? + bool IsWeighted() const { return (weights != NULL); } + /// \ru Получить массив весов. \en Get array of weights. + bool GetWeights( Array2 & wts ) const; + /// \ru Получить плоскость проецирования. \en Get the plane of projection. + const MbPlane * GetCloudPlane() const { return (pointsCloud ? cloudPlane : NULL);} + + /** \brief \ru Минимально возможный порядок сплайнов в случае облака точек. + \en The smallest possible order of splines in the case of point cloud. \~ + \details \ru Минимально возможный порядок сплайнов в случае облака точек.\n + Запрашивать после успешного создания поверхности, иначе вернет отрицательное значение. + \en The smallest possible order of splines in the case of point cloud.\n + Request after the successful creation of the surface otherwise returns a negative value. \~ + */ + ptrdiff_t GetMinCloudDegree() const { return minCloudDegree; } + + /** \brief \ru Максимально возможный порядок сплайнов в случае облака точек. + \en The maximum possible order of splines in the case of point cloud. \~ + \details \ru Максимально возможный порядок сплайнов в случае облака точек.\n + Запрашивать после успешного создания поверхности, иначе вернет отрицательное значение. + \en The maximum possible order of splines in the case of point cloud.\n + Request after the successful creation of the surface otherwise returns a negative value. \~ + */ + ptrdiff_t GetMaxCloudDegree() const { return maxCloudDegree; } + + /// \ru Выставить максимально возможный порядок по обработанному (регуляризованному) облаку точек. \en Set the maximum possible order by processed (regularized) point cloud. + bool SetCloudDegreeRange( const NurbsSurfaceValues & meshParam ) const; + +private: + void DeleteWeights(); + bool CreateWeights( double wt ); + void SetCloudPlane( MbPlane * ); + bool CreateOwnCloudPlane(); +public: + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( NurbsSurfaceValues, MATH_FUNC_EX ) +}; + + +//------------------------------------------------------------------------------ +// \ru Получить веса \en Get weights +// --- +inline bool NurbsSurfaceValues::GetWeights( Array2 & wts ) const +{ + if ( weights != NULL ) { + if ( wts.Init( *weights ) ) + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Установить порядок сплайна по u \en Set spline degree along u +// --- +inline bool NurbsSurfaceValues::SetUDegree( size_t uDeg ) +{ + if ( uDeg > 1 ) { + udegree = uDeg; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Установить порядок сплайна по v \en Set spline degree along v +// --- +inline bool NurbsSurfaceValues::SetVDegree( size_t vDeg ) +{ + if ( vDeg > 1 ) { + vdegree = vDeg; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Получить точку \en Get a point +// --- +inline bool NurbsSurfaceValues::GetUVPoint( size_t ui, size_t vi, MbCartPoint3D & pnt ) const +{ + if ( ui < GetUCount() && vi < GetVCount() ) { + pnt = points( vi, ui ); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Установить точку \en Set a point +// --- +inline bool NurbsSurfaceValues::SetUVPoint( size_t ui, size_t vi, const MbCartPoint3D & pnt ) +{ + bool bRes = false; + + if ( ui < GetUCount() && vi < GetVCount() ) { + MbCartPoint3D bakPoint( points( vi, ui ) ); + points( vi, ui ) = pnt; + + if ( pointsCloud && ownCloudPlane ) { + if ( CreateOwnCloudPlane() ) + bRes = true; + else + points( vi, ui ) = bakPoint; + } + } + return bRes; +} + + +//------------------------------------------------------------------------------ +// \ru Получить вес \en Get a weight +// --- +inline bool NurbsSurfaceValues::GetUVWeight( size_t ui, size_t vi, double & wt ) const +{ + if ( weights != NULL && ui < GetUCount() && vi < GetVCount() ) { + wt = (*weights)( vi, ui ); + return (wt != UNDEFINED_DBL); //-V550 + } + wt = weight; + return (wt != UNDEFINED_DBL); //-V550 +} + + +//------------------------------------------------------------------------------ +// \ru Получить общий вес, вернет true, если вес у вес одинаковый \en Get total weight, return true if all the weights are the same +// --- +inline bool NurbsSurfaceValues::GetCommonWeight( double & wt ) const +{ + if ( weights == NULL && weight != UNDEFINED_DBL ) { //-V550 + wt = weight; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Установить флаг прохождения поверхности через точки \en Set flag of surface passing through the points +// --- +inline void NurbsSurfaceValues::SetThroughPoints( bool tp ) +{ + throughPoints = tp; + + if ( throughPoints ) { + DeleteWeights(); + weight = 1.0; + } + if ( weights == NULL && weight == UNDEFINED_DBL ) //-V550 + weight = 1.0; +} + + +//----------------------------------------------------------------------------- +/** \brief \ru Параметры поверхности по сетке кривых. + \en Surface parameter by grid of curves. \~ + \details \ru Параметры содержат необходимые данные для построения поверхности по сетке кривых. \n + \en The parameters contain the necessary data to construct a surface by grid of curves. \n \~ + \ingroup Build_Parameters +*/ +//--- +struct MATH_CLASS MeshSurfaceValues { + friend class MbMeshShell; + +private: + RPArray curvesU; ///< \ru Набор кривых по первому направлению. \en Set of curves along the first direction. + RPArray curvesV; ///< \ru Набор кривых по второму направлению. \en Set of curves along the second direction. + RPArray chainsU; ///< \ru Набор цепочек по первому направлению. \en Set of chains along the first direction. + RPArray chainsV; ///< \ru Набор цепочек по второму направлению. \en Set of chains along the second direction. + bool uClosed; ///< \ru Замкнутость по U направлению. \en Closedness along U direction. + bool vClosed; ///< \ru Замкнутость по V направлению. \en Closedness along V direction. + bool checkSelfInt;///< \ru Искать самопересечения. \en Find self-intersections. + // \ru Сопряжения на границе (если сопряжения заданы, то кривые должны быть SurfaceCurve или контур из SurfaceCurve). \en Mates on the boundary (if mates are given, then curves must be SurfaceCurve or contour from SurfaceCurve). + MbeMatingType type0; ///< \ru Сопряжение на границе 0. \en Mate on the boundary 0. + MbeMatingType type1; ///< \ru Сопряжение на границе 1. \en Mate on the boundary 1. + MbeMatingType type2; ///< \ru Сопряжение на границе 2. \en Mate on the boundary 2. + MbeMatingType type3; ///< \ru Сопряжение на границе 3. \en Mate on the boundary 3. + + MbSurface * surface0; ///< \ru Сопрягаемая поверхность через границу 0 (curvesU[0]). \en Mating surface through the boundary 0 (curvesU[0]). + MbSurface * surface1; ///< \ru Сопрягаемая поверхность через границу 1 (curvesV[0]). \en Mating surface through the boundary 1 (curvesV[0]). + MbSurface * surface2; ///< \ru Сопрягаемая поверхность через границу 2 (curvesU[maxU]). \en Mating surface through the boundary 2 (curvesU[maxU]). + MbSurface * surface3; ///< \ru Сопрягаемая поверхность через границу 3 (curvesV[maxV]). \en Mating surface through the boundary 3 (curvesV[maxV]). + MbPoint3D * point; ///< \ru Точка на поверхности. Используется для уточнения. \en Point on the surface. Used for specializing. + + bool defaultDir0; ///< \ru Направление сопряжения на границе 0 по умолчанию. \en Default mate direction through the boundary 0. + bool defaultDir1; ///< \ru Направление сопряжения на границе 1 по умолчанию. \en Default mate direction through the boundary 1. + bool defaultDir2; ///< \ru Направление сопряжения на границе 2 по умолчанию. \en Default mate direction through the boundary 2. + bool defaultDir3; ///< \ru Направление сопряжения на границе 3 по умолчанию. \en Default mate direction through the boundary 3. + mutable uint8 directOrderV;///< \ru По второму семейству кривых порядок кривых совпадает. \en Order of the curves coincides by the second set of curves. +private: + /// \ru Конструктор копирования. \en Copy-constructor. + MeshSurfaceValues( const MeshSurfaceValues &, MbRegDuplicate * ireg ); +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MeshSurfaceValues(); + /// \ru Деструктор. \en Destructor. + ~MeshSurfaceValues(); + +public: + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации на оригиналах кривых и копиях поверхностей. + \en Initialization function on the original curves and copies of surfaces. \~ + \param[in] curvesU, curvesV - \ru Наборы кривых по первому и второму направлению. + \en Sets of curves along the first and second directions. \~ + \param[in] chainsU, chainsV - \ru Наборы цепочек по первому и второму направлению. + \en Sets of chains along the first and second directions. \~ + \param[in] uClosed, vClosed - \ru Признак замкнутости по направлениям u и v. + \en Closedness attribute along the u and v directions. \~ + \param[in] checkSelfInt - \ru Флаг проверки на самопересечение. + \en Flag of check for self-intersection. \~ + \param[in] type0, type1, type2, type3 - \ru Типы сопряжений на границах. + \en Mates types on the boundaries. \~ + \param[in] surfaces0, surfaces1, surfaces2, surfaces3 - \ru Соответствующие сопрягаемые поверхности. + \en Corresponding mating surfaces. \~ + \param[in] modify - \ru Флаг модификации кривых по сопряжениям. + \en Flag of curves modification by mates. \~ + */ + bool Init( const RPArray & curvesU, bool uClosed, + const RPArray & curvesV, bool vClosed, + bool checkSelfInt, + const RPArray * chainsU = NULL, + const RPArray * chainsV = NULL, + MbeMatingType type0 = trt_Position, MbeMatingType type1 = trt_Position, + MbeMatingType type2 = trt_Position, MbeMatingType type3 = trt_Position, + const MbSurface * surf_0 = NULL, // \ru Сопрягаемые поверхности через curvesU[0] \en Mating surfaces through curvesU[0] + const MbSurface * surf_1 = NULL, // \ru Сопрягаемые поверхности через curvesV[0] \en Mating surfaces through curvesV[0] + const MbSurface * surf_2 = NULL, // \ru Сопрягаемые поверхности через curvesU[maxU] \en Mating surfaces through curvesU[maxU] + const MbSurface * surf_3 = NULL, // \ru Сопрягаемые поверхности через curvesV[maxV] \en Mating surfaces through curvesV[maxV] + const MbPoint3D * pnt = NULL, + bool modify = true, + bool direct0 = true, bool direct1 = true, bool direct2 = true, bool direct3 = true ); + + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации на оригиналах или копиях кривых и поверхностей. + \en Initialization function on the originals or copies of curves and surfaces. \~ + \param[in] pars - \ru Исходные параметры. + \en Initial parameters. \~ + \param[in] sameItems - \ru Флаг использования оригиналов кривых и поверхностей. + \en Flag of using originals of curves and surfaces. \~ + */ + void Init( const MeshSurfaceValues & pars, bool sameItems ); + + /** \brief \ru Лежит ли кривая на поверхности. + \en Determine whether the curve lies on the surface. \~ + \details \ru Лежит ли кривая полностью на поверхности. + \en Determine whether the curve entirely lies on the surface. \~ + \param[in] curve - \ru Проверяемая кривая. + \en Checking curve. \~ + \param[in] surf - \ru Проверяемая поверхность. + \en Checking surface. \~ + */ + bool IsCurveOnSurface( const MbCurve3D & curve, const MbSurface & surf ) const; + + /** \brief \ru Сопрягаются ли кривые с поверхностью точках пересечения с otherCurve. + \en Whether the curves are mated with surface in the points of intersection with otherCurve. \~ + \details \ru Сопрягаются ли кривые (касательно, по нормали, гладко) с поверхностью в точках пересечения с otherCurve. + \en Whether the curves are mated (tangentially, along the normal, smoothly) with surface in the points of intersection with otherCurve. \~ + \param[in] curves - \ru Набор проверяемых кривых. + \en Set of checking curves. \~ + \param[in] surf - \ru Поверхность. + \en The surface. \~ + \param[in] otherCurve - \ru Кривая на этой поверхности. + \en Curve on this surface. \~ + \param[out] isTangent - \ru Признак касательного сопряжения. + \en Attribute of the tangent mate. \~ + \param[out] isNormal - \ru Признак сопряжения по нормали. + \en Attribute of normal mate. \~ + \param[out] isSmooth - \ru Признак гладкого сопряжения. + \en Attribute of the smooth mate. \~ + */ + void AreCurvesMatingToSurface( const RPArray & curves, + const MbSurface & surf, + const MbCurve3D * otherCurve, + bool & isTangent, + bool & isNormal, + bool & isSmooth ) const; + + /// \ru Получить точки скрещивания-пересечения кривой с семейством кривых. \en Get crossing-intersection points of curves with the set of curves. + bool GetPointsOfCrossing( const MbCurve3D & curve, const RPArray & otherCurves, + SArray & res ) const; + /// \ru Проверка на наличие контуров и ломаных. \en Check for contours and broken lines. + bool CheckMultiSegment( const MbSNameMaker & snMaker ) const; + /// \ru Обратить порядок следования кривых по второму направлению, чтобы directOrderV был true. \en Invert order of curves along the second direction to directOrderV is true. + void InvertCurvesV (); + + /// \ru Получить кривую на границе с номером i. \en Get i-th curve on the boundary. + const MbCurve3D * GetBorderCurve( ptrdiff_t i ) const; + /// \ru Получить тип сопряжения на границе с номером i. \en Get i-th mate type on the boundary. + MbeMatingType GetTransitType( ptrdiff_t i ) const; + /// \ru Получить поверхность сопряжения на границе с номером i. \en Get i-th mate surface on the boundary. + const MbSurface * GetSurface( size_t i ) const; + /// \ru Получить поверхность сопряжения на границе с номером i. \en Get i-th mate surface on the boundary. + MbSurface * SetSurface( size_t i ); + /// \ru Получить направление сопряжения на границе с номером i. \en Get i-th mate direction on the boundary. + bool IsDefaultDirection( size_t i ) const; + + /// \ru Замкнутость по U направлению. \en Closedness along U direction. + bool GetUClosed() const { return uClosed; } + /// \ru Замкнутость по V направлению. \en Closedness along V direction. + bool GetVClosed() const { return vClosed; } + /// \ru Замкнутость по U направлению. \en Closedness along U direction. + void SetUClosed( bool cls ) { uClosed = cls; } + /// \ru Замкнутость по V направлению. \en Closedness along V direction. + void SetVClosed( bool cls ) { vClosed = cls; } + + /// \ru Количество кривых по U. \en The count of curves along U. + size_t GetCurvesUCount() const { return curvesU.Count(); } + /// \ru Максимальный индекс в массиве кривых по U. \en The maximum index in the array of curves along U. + ptrdiff_t GetCurvesUMaxIndex() const { return curvesU.MaxIndex(); } + /// \ru Получить кривую по индексу. \en Get the curve by the index. + const MbCurve3D * GetCurveU( size_t k ) const { return ((k < curvesU.Count()) ? curvesU[k] : NULL); } + /// \ru Получить кривую по индексу. \en Get the curve by the index. + MbCurve3D * SetCurveU( size_t k ) { return ((k < curvesU.Count()) ? curvesU[k] : NULL); } + /// \ru Получить кривые по U. \en Get curves along U. + void GetCurvesU( RPArray & curves ) const { curves.AddArray(curvesU); } + /// \ru Установить кривые по U. \en Set curves along U. + void SetCurvesU( const RPArray & newCurves ); + /// \ru Отцепить кривые по U. \en Detach curves along U. + void DetachCurvesU( RPArray & curves ); + /// \ru Найти кривую. \en Find curve. + size_t FindCurveU( const MbCurve3D * curve ) const { return curvesU.FindIt( curve ); } + + /// \ru Количество кривых по V. \en The count of curves along V. + size_t GetCurvesVCount() const { return curvesV.Count(); } + /// \ru Максимальный индекс в массиве кривых по V. \en The maximum index in the array of curves along V. + ptrdiff_t GetCurvesVMaxIndex() const { return curvesV.MaxIndex(); } + /// \ru Получить кривую по индексу. \en Get the curve by the index. + const MbCurve3D * GetCurveV( size_t k ) const { return ((k < curvesV.Count()) ? curvesV[k] : NULL); } + /// \ru Получить кривую по индексу. \en Get the curve by the index. + MbCurve3D * SetCurveV( size_t k ) const { return ((k < curvesV.Count()) ? curvesV[k] : NULL); } + /// \ru Получить кривые по V. \en Get curves along V. + void GetCurvesV( RPArray & curves ) const { curves.AddArray(curvesV); } + /// \ru Установить кривые по V. \en Set curves along V. + void SetCurvesV( const RPArray & newCurves ); + /// \ru Отцепить кривые по V. \en Detach curves along V. + void DetachCurvesV( RPArray & curves ); + /// \ru Найти кривую. \en Find curve. + size_t FindCurveV( const MbCurve3D * curve ) const { return curvesV.FindIt( curve ); } + + /// \ru Количество цепочек по U. \en The count of chains along U. + size_t GetChainsUCount() const { return chainsU.Count(); } + /// \ru Максимальный индекс в массиве цепочек по U. \en The maximum index in the array of chains along U. + ptrdiff_t GetChainsUMaxIndex() const { return chainsU.MaxIndex(); } + /// \ru Получить цепочку по индексу. \en Get the chain by the index. + const MbPolyline3D * GetChainU( size_t k ) const { return ( ( k < chainsU.Count() ) ? chainsU[k] : NULL ); } + /// \ru Получить цепочку по индексу. \en Get the chain by the index. + MbPolyline3D * SetChainU( size_t k ) { return ( ( k < chainsU.Count() ) ? chainsU[k] : NULL ); } + /// \ru Получить цепочки по U. \en Get chains along U. + void GetChainsU( RPArray & chains ) const { chains.AddArray( chainsU ); } + /// \ru Установить цепочки по U. \en Set chains along U. + void SetChainsU( const RPArray & newChains ); + /// \ru Отцепить цепочки по U. \en Detach chains along U. + void DetachChainsU( RPArray & chains ); + /// \ru Найти цепочку. \en Find chain. + size_t FindChainU( const MbPolyline3D * curve ) const { return chainsU.FindIt( curve ); } + + /// \ru Количество цепочек по V. \en The count of chains along V. + size_t GetChainsVCount() const { return chainsV.Count(); } + /// \ru Максимальный индекс в массиве цепочек по V. \en The maximum index in the array of chains along V. + ptrdiff_t GetChainsVMaxIndex() const { return chainsV.MaxIndex(); } + /// \ru Получить цепочку по индексу. \en Get the chain by the index. + const MbPolyline3D * GetChainV( size_t k ) const { return ( ( k < chainsV.Count() ) ? chainsV[k] : NULL ); } + /// \ru Получить цепочку по индексу. \en Get the chain by the index. + MbPolyline3D * SetChainV( size_t k ) { return ( ( k < chainsV.Count() ) ? chainsV[k] : NULL ); } + /// \ru Получить цепочки по V. \en Get chains along V. + void GetChainsV( RPArray & chains ) const { chains.AddArray( chainsV ); } + /// \ru Установить цепочки по V. \en Set chains along V. + void SetChainsV( const RPArray & newChains ); + /// \ru Отцепить цепочки по V. \en Detach chains along V. + void DetachChainsV( RPArray & chains ); + /// \ru Найти цепочку. \en Find chain. + size_t FindChainV( const MbPolyline3D * curve ) const { return chainsV.FindIt( curve ); } + + /// \ru Установить точку. \en Set point. + void SetPoint( const MbPoint3D * pnt ); + /// \ru Получить точку. \en Get point. + const MbPoint3D * GetPoint() const { return point; } + /// \ru Получить точку. \en Get point. + MbPoint3D * SetPoint() { return point; } + + + /** + \ru \name Вспомогательные функции геометрических преобразований. + \en \name Auxiliary functions of geometric transformations. + \{ */ + /// \ru Преобразовать кривые согласно матрице. \en Transform curves according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * ireg ); + /// \ru Сдвинуть кривые вдоль вектора. \en Move curves along a vector. + void Move ( const MbVector3D &, MbRegTransform * ireg ); + /// \ru Повернуть кривые вокруг оси на заданный угол. \en Rotate curves at a given angle around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg ); + /// \ru Привести кривые к поверхностной форме (кривые на поверхности) \en Convert curves to the surface form (curves on the surface) + bool TransformCurves(); + /** \} */ + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MeshSurfaceValues &, double accuracy ) const; + + /// \ru Набор граничных поверхность пуст? \en Whether the set of boundary surfaces is empty? + bool AreSurfacesEmpty() const { return (surface0 == NULL && surface1 == NULL && surface2 == NULL && surface3 == NULL); } + /// \ru Нужно ли проверять самопересечения? \en Whether it is necessary to check self-intersections? + bool CheckSelfInt() const { return checkSelfInt; } + +private: + void AddRefCurves(); // \ru Увеличить счетчик ссылок у кривых. \en Increase the reference count of curves. + void AddRefPoint(); // \ru Увеличить счетчик ссылок у точки. \en Increase the reference count of point. + void AddRefSurfaces(); // \ru Увеличить счетчик ссылок у поверхностей. \en Increase the reference count of surfaces. + void ReleaseCurves(); // \ru Удалить кривые. \en Release curves. + void ReleasePoint(); // \ru Удалить точку. \en Release point. + void ReleaseSurfaces(); // \ru Удалить поверхности. \en Release surfaces. + // \ru Определить порядок следования кривых по второму направлению. \en Determine the order of curves along the second direction. + void CalculateOrderV() const; + // \ru Привести кривую к типу поверхностной кривой или к контура из SurfaceCurve. \en Convert the curve to type of surface curve or contour from SurfaceCurve. + bool TransformToSurfaceCurve( const MbCurve3D & initCurve, + const MbSurface & surface, + const RPArray & constrCurves, + MbSurfaceCurve *& resCurve ) const; +public: + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MeshSurfaceValues, MATH_FUNC_EX ) + OBVIOUS_PRIVATE_COPY( MeshSurfaceValues ) +}; + + +//------------------------------------------------------------------------------ +// \ru Получить тип сопряжения на границе с номером i \en Get i-th mate type on the boundary +//--- +inline +MbeMatingType MeshSurfaceValues::GetTransitType( ptrdiff_t i ) const +{ + MbeMatingType res = trt_Position; + + switch ( i ) { + case 0: res = type0; break; + case 1: res = type1; break; + case 2: res = type2; break; + case 3: res = type3; break; + } + + return res; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для построения линейчатой поверхности. + \en Data for the construction of a ruled surface. \~ + \details \ru Данные для построения линейчатой поверхности по двум кривым. \n + \en Data for the construction of a ruled surface by two curves. \n \~ + \ingroup Build_Parameters +*/ +//--- +struct MATH_CLASS RuledSurfaceValues { + friend class MbRuledShell; +private: + MbCurve3D * curve0; ///< \ru Первая кривая \en The first curve. + MbCurve3D * curve1; ///< \ru Вторая кривая. \en The second curve. + SArray breaks0; ///< \ru Параметры разбиения первой кривой curve0. \en Splitting parameters of the first curve0 curve. + SArray breaks1; ///< \ru Параметры разбиения второй кривой curve1. \en Splitting parameters of the second curve1 curve. + bool joinByVertices; ///< \ru Соединять контура с одинаковым количеством сегментов через вершины. \en Join contour with the same count of segments through vertices. + bool checkSelfInt; ///< \ru Искать самопересечения. \en Find self-intersections. + bool simplifyFaces; ///< \ru Упрощать грани. \en SimplifyFaces. +private: + /// \ru Конструктор копирования. \en Copy-constructor. + RuledSurfaceValues( const RuledSurfaceValues &, MbRegDuplicate * ireg ); +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + RuledSurfaceValues(); + /// \ru Деструктор. \en Destructor. + ~RuledSurfaceValues(); + +public: + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации на оригиналах кривых. + Контейнеры параметров разбиения кривых будут очищены. + \en Initialization function on the curves originals. + Containers of parameters of splitting curves will be cleared. \~ + \param[in] inCurve0 - \ru Кривая для замены первой кривой. + \en The curve for the replacement of the first curve. \~ + \param[in] inCurve1 - \ru Кривая для замены второй кривой. + \en The curve for the replacement of the second curve. \~ + \param[in] selfInt - \ru Флаг проверки самопересечений. + \en Flag of self-intersections checking. \~ + \return \ru Результат первичной проверки параметров. + \en The result of the primary scan of parameters. \~ + */ + bool Init( const MbCurve3D & inCurve0, + const MbCurve3D & inCurve1, + bool selfInt = false ); + + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации на оригиналах кривых. + \en Initialization function on the curves originals. \~ + \param[in] inCurve0 - \ru Кривая для замены первой кривой. + \en The curve for the replacement of the first curve. \~ + \param[in] inCurve1 - \ru Кривая для замены второй кривой. + \en The curve for the replacement of the second curve. \~ + \param[in] pars0 - \ru Параметры разбиения кривой inCurve0. + \en The parameters of splitting curve inCurve0. \~ + \param[in] pars1 - \ru Параметры разбиения кривой inCurve1. + \en The parameters of splitting curve inCurve1. \~ + \param[in] selfInt - \ru Флаг проверки самопересечений. + \en Flag of self-intersections checking. \~ + \return \ru Результат первичной проверки параметров. + \en The result of the primary scan of parameters. \~ + */ + bool Init( const MbCurve3D & inCurve0, + const MbCurve3D & inCurve1, + const SArray & pars0, + const SArray & pars1, + bool selfInt = false ); + + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации на оригиналах или копиях кривых. + \en Initialization function on the curves originals or copies of curve. \~ + \param[in] obj - \ru Копируемые параметры. + \en Copy parameters. \~ + \param[in] sameCurves - \ru Флаг использования оригиналов кривых. + \en Flag of using originals of curves. \~ + */ + void Init( const RuledSurfaceValues & obj, bool sameCurves ); + + /// \ru Первичная проверка корректности параметров. \en Initial check of parameters correctness + bool IsValid() const; + /// \ru Преобразовать по матрице. \en Transform by matrix. + void Transform( const MbMatrix3D &, MbRegTransform * ireg ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D &, MbRegTransform * ireg ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const RuledSurfaceValues &, double accuracy ) const; + + /// \ru Получить кривую (первую или вторую). \en Get curve (the first or second). + const MbCurve3D * GetCurve( bool first ) const { return (first ? curve0 : curve1); } + /// \ru Получить кривую (первую или вторую). \en Get curve (the first or second). + MbCurve3D * SetCurve( bool first ) { return (first ? curve0 : curve1); } + + /// \ru Выдать количество параметров разбиения. \en Get the count of splitting parameters. + size_t GetParamsCount( bool first ) const { return (first ? breaks0.Count() : breaks1.Count()); } + /// \ru Выдать массив разбиения. \en Get splitting array. + void GetParams( bool first, SArray & breaks ) const { breaks = (first ? breaks0 : breaks1); } + /// \ru Получить параметр разбиения по индексу. \en Get splitting parameter by index. + double GetParam( bool first, size_t k ) const { C3D_ASSERT( k < GetParamsCount( first ) ); return (first ? breaks0[k] : breaks1[k]); } + /// \ru Установить массив параметров разбиения. \en Set array of splitting parameters. + void SetParams( bool first, const SArray & ps ) { if ( first ) breaks0 = ps; else breaks1 = ps; } + /// \ru Заполнены ли массивы параметров разбиения? \en Whether arrays of splitting parameters are filled? + bool IsEmpty() const { return (breaks0.Count() < 1); } + /// \ru Нужно ли проверять самопересечения \en Whether it is necessary to check self-intersections + bool CheckSelfInt() const { return checkSelfInt; } + /// \ru Установить флаг соединения через вершины \en Set flag of connection through vertices + void SetJoinByVertices( bool byVerts ) { joinByVertices = byVerts; } + /// \ru Соединяются ли кривые через вершины? \en Whether curves are joined through vertices? + bool GetJoinByVertices() const { return joinByVertices; } + /// \ru Установить флаг упрощения граней. \en Set flag of faces simplification. + void SetSimplifyFaces( bool simplFaces ) { simplifyFaces = simplFaces; } + /// \ru Получить флаг упрощения граней. \en Get flag of faces simplification. + bool GetSimplifyFaces() const { return simplifyFaces; } + +private: + // \ru Проверить наличие параметров вершин контура в массиве параметров \en Check for loop vertices parameters in the parameters array + bool CheckVertices( const MbCurve3D & curve, + const SArray & breaks ) const; + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( RuledSurfaceValues, MATH_FUNC_EX ) + OBVIOUS_PRIVATE_COPY( RuledSurfaceValues ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры удлинения оболочки. + \en The shell extension parameters. \~ + \details \ru Параметры удлинения оболочки путём продления грани или достраивания грани. \n + \en The parameters of extension shell by extending or face-filling. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS ExtensionValues { +public: + /** \brief \ru Типы удлинения. + \en Types of extension. \~ + \details \ru Типы удлинения оболочки. Указывает форму поверхности удлинения. + \en Types of shell extension. Indicates the form extension surface. \~ + */ + enum ExtensionType { + et_same = 0, ///< \ru По той же поверхности. \en Along the same surface. + et_tangent, ///< \ru По касательной к краю. \en Along tangent to the edge. + et_direction, ///< \ru По направлению. \en Along the direction. + }; + /** \brief \ru Способы удлинения. + \en Ways of extension. \~ + \details \ru Способы удлинения оболочки. + \en Ways of shell extension. \~ + */ + enum ExtensionWay { + ew_distance = -2, ///< \ru Продолжить на расстояние. \en Prolong on the distance. + ew_vertex = -1, ///< \ru Продолжить до вершины. \en Prolong to the vertex. + ew_surface = 0, ///< \ru Продолжить до поверхности. \en Prolong to the surface. + }; + /** \brief \ru Способы построения боковых рёбер. + \en Methods of construction of the lateral edges. \~ + \details \ru Способы построения боковых рёбер при удлинении оболочки. + \en Methods of construction of the lateral edges when extending shell. \~ + */ + enum LateralKind { + le_normal = 0, ///< \ru По нормали к кромке. \en Along the normal to boundary. + le_prolong, ///< \ru Продлить исходные рёбра. \en Extend the initial edges. + }; + +public: + ExtensionType type; ///< \ru Тип удлинения. \en Type of extension. + ExtensionWay way; ///< \ru Способ удлинения. \en Way of extension. + LateralKind kind; ///< \ru Способ построения боковых рёбер. \en Method of construction of the lateral edges. + MbCartPoint3D point; ///< \ru Точка, до которой удлинить. \en The point to extend.up to which. + MbVector3D direction; ///< \ru Направление удлинения. \en Direction of extension. + double distance; ///< \ru Расстояние. \en Distance. + bool prolong; ///< \ru Продолжить по гладко стыкующимся рёбрам. \en Prolong along smoothly mating edges. + bool combine; ///< \ru Объединять грани при возможности. \en Combine faces if it is possible. +private: + MbFaceShell * shell; ///< \ru Оболочка. \en A shell. + MbItemIndex faceIndex; ///< \ru Номер грани в оболочке. \en The index of face in the shell. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + ExtensionValues(); + /// \ru Конструктор копирования. \en Copy-constructor. + ExtensionValues( const ExtensionValues & other ); + /// \ru Конструктор. \en Constructor. + ExtensionValues( ExtensionType t, ExtensionWay w, LateralKind k, const MbCartPoint3D & p, + const MbVector3D & dir, double d, bool pro, bool comb, const MbFaceShell * s, const MbItemIndex & fIndex ); + /// \ru Деструктор. \en Destructor. + virtual ~ExtensionValues(); +public: + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации удлинения на расстояние. + \en Initialization function of extending to a distance. \~ + \param[in] t - \ru Тип удлинения. + \en Type of extension. \~ + \param[in] k - \ru Способ построения боковых рёбер. + \en Method of construction of the lateral edges. \~ + \param[in] v - \ru Направление удлинения. + \en Direction of extension. \~ + \param[in] d - \ru Величина удлинения. + \en Value of extension. \~ + */ + void InitByDistance( ExtensionType t, LateralKind k, const MbVector3D & v, double d ); + + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации удлинения до вершины. + \en Initialization function of extension to the vertex. \~ + \param[in] t - \ru Тип удлинения. + \en Type of extension. \~ + \param[in] k - \ru Способ построения боковых рёбер. + \en Method of construction of the lateral edges. \~ + \param[in] v - \ru Вершина, до которой строится удлинение. + \en The vertex to construct up to. \~ + */ + void InitByVertex ( ExtensionType t, LateralKind k, const MbCartPoint3D & v ); + + /** \brief \ru Функция инициализации. + \en Initialization function. \~ + \details \ru Функция инициализации удлинения до поверхности. + \en Initialization function of extension to the surface. \~ + \param[in] t - \ru Тип удлинения. + \en Type of extension. \~ + \param[in] k - \ru Способ построения боковых рёбер. + \en Method of construction of the lateral edges. \~ + \param[in] f - \ru Грань оболочки. + \en Face of the shell. \~ + \param[in] s - \ru Тело для замены оболочки. + \en Solid for replacement of shell. \~ + */ + void InitBySurface ( ExtensionType t, LateralKind k, const MbFace * f, const MbSolid * s ); + + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr, MbRegTransform * ireg = NULL ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to, MbRegTransform * ireg = NULL ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang, MbRegTransform * ireg = NULL ); + + /// \ru Получить оболочку. \en Get the shell. + const MbFaceShell * GetShell() const { return shell; } + /// \ru Номер грани в оболочке. \en The index of face in the shell. + const MbItemIndex & GetFaceIndex() const { return faceIndex; } + /// \ru Замена оболочки и ее выбранной грани. \en Replacement of shell and its selected face. + void SetShell( const MbFace * f, const MbSolid * s ); + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const ExtensionValues & other ); + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const ExtensionValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( ExtensionValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для построения поверхности соединения. + \en Data for construction of surface of the joint. \~ + \details \ru Данные для построения поверхности соединения по двум кривым на поверхностях. \n + \en Data for the construction of surface of the joint by two curves on the surfaces. \n \~ + \ingroup Build_Parameters +*/ +//--- +struct MATH_CLASS JoinSurfaceValues { +public: + /** \brief \ru Типы сопряжения поверхностей. + \en Type of surfaces join. \~ + \details \ru Типы сопряжения поверхностей определяет стыковку края сопрягаемой поверхности и поверхности сопряжения. + \en Types of join of surfaces determines join of edge of joining surface and surface of the joint. \~ + */ + enum JoinConnType { + js_Position = 0, ///< \ru По позиции. \en By position. + js_NormPlus, ///< \ru По нормали в положительном направлении вектора нормали. \en Along the normal in the positive direction of normal vector. + js_NormMinus, ///< \ru По нормали в отрицательном направлении вектора нормали. \en Along the normal in the negative direction of normal vector. + js_G1Plus, ///< \ru По касательной к поверхности, слева по направлению касательной к кривой пересечения. \en The type of conjugation along the tangent to the surface, to the left along the tangent to the intersection curve. + js_G1Minus, ///< \ru По касательной к поверхности, справа по направлению касательной к кривой пересечения. \en The type of conjugation along the tangent to the surface, to the right along the tangent to the intersection curve. + js_G2Plus, ///< \ru По касательной к поверхности, слева по направлению касательной к кривой пересечения, гладкая. \en The type of conjugation along the tangent to the surface, to the left along the tangent to the intersection curve, smooth. + js_G2Minus, ///< \ru По касательной к поверхности, справа по направлению касательной к кривой пересечения, гладкая. \en The type of conjugation along the tangent to the surface, to the right along the tangent to the intersection curve, smooth. + }; +public: + JoinConnType connType1; ///< \ru Тип сопряжения поверхности соединения с поверхностью 1. \en Join type of surface of the joint with the surface 1. + JoinConnType connType2; ///< \ru Тип сопряжения поверхности соединения с поверхностью 2. \en Join type of surface of the joint with the surface 2. + double tension1; ///< \ru Натяжение для соединения с поверхностью 1. \en Tension for joining with surface 1. + double tension2; ///< \ru Натяжение для соединения с поверхностью 2. \en Tension for joining with surface 2. + SArray breaks0; ///< \ru Параметры разбиения первой кривой curve0. \en Splitting parameters of the first curve0 curve. + SArray breaks1; ///< \ru Параметры разбиения первой кривой curve1. \en Splitting parameters of the first curve1 curve. + bool checkSelfInt; ///< \ru Искать самопересечения. \en Find self-intersections. + bool edgeConnType1; ///< \ru Построение боковой границы как продолжение ребра. \en Construct lateral boundary as edge extension. + bool edgeConnType2; ///< \ru Построение боковой границы как продолжение ребра. \en Construct lateral boundary as edge extension. + MbVector3D * boundDirection11; ///< \ru Вектор направления, определяющий боковую границу, в точке (0, 0) поверхности. \en Direction vector determines lateral boundary in the point (0, 0) of the surface. + MbVector3D * boundDirection12; ///< \ru Вектор направления, определяющий боковую границу, в точке (1, 0) поверхности. \en Direction vector determines lateral boundary in the point (1, 0) of the surface. + MbVector3D * boundDirection21; ///< \ru Вектор направления, определяющий боковую границу, в точке (0, 1) поверхности. \en Direction vector determines lateral boundary in the point (0, 1) of the surface. + MbVector3D * boundDirection22; ///< \ru Вектор направления, определяющий боковую границу, в точке (1, 1) поверхности. \en Direction vector determines lateral boundary in the point (1, 1) of the surface. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + JoinSurfaceValues() + : connType1 ( js_G1Plus ) + , connType2 ( js_G1Plus ) + , tension1 ( 0.5 ) + , tension2 ( 0.5 ) + , breaks0 ( 0, 1 ) + , breaks1 ( 0, 1 ) + , checkSelfInt ( false ) + , edgeConnType1 ( false ) + , edgeConnType2 ( false ) + , boundDirection11 ( NULL ) + , boundDirection12 ( NULL ) + , boundDirection21 ( NULL ) + , boundDirection22 ( NULL ) + {} + /// \ru Конструктор по параметрам. \en Constructor by parameters. + JoinSurfaceValues( JoinConnType t1, JoinConnType t2, double tens1, double tens2, bool selfInt = false ) + : connType1 ( t1 ) + , connType2 ( t2 ) + , tension1 ( tens1 ) + , tension2 ( tens2 ) + , breaks0 ( 0, 1 ) + , breaks1 ( 0, 1 ) + , checkSelfInt ( selfInt ) + , edgeConnType1 ( false ) + , edgeConnType2 ( false ) + , boundDirection11 ( NULL ) + , boundDirection12 ( NULL ) + , boundDirection21 ( NULL ) + , boundDirection22 ( NULL ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + JoinSurfaceValues( const JoinSurfaceValues & other ); + +public: + /// \ru Деструктор. \en Destructor. + virtual ~JoinSurfaceValues(); + /// \ru Функция инициализации. \en Initialization function. + bool Init( const SArray & initBreaks0, + const SArray & initBreaks1, + bool initCheckSelfInt, + JoinConnType initConnType1, + double initTension1, + bool initEdgeConnType1, + const MbVector3D * initBoundDir11, + const MbVector3D * initBoundDir12, + JoinConnType initConnType2, + double initTension2, + bool initEdgeConnType2, + const MbVector3D * initBoundDir21, + const MbVector3D * initBoundDir22 ); + /// \ru Функция копирования. \en Copy function. + void Init( const JoinSurfaceValues & other ); + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const JoinSurfaceValues & other ) { Init( other ); } + + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * ireg ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D &, MbRegTransform * ireg ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * ireg ); + + /// \ru Выдать количество параметров разбивки. \en Get the count of splitting parameters. + size_t GetParamsCount( bool first ) const { return (first ? breaks0.size() : breaks1.size()); } + /// \ru Получить параметры разбивки (первую или вторую группу). \en Get splitting parameters (the first or second group). + void GetParams( bool first, SArray & breaks ) const { breaks = (first ? breaks0 : breaks1); } + /// \ru Получить параметры разбивки (первую или вторую группу). \en Get splitting parameters (the first or second group). + double GetParam( bool first, size_t k ) const { C3D_ASSERT( k < GetParamsCount( first ) ); return (first ? breaks0[k] : breaks1[k]); } + /// \ru Установить параметры разбивки. \en Set splitting parameters. + void SetParams( bool first, const SArray & ps ) { if ( first ) breaks0 = ps; else breaks1 = ps; } + /// \ru Параметры разбивки не заполнены? \en Whether splitting parameters are not filled? + bool IsEmpty() const { return breaks0.empty(); } + /// \ru Получить флаг проверки самопересечений. \en Get the flag of checking self-intersection. + bool CheckSelfInt() const { return checkSelfInt; } + /// \ru Установить флаг проверки самопересечений. \en Set the flag of checking self-intersection. + void SetSelfInt( bool aChech ) { checkSelfInt = aChech; } + + /// \ru Выдать параметры параметры установки боковых граней. \en Get setting parameters of lateral faces. + bool GetEdgeConnType( bool isFirst = true ) const { return isFirst ? edgeConnType1 : edgeConnType2; } + /// \ru Установить параметры параметры установки боковых граней. \en Set setting parameters of lateral faces. + void SetEdgeConnType( bool connType, bool isFirst = true ) { isFirst ? edgeConnType1 = connType : edgeConnType2 = connType; } + + /** \brief \ru Выдать вектор направления. + \en Get the direction vector. \~ + \details \ru Выдать вектор направления, определяющий боковую границу. + \en Get the direction vector determining lateral boundary. \~ + \param[in] num - \ru Номер границы:\n + num = 1 - вектор boundDirection11,\n + num = 2 - вектор boundDirection12,\n + num = 3 - вектор boundDirection21,\n + num = 4 - вектор boundDirection22. + \en The index of boundary:\n + num = 1 - vector boundDirection11,\n + num = 2 - vector boundDirection12,\n + num = 3 - vector boundDirection21,\n + num = 4 - vector boundDirection22. \~ + */ + const MbVector3D * GetBoundDirection( size_t num ) const; + + /** \brief \ru Установить вектор направления. + \en Set the direction vector. \~ + \details \ru Установить вектор направления, определяющий боковую границу. + \en Set the direction vector determining lateral boundary. \~ + \param[in] num - \ru Номер границы:\n + num = 1 - изменяем вектор boundDirection11,\n + num = 2 - изменяем вектор boundDirection12,\n + num = 3 - изменяем вектор boundDirection21,\n + num = 4 - изменяем вектор boundDirection22. + \en The index of boundary:\n + num = 1 - change vector boundDirection11,\n + num = 2 - change vector boundDirection12,\n + num = 3 - change vector boundDirection21,\n + num = 4 - change vector boundDirection22. \~ + \param[in] aDirect - \ru Новый вектор направления. + \en The new direction vector. \~ + */ + void SetBoundDirection( size_t num, const MbVector3D * aDirect ); + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const JoinSurfaceValues & other, double accuracy ) const + { + bool isSame = false; + + if ( (other.connType1 == connType1) && + (other.connType2 == connType2) && + (other.checkSelfInt == checkSelfInt) && + (other.edgeConnType1 == edgeConnType1) && + (other.edgeConnType2 == edgeConnType2) && + (::fabs(other.tension1 - tension1) < accuracy) && + (::fabs(other.tension2 - tension2) < accuracy) ) + { + const size_t breaksCnt0 = breaks0.size(); + const size_t breaksCnt1 = breaks1.size(); + if ( (other.breaks0.size() == breaksCnt0) && (other.breaks1.size() == breaksCnt1) ) { + isSame = true; + + size_t k; + for ( k = 0; k < breaksCnt0 && isSame; ++k ) { + if ( ::fabs(other.breaks0[k] - breaks0[k]) > accuracy ) + isSame = false; + } + if ( isSame ) { + for ( k = 0; k < breaksCnt1 && isSame; ++k ) { + if ( ::fabs(other.breaks1[k] - breaks1[k]) > accuracy ) + isSame = false; + } + } + if ( isSame ) { + bool isBoundDir11 = ((other.boundDirection11 != NULL) && (boundDirection11 != NULL)); + bool isBoundDir12 = ((other.boundDirection12 != NULL) && (boundDirection12 != NULL)); + bool isBoundDir21 = ((other.boundDirection21 != NULL) && (boundDirection21 != NULL)); + bool isBoundDir22 = ((other.boundDirection22 != NULL) && (boundDirection22 != NULL)); + + if ( isSame && isBoundDir11 ) + isSame = c3d::EqualVectors( *other.boundDirection11, *boundDirection11, accuracy ); + if ( isSame && isBoundDir12 ) + isSame = c3d::EqualVectors( *other.boundDirection12, *boundDirection12, accuracy ); + if ( isSame && isBoundDir21 ) + isSame = c3d::EqualVectors( *other.boundDirection21, *boundDirection21, accuracy ); + if ( isSame && isBoundDir22 ) + isSame = c3d::EqualVectors( *other.boundDirection22, *boundDirection22, accuracy ); + } + } + } + return isSame; + } + +public: + KNOWN_OBJECTS_RW_REF_OPERATORS( JoinSurfaceValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. + DECLARE_NEW_DELETE_CLASS( JoinSurfaceValues ) + DECLARE_NEW_DELETE_CLASS_EX( JoinSurfaceValues ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры преобразования триангуляции в оболочку. + \en Operation parameters of grids-to-shell conversion. \~ + \details \ru Параметры преобразования триангуляции в оболочку. + \en Operation parameters of grids-to-shell conversion. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS GridsToShellValues { +public: + bool sewGrids; ///< \ru Сшивать наборы граней от разных сеток триангуляции. \en Sew together faces of grids. + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool useGridSurface; ///< \ru Использовать поверхность на базе триангуляции. \en Use the surface based on triangulation. +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + GridsToShellValues() + : sewGrids ( true ) + , mergeFaces ( false ) + , useGridSurface( false ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + GridsToShellValues( const GridsToShellValues & other ) + : sewGrids ( other.sewGrids ) + , mergeFaces ( other.mergeFaces ) + , useGridSurface( other.useGridSurface ) + {} + /// \ru Конструктор по параметрам. \en Constructor by parameters. + GridsToShellValues( bool sg, bool mf, bool ugs = false ) + : sewGrids ( sg ) + , mergeFaces ( mf ) + , useGridSurface( ugs ) + {} + /// \ru Оператор присваивания. \en Assignment operator. + GridsToShellValues & operator = ( const GridsToShellValues & other ) + { + sewGrids = other.sewGrids; + mergeFaces = other.mergeFaces; + useGridSurface = other.useGridSurface; + return *this; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры создания срединной оболочки между выбранными гранями тела. + \en Operation parameters of median shell between selected faces of solid. \~ + \details \ru Параметры создания срединной оболочки между выбранными гранями тела. + Выбранные грани должны быть эквидистантны по отношению друг к другу. + Грани должны принадлежать одному и тому же телу. + \en Operation parameters of median shell between selected faces of solid. + Selected face pairs should be offset from each other. + The faces must belong to the same body.\~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MedianShellValues { +public: + double position; ///< \ru Параметр смещения срединной оболочки относительно первой грани из пары. По умолчанию равен 50% расстояния между гранями. \en Parameter of shift the median surface from first face in faces pair. By default is 50% from distance between faces in pair. + double dmin; ///< \ru Минимальный параметр эквидистантности. \en Minimal equidistation value. + double dmax; ///< \ru Максимальный параметр эквидистантности. \en Maximal equidistation value. +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MedianShellValues() + : position ( 0.5 ) + , dmin ( 0.0 ) + , dmax ( 0.0 ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MedianShellValues( const MedianShellValues & other ) + : position ( other.position ) + , dmin ( other.dmin ) + , dmax ( other.dmax ) + {} + /// \ru Конструктор по параметрам. \en Constructor by parameters. + MedianShellValues( double pos, double d1, double d2 ) + : position ( pos ) + , dmin ( d1 ) + , dmax ( d2 ) + {} + +public: + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MedianShellValues & obj, double accuracy ) const + { + if ( (::fabs(dmin - obj.dmin) < accuracy) && + (::fabs(dmax - obj.dmax) < accuracy) && + (::fabs( position - obj.position) < accuracy ) ) + { + return true; + } + return false; + } + +public: + /// \ru Оператор присваивания. \en Assignment operator. + MedianShellValues & operator = ( const MedianShellValues & other ) + { + position = other.position; + dmin = other.dmin; + dmax = other.dmax; + return *this; + } + +KNOWN_OBJECTS_RW_REF_OPERATORS( MedianShellValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество граней для создания срединной оболочки. + \en Set of faces for build a median shell. \~ +\details \ru Множество граней для создания срединной оболочки. + \en Set of faces for build a median shell.\~ +\ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MedianShellFaces { +private: + std::vector facePairs; ///< \ru Набор пар выбранных граней. \en Set of selected faces pairs. + std::vector distances; ///< \ru Вектор смещений второй грани по отношению к первой в каждой паре. \en Vector of shift values of second face in reference to first face in each pair. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MedianShellFaces() { + facePairs.resize( 0 ); + distances.resize( 0 ); + } + /// \ru Конструктор по параметрам. \en Constructor by parameters. + MedianShellFaces( const std::vector & pairs ) + { + facePairs = pairs; + distances.resize( pairs.size() ); + } + /// \ru Деструктор. \en Destructor. + ~MedianShellFaces() {} + +public: + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move( const MbVector3D & ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate( const MbAxis3D &, double angle ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MedianShellFaces & obj, double accuracy ) const; + +public: + /// \ru Добавить в набор пару граней. \en Add pair of faces. + void AddFacePair( const MbItemIndex & f1, const MbItemIndex & f2, double dist = 0.0 ) + { + facePairs.push_back( c3d::ItemIndexPair(f1,f2) ); + distances.push_back( dist ); + } + /// \ru Получить пару граней по индексу. \en Get pair of faces by index. + const c3d::ItemIndexPair & _GetFacePair( size_t index ) const { return facePairs[index];} + /// \ru Удалить пару граней из набора. \en Remove pair of faces from set. + void RemovePairByIndex( size_t index ) + { + facePairs.erase( facePairs.begin() + index ); + distances.erase( distances.begin() + index ); + } + /// \ru Вернуть расстояние между гранями. \en Get distance between faces. + const double & _GetDistance( size_t index ) const { return distances[index]; } + /// \ru Установить расстояние между гранями. \en Set distance between faces. + void _SetDistance( size_t index, double value ) { distances[index] = value; } + /// \ru Вернуть количество пар граней в наборе. \en Get count of pairs in given set. + size_t Count() const { return facePairs.size(); } + /// \ru Оператор присваивания. \en Assignment operator. + MedianShellFaces & operator = ( const MedianShellFaces & other ) { + facePairs = other.facePairs; + distances = other.distances; + return *this; + } + /// \ru Очистка текущего набора. \en Clear current faces set. + void Clear() { facePairs.clear(); distances.clear(); } + +KNOWN_OBJECTS_RW_REF_OPERATORS( MedianShellFaces ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/// \ru Типы продления секущих поверхностей. \en Prolongation types of cutter surfaces. +// --- +enum MbeSurfaceProlongType { + cspt_None = 0x00, // 0000 ///< \ru Не продлевать. \en Don't prolong. + cspt_Planar = 0x01, // 0001 ///< \ru Плоские поверхности. \en Planar surfaces. + cspt_RevolutionAxis = 0x02, // 0010 ///< \ru Поверхности вращения (вдоль оси). \en Revolution surfaces (along axis). + cspt_RevolutionAngle = 0x04, // 0100 ///< \ru Поверхности вращения (по углу). \en Revolution surfaces (by angle). + cspt_Revolution = 0x06, // 0110 ///< \ru Поверхности вращения. \en Revolution surfaces. +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры операции резки оболочки. + \en Shell cutting operation parameters. \~ + \details \ru Параметры операции резки оболочки. \n + \en Shell cutting operation parameters. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MbShellCuttingParams { +public: + /// \ru Состояние типа продления секущих поверхностей. \en State of prolongation types of cutter surfaces. + struct ProlongState { + typedef uint8 UintType; + protected: + bool active; ///< \ru Включено ли дополнительное управление продлением. \en Whether additional prolongation control is active. + UintType type; ///< \ru Тип продления секущей поверхности. \en Prolongation type of cutting surface. + public: + ProlongState() : active( false ), type( cspt_None ) {} + explicit ProlongState( MbeSurfaceProlongType t ) : active( true ), type( (UintType)t ) {} + ProlongState( const ProlongState & ps ) { active = ps.active; type = ps.type; } + public: + const ProlongState & operator = ( const ProlongState & ps ) { active = ps.active; type = ps.type; return *this; } + bool operator == ( const ProlongState & ps ) const { return (active == ps.active && type == ps.type); } + public: + void Reset() { active = false; type = cspt_None; } + void Init( const ProlongState & ps ) { active = ps.active; type = ps.type; } + void Init( bool a, UintType t ) { active = a; type = t; } + bool IsActive() const { return active; } + void SetActive( bool a ) { active = a; } + UintType GetType() const { return type; } + void SetType( MbeSurfaceProlongType t ) { type = (UintType)t; } + void AddType( MbeSurfaceProlongType t ) { type |= (UintType)t; } + void SetActiveType( bool a, MbeSurfaceProlongType t ) { active = a; type = (UintType)t; } + void AddActiveType( bool a, MbeSurfaceProlongType t ) { active = a; type |= (UintType)t; } + }; +private: + MbSplitData cutterData; ///< \ru Данные секущего объекта. \en Cutter object(s) data. + MbBooleanFlags booleanFlags; ///< \ru Управляющие флаги булевой операции. \en Control flags of the Boolean operation. + MbSNameMaker nameMaker; ///< \ru Именователь операции. \en An object defining names generation in the operation. + ThreeStates retainedPart; ///< \ru Направление отсечения (сохраняемая часть исходной оболочки). \en The direction of cutting off (a part of the source shell to be kept). + ProlongState prolongState; ///< \ru Тип продления режущей поверхности. \en Prolongation type of cutter surface. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. \n + \en Constructor. \n \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( int part, const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData ( ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + } + /** \brief \ru Конструктор по контуру. + \en Constructor by a contour. \~ + \details \ru Конструктор по контуру. \n + \en Constructor by a contour. \n \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которой расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур выдавливания расположен в плоскости XY локальной системы координат. + \en The two-dimensional contour of extrusion is located in XY plane of the local coordinate system. \~ + \param[in] sameContour - \ru Использовать исходный контур (true) или его копию (false). + \en Use the source contour (true) or its copy (false). \~ + \param[in] dir - \ru Направление выдавливания контура. + \en Extrusion direction of the contour. \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( const MbPlacement3D & place, const MbContour & contour, bool sameContour, const MbVector3D & dir, int part, + const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData( place, dir, contour, sameContour ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + } + /** \brief \ru Конструктор по контуру. + \en Constructor by a contour. \~ + \details \ru Конструктор по контуру. \n + \en Constructor by a contour. \n \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которой расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур выдавливания расположен в плоскости XY локальной системы координат. + \en The two-dimensional contour of extrusion is located in XY plane of the local coordinate system. \~ + \param[in] sameContour - \ru Использовать исходный контур (true) или его копию (false). + \en Use the source contour (true) or its copy (false). \~ + \param[in] dir - \ru Направление выдавливания контура. + \en Extrusion direction of the contour. \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( const MbPlacement3D & place, const MbContour & contour, bool sameContour, const MbVector3D & dir, + const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData( place, dir, contour, sameContour ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + } + /** \brief \ru Конструктор по поверхности. + \en Constructor by a surface. \~ + \details \ru Конструктор по поверхности. \n + \en Constructor by a surface. \n \~ + \param[in] surface - \ru Режущая поверхность. + \en Cutting plane. \~ + \param[in] sameSurface - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( const MbSurface & surface, bool sameSurface, int part, + const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData( surface, sameSurface ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + } + /** \brief \ru Конструктор по поверхности. + \en Constructor by a surface. \~ + \details \ru Конструктор по поверхности. \n + \en Constructor by a surface. \n \~ + \param[in] surface - \ru Режущая поверхность. + \en Cutting plane. \~ + \param[in] sameSurface - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( const MbSurface & surface, bool sameSurface, + const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData( surface, sameSurface ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + } + /** \brief \ru Конструктор по оболочке. + \en Constructor by a shell. \~ + \details \ru Конструктор по оболочке. \n + \en Constructor by a shell. \n \~ + \param[in] solid - \ru Режущая оболочка. + \en Cutting shell. \~ + \param[in] sameSolid - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + MbShellCuttingParams( const MbSolid & solid, bool sameSolid, + int part, const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + : cutterData( solid, sameSolid, true ) + , booleanFlags( ) + , nameMaker ( snMaker ) + , retainedPart( ts_neutral ) + , prolongState( ) + { + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + } + /// \ru Копирующий конструктор. \en Copy constructor. + MbShellCuttingParams( const MbShellCuttingParams & other, MbRegDuplicate * iReg ) + : cutterData ( other.cutterData, false, iReg ) + , booleanFlags( other.booleanFlags ) + , nameMaker ( other.nameMaker ) + , retainedPart( other.retainedPart ) + , prolongState( other.prolongState ) + { + } + ~MbShellCuttingParams() + {} +public: + /** \brief \ru Инициализация по контуру. + \en Initialize by a contour. \~ + \details \ru Инициализация по контуру. \n + \en Initialize by a contour. \n \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которой расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур выдавливания расположен в плоскости XY локальной системы координат. + \en The two-dimensional contour of extrusion is located in XY plane of the local coordinate system. \~ + \param[in] sameContour - \ru Использовать исходный контур (true) или его копию (false). + \en Use the source contour (true) or its copy (false). \~ + \param[in] dir - \ru Направление выдавливания контура. + \en Extrusion direction of the contour. \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + bool InitPlaneContour( const MbPlacement3D & place, const MbContour & contour, bool sameContour, const MbVector3D & dir, + int part, const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + { + if ( cutterData.InitPlaneContour( place, dir, contour, sameContour ) ) { + nameMaker.SetName( snMaker, true ); + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + prolongState.Reset(); + return true; + } + return false; + } + /** \brief \ru Инициализация по контуру. + \en Initialize by a contour. \~ + \details \ru Инициализация по контуру. \n + \en Initialize by a contour. \n \~ + \param[in] place - \ru Локальная система координат, в плоскости XY которой расположен двумерный контур. + \en A local coordinate system the two-dimensional contour is located in XY plane of. \~ + \param[in] contour - \ru Двумерный контур выдавливания расположен в плоскости XY локальной системы координат. + \en The two-dimensional contour of extrusion is located in XY plane of the local coordinate system. \~ + \param[in] sameContour - \ru Использовать исходный контур (true) или его копию (false). + \en Use the source contour (true) or its copy (false). \~ + \param[in] dir - \ru Направление выдавливания контура. + \en Extrusion direction of the contour. \~ + */ + bool InitPlaneContour( const MbPlacement3D & place, const MbContour & contour, bool sameContour, const MbVector3D & dir ) + { + if ( cutterData.InitPlaneContour( place, dir, contour, sameContour ) ) { + prolongState.Reset(); + return true; + } + return false; + } + /** \brief \ru Конструктор по поверхности. + \en Constructor by a surface. \~ + \details \ru Конструктор по поверхности. \n + \en Constructor by a surface. \n \~ + \param[in] surface - \ru Режущая поверхность. + \en Cutting plane. \~ + \param[in] sameSurface - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + bool InitSurface( const MbSurface & surface, bool sameSurface, + int part, const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + { + if ( cutterData.InitSurfaces( surface, sameSurface ) ) { + nameMaker.SetName( snMaker, true ); + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + prolongState.Reset(); + return true; + } + return false; + } + /** \brief \ru Конструктор по поверхности. + \en Constructor by a surface. \~ + \details \ru Конструктор по поверхности. \n + \en Constructor by a surface. \n \~ + \param[in] surface - \ru Режущая поверхность. + \en Cutting plane. \~ + \param[in] sameSurface - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] prType - \ru Тип продления режущей поверхности. + \en Cutter surface prolong type. \~ + */ + bool InitSurface( const MbSurface & surface, bool sameSurface, ProlongState prState ) + { + if ( cutterData.InitSurfaces( surface, sameSurface ) ) { + prolongState.Init( prState ); + return true; + } + return false; + } + /** \brief \ru Конструктор по оболочке. + \en Constructor by a shell. \~ + \details \ru Конструктор по оболочке. \n + \en Constructor by a shell. \n \~ + \param[in] solid - \ru Режущая оболочка. + \en Cutting shell. \~ + \param[in] sameSolid - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + \param[in] part - \ru Сохраняемая часть исходной оболочки (+1, -1). + \en A part of the source shell to be kept (+1, -1). \~ + \param[in] mergingFlags - \ru Флаги слияния элементов оболочки. + \en Control flags of shell items merging. \~ + \param[in] cutAsClosed - \ru Построить замкнутую оболочку. + \en Create a closed shell. \~ + \param[in] snMaker - \ru Именователь операции. + \en An object defining names generation in the operation. \~ + */ + bool InitSolid( const MbSolid & solid, bool sameSolid, + int part, const MbMergingFlags & mergingFlags, bool cutAsClosed, + const MbSNameMaker & snMaker ) + { + if ( cutterData.InitSolid( solid, sameSolid, true ) ) { + nameMaker.SetName( snMaker, true ); + booleanFlags.InitCutting( cutAsClosed ); + booleanFlags.SetMerging( mergingFlags ); + SetRetainedPart( part ); + prolongState.Reset(); + return true; + } + return false; + } + /** \brief \ru Конструктор по оболочке. + \en Constructor by a shell. \~ + \details \ru Конструктор по оболочке. \n + \en Constructor by a shell. \n \~ + \param[in] solid - \ru Режущая оболочка. + \en Cutting shell. \~ + \param[in] sameSolid - \ru Использовать исходную поверхность (true) или её копию (false). + \en Use the source surface (true) or its copy (false). \~ + */ + bool InitSolid( const MbSolid & solid, bool sameSolid ) + { + if ( cutterData.InitSolid( solid, sameSolid, true ) ) { + prolongState.Reset(); + return true; + } + return false; + } + /** \brief \ru Конструктор по оболочке. + \en Constructor by a shell. \~ + \details \ru Конструктор по оболочке. \n + \en Constructor by a shell. \n \~ + \param[in] creators - \ru Построители режущей оболочки. + \en Cutting shell creators. \~ + \param[in] sameCreators - \ru Использовать оригиналы (true) или копии (false) построителей. + \en Use original creators (true) or its copies (false). \~ + */ + template + bool InitSolid( const CreatorsVector & creators, bool sameCreators ) + { + if ( cutterData.InitSolid( creators, sameCreators ) ) { + prolongState.Reset(); + return true; + } + return false; + } +public: + /// \ru Это резка плоским контуром? \en Is cutting by planar contour? + bool IsCuttingByPlanarContour() const { return (cutterData.GetSketchCurvesCount() > 0 && cutterData.GetSketchCurve(0) != NULL); } + /// \ru Это резка поверхностью? \en Is cutting by surface? + bool IsCuttingBySurface() const { return (cutterData.GetSurfacesCount() > 0 && cutterData.GetSurface(0) != NULL); } + /// \ru Это резка оболочкой? \en Is cutting by shell? + bool IsCuttingBySolid() const { return (cutterData.GetCreatorsCount() > 0 && cutterData.GetCreator(0) != NULL) || (cutterData.GetSolidShell() != NULL); } + + /// \ru Получить данные секущего объекта. \en Get cutter object(s) data. + const MbSplitData & GetCutterData() const { return cutterData; } + + /// \ru Получить управляющие флаги булевой операции. \en Get control flags of the Boolean operation. + const MbBooleanFlags & GetBooleanFlags() const { return booleanFlags; } + /// \ru Получить управляющие флаги булевой операции. \en Get control flags of the Boolean operation. + MbBooleanFlags & SetBooleanFlags() { return booleanFlags; } + + /// \ru Получить именователь операции. \en Get the object defining names generation in the operation. + const MbSNameMaker & GetNameMaker() const { return nameMaker; } + + /// \ru Получить требование по оставляемой части. \en Get retained part demand. + ThreeStates GetRetainedPart() const { return retainedPart; } + /// \ru Установить требование по оставляемой части. \en Set retained part demand. + void SetRetainedPart( int part ); + + /// \ru Получить тип продления режущей поверхности. \en Get cutter surface prolong type. + const ProlongState & GetProlongState() const { return prolongState; } + /// \ru Получить тип продления режущей поверхности. \en Get cutter surface prolong type. + void ResetProlongState() { prolongState.Reset(); } + /// \ru Добавить тип продления режущей поверхности. \en Add cutter surface prolong type. + void SetSurfaceProlongType( MbeSurfaceProlongType pt ) { prolongState.SetActiveType( true, pt ); } + /// \ru Добавить тип продления режущей поверхности. \en Add cutter surface prolong type. + void AddSurfaceProlongType( MbeSurfaceProlongType pt ) { prolongState.AddActiveType( true, pt ); } + + /// \ru Получить локальную систему координат двумерных кривых. \en Get the local coordinate system of two-dimensional curves. + const MbPlacement3D & GetSketchPlace() const { return cutterData.GetSketchPlace(); } + /// \ru Получить вектор направления выдавливания двумерных кривых. \en Get the extrusion direction vector of two-dimensional curves. + const MbVector3D & GetSketchDirection() const { return cutterData.GetSketchDirection(); } + /// \ru Получить двумерную кривую. \en Get two-dimensional curve. + const MbContour * GetSketchCurve() const { return cutterData.GetSketchCurve( 0 ); } + + /// \ru Получить поверхность. \en Get a surface. + const MbSurface * GetSurface() const { return cutterData.GetSurface( 0 ); } + + /// \ru Сливать подобные грани (true)? \en Whether to merge similar faces (true)? + bool MergeFaces() const { return booleanFlags.MergeFaces(); } + /// \ru Сливать подобные ребра (true)? \en Whether to merge similar edges (true)? + bool MergeEdges() const { return booleanFlags.MergeEdges(); } + /// \ru Построить замкнутую оболочку. \en Create a closed shell. + bool IsCuttingAsClosed() const { return booleanFlags.IsCutting(); } + +OBVIOUS_PRIVATE_COPY ( MbShellCuttingParams ) +}; + + +//------------------------------------------------------------------------------ +// \ru Установить требование по оставляемой части. \en Set retained part demand. +// --- +inline +void MbShellCuttingParams::SetRetainedPart( int part ) +{ + retainedPart = ts_neutral; // If part == 0 retain both parts + if ( part > 0 ) // If part > 0 + retainedPart = ts_positive; // retain a part above cutter surface. + else if ( part < 0 ) // if part < 0 + retainedPart = ts_negative; // Retain part below cutter surface.. +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры развёртки грани на плоскость. + \en Parameter for an unwrapping the face on a plane. \~ + \details \ru Параметры развёртки грани на плоскость. \n + Параметры содержат информацию о положении развёртки и свойствах материала. + \en Parameter for an unwrapping the face on a plane. \n + The parameters contain information about the scan position and material properties. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS RectifyValues { + +protected : + MbPlacement3D place; ///< \ru Локальная система координат развернутой поверхности грани. \en The local coordinat system for result surface. \~ + MbCartPoint init; ///< \ru Параметры поверхности, которые будут соответствовать начальной точке place. \en The parameters of the surface, which will correspond to the origin of the place. \~ + MbStepData stepData; ///< \ru Данные для вычисления шага при триангуляции. \en Data for step calculation during triangulation. \~ + double myu; ///< \ru Коэффициент Пуассона материала грани. \en The Poisson's ratio of face material. \~ + bool faceted; ///< \ru Добавить в атрибуты мозаичный объект (true) или нет (false). \en Add to the attributes a mosaic object (true), or do't. \~ + +public : + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров операции удаления из тела выбранных граней. + \en Constructor of operation parameters of removing the specified faces from the solid. \~ + */ + RectifyValues() + : place() + , init() + , stepData() + , myu( 0.25 ) + , faceted( false ) + {} + /// \ru Конструктор по способу модификации и вектору перемещения. \en Constructor by way of modification and movement vector. + RectifyValues( const MbPlacement3D & pl, const MbCartPoint & r, const MbStepData & s, double m = 0.25, bool fset = false ) + : place( pl ) + , init( r ) + , stepData( s ) + , myu( m ) + , faceted( fset ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + RectifyValues( const RectifyValues & other ) + : place ( other.place ) + , init ( other.init ) + , stepData( other.stepData ) + , myu ( other.myu ) + , faceted ( other.faceted ) + {} + /// \ru Деструктор. \en Destructor. + ~RectifyValues() {} +public: + /// \ru Функция копирования. \en Copy function. + void Init( const RectifyValues & other ) { + place.Init( other.place ); + init.Init( other.init ); + stepData.Init( other.stepData ); + myu = other.myu; + faceted = other.faceted; + } + /// \ru Оператор присваивания. \en Assignment operator. + RectifyValues & operator = ( const RectifyValues & other ) { + place.Init( other.place ); + init.Init( other.init ); + stepData.Init( other.stepData ); + myu = other.myu; + faceted = other.faceted; + return *this; + } + + // \ru Локальная система координат развернутой поверхности грани. \en The local coordinat system for result surface. \~ + void SetPlacement( const MbPlacement3D & pl ) { place.Init( pl ); } + const MbPlacement3D & GetPlacement() const { return place; } + // \ru Параметры поверхности, которые будут соответствовать начальной точке place. \en The parameters of the surface, which will correspond to the origin of the place. \~ + void SetOrigin( const MbCartPoint & r ) { init = r; } + const MbCartPoint & GetOrigin() const { return init; } + // \ru Данные для вычисления шага при триангуляции. \en Data for step calculation during triangulation. \~ + void SetStepData( const MbStepData & step ) { stepData = step; } + const MbStepData & GetStepData() const { return stepData; } + // \ru Коэффициент Пуассона материала грани. \en The Poisson's ratio of face material. \~ + void SetPoissonsRatio( double m ) { myu = m; } + double GetPoissonsRatio() const { return myu; } + // \ru Добавить в атрибуты мозаичный объект (true) или нет (false). \en Add to the attributes a mosaic object (true), or do't. \~ + void SetAddFacet( bool b ) { faceted = b; } + bool AddFacet() const { return faceted; } + + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const RectifyValues & other, double accuracy ) const; + + KNOWN_OBJECTS_RW_REF_OPERATORS( RectifyValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; // RectifyValues + + +#endif // __OP_SHELL_PARAMETERS_H diff --git a/C3d/Include/op_swept_parameter.h b/C3d/Include/op_swept_parameter.h new file mode 100644 index 0000000..e8dae02 --- /dev/null +++ b/C3d/Include/op_swept_parameter.h @@ -0,0 +1,1416 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Параметры операций над телами. + \en Parameters of operations on the solids. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __OP_SWEPT_PARAMETERS_H +#define __OP_SWEPT_PARAMETERS_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbPlacement3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCurve3D; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные об образующей. + \en The generating data. \~ + \details \ru Данные об образующей операции движения. \n + Образующая операции выдавливания, вращения или кинематической операции + может включать в себя набор двумерных контуров, набор трехмерных контуров, тело. \n + Для набора двумерных контуров на поверхности существуют следующие ограничения:\n + – может быть один или несколько контуров;\n + – если контуров несколько, они должны быть либо все замкнуты, либо все разомкнуты;\n + - если контуры замкнуты, они могут быть вложенными друг в друга, уровень вложенности не ограничивается;\n + – контуры не должны пересекаться между собой или самопересекаться.\n + Для двумерных контуров на не плоской поверхности есть дополнительное ограничение: + все контуры должны быть замкнуты.\n + Построение операции по двумерным контурам на не плоской поверхности рассчитано на указание пользователем + грани тела в качестве образующей. В этом случае данные для образующей можно получить + с помощью метода грани MbFace::GetSurfaceCurvesData.\n + Ограничения для трехмерных контуров:\n + – контуры не должны пересекаться между собой или самопересекаться.\n + \en Data about generating of movement operation. \n + Generating of extrusion operation, rotation or sweeping operation + can include a set of two-dimensional contours, a set of three-dimensional contours, solid. \n + For a set of two-dimensional contours on the surface, the following restrictions:\n + - can be one or multiple contours;\n + - If there are multiple contours, all of them must be either closed or open;\n + - if contours are closed, then they can be nested into each other, the level of nesting is not limited;\n + - contours can't overlap each other or self-intersect.\n + For two-dimensional contour on the non-planar surface is additional constraint: + all the contours must be closed.\n + Constructing operation by two-dimensional contours on non-planar surface it is necessary to specify the by the user + face of solid as generating. In this case, the generating data can be obtained + by the method of face MbFace::GetSurfaceCurvesData.\n + Constraints for three-dimensional contour:\n + - contours can't overlap each other or self-intersect.\n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MbSweptData { + +private: + // \ru Данные о двумерных контурах на поверхности. \en Data about two-dimensional contours on the surface. + c3d::SurfaceSPtr surface; ///< \ru Поверхность. \en The surface. + c3d::PlaneContoursSPtrVector contours; ///< \ru Множество двумерных контуров. \en Set of two-dimensional contours. + // \ru Трехмерные контуры. \en Three-dimensional contours. + c3d::SpaceContoursSPtrVector contours3D; ///< \ru Множество трёхмерных контуров. \en Set of three-dimensional contours. + // \ru Тело. \en Solid. + c3d::SolidSPtr solid; ///< \ru Тело. \en A solid. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSweptData(); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSweptData( const MbSweptData &, MbRegDuplicate * ireg = NULL ); + +public: + + /** \brief \ru Конструктор плоской образующей. + \en Constructor of planar swept. \~ + \details \ru Конструктор плоской образующей из одного контура. + \en Constructor of planar swept from one contour. \~ + \param[in] place - \ru Локальная система координат. + \en A local coordinate system. \~ + \param[in] contour - \ru Контур в параметрах заданной системы координат. Используется оригинал. + \en Contour in parameters of the given coordinate system. Used original. \~ + */ + MbSweptData( const MbPlacement3D & place, MbContour & contour ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по набору контуров на поверхности. + \en Constructor by a set of contours on a surface. \~ + \param[in] _surface - \ru Поверхность. Используется оригинал. + \en The surface. Used original. \~ + \param[in] _contours - \ru Набор контуров. Используются оригиналы. + \en A set of contours. Used originals. \~ + */ + MbSweptData( MbSurface & _surface, RPArray & _contours ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по набору контуров на поверхности. + \en Constructor by a set of contours on a surface. \~ + \param[in] _surface - \ru Поверхность. Используется оригинал. + \en The surface. Used original. \~ + \param[in] _contours - \ru Набор контуров. Используются оригиналы. + \en A set of contours. Used originals. \~ + */ + MbSweptData( MbSurface & _surface, c3d::PlaneContoursSPtrVector & _contours ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по кривой. + \en Constructor by a contour. \~ + \param[in] _contour3d - \ru Кривая. Используются оригиналы. + \en A curve. Used originals. \~ + */ + MbSweptData( MbCurve3D & _curve3d ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по контуру. + \en Constructor by a contour. \~ + \param[in] _contour3d - \ru Контур. Используются оригиналы. + \en A contour. Used originals. \~ + */ + MbSweptData( MbContour3D & _contour3d ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по набору пространственных контуров. + \en Constructor by a set of spatial contours. \~ + \param[in] _contours3d - \ru Набор контуров. Используются оригиналы. + \en A set of contours. Used originals. \~ + */ + MbSweptData( RPArray & _contours3d ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по набору пространственных контуров. + \en Constructor by a set of spatial contours. \~ + \param[in] _contours3d - \ru Набор контуров. Используются оригиналы. + \en A set of contours. Used originals. \~ + */ + MbSweptData( c3d::SpaceContoursSPtrVector & _contours3d ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по телу. + \en Constructor by a solid. \~ + \param[in] _solid - \ru Тело. Используется оригинал объекта. + \en A solid. Used original of object. \~ + */ + MbSweptData( MbSolid & _solid ); + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор смешанной образующей. + \en Constructor of mixed swept. \~ + \param[in] _surface - \ru Поверхность. Используется оригинал. + \en The surface. Used original. \~ + \param[in] _contours - \ru Набор двумерных контуров в параметрах заданной поверхности. Используются оригиналы. + \en Set of two-dimensional contours in the parameters of the given surface. Used originals. \~ + \param[in] _contours3d - \ru Набор трехмерных контуров. Используются оригиналы. + \en A set of three-dimensional contours. Used originals. \~ + \param[in] _solid - \ru Тело. Используется оригинал объекта. + \en A solid. Used original of object. \~ + */ + MbSweptData( MbSurface * _surface, RPArray & _contours, + RPArray & _contours3d, MbSolid * _solid ); + + /// \ru Деструктор. \en Destructor. + ~MbSweptData(); + +public: + /** \brief \ru Добавить данные. + \en Add data. \~ + \details \ru Добавить данные о контурах на поверхности. + \en Add data about contours to the surface. \~ + \param[in] _surface - \ru Поверхность. Добавляется оригинал объекта. + \en The surface. Added original of the object. \~ + \param[in] _contours - \ru Набор контуров. Добавляются оригиналы. + \en A set of contours. Originals are added. \~ + */ + bool AddData( MbSurface & _surface, const RPArray & _contours ); + + /** \brief \ru Добавить данные. + \en Add data. \~ + \details \ru Добавить данные о контурах на поверхности. + \en Add data about contours to the surface. \~ + \param[in] _surface - \ru Поверхность. Добавляется оригинал объекта. + \en The surface. Added original of the object. \~ + \param[in] _contours - \ru Набор контуров. Добавляются оригиналы. + \en A set of contours. Originals are added. \~ + */ + bool AddData( MbSurface & _surface, c3d::PlaneContoursSPtrVector & _contours ); + + /** \brief \ru Количество всех кривых. + \en The count of all the curves. \~ + \details \ru Общее количество двумерных и трехмерных кривых. + \en The total count of two and three-dimensional curves. \~ + */ + size_t CurvesCount() const; + + /** \brief \ru Получить кривую по индексу. + \en Get the curve by the index. \~ + \details \ru Получить кривую из множества кривых на поверхности + и трехмерных кривых. + \en Get the curve from set of curves on the surface + and three-dimensional curves. \~ + \param[in] i - \ru Номер кривой в пределах от 0 до CurvesCount(). + \en The index of curve from 0 to CurvesCount(). \~ + \return \ru Кривую на поверхности или трехмерную кривую. + \en Curve on the surface or three-dimensional curve. \~ + */ + SPtr GetCurve3D( size_t i ) const; + + /// \ru Есть данные о двумерных кривых на поверхности? \en Is there data of two-dimensional curves on the surface? + bool IsSurfaceCurvesData() const; + /// \ru Есть данные о пространственных кривых? \en Is there data of spatial curves? + bool IsSpaceCurvesData() const; + /// \ru Есть данные о теле? \en Is there data about the solid? + bool IsSolidData() const; + + /// \ru Выдать поверхность. \en Get the surface. + const MbSurface * GetSurface() const { return surface; } + /// \ru Выдать поверхность для изменения. \en Get the surface for editing. + MbSurface * SetSurface() { return surface; } + /// \ru Положить поверхность. \en Set a surface. + void SetSurface( MbSurface * surf ) { surface = surf; } + /// \ru Выдать набор двумерных контуров. \en Get the set of two-dimensional contours. + const c3d::PlaneContoursSPtrVector & GetContours() const { return contours; } + /// \ru Выдать набор трехмерных контуров. \en Get the set of three-dimensional contours. + const c3d::SpaceContoursSPtrVector & GetContours3D() const { return contours3D; } + /// \ru Выдать тело. \en Get the solid. + const MbSolid * GetSolid() const { return solid; } + /// \ru Выдать тело для изменения. \en Get the solid for editing. + MbSolid * SetSolid() const { return solid; } + + /** \brief \ru Преобразовать объект. + \en Transform the object. \~ + \details \ru Преобразовать исходный объект согласно матрице c использованием регистратора. + \en Transform the initial object according to the matrix using the registrator. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + /** \brief \ru Сдвинуть объект. + \en Move the object. \~ + \details \ru Сдвинуть геометрический объект вдоль вектора с использованием регистратора. + \en Move a geometric object along the vector using the registrator. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Move ( const MbVector3D & to, MbRegTransform * iReg = NULL ); + /** \brief \ru Повернуть объект. + \en Rotate the object. \~ + \details \ru Повернуть объект вокруг оси на заданный угол с использованием регистратора. + \en Rotate an object about the axis by the given angle using the registrator. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + + /** \brief \ru Определить, являются ли объекты равными. + \en Determine whether the objects are equal. \~ + \details \ru Определить, являются ли объекты равными с заданной точностью. + \en Determine whether the objects are equal with defined accuracy. \~ + \param[in] other - \ru Объект для сравнения. + \en Object for comparison. \~ + \return \ru Подобны ли объекты. + \en Whether the objects are similar. \~ + */ + bool IsSame( const MbSweptData & other, double accuracy ) const; + /** \brief \ru Определить, являются ли объекты подобными. + \en Determine whether the objects are similar. \~ + \details \ru Подобный объект можно инициализировать по данным подобного ему объекта. + \en Similar object can be initialized by data of object which is similar to it. \~ + \param[in] other - \ru Объект для сравнения. + \en Object for comparison. \~ + \return \ru Подобны ли объекты. + \en Whether the objects are similar. \~ + */ + bool IsSimilar( const MbSweptData & other ) const; + /** \brief \ru Сделать объекты равным. + \en Make objects equal. \~ + \details \ru Равными можно сделать только подобные объекты. + \en It is possible to make equal only similar objects. \~ + \param[in] init - \ru Объект для инициализации. + \en Object for initialization. \~ + \return \ru Сделан ли объект равным присланному. + \en Whether the object is made equal to the given one. \~ + */ + bool SetEqual ( const MbSweptData & other ); + + /** \brief \ru Замкнуты ли все контуры. + \en Whether all contours are closed. \~ + \details \ru Замкнуты ли все контуры. \n + \en Whether all contours are closed. \n \~ + \return \ru Возвращает true, если все контуры замкнуты. + \en Returns true if all contours are closed. \~ + */ + bool IsContoursClosed() const; + + /// \ru Проверить, что нет разрывов между сегментами поверхностных контуров. \en Check that there are no gaps between the segments of the surface contours. + bool CheckSurfaceContourConnection( double eps ) const; + /// \ru Проверить, что нет разрывов между сегментами пространственных контуров. \en Check that there are no gaps between the segments of the spatial contours. + bool CheckSpaceContourConnection( double eps ) const; + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbSweptData & operator = ( const MbSweptData & ); + +KNOWN_OBJECTS_RW_REF_OPERATORS( MbSweptData ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Cпособ выдавливания/вращения. + \en Method of extrusion/rotation. \~ + \details \ru Cпособ построения выдавливания/вращения. \n + \en Method of extrusion/rotation constructing. \n \~ + \ingroup Build_Parameters +*/ +// --- +enum MbSweptWay { + sw_scalarValue = -2, ///< \ru Выдавить на заданную глубину / вращать на заданный угол. \en Extrude to a given depth / rotate by a given angle. + sw_shell = -1, ///< \ru До ближайшего объекта (тела). \en To the nearest object (solid). + sw_surface = 0, ///< \ru До поверхности. \en To the surface. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры вращения и выдавливания. + \en Parameters of rotation and extrusion. \~ + \details \ru Данные о построении операции вращения или выдавливания + в одном из направлений: прямом или обратном. + \en Data about construction of rotation and extrusion + in one of directions: forward or backward. \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS MbSweptSide { +public: + MbSweptWay way; ///< \ru Способ выдавливания/вращения. \en Method of extrusion/rotation. + double scalarValue; ///< \ru Угол вращения/глубина выдавливания. \en Angle of rotation/depth of extrusion. + + /** \brief \ru Расстояние от поверхности. + \en Distance from the surface. \~ + \details \ru Расстояние от поверхности, до которой строим операцию. + Задавать при построении операции до поверхности (way = sw_surface). + distance < 0.0 при построении операции за поверхность, + distance > 0.0 при построении операции до поверхности. + \en Distance from the surface to construct up to. + Set when constructing operation to the surface (way = sw_surface). + distance < 0.0 when constructing operation back of surface, + distance > 0.0 when constructing operation front of surface. \~ + */ + double distance; + + /** \brief \ru Угол уклона. + \en Draft angle. \~ + \details \ru Угол уклона при выдавливании.\n + Операцию выдавливания с уклоном можно построить только в случае плоской образующей. + \en Draft angle when extruding.\n + Extrusion operation with draft can be constructed in the case of planar swept. \~ + */ + double rake; + +protected: + /** \brief \ru Поверхность, до которой строим операцию. + \en The surface to construct up to. \~ + \details \ru Поверхность, до которой строим операцию.\n + Задавать при построении операции до поверхности (way = sw_surface). + \en The surface to construct up to.\n + Set when constructing operation to the surface (way = sw_surface). \~ + */ + MbSurface * surface; + + /** \brief \ru Признак совпадения нормали поверхности с нормалью грани. + \en An attribute of coincidence between the surface normal and the face normal. \~ + \details \ru Признак совпадения нормали поверхности, до которой строим операцию, с нормалью грани.\n + Задавать при построении операции до поверхности (way = sw_surface).\n + Указывает положение оболочки-результата относительно поверхности. + Используется при построении массива операций до поверхности. + Если у всех элементов массива признак должен быть одинаковым, + то при построении исходной операции нужно задать признак равным orient_BOTH (направление не определено). + При построении признак будет определен, и его значение нужно использовать для построения остальных элементов массива. + \en An attribute of coincidence between the face normal and the normal of surface to which to create operation.\n + Set when constructing operation to the surface (way = sw_surface).\n + Specifies the position of shell-result relative to the surface. + Used when constructing the array of operations to the surface. + If attributes of all the elements of array must be the same, + then when constructing of the original operation need to set attribute which is equal to orient_BOTH (the direction is not determined). + When constructing the attribute is determined and its value should be used for the construction of other elements of the array. \~ + */ + MbeSenseValue sameSense; + + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Задает параметры операции со способом "на заданную глубину". + Для построения операции параметры нужно изменить, + например, указать глубину выдавливания (угол вращения). + \en Sets parameters of the operation with the method "to a given depth". + For construction of operation the parameters need to change, + for example: specify the depth of extrusion (angle of rotation). \~ + */ + MbSweptSide() + : way ( sw_scalarValue ) + , scalarValue( 0.0 ) + , distance ( 0.0 ) + , rake ( 0.0 ) + , surface ( NULL ) + , sameSense ( orient_BOTH ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор на угол вращения\глубину выдавливания. + \en Constructor by angle of rotation\depth of extrusion. \~ + \param[in] sVal - \ru Угол вращения\глубина выдавливания. + \en Angle of rotation\depth of extrusion. \~ + */ + MbSweptSide( double sVal ) + : way ( sw_scalarValue ) + , scalarValue( sVal ) + , distance ( 0.0 ) + , rake ( 0.0 ) + , surface ( NULL ) + , sameSense ( orient_BOTH ) + {} + + /** \brief \ru Конструктор до поверхности. + \en Constructor to the surface. \~ + \details \ru Конструктор до поверхности. Расстояние от поверхности задается равным 0.0. + \en Constructor to the surface. Distance from the surface is set to 0.0. \~ + \param[in] surf - \ru Поверхность, до которой строится операция. + \en The surface to construct up to. \~ + */ + MbSweptSide( MbSurface * surf ); + + /** \brief \ru Конструктор до поверхности. + \en Constructor to the surface. \~ + \details \ru Конструктор до поверхности. Для элемента массива. + \en Constructor to the surface. For array element. \~ + \param[in] surf - \ru Поверхность, до которой строится операция. + \en The surface to construct up to. \~ + \param[in] sense - \ru Признак совпадения нормали заданной поверхности с нормалью грани. + Указывает, по какую сторону от поверхности должна находиться построенная оболочка. + \en An attribute of coincidence between the normal of given surface and the face normal. + Indicates at which side of the surface the must be located constructed shell. \~ + */ + MbSweptSide( MbSurface * surf, MbeSenseValue sense ); + + /** \brief \ru Конструктор копирования. + \en Copy-constructor. \~ + \details \ru Конструктор копирования данных с использованием той же поверхности. + \en Copy-constructor of data with using of the same surface. \~ + \param[in] other - \ru Исходные параметры. + \en Initial parameters. \~ + */ + MbSweptSide( const MbSweptSide & other ); + + /** \brief \ru Конструктор копирования с регистратором. + \en Copy-constructor with the registrator. \~ + \details \ru Конструктор копирования с регистратором. Поверхность копируется. + \en Copy-constructor with the registrator. Surface is copying. \~ + \param[in] other - \ru Исходные параметры. + \en Initial parameters. \~ + */ + MbSweptSide( const MbSweptSide & other, MbRegDuplicate * ireg ); + + /// \ru Деструктор. \en Destructor. + virtual ~MbSweptSide(); + + /// \ru Оператор присваивания данных с использованием той же поверхности. \en Assignment operator of data with using of the same surface. + MbSweptSide & operator = ( const MbSweptSide & other ); + + /// \ru Получить поверхность. \en Get the surface. + MbSurface * GetSurface() const { return surface; } + /// \ru Заменить поверхность. \en Replace surface. + void SetSurface( MbSurface * s ); + + /// \ru Получить признак совпадения нормали поверхности с нормалью грани. \en Get the attribute of coincidence between the surface normal and the face normal. + MbeSenseValue GetSameSense() const { return sameSense; } + /// \ru Установить признак совпадения нормали поверхности с нормалью грани. \en Set the attribute of coincidence between the surface normal and the face normal. + void SetSameSense( MbeSenseValue sense ) { sameSense = sense; } + /// \ru Доступ к признаку совпадения нормали поверхности с нормалью грани. \en Access to the attribute of coincidence between the surface normal and the face normal. + MbeSenseValue & SetSameSense() { return sameSense; } + + /// \ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSweptSide & other, double accuracy ) const + { + if ( (other.way == way) && (other.sameSense == sameSense) ) { + if ( (::fabs(other.scalarValue - scalarValue) < accuracy) && + (::fabs(other.distance - distance) < accuracy) && + (::fabs(other.rake - rake) < accuracy) ) + { + bool isSurf1 = (surface != NULL); + bool isSurf2 = (other.surface != NULL); + + if ( isSurf1 == isSurf2 ) { + if ( isSurf1 && isSurf2 ) { + if ( !other.surface->IsSame( *surface, accuracy ) ) + return false; + } + return true; + } + } + } + + return false; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры формообразующей операции. + \en The parameters of form-generating operation. \~ + \details \ru Параметры построения формообразующей операции + (например, выдавливания, вращения, кинематической, по сечениям). \n + \en The construction parameters of form-generating operation. + (for example: extrusion, rotation, sweeping, loft). \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS SweptValues { +public: + + /** \brief \ru Толщина стенки (величина эквидистанты) в прямом направлении. + \en Wall thickness (offset distance) along the forward direction. \~ + \details \ru Толщина стенки (величина эквидистанты) в положительном направлении нормали объекта + (грани, поверхности, плоскости кривой). + \en Wall thickness (offset distance) along the positive direction of the normal of an object + (face, surface, plane of the curve). \~ + */ + double thickness1; + + /** \brief \ru Толщина стенки (величина эквидистанты) в обратном направлении. + \en Wall thickness (offset distance) along the backward direction. \~ + \details \ru Толщина стенки (величина эквидистанты) в отрицательном направлении нормали объекта + (грани, поверхности, плоскости кривой). + \en Wall thickness (offset distance) along the negative direction of the normal of an object + (face, surface, plane of the curve). \~ + */ + double thickness2; + + bool shellClosed; ///< \ru Замкнутость оболочки. \en Closedness of shell. + +private: + bool checkSelfInt; ///< \ru Флаг проверки самопересечений (вычислительно "тяжелыми" методами). \en Flag for checking of self-intersection (computationally by "heavy" methods). + bool mergeFaces; ///< \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + SweptValues() + : thickness1 ( 0.0 ) + , thickness2 ( 0.0 ) + , shellClosed ( true ) + , checkSelfInt( true ) + , mergeFaces ( true ) + {} + /// \ru Конструктор по толщинам и замкнутости. \en Constructor by thicknesses and closedness. + SweptValues( double t1, double t2, bool c = true ) + : thickness1 ( t1 ) + , thickness2 ( t2 ) + , shellClosed ( c ) + , checkSelfInt( true ) + , mergeFaces ( true ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + SweptValues( const SweptValues & other ) + : thickness1 ( other.thickness1 ) + , thickness2 ( other.thickness2 ) + , shellClosed ( other.shellClosed ) + , checkSelfInt( other.checkSelfInt ) + , mergeFaces ( other.mergeFaces ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~SweptValues() {} + +public: + /// \ru Это параметры выдавливания? \en This is extrusion parameters? + virtual bool IsExtrusionValues() const { return false; } + /// \ru Это параметры вращения? \en This is rotation parameters? + virtual bool IsRevolutionValues() const { return false; } + /// \ru Это параметры кинематики? \en This is "evolution" parameters? + virtual bool IsEvolutionValues() const { return false; } + /// \ru Это параметры операции по сечениям? \en This is "lofted" parameters? + virtual bool IsLoftedValues() const { return false; } + /// \ru Это параметры операции ребра жесткости? \en This is "rib" parameters? + virtual bool IsRibValues() const { return false; } + + /// \ru Определить, являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const; + /// \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. \~ + virtual bool IsSimilar( const MbSweptData & other ) const; + /// \ru Сделать объекты равным. \en Make objects equal. \~ + virtual bool SetEqual ( const MbSweptData & other ); + +public: + /// \ru Функция копирования данных. \en Function of copying data. + void Init( const SweptValues & other ) { + thickness1 = other.thickness1; + thickness2 = other.thickness2; + shellClosed = other.shellClosed; + checkSelfInt = other.checkSelfInt; + mergeFaces = other.mergeFaces; + } + + /// \ru Получить состояние замкнутости. \en Get the closedness state. + bool IsShellClosed() const { return shellClosed; } + /// \ru Установит состояние замкнутости. \en Set the closedness state. + void SetShellClosed( bool cl ) { shellClosed = cl; } + /// \ru Получить состояние флага проверки самопересечений. \en Get the state of flag of checking self-intersection. + bool CheckSelfInt() const { return checkSelfInt; } + /// \ru Установить состояние флага проверки самопересечений. \en Set the state of flag of checking self-intersection. + void SetCheckSelfInt( bool c ) { checkSelfInt = c; } + /// \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + bool MergeFaces() const { return mergeFaces; } + /// \ru Сливать подобные грани (true). \en Whether to merge similar faces (true). + void SetMergeFaces( bool mf ) { mergeFaces = mf; } + + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const SweptValues & other ) { Init( other ); } + + KNOWN_OBJECTS_RW_REF_OPERATORS( SweptValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры выдавливания или вращения. + \en The parameters of extrusion or rotation. \~ + \details \ru Параметры выдавливания или вращения кривых с опциями по направлениям. \n + В операции выдавливания прямым направлением считается направление, сонаправленное + с вектором выдавливания, а обратным - противоположное направление. + В операции вращения прямое направлением определяется по оси вращения с помощью правила правой руки. + \en The parameters of extrusion or rotation of curves with options along the directions. \n + In the extrusion operations the forward direction is the direction collinear + with the vector of extrusion and back - the opposite direction. + In the rotation operation the forward direction is determined by the axis of rotation using the right hand rule. \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS SweptValuesAndSides: public SweptValues { +public: + MbSweptSide side1; ///< \ru Параметры выдавливания/вращения в прямом направлении. \en The parameters of extrusion/rotation along the forward direction. + MbSweptSide side2; ///< \ru Параметры выдавливания/вращения в обратном направлении. \en The parameters of extrusion/rotation along the backward direction. + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров для построения замкнутой оболочки без тонкой стенки. + Способ построение в обоих направлениях - на заданную глубину, равную 0.0. + \en Constructor of parameters for construction of closed shell without the thin wall. + Method of construction in both directions - to a given depth equal to 0.0. \~ + */ + SweptValuesAndSides() + : SweptValues() + , side1 () + , side2 () + {} + /** \brief \ru Конструктор по углам вращения или глубинам выдавливания. + \en Constructor by rotation angles and extrusion depths. \~ + \details \ru Конструктор параметров для построения замкнутой оболочки без тонкой стенки. + Способ построение в обоих направлениях - на заданную глубину. + \en Constructor of parameters for construction of closed shell without the thin wall. + Method of construction in both directions - to a given depth. \~ + \param[in] scalarValue1 - \ru Угол вращения\глубина выдавливания в прямом направлении. + \en Angle of rotation\depth of extrusion along the forward direction. \~ + \param[in] scalarValue2 - \ru Угол вращения\глубина выдавливания в обратном направлении. + \en Angle of rotation\depth of extrusion along the backward direction. \~ + */ + SweptValuesAndSides( double scalarValue1, double scalarValue2 ) + : SweptValues( ) + , side1 ( scalarValue1 ) + , side2 ( scalarValue2 ) + {} + /// \ru Конструктор копирования данных на тех же поверхностях. \en Copy-constructor of data on the same surfaces. + SweptValuesAndSides( const SweptValuesAndSides & other ) + : SweptValues( other ) + , side1 ( other.side1 ) + , side2 ( other.side2 ) + {} + /// \ru Конструктор полного копирования данных. \en Constructor of complete copying of data. + SweptValuesAndSides( const SweptValuesAndSides & other, MbRegDuplicate * ireg ) + : SweptValues( other ) + , side1 ( other.side1, ireg ) + , side2 ( other.side2, ireg ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~SweptValuesAndSides(); + +public: + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const SweptValuesAndSides * obj = dynamic_cast( &other ); + if ( obj != NULL ) { + if ( side1.IsSame( obj->side1, accuracy ) && side2.IsSame( obj->side2, accuracy ) ) { + if ( obj->SweptValues::IsSame( *this, accuracy ) ) { + return true; + } + } + } + return false; + } + +public: + /// \ru Оператор присваивания данных на тех же поверхностях. \en Assignment operator of data copying on the same surfaces. + void operator = ( const SweptValuesAndSides & other ) { + SweptValues::Init( other ); + side1 = other.side1; + side2 = other.side2; + } + + /** \brief \ru Преобразовать согласно матрице. + \en Transform according to the matrix. \~ + \details \ru Преобразовать согласно матрице поверхности в прямом и обратном направлении. + \en Transform according to the matrix of surface in the forward and backward direction. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + /** \brief \ru Сдвинуть вдоль вектора. + \en Move along a vector. \~ + \details \ru Сдвинуть вдоль вектора поверхности в прямом и обратном направлении. + \en Move along the vector of the surface along the forward and backward direction. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Move ( const MbVector3D & to, MbRegTransform * iReg = NULL ); + /** \brief \ru Повернуть вокруг оси. + \en Rotate around an axis. \~ + \details \ru Повернуть вокруг оси поверхности в прямом и обратном направлении. + \en Rotate around the axis of the surface along the forward and backward direction. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + + /** \brief \ru Сделать копии поверхностей. + \en Make copies of surfaces. \~ + \details \ru Если в каком-либо направлении задана поверхность, заменить эту поверхность на ее копию. + \en If the surface is given in any direction, then replace the surface with its copy. \~ + \param[in] ireg - \ru Регистратор копий. + \en Registrator of copies. \~ + \return \ru true, если хотя бы одна поверхность имелась и сдублирована. + \en True if at least one surface is had and copied. \~ + */ + bool DuplicateSurfaces( MbRegDuplicate * ireg = NULL ); + + /// \ru Получить поверхность в положительном направлении. \en Get the surface along the positive direction. + MbSurface * GetSurface1() const { return side1.GetSurface(); } + /// \ru Получить поверхность в отрицательном направлении. \en Get the surface along the negative direction. + MbSurface * GetSurface2() const { return side2.GetSurface(); } + /// \ru Установить поверхность в положительном направлении. \en Set the surface along the positive direction. + void SetSurface1( MbSurface * s ) { side1.SetSurface( s ); } + /// \ru Установить поверхность в отрицательном направлении. \en Set the surface along the negative direction. + void SetSurface2( MbSurface * s ) { side2.SetSurface( s ); } + /// \ru Поменять поверхности местами. \en Swap surfaces. + void ExchangeSurfaces(); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры операции выдавливания. + \en The parameters of extrusion operation. \~ + \details \ru Параметры операции выдавливания кривых с опциями по направлениям. \n + \en The parameters of extrusion operation of curves with options along directions. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS ExtrusionValues : public SweptValuesAndSides { +public: + + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров выдавливания для построения замкнутой оболочки без тонкой стенки + в прямом направлении на величину, равную 10.0. + \en Constructor of extrusion parameters for construction of closed shell without the thin wall. + along the forward direction by value 10.0. \~ + */ + ExtrusionValues() + : SweptValuesAndSides( 10., 0. ) {} + /** \brief \ru Конструктор по глубинам выдавливания. + \en Constructor by extrusion depths. \~ + \details \ru Конструктор параметров выдавливания для построения замкнутой оболочки без тонкой стенки. + Способ построение в обоих направлениях - на заданную глубину. + \en Constructor of extrusion parameters for construction of closed shell without the thin wall. + Method of construction in both directions - to a given depth. \~ + \param[in] scalarValue1 - \ru Глубина выдавливания в прямом направлении. + \en Depth of extrusion along the forward direction. \~ + \param[in] scalarValue2 - \ru Глубина выдавливания в обратном направлении. + \en Depth of extrusion along the backward direction. \~ + */ + ExtrusionValues( double scalarValue1, double scalarValue2 ) + : SweptValuesAndSides( scalarValue1, scalarValue2 ) {} + /// \ru Конструктор копирования, на тех же поверхностях. \en Copy-constructor on the same surfaces. + ExtrusionValues( const ExtrusionValues & other ) + : SweptValuesAndSides( other ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + ExtrusionValues( const ExtrusionValues & other, MbRegDuplicate * ireg ) + : SweptValuesAndSides( other, ireg ) {} + /// \ru Деструктор. \en Destructor. + virtual ~ExtrusionValues(); + +public: + // \ru Это параметры выдавливания? \en This is extrusion parameters? + virtual bool IsExtrusionValues() const { return true; } + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const ExtrusionValues * obj = dynamic_cast( &other ); + if ( obj != NULL ) { + if ( obj->SweptValuesAndSides::IsSame( *this, accuracy ) ) + return true; + } + return false; + } + +public: + /// \ru Оператор присваивания, на тех же поверхностях. \en Assignment operator on the same surfaces. + ExtrusionValues & operator = ( const ExtrusionValues & other ) { + *static_cast(this) = *static_cast(&other); + return *this; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( ExtrusionValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры операции вращения. + \en The parameters of revolution operation. \~ + \details \ru Параметры операции вращения кривых с опциями по направлениям. \n + \en The parameters of revolution operation of curves with options along directions. \n \~ + \ingroup Build_Parameters +*/ +// --- +class MATH_CLASS RevolutionValues : public SweptValuesAndSides { +public: + /** \brief \ru Форма топологии. + \en Topology shape. \~ + \details \ru Форма топологии: 0 - тело типа сферы, 1 - тело типа тора.\n + Если образующая - не замкнутая плоская кривая, и ось вращения лежит в плоскости кривой, + то возможно построение тела вращения с топологией типа сферы. В этом случае образующая достраивается до оси вращения. + \en Topology shape: 0 - sphere, 1 - torus.\n + If swept is non-closed planar curve and axis of rotation lies on the curve plane, + then is possible to construct revolution solids with the topology of sphere type. In this case the swept is being updated to the rotation axis. +I \~ */ + int shape; + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров вращения для построения замкнутой оболочки типа тора + без тонкой стенки в прямом направлении на полный оборот. + \en Constructor of revolution parameters for construction of closed shell of torus type + without thin wall along the forward direction at full turn. \~ + */ + RevolutionValues() + : SweptValuesAndSides( M_PI, 0. ) + , shape( 1 ) + {} + /** \brief \ru Конструктор по углам вращения. + \en Constructor by revolution angles. \~ + \details \ru Конструктор параметров вращения для построения замкнутой оболочки без тонкой стенки. + Способ построение в обоих направлениях - на заданную глубину (заданный угол). + \en Constructor of revolution parameters for construction of closed shell without the thin wall. + Method of construction in both directions - to a given depth (given angle). \~ + \param[in] scalarValue1 - \ru Угол вращение в прямом направлении. + \en Revolution angle along the forward direction. \~ + \param[in] scalarValue2 - \ru Угол вращения в обратном направлении. + \en Revolution angle along the backward direction. \~ + \param[in] s - \ru Форма топологии. + \en Topology shape. \~ + */ + RevolutionValues( double scalarValue1, double scalarValue2, int s ) + : SweptValuesAndSides( scalarValue1, scalarValue2 ) + , shape( s ) + {} + /// \ru Конструктор копирования, на тех же поверхностях. \en Copy-constructor on the same surfaces. + RevolutionValues( const RevolutionValues & other ) + : SweptValuesAndSides( other ) + , shape( other.shape ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + RevolutionValues( const RevolutionValues & other, MbRegDuplicate * ireg ) + : SweptValuesAndSides( other, ireg ) + , shape( other.shape ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~RevolutionValues(); + +public: + // \ru Это параметры вращения? \en This is rotation parameters? + virtual bool IsRevolutionValues() const { return true; } + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const RevolutionValues * obj = dynamic_cast( &other ); + if ( obj != NULL ) { + if ( obj->shape == shape ) { + if ( obj->SweptValuesAndSides::IsSame( *this, accuracy ) ) + return true; + } + } + return false; + } + +public: + /// \ru Оператор присваивания, на тех же поверхностях. \en Assignment operator on the same surfaces. + RevolutionValues & operator = ( const RevolutionValues & other ) { + *static_cast(this) = *static_cast(&other); + shape = other.shape; + return *this; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( RevolutionValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры кинематической операции. + \en Parameters of the sweeping operation. \~ + \details \ru Параметры операции движения образующей по направляющей кривой. \n + \en The operation parameters of moving the generating curve along the spine curve. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS EvolutionValues : public SweptValues { +public: + /** \brief \ru Способ переноса образующего контура вдоль направляющей. + \en Moving method of generating contour along the spine curve. \~ + \details \ru Способ переноса образующего контура вдоль направляющей: \n + parallel <= 0 - образующая переносится параллельно самой себе; \n + parallel == 1 - образующая при переносе сохраняет исходный угол с направляющей; \n + parallel >= 2 - плоскость образующей выставляется и сохраняется ортогональной направляющей. \n + \en Moving method of generating contour along the spine curve: \n + parallel <= 0 - generating curve is moved parallel to itself; \n + parallel == 1 - generating curve when moving preserves initial angle with spine; \n + parallel >= 2 - plane of generating curve is set and saved as orthogonal to spine. \n \~ + */ + int parallel; + // \ru Данные о функциях изменения образующих кривых вдоль напрвлябшей кривой (могут быть NULL). \en Data about changes of generating curves along the guide curve (can be NULL). + double range; ///< \ru Эквидистантное смещение точек образующей кривой в конце траектории. \en The offset range of generating curve on the end of spine curve. + SPtr scaling; ///< \ru Функция масштабирования образующей кривой. \en The fanction of curve scale. + SPtr winding; ///< \ru Функция вращения образующей кривой. \en The fanction of curve rotation. + +public: + + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров кинематической операции для построения замкнутой оболочки + без тонкой стенки с сохранением угла наклона. + \en Constructor of sweeping operation parameters for construction of closed shell + without the thin wall with keeping the angle inclination. \~ + */ + EvolutionValues() + : SweptValues( ) + , parallel ( 1 ) + , range ( 0.0 ) + , scaling ( NULL ) + , winding ( NULL ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + EvolutionValues( const EvolutionValues & other ); + /// \ru Деструктор. \en Destructor. + virtual ~EvolutionValues(); + +public: + // \ru Это параметры кинематики? \en This is "evolution" parameters? + virtual bool IsEvolutionValues() const { return true; } + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const; + // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. \~ + virtual bool IsSimilar( const SweptValues & other ) const; + // \ru Сделать объекты равным. \en Make objects equal. \~ + virtual bool SetEqual ( const SweptValues & other ); + + /// \ru Выдать функцию масштабирования образующей кривой. \en Get the fanction of curve scale. + double GetRange() const { return range; } + double & SetRange() { return range; } + void SetRange( double r ) { range = r; } + + /** \brief \ru Добавить данные. + \en Add data. \~ + \details \ru Добавить данные об изменении образующих контурах на поверхности вдоль образующей кривой. + \en Add data about changes of generatig contours on the surface along the guide curve. \~ + \param[in] _scaling - \ru Масштабирование. + \en The scaling. \~ + \param[in] _winding - \ru Поворот. + \en The winding. \~ + */ + bool AddData( MbFunction & _scaling, MbFunction & _winding ); + + /// \ru Выдать функцию масштабирования образующей кривой. \en Get the fanction of curve scale. + const MbFunction* GetScaling() const { return scaling; } + MbFunction * SetScaling() { return scaling; } + + /// \ru Выдать функцию вращения образующей кривой. \en Get the fanction of curve rotation. + const MbFunction* GetWinding() const { return winding; } + MbFunction * SetWinding() { return winding; } + +public: + /// \ru Оператор присваивания. \en Assignment operator. + EvolutionValues & operator = ( const EvolutionValues & other ); + + KNOWN_OBJECTS_RW_REF_OPERATORS( EvolutionValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры операции построения тела по плоским сечениям. + \en The operation parameters of constructing solid by lofted. \~ + \details \ru Параметры операции построения тела по плоским сечениям, заданных контурами. \n + \en The parameters of constructing operation by lofted which are given by contours. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS LoftedValues : public SweptValues { +public: + bool closed; ///< \ru Замкнутость трубки сечений. \en Closedness of tube. + MbVector3D vector1; ///< \ru Производная в начале. \en The derivative at the start. + MbVector3D vector2; ///< \ru Производная в конце. \en The derivative at the end. + bool setNormal1; ///< \ru Установлена нормаль в начале. \en The normal is set at the start. + bool setNormal2; ///< \ru Установлена нормаль в конце. \en The normal is set at the end. + +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор параметров операции по сечениям для построения замкнутой оболочки без тонкой стенки. + \en Constructor of lofted operation parameters for construction of closed shell without the thin wall. \~ + */ + LoftedValues() + : SweptValues ( ) + , closed ( false ) + , vector1 ( 0.0, 0.0, 0.0 ) + , vector2 ( 0.0, 0.0, 0.0 ) + , setNormal1 ( false ) + , setNormal2 ( false ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + LoftedValues( const LoftedValues & other ) + : SweptValues ( other ) + , closed ( other.closed ) + , vector1 ( other.vector1 ) + , vector2 ( other.vector2 ) + , setNormal1 ( other.setNormal1 ) + , setNormal2 ( other.setNormal2 ) + {} + /// \ru Оператор присваивания. \en Assignment operator. + LoftedValues & operator = ( const LoftedValues & other ) + { + SweptValues::Init( other ); + closed = other.closed; + vector1 = other.vector1; + vector2 = other.vector2; + setNormal1 = other.setNormal1; + setNormal2 = other.setNormal2; + return *this; + } + /// \ru Деструктор. \en Destructor. + virtual ~LoftedValues(); + +public: + // \ru Это параметры операции по сечениям? \en This is "lofted" parameters? + virtual bool IsLoftedValues() const { return true; } + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const LoftedValues * obj = dynamic_cast( &other ); + if ( obj != NULL ) { + if ( obj->closed == closed ) { + if ( c3d::EqualVectors(vector1, obj->vector1, accuracy) && c3d::EqualVectors(vector2, obj->vector2, accuracy) ) { + if ( obj->setNormal1 == setNormal1 && obj->setNormal2 == setNormal2 ) { + if ( obj->SweptValues::IsSame(*this, accuracy) ) { + return true; + } + } + } + } + } + return false; + } + +public: + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D & to ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D & axis, double ang ); + + KNOWN_OBJECTS_RW_REF_OPERATORS( LoftedValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры ребра жёсткости. + \en Parameters of a rib. \~ + \details \ru Параметры построения ребра жёсткости по кривой, задающей его форму. \n + \en The construction parameters of rib by curve gives its shape. \n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS RibValues : public SweptValues { +public: + /** \brief \ru Сторона заполнения пространства телом ребра. + \en The side to place the rib on. \~ + \details \ru С какой стороны от кривой располагается ребро. \n + \en With which side of the curve is rib. \n \~ + \ingroup Build_Parameters + */ + enum ExtrudeSide { + es_Left = 0, ///< \ru Ребро выдавливается в левую сторону от кривой вдоль плоскости. \en Rib is extruded to the left side of the curve along the plane. + es_Right, ///< \ru Ребро выдавливается в правую сторону от кривой вдоль плоскости. \en Rib is extruded to the right side of the curve along the plane. + es_Up, ///< \ru Ребро выдавливается в сторону нормали плоскости. \en Rib is extruded to the side of the surface normal. + es_Down, ///< \ru Ребро выдавливается в сторону против нормали плоскости. \en Rib is extruded to the side opposite to the surface normal. + }; + +public: + double angle1; ///< \ru Угол уклона плоскости в прямом направлении. \en Draft angle of the plane along the forward direction. + double angle2; ///< \ru Угол уклона плоскости в обратном направлении. \en Draft angle of the plane along the backward direction. + ExtrudeSide side; ///< \ru Сторона заполнения пространства телом ребра. \en The side to place the rib on. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + RibValues() + : SweptValues( ) + , angle1 ( 0.0 ) + , angle2 ( 0.0 ) + , side ( es_Right ) + {} + /// \ru Конструктор по толщинам, углам и стороне заполнения пространства. \en Constructor by thickness, angles and filling space. + RibValues( double t1, double t2, double a1, double a2, int s ) + : SweptValues( t1, t2 ) + , angle1 ( a1 ) + , angle2 ( a2 ) + , side ( (ExtrudeSide)s ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + RibValues( const RibValues & other ) + : SweptValues( other ) + , angle1 ( other.angle1 ) + , angle2 ( other.angle2 ) + , side ( other.side ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~RibValues(); + +public: + // \ru Это параметры операции ребра жесткости? \en This is "rib" parameters? + virtual bool IsRibValues() const { return true; } + + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const RibValues * obj = dynamic_cast( &other ); + + if ( obj != NULL ) { + if ( obj->side == side ) { + if ( ::fabs(obj->angle1 - angle1) < accuracy && ::fabs(obj->angle2 - angle2) < accuracy ) + return SweptValues::IsSame( *obj, accuracy ); + } + } + return false; + } + +public: + /// \ru Функция копирования. \en Copy function. + void Init( const RibValues & other ) + { + SweptValues::Init( other ); + angle1 = other.angle1; + angle2 = other.angle2; + side = other.side; + } + /// \ru Оператор присваивания. \en Assignment operator. + RibValues & operator = ( const RibValues & other ) + { + Init( other ); + return *this; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( RibValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры ребра жёсткости листового тела. + \en Parameters of a sheet metal rib. \~ + \details \ru Параметры построения ребра жёсткости листового тела по кривой, задающей его форму. \n + \en The construction parameters of a sheet metal rib by curve gives its shape. \n \~ +\ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS SheetRibValues: public RibValues { +public: + double radRibConvex; ///< \ru Радиус скругления выпуклой части ребра жесткости. \en Fillet radius of convex part of rib. + double radSideConcave; ///< \ru Радиус скругления примыкания вогнутой части ребра жесткости к листовому телу. \en Fillet radius of connection of concave part of rib and metal sheet. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + SheetRibValues() + : RibValues ( ) + , radRibConvex ( 0.0 ) + , radSideConcave( 0.0 ) + {} + /// \ru Конструктор по параметрам. \en Constructor by parameters. + SheetRibValues( double t1, double t2, double a1, double a2, int s, double rFilletRib, const double & rFilletSide ) + : RibValues ( t1, t2, a1, a2, s ) + , radRibConvex ( ::fabs(rFilletRib) ) + , radSideConcave( ::fabs(rFilletSide) ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + SheetRibValues( const SheetRibValues & other ) + : RibValues ( other ) + , radRibConvex ( other.radRibConvex ) + , radSideConcave( other.radSideConcave ) + {} + /// \ru Деструктор. \en Destructor. + virtual ~SheetRibValues(); + +public: + // \ru Являются ли объекты равными? \en Determine whether an object is equal? + virtual bool IsSame( const SweptValues & other, double accuracy ) const + { + const SheetRibValues * obj = dynamic_cast( &other ); + + if ( obj != NULL ) { + if ( (::fabs(radRibConvex - obj->radRibConvex) < accuracy) && (::fabs(radSideConcave - obj->radSideConcave) < accuracy) ) + return RibValues::IsSame( *obj, accuracy ); + } + return false; + } + +public: + /// \ru Функция копирования. \en Copy function. + void Init( const SheetRibValues & other ) + { + RibValues::Init( other ); + radRibConvex = other.radRibConvex; + radSideConcave = other.radSideConcave; + } + + /// \ru Оператор присваивания. \en Assignment operator. + SheetRibValues & operator = ( const SheetRibValues & other ) { + Init( other ); + return *this; + } + + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D & matr ); + + KNOWN_OBJECTS_RW_REF_OPERATORS( SheetRibValues ) // \ru Для работы со ссылками и объектами класса. \en For working with references and objects of the class. +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры булевой операции выдавливания или вращения до объекта. + \en The parameters of Boolean operation of extrusion or revolution to object. \~ + \details \ru Параметры булевой операции выдавливания или вращения до объекта. \n + Используется при булевой операции исходного тела + и построенной операции выдавливания или вращения двумерных контуров на поверхности. + \en The parameters of Boolean operation of extrusion or revolution to object. \n + Used in Boolean operation of initial solid + and constructed operation of extrusion or revolution of two-dimensional contours on the surface. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSweptLayout { + /** \brief \ru Направление выдавливания (вращения). + \en A direction of extrusion (revolution). \~ + \details \ru Направление выдавливания (вращения) по отношению к вектору выдавливания (оси вращения). + \en The direction of extrusion relative to the extrusion vector. \~ + */ + enum Direction { + ed_minus_minus = -2, ///< \ru В обратном направлении, для обеих строн. \en Along the backward direction, for both sides. + ed_minus = -1, ///< \ru В обратном направлении, для одной стороны. \en Along the backward direction, for one sides. + ed_both = 0, ///< \ru В обоих направлениях. \en Along both directions. + ed_plus = 1, ///< \ru В прямом направлении, для одной стороны. \en Along the forward direction, for one sides. + ed_plus_plus = 2, ///< \ru В прямом направлении, для обеих сторон. \en Along the forward direction, for both sides. + }; + Direction direction; ///< \ru Направление выдавливания относительно вектора. \en The direction of extrusion relative to the vector. + bool skipUnion; ///< \ru Создавать новое тело (Не приклеивать к телу). \en Create a new solid. + +protected: + SPtr surface; ///< \ru Поверхность, на которой размещена образующая. \en The surface, which contains the generating curve. + +protected: + /// \ru Конструктор. \en Constructor. + MbSweptLayout( const MbSurface & surf, Direction dir ) : surface( &surf ), direction( dir ), skipUnion( false ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbSweptLayout( const MbSweptLayout & other ) : surface( other.surface ), direction( other.direction ), skipUnion( other.skipUnion ) {} + /// \ru Деструктор. \en Destructor. + virtual ~MbSweptLayout(); +public: + /// \ru Получить поверхность. \en Get the surface. + const MbSurface & GetSurface() const { return *surface; } + + /// \ru Создавать новое тело (Не приклеивать к телу). \en Create a new solid. + bool SkipUnion() const { return skipUnion; } + /// \ru Создавать новое тело (Не приклеивать к телу). \en Create a new solid. + void SkipUnion( bool su ) { skipUnion = su; } +public: + /// \ru Это параметры выдавливания? \en This is extrusion parameters? + virtual bool IsExtrusionLayout() const { return false; } + /// \ru Это параметры вращения? \en This is rotation parameters? + virtual bool IsRevolutionLayout() const { return false; } +public: + /// \ru Классификация точки относительно несущей поверхности. \en Classification point relative to the surface. + MbeItemLocation PointRelative( const MbCartPoint3D & p ) const; +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + MbSweptLayout & operator = ( const MbSweptLayout & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры булевой операции выдавливания до объекта. + \en The parameters of Boolean operation of extrusion to object. \~ + \details \ru Параметры булевой операции выдавливания до объекта. \n + Используется при булевой операции исходного тела + и построенной операции выдавливания двумерных контуров на поверхности. + \en The parameters of Boolean operation of extrusion to object. \n + Used in Boolean operation of initial solid + and constructed operation of extrusion of two-dimensional contours on the surface. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbExtrusionLayout : public MbSweptLayout { + MbVector3D dirVector; ///< \ru Вектор выдавливания. \en An extrusion vector. +public: + /// \ru Конструктор. \en Constructor. + MbExtrusionLayout( const MbSurface & surf, Direction dir, const MbVector3D & dirVec ) : MbSweptLayout( surf, dir ), dirVector( dirVec ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbExtrusionLayout( const MbExtrusionLayout & other ) : MbSweptLayout( other ), dirVector( other.dirVector ) {} + /// \ru Деструктор. \en Destructor. + virtual ~MbExtrusionLayout(); +public: + /// \ru Это параметры выдавливания? \en This is extrusion parameters? + virtual bool IsExtrusionLayout() const { return true; } +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbExtrusionLayout & ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры булевой операции вращения до объекта. + \en The parameters of Boolean operation of revolution to object. \~ + \details \ru Параметры булевой операции вращения до объекта. \n + Используется при булевой операции исходного тела + и построенной операции вращения двумерных контуров на поверхности. + \en The parameters of Boolean operation of revolution to object. \n + Used in Boolean operation of initial solid + and constructed operation of revolution of two-dimensional contours on the surface. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbRevolutionLayout : public MbSweptLayout { + MbAxis3D revAxis; ///< \ru Ось вращения. \en An revolution axis. +public: + /// \ru Конструктор. \en Constructor. + MbRevolutionLayout( const MbSurface & surf, Direction dir, const MbAxis3D & rotAxis ) : MbSweptLayout( surf, dir ), revAxis( rotAxis ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbRevolutionLayout( const MbRevolutionLayout & other ) : MbSweptLayout( other ), revAxis( other.revAxis ) {} + /// \ru Деструктор. \en Destructor. + virtual ~MbRevolutionLayout(); +public: + /// \ru Это параметры вращения? \en This is rotation parameters? + virtual bool IsRevolutionLayout() const { return true; } +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbRevolutionLayout & ); +}; + + +#endif // __OP_SHELL_PARAMETERS_H diff --git a/C3d/Include/pars_equation_tree.h b/C3d/Include/pars_equation_tree.h new file mode 100644 index 0000000..bf685e8 --- /dev/null +++ b/C3d/Include/pars_equation_tree.h @@ -0,0 +1,1549 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Узел бинарного дерева. + \en Node of a binary tree. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PARS_EQUATION_TREE_H +#define __PARS_EQUATION_TREE_H + + +#include // \ru СМВ для компиляции ICC \en СМВ for compilation by ICC +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Количество параметров. + \en Parameters count. \~ + \details \ru Выдать количество параметров для типа операции.\n + \en Get the count of parameters for type of operation.\n \~ + \param[in] operationType - \ru Тип операцции. + \en An operation type. \~ + \return \ru Количество параметров операции. + \en Operation parameters count. \~ + \ingroup Parser +*/ +// --- +uint inline GetCountOfParams( PceOperationType operationType ) +{ + uint res = 1; + if ( operationType < oprt_BinaryOperation ) + res = 3; + else if ( operationType < oprt_UnaryOperation ) + res = 2; + + return res; +} + + +//----------------------------------------------------------------------------- +/** \brief \ru Информация о характерных точках дерева. + \en Information about characteristic points of a tree. \~ + \details \ru Информация о характерных точках дерева. \n + \en Information about characteristic points of a tree. \n \~ + \ingroup Parser +*/ +// --- +class BTreeNode; +struct CharacterPointInfo +{ + /** \brief \ru Тип характерной точки. + \en Type of a characteristic point. \~ + \details \ru Тип характерной точки.\n + \en Type of a characteristic point.\n \~ + */ + enum EquCharacterPointType + { + equPoint_DefRangeRight, ///< \ru Граница области определения. \en Boundary of the definition domain. + equPoint_DefRangeLeft, ///< \ru Граница области определения. \en Boundary of the definition domain. + equPoint_Extr, ///< \ru Экстремум. \en Extremum. + equPoint_Break1, ///< \ru Разрыв первого рода. \en Discontinuity of the first kind. + equPoint_Break2, ///< \ru Разрыв второго рода. \en Discontinuity of the second kind. + equPoint_DerBreak1 ///< \ru Разрыв производной. \en Derivative discontinuity. + }; + + const BTreeNode * m_tree; ///< \ru Узел дерева. Не равен NULL. \en Node of a tree. Not equal to NULL. + EquCharacterPointType m_type; ///< \ru Тип характорной точки. \en Type of a characteristic point. + double m_ph; ///< \ru Значение параметра функции. \en The value of the function parameter. + double m_period; ///< \ru Период функции. \en A period of a function. + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] tree - \ru Узел дерева. + \en Node of a tree. \~ + \param[in] type - \ru Тип характорной точки. + \en Type of a characteristic point. \~ + \param[in] ph - \ru Значение параметра функции. + \en Value of a function parameter. \~ + \param[in] period - \ru Период функции. + \en Period of a function. \~ + */ + CharacterPointInfo( const BTreeNode & tree, EquCharacterPointType type, double ph, double period ) + : m_tree ( &tree ) + , m_type ( type ) + , m_ph ( ph ) + , m_period( period ) + {} + +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru Элемент области определения функции. + \en Element of the function definition domain. \~ + \details \ru Элемент области определения функции. \n + \en Element of the function definition domain. \n \~ + \ingroup Parser +*/ +// --- +struct DefRangeItem +{ + /** \brief \ru Тип элемента. + \en A type of the element. \~ + \details \ru Тип элемента области определения функции. \n + \en Type of an element of the function definition domain. \n \~ + */ + enum RangeItemType + { + range_def, ///< \ru Область определения. \en Definition domain. + range_break, ///< \ru Разрыв. \en Discontinuity. + range_extr, ///< \ru Экстремум. \en Extremum. + }; + + double lbound; ///< \ru Левая граница элемента области определения. \en Left bound of an element of the definition domain. + double rbound; ///< \ru Правая граница элемента области определения. \en Right bound of an element of the definition domain. + RangeItemType type; ///< \ru Тип элемента. \en A type of an element. + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. \n + \en Constructor. \n \~ + \param[in] l - \ru Левая граница элемента области определения. + \en The left bound of an element of the definition domain. \~ + \param[in] r - \ru Правая граница элемента области определения. + \en The right bound of an element of the definition domain. \~ + \param[in] t - \ru Тип элемента. + \en A type of the element. \~ + */ + DefRangeItem( double l, double r, RangeItemType t = range_def ) + : lbound( l ) + , rbound( r ) + , type( t ) + { + if ( lbound > rbound ) + std::swap( lbound, rbound ); + } +}; + + +namespace std { +//----------------------------------------------------------------------------- +/** \brief \ru Сравнение элементов области определения. + \en Comparison of elements of the definition domain. \~ + \details \ru Сравнение элементов области определения функции. \n + \en Comparison of elements of the function definition domain. \n \~ + \ingroup Parser +*/ +// --- +template<> +struct less +{ + /** \brief \ru Сравнение элементов области определения. + \en Comparison of elements of the definition domain. \~ + \details \ru Сравнение элементов области определения функции. \n + \en Comparison of elements of the function definition domain. \n \~ + \param[in] _Left - \ru Первый элемент. + \en The first element. \~ + \param[in] _Right - \ru Второй элемент + \en The second element \~ + \return \ru true, если первый элемент меньше второго. + \en true if the first element is less than second one. \~ + */ + bool operator()(const DefRangeItem & _Left, const DefRangeItem & _Right) const + { return ( _Right.lbound - _Left.rbound > -METRIC_EPSILON ); } +}; + +} // namespace std + + +//----------------------------------------------------------------------------- +/** \brief \ru Область определения функции. + \en The function domain. \~ + \details \ru Область определения функции. \n + \en The function domain. \n \~ + \ingroup Parser +*/ +// --- +class DefRange +{ + std::set arr; + bool m_hasbreak; +public: + static const double eps; ///< \ru Погрешность. \en Tolerance. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор области определения без разрывов. \n + \en Constructor of the definition domain without discontinuities. \n \~ + \param[in] l - \ru Левая граница области определения. + \en Left bound of the definition domain. \~ + \param[in] r - \ru Правая граница области определения. + \en Right bound of the definition domain. \~ + */ + DefRange( double l, double r ) + : m_hasbreak( false ) + { + if ( l > r ) + std::swap( l, r ); + arr.insert( DefRangeItem(l - METRIC_EPSILON, r + METRIC_EPSILON) ); + } + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор области определения без разрывов. \n + \en Constructor of the definition domain without discontinuities. \n \~ + */ + DefRange() : m_hasbreak( false ) {}; + + /// \ru Дать набор элементов области определения. \en Get a set of elements of the definition domain. + const std::set & GetSet() const { return arr; } + + /// \ru Есть ли разрывы в области определения. \en Whether the discontinuities is in the definition domain. + bool HasBreaks() const { return m_hasbreak; } + + /// \ru Разрезать область определения. \en Cut the domain. + bool Cut( DefRangeItem & i ); + /// \ru Добавить элемент области определения. \en Add element of the definition domain. + void Add( DefRangeItem & i ); + /// \ru Оператор сравнения. \en Comparison operator. + bool operator == ( const DefRange & other ); +}; + + +class BTreeConst; +class BTreeIdent; +class BTreeFunction; +class BTreeOperation; +class BTreeOperation1Arg; +class BTreeOperation3Args; +class BTreeUserFunc; + + +//----------------------------------------------------------------------------- +/** \brief \ru Значение функции и производных. + \en Value of the function and derivatives. \~ + \details \ru Значение функции и её первой, второй и третьей производных. \n + \en Values of function, its first, second and third derivatives. \n \~ + \ingroup Parser +*/ +// --- +struct DerivesValues +{ + double value; ///< \ru Значение функции. \en The value of function. + double firstDer; ///< \ru Первая производная. \en The first derivative. + double secondDer; ///< \ru Вторая производная. \en The second derivative. + double thirdDer; ///< \ru Третья производная. \en The third derivative. +}; + +//----------------------------------------------------------------------------- +/** \brief \ru Базовый класс для узлов дерева выражения. + \en Base class for nodes of the expression tree. \~ + \details \ru Базовый класс для узлов дерева выражения. \n + \en Base class for nodes of the expression tree. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS BTreeNode : public TapeBase +{ +public: + typedef std::map EqualVarsMap; ///< \ru Набор пар переменных. \en A set of pairs of variables. + typedef std::map VarsDerives; ///< \ru Набор пар: координата - значение и производные. \en A set of pairs: coordinate - value and derivatives. + +public: + BteNodeType type; ///< \ru Тип узла. \en A type of node. \~ \internal \ru Для отладки. \en For debugging. \~ \endinternal +protected: + mutable VarsDerives varDers; ///< \ru Рабочие переменные. \en Working variables. \~ + +protected: + /// \ru Конструктор по умолчанию. \en Default constructor. + BTreeNode() {} + +public: + virtual ~BTreeNode() {} + /// \ru Выдать тип узла дерева. \en Get type of a tree node. + virtual BteNodeType IsA () const = 0; + /// \ru Создать копию объекта. \en Create a copy of the object. + virtual BTreeNode * Duplicate() const = 0; + + /// \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const = 0; + + /**\ru \name Функции для вычисления значения и производной. + \en \name Functions for calculation of the value and the derivative. + \{ */ + + /** \brief \ru Вычислить значение. + \en Calculate value. \~ + \details \ru Вычислить значение узла.\n + \en Calculate value of node.\n \~ + \param[out] fValue - \ru Значение. + \en Value. \~ + \return \ru Код результата разбора строки. + \en String parsing result code. \~ + */ + virtual EquTreeResCode GetValue( double & fValue ) const = 0; + + /** \brief \ru Установить значение. + \en Set value. \~ + \details \ru Устанавливает значение v узлу дерева. + \en Set 'v' value to a tree node. \~ + \param[in] v - \ru Желаемое значение. + \en Desirable value. \~ + \param[in] unfixedDVars - \ru Переменные, значение которых можно менять. + \en Variables which values can be changed. \~ + */ + virtual bool SetValue( double v, const std::set & unfixedDVars ) = 0; + + /** \brief \ru Вычислить значение и производные. + \en Calculate a value and derivatives. \~ + \details \ru Вычислить значение и производные. \n + \en Calculate a value and derivatives. \n \~ + \param[out] fValue - \ru Значение. + \en Value. \~ + \param[out] derive1 - \ru Первая производная. + \en The first derivative. \~ + \param[out] derive2 - \ru Вторая производная. + \en The second derivative. \~ + \param[out] derive3 - \ru Третья производная. + \en The third derivative. \~ + \param[in] ders - \ru Набор значений и производных. + \en Set of values and derivatives. \~ + \return \ru Код результата разбора строки. + \en String parsing result code. \~ + */ + virtual EquTreeResCode CalculateDerives( double & fValue, double & derive1, + double & derive2, double & derive3, const VarsDerives & ders ) const = 0; + + /** \brief \ru Вычислить значение и производные. + \en Calculate a value and derivatives. \~ + \details \ru Вычислить значение и производные. \n + \en Calculate a value and derivatives. \n \~ + \param[in] coord - \ru Координата. + \en Coordinate. \~ + \param[out] v - \ru Значение. + \en Value. \~ + \param[out] fd - \ru Первая производная. + \en The first derivative. \~ + \param[out] sd - \ru Вторая производная. + \en The second derivative. \~ + \param[out] td - \ru Третья производная. + \en The third derivative. \~ + \return \ru Код результата разбора строки. + \en String parsing result code. \~ + */ + EquTreeResCode CalculateDerives( const ItCoord * coord, double & v, double & fd, double & sd, double & td ) const; + + /** \brief \ru Выдать использованные переменные. + \en Get the used variables. \~ + \details \ru Выдать использованные переменные. \n + \en Get the used variables. \n \~ + \param[out] arr - \ru Переменные. + \en Variables. \~ + \param[out] funcs - \ru Пользовательские функции. + \en User functions. \~ + */ + virtual void GetUsedVariables( SSArray & arr, SSArray & funcs ) const = 0; + + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + /** \brief \ru Заменить переменные. + \en Replace variables. \~ + \details \ru Заменить все переменные с указанными именем на новую переменную.\n + \en Replace all variables with the specified name by a new variable.\n \~ + \param[out] varName - \ru Имя. + \en Name. \~ + \param[out] newVar - \ru Новая переменная. + \en New variable. \~ + */ + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ) = 0; + + /** \brief \ru Заменить узел. + \en Replace a node. \~ + \details \ru Заменить узел на копию нового, если заданная переменная использована.\n + \en Replace a node with a copy of a new one if the given variable is used.\n \~ + \param[out] var - \ru Переменная. + \en Variable. \~ + \param[out] subTree - \ru Новый узел. + \en New node. \~ + */ + virtual void ReplaceParVariable( const ItTreeVariable & var, const BTreeNode & subTree ) = 0; + + /** \brief \ru Заменить переменные. + \en Replace variables. \~ + \details \ru Заменить все переменные с указанными именем на новую переменную.\n + \en Replace all variables with the specified name by a new variable.\n \~ + */ + virtual void ReplaceIntVariable( const c3d::string_t &, ItIntervalTreeVariable & ) {} + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /** \brief \ru Выдать значение параметра экстремума. + \en Get value of parameter of extremum. \~ + \details \ru Выдать значение параметра экстремума, если это возможно.\n + \en Get value of parameter of extremum if it is possible.\n \~ + \param[in] interval - \ru Интервал для поиска. + \en Interval to search. \~ + \param[in] var - \ru Переменная. + \en Variable. \~ + \param[out] points - \ru Точки экстремума. + \en Points of extremum. \~ + */ + bool GetExtremumPoints( std::pair interval, ItTreeVariable & var, + std::vector & points ); + + /** \brief \ru Область определения. + \en Domain. \~ + \details \ru Область определения.\n + \en Domain.\n \~ + \param[in,out] defRange - \ru Область определения. + \en Domain. \~ + \param[out] var - \ru Переменная. + \en Variable. \~ + \param[in] stopOnBreak - \ru Не искать разрывы области определения. + \en Not to search the discontinuities in the definition domain. \~ + */ + virtual bool GetDefRange( DefRange & defRange, ItTreeVariable & var, bool stopOnBreak ) const = 0; + + /** \brief \ru Только для внутреннего использования! Порядок переменной. + \en For internal use only! Order of variable. \~ + \details \ru Порядок переменной.\n + \en Order of variable.\n \~ + \param[in] var - \ru Переменная. + \en Variable. \~ + \return \ru Порядок. + \en Order. \~ + */ + virtual size_t GetPseudoOrderByVar ( ItTreeVariable & var ) const = 0; + + /** \brief \ru Фиксированные переменные. + \en Fixed variables. \~ + \details \ru Фиксированные переменные.\n + \en Fixed variables.\n \~ + \param[in] unfixedVars - \ru Набор нефиксированных переменных. Если переменная нашлась в наборе, фиксировать копию. + \en A set of unfixed variables. If variable was found in set, then fix the copy. \~ + \param[in] newFuncs - \ru Пользовательские функции. + \en User functions. \~ + \param[out] code - \ru Коды результата разбора строки. + \en Result codes of string parsing. \~ + \return \ru Переменную для фиксирования. + \en Variable for fixation. \~ + */ + virtual std_unique_ptr FixVars ( const RPArray & unfixedVars, + PArray & newFuncs, EquTreeResCode & code ) const = 0; + + /// \ru Дать эквивалентный узел. \en Get equivalent node. + virtual std_unique_ptr GetCalcEquivalent() const = 0; + + /** \brief \ru Дать строку. + \en Get string. \~ + \details \ru Дать строку выражения.\n + \en Get expression string.\n \~ + \param[out] - \ru Строка. + \en String. \~ + */ + virtual void GetString( c3d::string_t & ) const = 0; + + /// \ru Вычислить размер в байтах. \en Get size in bytes. + virtual size_t SizeOf() const = 0; + + /** \} */ + /**\ru \name Функции сравнения. + \en \name Comparison function. + \{ */ + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] varsMap - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual( const BTreeNode & other, const EqualVarsMap & varsMap ) const = 0; + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeConst & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeIdent & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeFunction & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeOperation & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeOperation1Arg & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeOperation3Args & , const EqualVarsMap & ) const { return false; } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether the node is equal to the given node.\n \~ + \return false. + */ + virtual bool IsEqual( const BTreeUserFunc & , const EqualVarsMap & ) const { return false; } + /** \} */ + +private: + // \ru не реализовано \en not implemented + BTreeNode( const BTreeNode & ); + void operator =( const BTreeNode & ); + + DECLARE_PERSISTENT_CLASS( BTreeNode ) +}; + +IMPL_PERSISTENT_OPS( BTreeNode ) + +//----------------------------------------------------------------------------- +/** \brief \ru Типы узлов бинарного дерева. + \en Types of nodes of the binary tree. \~ + \details \ru Типы узлов бинарного дерева. \n + \en Types of nodes of the binary tree. \n \~ + \ingroup Parser +*/ +// --- +enum TeIntervalNodeType +{ + tei_Const, ///< \ru Константа. \en Constant. + tei_Ident ///< \ru Идентификатор. \en Identifier. +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru Узел дерева интервального выражения. + \en Node of interval expression tree. \~ + \details \ru Узел дерева интервального выражения. \n + \en Node of interval expression tree. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS TreeIntervalNode : public TapeBase/*, public BTreeBaseNode*/ +{ +protected: + TreeIntervalNode() {} + +public: + /// \ru Выдать тип узла дерева. \en Get type of a tree node. + virtual TeIntervalNodeType IsA () const = 0; + /// \ru Выдать копию объекта. \en Get a copy of the object. + virtual TreeIntervalNode * Duplicate() const = 0; + + /// \ru Дать первую переменную. \en Get the first variable. + virtual EquTreeResCode GetFirstValue ( double & ) const = 0; + /// \ru Дать вторую переменную. \en Get the second variable. + virtual EquTreeResCode GetSecondValue ( double & ) const = 0; + /// \ru Дать строку. \en Get a string. + virtual void GetString ( c3d::string_t & ) const = 0; + + /** \brief \ru Установить значение. + \en Set value. \~ + \details \ru Попытаться установить значение [f;s] узлу дерева. + \en Try to set value [f;s] to a tree node. \~ + \param[in] f - \ru Нижняя граница интервала. + \en Lower bound of the interval. \~ + \param[in] s - \ru Верхняя граница интервала. + \en Upper bound of the interval. \~ + \param[in] unfixedIVars - \ru Mножество интервальных переменных, которые можно менять. + \en Set of interval variables, which can be changed. \~ + \param[in] unfixedDVars - \ru Mножество вещественных переменных, которые можно менять. + \en Set of real variables, which can be changed. \~ + \access public + \return \ru Истину, если удалось установить значение. + \en True if it was succeeded to set value. \~ + */ + virtual std::pair SetValue ( double f, double s + , const std::set & unfixedIVars + , const std::set & unfixedDVars ) = 0; + + /** \brief \ru Заменить переменные. + \en Replace variables. \~ + \details \ru Заменить все переменные с указанными именем на новую переменную.\n + \en Replace all variables with the specified name by a new variable.\n \~ + \param[out] varName - \ru Имя. + \en Name. \~ + \param[out] newVar - \ru Новая переменная. + \en New variable. \~ + */ + virtual void ReplaceParVariable ( const c3d::string_t & varName, ItTreeVariable & newVar ) = 0; + +private: + // \ru не реализовано \en not implemented + TreeIntervalNode( const TreeIntervalNode & ); + void operator = ( const TreeIntervalNode & ); + + DECLARE_PERSISTENT_CLASS( TreeIntervalNode ) +}; + +IMPL_PERSISTENT_OPS( TreeIntervalNode ) + +//----------------------------------------------------------------------------- +/** \brief \ru Интервал простых выражений. + \en Interval of simple expressions. \~ + \details \ru Операция [] - получение интервала из простых выражений.\n + \en operation [] - obtaining of interval of simple expressions.\n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS IntervalConstNode : public TreeIntervalNode +{ + BTreeNode * m_firstValue; ///< \ru Первое значение (всегда не NULL). \en First value (always not NULL). + BTreeNode * m_secondValue; ///< \ru Второе значение (всегда не NULL). \en Second value (always not NULL). + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] firstValue - \ru Первый узел. + \en The first node. \~ + \param[in] secondValue - \ru Второй узел. + \en The second node. \~ + */ + IntervalConstNode( BTreeNode & firstValue, BTreeNode & secondValue ) + : m_firstValue ( &firstValue ) + , m_secondValue( &secondValue ) + {} + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор копирования.\n + \en Copy-constructor.\n \~ + \param[in] other - \ru Копируемый объект. + \en Object to copy. \~ + */ + IntervalConstNode( const IntervalConstNode & other ) + : m_firstValue( other.m_firstValue ) + , m_secondValue( other.m_secondValue ) + {} + +public: + /**\ru \name Функции узла дерева интервального выражения. + \en \name Functions of interval expression tree node. + \{ */ + + virtual TeIntervalNodeType IsA () const { return tei_Const; } // \ru выдать тип узла дерева \en get type of a tree node + virtual IntervalConstNode * Duplicate() const { return new IntervalConstNode( *this ); } + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetFirstValue ( double & v ) const { return m_firstValue->GetValue( v ); } + virtual EquTreeResCode GetSecondValue ( double & v ) const { return m_secondValue->GetValue( v ); } + + // \ru Установить значение. \en Set value. + virtual std::pair SetValue ( double f, double s + , const std::set & unfixedIVars + , const std::set & unfixedDVars ); + + virtual void GetString( c3d::string_t & ) const {} + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + + /** \} */ + /**\ru \name Функции операции []. + \en \name Functions of operation []. + \{ */ + + /// \ru Дать первый узел. \en Get the first node. + BTreeNode & GetFirstTree () { return *m_firstValue; } + /// \ru Дать второй узел. \en Get the second node. + BTreeNode & GetSecondTree () { return *m_secondValue; } + + /** \brief \ru Заменить переменные. + \en Replace variables. \~ + \details \ru Заменить все переменные с указанными именем на новую интервальную переменную.\n + \en Replace all variables with the specified names by a new interval variable.\n \~ + */ + virtual void ReplaceIntVariable( const c3d::string_t & /*varName*/, ItIntervalTreeVariable & /*newVar*/ ) {} + /** \} */ +// ССА K13 virtual size_t SizeOf() const = 0; + +private: + // \ru не реализовано \en not implemented + void operator =( const TreeIntervalNode & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( IntervalConstNode ) +}; + +IMPL_PERSISTENT_OPS( IntervalConstNode ) + +//----------------------------------------------------------------------------- +/** \brief \ru Интервальная переменная как узел бинарного дерева. + \en Interval variable as a node of a binary tree. \~ + \details \ru Узел дерева - интервальная переменная.\n + \en Tree node is an interval variable.\n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS IntervalIdentNode : public TreeIntervalNode +{ + ItIntervalTreeVariable * m_ident; ///< \ru Всегда не NULL. \en Always not NULL. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по интервальной переменной.\n + \en Constructor by an interval variable.\n \~ + \param[in] ident - \ru Интервальная переменная. + \en Interval variable. \~ + */ + IntervalIdentNode( ItIntervalTreeVariable & ident ) + : m_ident( &ident ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + IntervalIdentNode( const IntervalIdentNode & other ); + +public: + /**\ru \name Функции узла дерева интервального выражения. + \en \name Functions of the interval expression tree node. + \{ */ + virtual TeIntervalNodeType IsA () const { return tei_Ident; } // \ru выдать тип узла дерева \en get type of a tree node + virtual IntervalIdentNode * Duplicate() const { return new IntervalIdentNode( *this ); } + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetFirstValue ( double & v ) const; + virtual EquTreeResCode GetSecondValue ( double & v ) const; + virtual void GetString( c3d::string_t & ) const {}; + virtual void ReplaceParVariable( const c3d::string_t & /*varName*/, ItTreeVariable & /*newVar*/ ){} + + // \ru Установить значение. \en Set value. + virtual std::pair SetValue ( double f, double s + , const std::set & unfixedIVars + , const std::set & unfixedDVars ); + /** \} */ + +// ССА K13 virtual void ReplaceIntVariable( const string & varName, ItIntervalTreeVariable & newVar ){} +// ССА K13 virtual size_t SizeOf() const; + +private: + void operator =( const IntervalIdentNode & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( IntervalIdentNode ) +}; + +IMPL_PERSISTENT_OPS( IntervalIdentNode ) + +//------------------------------------------------------------------------------ +/** \brief \ru Константа как узел бинарного дерева. + \en Constant as a node of a binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий константу. \n + \en Node of a binary tree denoting a constant. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS BTreeConst : public BTreeNode +{ +private: + double value; ///< \ru Значение константы. \en Value of a constant. + c3d::string_t m_name; ///< \ru Имя константы, если есть, в файл не пишется. \en A name of a constant if it exists, not written to file. + +public: + + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по значению.\n + \en Constructor by value.\n \~ + \param[in] val - \ru Значение константы. + \en Value of a constant. \~ + \param[in] name - \ru Имя константы. + \en Name of a constant. \~ + */ + BTreeConst( double val, const c3d::string_t & name = _T("") ); + + /// \ru Конструктор копирования. \en Copy-constructor. + BTreeConst( const BTreeConst & ); + +public: + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA() const; + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const { return false; } + + /**\ru \name Функции для вычисления значения и производной. + \en \name Functions for calculation of the value and the derivative. + \{ */ + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetValue ( double & fvalue ) const; + virtual EquTreeResCode CalculateDerives( double &, double &, double &, double &, const VarsDerives & ) const; + + virtual bool SetValue( double, const std::set & ) { return false; } + + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + // \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & /*varName*/, ItTreeVariable & /*newVar*/ ) {} + virtual void ReplaceParVariable( const ItTreeVariable & /*var*/, const BTreeNode & /*subTree*/ ) {} + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /** \brief \ru Получить вложенный узел. + \en Get a child node. \~ + \details \ru Получить вложенный узел по индексу.\n + \en Get a child node by an index.\n \~ + */ + virtual BTreeNode * GetSubNode( size_t /*i*/ ) { return NULL; } + + virtual bool GetDefRange(DefRange &, ItTreeVariable &, bool /*stopOnBreak*/ ) const { return true; } + + virtual void GetUsedVariables( SSArray &, SSArray & )const{} + + virtual std_unique_ptr FixVars( const RPArray & /*unfixedVars*/, + PArray & /*newFuncs*/, EquTreeResCode & ) const + { return std_unique_ptr(Duplicate()); } + + virtual std_unique_ptr GetCalcEquivalent() const + { return std_unique_ptr(Duplicate()); } + + virtual void GetString( c3d::string_t & str ) const; + virtual size_t SizeOf() const; + + // \ru доступ к данным \en access to data + double GetValue() const { return value; } ///< \ru Дать переменную. \en Get variable. + void SetValue( double val ) { value = val; } ///< \ru Установить значение переменную. \en Set value of a variable. + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether the node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual ( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual ( const BTreeConst & other, const EqualVarsMap & ) const { return other.value == value; } + /** \} */ +private: + void operator =( const BTreeConst & ); // \ru не реализовано \en not implemented + virtual size_t GetPseudoOrderByVar( ItTreeVariable & ) const { return 0; } // \ru Только для внутреннего использования! \en For internal use only! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeConst ) +}; + +IMPL_PERSISTENT_OPS( BTreeConst ) + +//------------------------------------------------------------------------------ +/** \brief \ru Переменная как узел бинарного дерева. + \en Variable as a node of a binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий переменную. \n + \en Node of a binary tree denoting variable. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS BTreeIdent : public BTreeNode +{ +private: + ItTreeVariable * id; + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по переменной. \n + \en Constructor by a variable \n \~ + */ + BTreeIdent( ItTreeVariable & ); + + /// \ru Копирующий конструктор. \en Copy-constructor. + BTreeIdent( const BTreeIdent & ); + + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA () const; + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const; + + /**\ru \name Функции для вычисления значения и производной. + \en \name Functions for calculation of the value and the derivative. + \{ */ + + virtual EquTreeResCode GetValue ( double & fvalue ) const; + virtual EquTreeResCode CalculateDerives( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables ( SSArray &, SSArray & ) const; + + virtual bool SetValue( double, const std::set & ); + + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + // \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable &, const BTreeNode & /*subTree*/ ) {} + + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + /// \ru Дать вложенный узел по индексу. \en Get a child node by an index. + virtual BTreeNode * GetSubNode( size_t /*i*/ ) { return NULL; } + + virtual bool GetDefRange( DefRange &, ItTreeVariable &, bool /*stopOnBreak*/ ) const{ return true; } + + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const { return std_unique_ptr(Duplicate()); } + + virtual void GetString( c3d::string_t & str ) const { str += id->GetName(); } + virtual size_t SizeOf() const; + + // \ru доступ к данным \en access to data + ItTreeVariable & GetVariable() const { C3D_ASSERT( id ); return *id; } ///< \ru Дать параметрический идентификатор (переменную). \en Get parametric identifier (variable). + void SetVariable( ItTreeVariable & var ) { id = &var; } ///< \ru Установить параметрический идентификатор (переменную) \en Set a parametric identifier (variable). + + /** \} */ + /**\ru \name Функции сравнения. + \en \name Comparison function. + \{ */ + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual( const BTreeIdent & other, const EqualVarsMap & equVars ) const; + +private: + void operator = ( const BTreeIdent & ); // \ru не реализовано \en not implemented + virtual size_t GetPseudoOrderByVar( ItTreeVariable & var ) const { return ( &var == id ) ? 1 : 0; } // \ru Только для внутреннего использования! \en For internal use only! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeIdent ) +}; + +IMPL_PERSISTENT_OPS( BTreeIdent ) + +//------------------------------------------------------------------------------ +/** \brief \ru Функция как узел бинарного дерева. + \en Function as node of a binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий функцию. \n + \en Node of a binary tree denoting a function. \n \~ + \ingroup Parser +*/ +// --- +class BTreeFunction : public BTreeNode +{ +public: + + /** \brief \ru Типы функций. + \en Types of functions. \~ + \details \ru Типы функций. \n + \en Types of functions. \n \~ + */ + // \ru ССА K13 не менять! Пишутся в файл! \en ССА K13 not to change! Are written to file! + enum EquFnCode + { + eFnCode_unknown = -1, ///< \ru Неизвестный тип. \en An unknown type. + eFnCode_first = 0, ///< \ru Начало диапазона известных функций. \en Start of the range of known functions. + eFnCode_sin = eFnCode_first, ///< \ru Синус. \en Sine. + eFnCode_cos, ///< \ru Косинус. \en Cosine. + eFnCode_tan, ///< \ru Тангенс. \en Tangent. + eFnCode_sqrt, ///< \ru Квадратный корень. \en Square root. + eFnCode_atan, ///< \ru Арктангенс. \en Arctangent. + eFnCode_exp, ///< \ru Экспонента. \en Exponent. + eFnCode_ln, ///< \ru Натуральный логарифм. \en Natural logarithm. + eFnCode_abs, ///< \ru Модуль. \en Absolute value. + eFnCode_DegBegin, ///< \ru Начала диапазона функций с аргументом в градусах. \en Start of the range of functions with argument in degrees. + eFnCode_sind = eFnCode_DegBegin, ///< \ru Синус угла в градусах. \en Sine of the angle in degrees. + eFnCode_cosd, ///< \ru Косинус угла в градусах. \en Cosine of the angle in degrees. + eFnCode_tand, ///< \ru Тангенс угла в градусах. \en Tangent of the angle in degrees. + eFnCode_DegEnd = eFnCode_tand, ///< \ru Конец диапазона функций с аргументом в градусах. \en End of the range of functions with argument in degrees. + eFnCode_atand, ///< \ru Арктангенс с результатом в градусах. \en Arctangent with the result in degrees. + eFnCode_lg, ///< \ru Десятичный логарифм. \en Decimal logarithm. + eFnCode_ceil, ///< \ru Ближайшее большее целое число. \en Nearest largest integer number. + eFnCode_floor, ///< \ru Ближайшее меньшее целое число. \en Nearest smallest integer number. + eFnCode_round, ///< \ru Ближайшее целое число. \en Nearest integer number. + eFnCode_acos, ///< \ru Арккосинус. \en Arccosine. + eFnCode_acosd, ///< \ru Арккосинус с результатом в градусах. \en Arccosine with the result in degrees. + eFnCode_asin, ///< \ru Арксинус. \en Arcsine. + eFnCode_asind, ///< \ru Арксинус с результатом в градусах. \en Arcsine with the result in degrees. + eFnCode_rad, ///< \ru Перевод из градусов в радианы. \en Conversion from degrees to radians. + eFnCode_deg, ///< \ru Перевод из радиан в градусы. \en Conversion from radians to degrees. + eFnCode_last = eFnCode_deg ///< \ru Конец диапазона известных функций. \en End of the range of known functions. + }; + +private : + EquFnCode fnCode; // \ru код функции \en code of function + BTreeNode * par; // \ru параметр функции \en parameter of the function + +public : + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор. \n + \en Constructor. \n \~ + \param[in] code - \ru Тип функции. + \en Type of a function. \~ + \param[in] p - \ru Параметр функции. + \en Parameter of a function. \~ + */ + BTreeFunction( EquFnCode code, BTreeNode & p ); + + /// \ru Копирующий конструктор. \en Copy-constructor. + BTreeFunction( const BTreeFunction & ); + + /// \ru Деструктор. \en Destructor. + virtual ~BTreeFunction(); + +public : + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA () const; + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const; + + /**\ru \name Функции для вычисления значения и производной. + \en \name Functions for calculation of the value and the derivative. + \{ */ + + virtual EquTreeResCode GetValue ( double & value ) const; + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode CalculateDerives ( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables ( SSArray &, SSArray & ) const; + + virtual bool SetValue ( double, const std::set & ) { return false; } // \ru не реализовано \en not implemented + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable & var, const BTreeNode & subTree ); + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Дать вложенный узел по индексу. \en Get a child node by an index. + virtual BTreeNode * GetSubNode( size_t i ); + virtual bool GetDefRange( DefRange &, ItTreeVariable &, bool stopOnBreak ) const; + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const; + + virtual void GetString( c3d::string_t & str ) const; + virtual size_t SizeOf() const; + + /** \} */ + /**\ru \name Функции сравнения. + \en \name Comparison function. + \{ */ + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual ( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual ( const BTreeFunction & other, const EqualVarsMap & equVars )const; + /** \} */ + + bool IsCos() const; ///< \ru имеет ли вид a * cos() + b \en looks like a * cos() + b + + + +private: + // \ru выдать значение параметра для экстремума( если это возможно ). \en get value of parameter of extremum( if it is possible ). + virtual bool GetCharacterPoints( std::vector & ) const; + EquTreeResCode GetValue( double arg, double & value ) const; + // \ru Только для внутреннего использования! \en For internal use only! + virtual size_t GetPseudoOrderByVar( ItTreeVariable & var ) const; + void operator = ( const BTreeFunction & ); // \ru не реализовано \en not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeFunction ) +}; + +IMPL_PERSISTENT_OPS( BTreeFunction ) + +//------------------------------------------------------------------------------ +/** \brief \ru Дать тип функции. + \en Get type of function. \~ + \details \ru Дать тип функции по имени.\n + \en Get type of function by name.\n \~ + \param[in] name - \ru Имя функции. + \en Name of function. \~ + \return \ru Тип функции. + \en Type of a function. \~ + \ingroup Parser +*/ +// --- +BTreeFunction::EquFnCode GetFunCodeByName( const c3d::string_t & name ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Дать имя функции. + \en Get name of function. \~ + \details \ru Дать имя функции по типу.\n + \en Get name of function by type.\n \~ + \param[in] code - \ru Тип функции. + \en Type of a function. \~ + \param[out] name - \ru Имя функции. + \en Name of function. \~ + \ingroup Parser +*/ +// --- +void GetFunNameByCode( BTreeFunction::EquFnCode code, c3d::string_t & name ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Операция с двумя аргументами как узел бинарного дерева. + \en Operation with two arguments as node of binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий операцию с двумя аргументами. \n + \en Node of binary tree denoting operation with two arguments. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS BTreeOperation : public BTreeNode +{ +private: + PceOperationType opCode; ///< \ru Код операции. \en Code of operation. + BTreeNode * op1; ///< \ru Первый операнд. \en The first operand. + BTreeNode * op2; ///< \ru Второй операнд. \en The second operand. + + static SArray varsDerives; ///< \ru Производные аргументов для вычисления производных показательно-степенной функции \en Derivatives of arguments for calculation of derivatives of exponential-power function + static std_unique_ptr deriveFunc; ///< \ru Функция для вычисления производной показательно-степенной функции \en Function for calculation of derivative of the exponential-power function + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор.\n + \en Constructor.\n \~ + \param[in] code - \ru Код операции. + \en Code of operation. \~ + \param[in] op1 - \ru Первый операнд. + \en The first operand. \~ + \param[in] op2 - \ru Второй операнд. + \en The second operand. \~ + \ingroup Parser + */ + BTreeOperation( PceOperationType code, BTreeNode & op1, BTreeNode & op2 ); + + /// \ru Конструктор копирования. \en Copy-constructor. + BTreeOperation( const BTreeOperation & ); + + /// \ru Деструктор. \en Destructor. + virtual ~BTreeOperation(); + +public: + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA () const; + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const; + + /**\ru \name Функции для вычисления значения и производной. + \en \name Functions for calculation of the value and the derivative. + \{ */ + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetValue ( double &fvalue ) const; + virtual EquTreeResCode CalculateDerives( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables( SSArray &, SSArray & ) const; + + virtual bool SetValue ( double, const std::set & ) { return false; }// \ru не реализовано \en not implemented + + /** \} */ + /**\ru \name Функции замены переменных по именам. + \en \name Functions for replacing variables by names. + \{ */ + + // \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable & var, const BTreeNode & subTree ); + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Дать вложенный узел по индексу. \en Get a child node by an index. + virtual BTreeNode * GetSubNode( size_t i ); + virtual bool GetDefRange( DefRange &, ItTreeVariable &, bool stopOnBreak ) const; + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const; + virtual void GetString( c3d::string_t & str ) const; + virtual size_t SizeOf() const; + + /** \} */ + /**\ru \name Функции сравнения. + \en \name Comparison function. + \{ */ + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + + /** \brief \ru Равен ли узел заданному узлу. + \en Whether a node is equal to the given node. \~ + \details \ru Равен ли узел заданному узлу.\n + \en Whether a node is equal to the given node.\n \~ + \param[in] other - \ru Узел для сравнения. + \en Node for comparison. \~ + \param[in] equVars - \ru Набор пар равных переменных. + \en A set of pairs of equal variables. \~ + \return \ru true, если узлы равны. + \en true if nodes are equal. \~ + */ + virtual bool IsEqual( const BTreeOperation & other, const EqualVarsMap & equVars ) const; + + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + + /// \ru Код операции. \en Code of operation. + int16 GetOperationCode() const { return (int16)opCode; } + /// \ru Первый операнд. \en The first operand. + BTreeNode & GetFirstOperand () const { C3D_ASSERT( op1 ); return *op1; } + /// \ru Второй операнд. \en The second operand. + BTreeNode & GetSecondOperand() const { C3D_ASSERT( op2 ); return *op2; } + /** \} */ + + ///< \ru имеет ли вид a * cos() + b. \en look like a * cos() + b. + virtual bool IsCos ( double &a, double& b ) const; + +private: + void operator = ( const BTreeOperation & ); // \ru не реализовано \en not implemented + EquTreeResCode GetValue( double par1, double par2, double & value ) const; + // \ru выдать значение параметра для экстремума( если это возможно ). \en get value of parameter of extremum( if it is possible ). + virtual bool GetCharacterPoints( std::vector &, const ItTreeVariable & ) const; + // \ru Только для внутреннего использования! \en For internal use only! + virtual size_t GetPseudoOrderByVar( ItTreeVariable & var ) const; + + static MbUserFunc & GetFuncForDerInvolving(); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeOperation ) +}; + +IMPL_PERSISTENT_OPS( BTreeOperation ) + +//------------------------------------------------------------------------------ +/** \brief \ru Операция с одним аргументом как узел бинарного дерева. + \en Operation with one argument as a node of a binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий операцию с одним аргументом. \n + \en Node of a binary tree denoting an operation with one argument. \n \~ + \ingroup Parser +*/ +// --- +class BTreeOperation1Arg : public BTreeNode +{ +private : + PceOperationType opCode; ///< \ru Код операции. \en Code of operation. + BTreeNode * op; ///< \ru Операнд. \en Operand. + +public : + BTreeOperation1Arg( PceOperationType code, BTreeNode & ); + BTreeOperation1Arg( const BTreeOperation1Arg & ); + virtual ~BTreeOperation1Arg(); + + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA () const; + PceOperationType GetOperationType() const { return opCode; } + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const; + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetValue ( double &fvalue ) const; + virtual EquTreeResCode CalculateDerives( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables( SSArray &, SSArray & ) const; + + virtual bool SetValue ( double, const std::set & ); + + /// \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable &, const BTreeNode & ); + virtual BTreeNode * GetSubNode( size_t i ); + // \ru выдать значение параметра для экстремума( если это возможно ). \en get value of parameter of extremum( if it is possible ). + virtual bool GetCharacterPoints( std::vector & ) const; + virtual bool GetDefRange( DefRange & range, ItTreeVariable & var, bool stopOnBreak ) const { C3D_ASSERT( op ); + return op->GetDefRange( range, var, stopOnBreak ); } + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const; + virtual void GetString( c3d::string_t & str ) const; + + virtual bool IsEqual ( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + virtual bool IsEqual ( const BTreeOperation1Arg & other, const EqualVarsMap & equVars ) const; + virtual size_t SizeOf() const; + +private: + void operator =( const BTreeOperation1Arg & ); // \ru не реализовано \en not implemented + EquTreeResCode GetValue( double arg, double & value ) const; + // \ru Только для внутреннего использования! \en For internal use only! + virtual size_t GetPseudoOrderByVar( ItTreeVariable & var ) const { return opCode == oprt_NOT ? SYS_MAX_T : op->GetPseudoOrderByVar(var); } + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeOperation1Arg ) +}; + +IMPL_PERSISTENT_OPS( BTreeOperation1Arg ) + +//------------------------------------------------------------------------------ +/** \brief \ru Операция с тремя аргументами как узел синтаксического дерева. + \en Operation with three arguments as node of syntax tree. \~ + \details \ru Узел бинарного дерева, обозначающий операцию с тремя аргументами. \n + \en Node of binary tree denoting operation with three arguments. \n \~ + \ingroup Parser +*/ +// --- +class BTreeOperation3Args : public BTreeNode +{ +private : + BTreeNode * op1; ///< \ru Первый операнд. \en The first operand. + BTreeNode * op2; ///< \ru Второй операнд. \en The second operand. + BTreeNode * op3; ///< \ru Третий операнд. \en The third operand. + +public : + BTreeOperation3Args( BTreeNode &, BTreeNode &, BTreeNode & ); + BTreeOperation3Args( const BTreeOperation3Args & ); + virtual ~BTreeOperation3Args(); + + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA() const; + virtual BTreeNode * Duplicate() const; + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const; + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetValue ( double & fVal ) const; + virtual EquTreeResCode CalculateDerives ( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables ( SSArray &, SSArray & ) const; + + virtual bool SetValue ( double, const std::set & ){ return false;} // \ru не реализовано \en not implemented + + /// \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable &, const BTreeNode & ); + virtual BTreeNode * GetSubNode( size_t i ); + virtual bool GetDefRange( DefRange &, ItTreeVariable &, bool stopOnBreak ) const; + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const; + virtual void GetString( c3d::string_t & str ) const; + + virtual bool IsEqual ( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + virtual bool IsEqual ( const BTreeOperation3Args & other, const EqualVarsMap & equVars ) const; + virtual size_t SizeOf() const; + +private: + // \ru выдать значение параметра для экстремума( если это возможно ). \en get value of parameter of extremum( if it is possible ). + virtual bool GetCharacterPoints( std::vector &, ItTreeVariable & ) const; + // \ru Только для внутреннего использования! \en For internal use only! + virtual size_t GetPseudoOrderByVar( ItTreeVariable & ) const { return SYS_MAX_T; } + void operator =( const BTreeOperation3Args & ); // \ru не реализовано \en not implemented + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeOperation3Args ) +}; + +IMPL_PERSISTENT_OPS( BTreeOperation3Args ) + +//------------------------------------------------------------------------------ +/** \brief \ru Пользовательская функция как узел бинарного дерева. + \en User-defined function as a node of a binary tree. \~ + \details \ru Узел бинарного дерева, обозначающий пользовательскую функцию. \n + \en Node of a binary tree denoting a user-defined function. \n \~ + \ingroup Parser +*/ +// --- +class BTreeUserFunc : public BTreeNode +{ + ItUserFunc * func; ///< \ru Пользовательская функция. \en A user-defined function. + PArray pars; + +public: + BTreeUserFunc( const BTreeUserFunc & other ); + BTreeUserFunc( ItUserFunc & _func, const RPArray & _pars ); + + // \ru выдать тип узла дерева \en get type of a tree node + virtual BteNodeType IsA () const { return bt_Function; } + virtual BTreeNode * Duplicate() const { return new BTreeUserFunc( *this ); } + + // \ru Функция линейная. \en Function is linear. + virtual bool IsLine() const {return false; } + + virtual bool SetValue( double, const std::set & ) { return false; } // \ru не реализовано \en not implemented + + // \ru вычисление значения функции и производной по переменной V \en calculate the value of a function and the derivative with respect to V + virtual EquTreeResCode GetValue ( double & ) const; + virtual EquTreeResCode CalculateDerives( double &, double &, double &, double &, const VarsDerives & ) const; + virtual void GetUsedVariables( SSArray &, SSArray & ) const; + /// \ru Заменить все переменные с именем varName на переменную newVar \en Replace all variables with name 'varName' by variable 'newVar' + virtual void ReplaceParVariable( const c3d::string_t & varName, ItTreeVariable & newVar ); + virtual void ReplaceParVariable( const ItTreeVariable &, const BTreeNode & ); + virtual BTreeNode * GetSubNode ( size_t i ); + // \ru выдать значение параметра для экстремума( если это возможно ). \en get value of parameter of extremum( if it is possible ). +// ССА K13 virtual bool GetCharacterPoints( std::vector & ) const { return false; } + virtual bool GetDefRange( DefRange &, ItTreeVariable &, bool stopOnBreak ) const; + virtual std_unique_ptr FixVars( const RPArray & unfixed, + PArray & newFuncs, EquTreeResCode & ) const; + + virtual std_unique_ptr GetCalcEquivalent() const; + + virtual void GetString( c3d::string_t & str ) const; + + virtual bool IsEqual ( const BTreeNode & other, const EqualVarsMap & equVars ) const { return other.IsEqual( *this, equVars ); } + virtual bool IsEqual ( const BTreeUserFunc & other, const EqualVarsMap & equVars ) const; + + virtual size_t SizeOf() const { return 0; }; + +private: + void operator =( const BTreeOperation3Args & ); // \ru не реализовано \en not implemented + EquTreeResCode GetValue( SArray &, double & value ) const; + // \ru Только для внутреннего использования! \en For internal use only! + virtual size_t GetPseudoOrderByVar( ItTreeVariable & var ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( BTreeUserFunc ); +}; + +IMPL_PERSISTENT_OPS( BTreeUserFunc ) + +#endif // __PARS_EQUATION_TREE_H diff --git a/C3d/Include/pars_list.h b/C3d/Include/pars_list.h new file mode 100644 index 0000000..a108591 --- /dev/null +++ b/C3d/Include/pars_list.h @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Список переменных. + \en List of variables. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PARS_LIST_H +#define __PARS_LIST_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Список переменных. + \en List of variables. \~ + \details \ru Список переменных симфольной записи выражения. \n + \en A list of variables with symbol writing of expression. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS MbListVars { +private: + RPArray _vars; ///< \ru Список переменных. \en List of variables. + +public: + MbListVars(); ///< \ru Пустой конструктор. \en Empty constructor. + virtual ~MbListVars(); ///< \ru Деструктор. \en Destructor. + +public: + /// \ru Найти переменную по имени. \en Find variable by name. + MbVar * FindVariable ( const c3d::string_t & name ) const; + /// \ru Получить переменную по индексу. \en Get variable by index. + MbVar * GetVariable ( size_t index ) const; + /// \ru Количество переменных. \en The number of variables. + size_t CountVariables() const; + /// \ru Добавить переменную. \en Add a variable. + void AddVariable ( MbVar * var ); + /// \ru Убрать переменную. \en Remove a variable. + void RemoveVariable( MbVar * var ); +private: + MbListVars( const MbListVars & other ); + MbListVars & operator = ( const MbListVars & other ); +}; + + +#endif // __PARS_LIST_H \ No newline at end of file diff --git a/C3d/Include/pars_tree_variable.h b/C3d/Include/pars_tree_variable.h new file mode 100644 index 0000000..1a9edd4 --- /dev/null +++ b/C3d/Include/pars_tree_variable.h @@ -0,0 +1,233 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Интерфейс переменной. + \en Interface of variable. +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __ITTREEVARS_H +#define __ITTREEVARS_H + +#include + +class DefRange; +class BTreeNode; +struct DerivesValues; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы узлов бинарного дерева. + \en Types nodes of binary tree. \~ + \details \ru Типы узлов бинарного дерева.\n + \en Types nodes of binary tree.\n \~ + \ingroup Parser +*/ +// --- +enum BteNodeType +{ + bt_Const, ///< \ru Константа. \en Constant. + bt_Ident, ///< \ru Идентификатор. \en Identifier. + bt_Function, ///< \ru Функция. \en A function. + bt_Operation2Args, ///< \ru Операция c двумя аргументами. \en Operation with two arguments. + bt_Operation1Arg, ///< \ru Операция c одним аргументом. \en Operation with one argument. + bt_Operation3Args, ///< \ru Операция c тремя аргументами. \en Operation with three arguments. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы операций. + \en Operations types. \~ + \details \ru Типы операций.\n + \en Operations types.\n \~ + \attention \ru Значения пишутся в файл. \en Values are written in file. \~ + \ingroup Parser +*/ +// --- +enum PceOperationType +{ + oprt_TernaryOperation = 0, ///< \ru Тернарная операция. \en Ternary operation. + oprt_BinaryOperation = 8, ///< \ru Бинарная операция. \en Binary operation. + oprt_Addition = oprt_BinaryOperation, ///< \ru Сложение. \en Addition. + oprt_Subtraction = 9, ///< \ru Вычитание. \en Subtraction. + oprt_Division = 10, ///< \ru Деление. \en Division. + oprt_Multiplication = 11, ///< \ru Умножение. \en Multiplication + oprt_IntDivision = 12, ///< \ru Целочисленное деление. \en Integer division. + oprt_OR = 13, ///< \ru Или. \en Or. + oprt_AND = 14, ///< \ru И. \en And. + oprt_NEQU = 15, ///< \ru Не равно. \en Not equal. + oprt_EQU = 16, ///< \ru Равно. \en Equal. + oprt_GT = 17, ///< \ru Больше. \en More. + oprt_GE = 18, ///< \ru Больше или равно. \en More or equal. + oprt_LT = 19, ///< \ru Меньше. \en Less. + oprt_LE = 20, ///< \ru Меньше или равно. \en Less or equal. + oprt_Involution = 21, ///< \ru Возведение в степень. \en Involution. + oprt_UnaryOperation = 22, ///< \ru Унарная операция. \en Unary operation. + oprt_NOT = oprt_UnaryOperation, ///< \ru Не. \en Not. + oprt_UnaryMinus = 23, ///< \ru Унарный минус. \en Unary minus. + oprt_UnaryPlus = 24, ///< \ru Унарный плюс. \en Unary plus. + oprt_Parentheses = 25 ///< \ru Скобки. \en Brackets. +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru Коды результата разбора строки. + \en Result codes of string parsing. \~ + \details \ru Коды результата разбора строки.\n + \en Result codes of string parsing.\n \~ + \ingroup Parser +*/ +// --- +enum EquTreeResCode { + // \ru Эта группа кодов ошибок полностью повторяет то, что было до V9. \en This group of result codes fully repeats all that was before V9. + equTreeResCode_Ok = 0, ///< \ru Все хорошо. \en Everything is OK. + equTreeResCode_First = 1, ///< \ru Начало диапазона ошибок. \en Start of errors range. + equTreeResCode_SyntaxError = equTreeResCode_First, ///< \ru Ошибка: Синтаксическая ошибка в выражении. \en Error: Syntax error in expression. + equTreeResCode_TooComplex, ///< \ru Ошибка: Слишком сложное выражение. \en Error: Expression is too complex. + equTreeResCode_InvalidAssignment, ///< \ru Ошибка: Переменная присваивается самой себе. \en Error: Variable is assigned by itself. + equTreeResCode_NoVariables, ///< \ru Ошибка: В выражении должна быть хотя бы одна переменная. \en Error: There should be at least one variable in expression. + equTreeResCode_TooLargeIdent, ///< \ru Ошибка: Превышено количество символов в имени переменной. \en Error: The number of symbols in a name of variable is exceeded. + equTreeResCode_TangentsDomain , ///< \ru Ошибка: Аргумент тангенса не в области определения. \en Error: An argument of tangent is out of domain. + equTreeResCode_SqrtDomain, ///< \ru Ошибка: Недопустимое значение аргумента для sqrt. \en Error: Invalid argument value for sqrt. + equTreeResCode_LogarithmDomain, ///< \ru Ошибка: Недопустимое значение аргумента для логарифмической функции. \en Error: Invalid argument value for logarithmic function. + equTreeResCode_ZeroDivide, ///< \ru Ошибка: Деление на ноль. \en Error: Division by zero. + equTreeResCode_TrigonometricDomain, ///< \ru Ошибка: Аргумент тригонометрической функции не в области определения. \en Error: An argument of trigonometric function is out of domain. + equTreeResCode_CyclicRelation, ///< \ru Ошибка: Найдена замкнутая зависимость. \en Error: There is found a closed dependence. + equTreeResCode_PowDomain, ///< \ru Ошибка: недопустимое значение аргумента для степенной функции. \en Error: Invalid argument value for power function. + equTreeResCode_WrongFuncFormat, ///< \ru Ошибка: Выражение содержит функцию, не соответствующую своему формату. \en Error: Expression contains a function which does not correspond to its format. + + // \ru ДОБАВЛЯТЬ НОВЫЕ СООБЩЕНИЯ ТОЛЬКО ПЕРЕД ЭТОЙ СТРОКОЙ; \en ADD NEW MESSAGES ONLY BEFORE THIS STRING; + equTreeResCode_Last ///< \ru Конец диапазона ошибок. \en End of errors range. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс координаты. + \en Interface of coordinate. \~ + \details \ru Интерфейс координаты. \n + \en Interface of coordinate. \n \~ + \ingroup Parser +*/ +// --- +struct ItCoord +{ + virtual void SetValue( double v ) = 0; ///< \ru Установить переменную. \en Set variable. + virtual double GetValue() const = 0; ///< \ru Дать переменную. \en Get variable. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс переменной. + \en Interface of variable. \~ + \details \ru Интерфейс переменной. \n + \en Interface of variable. \n \~ + \ingroup Parser +*/ +// --- +struct ItTreeVariable +{ + ItTreeVariable() {} + + /// \ru Дать имя. \en Get name. + virtual const c3d::string_t & GetName() const = 0; + /// \ru Установить имя. \en Set name. + virtual void SetName( const c3d::string_t & ) = 0; + /// \ru Дать переменную. \en Get variable. + virtual double GetValue() const = 0; + /// \ru Установить переменную. \en Set variable. + virtual void SetValue( double ) = 0; + /// \ru Дать координату. \en Get coordinate. + virtual const ItCoord & GetCoord() const = 0; + /// \ru Вычислить размер в байтах. \en Get size in bytes. + virtual size_t SizeOf() const = 0; + + /// \ru Захватить \en Catch. + virtual refcount_t AddRef () const = 0; + /// \ru Отпустить. \en Free. + virtual refcount_t Release() const = 0; + + /// \ru Установить имя. Обработка нулевого указателя. \en Set name. Null pointer processing. + virtual void SetName( const TCHAR* s ) { SetName( s ? s : _T("") ); }; + + /// \ru Операторы чтения, записи. \en Reading and writing operators. + DECLARE_PERSISTENT_OPS( ItTreeVariable ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс интервальной переменной. + \en Interface of interval variable. \~ + \details \ru Интерфейс интервальной переменной. \n + \en Interface of interval variable. \n \~ + \ingroup Parser +*/ +// --- +struct ItIntervalTreeVariable +{ + ItIntervalTreeVariable() {} + + /// \ru Дать имя. \en Get name. + virtual const c3d::string_t & GetName() const = 0; + /// \ru Установить имя. \en Set name. + virtual void SetValue( double f, double s ) = 0; + /// \ru Первая граница. \en The first boundary. + virtual double First() const = 0; + /// \ru Вторая граница. \en The second boundary. + virtual double Second() const = 0; + + /// \ru Захватить. \en Catch. + virtual refcount_t AddRef() const = 0; + /// \ru Отпустить. \en Free. + virtual refcount_t Release() const = 0; + + /// \ru Операторы чтения, записи. \en Reading and writing operators. + DECLARE_PERSISTENT_OPS( ItIntervalTreeVariable ); +}; + + +class MbUserFunc; + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс функции. + \en Interface of function. \~ + \details \ru Интерфейс функции. \n + \en Interface of function. \n \~ + \ingroup Parser +*/ +// --- +struct ItUserFunc +{ + ItUserFunc(){}; + virtual ~ItUserFunc(){}; + + /// \ru Дать копию объекта. \en Get a copy of the object. + virtual ItUserFunc & Duplicate() const = 0; + /// \ru Дать имя. \en Get name. + virtual const c3d::string_t & GetName() const = 0; + /// \ru Дать количество параметров. \en Get count of parameters.. + virtual size_t GetParsCount() const = 0; + /// \ru Значение функции. \en Value of function. + virtual EquTreeResCode GetValue ( const SArray &, double & ) const = 0; + /// \ru Значение функции и производных. \en Value of function and derivatives. + virtual EquTreeResCode GetDerivates( const SArray &, + double & v, double & f, + double & s, double & t, + size_t dIndex = 0 ) const = 0; + /// \ru Внешние переменные. \en External variables. + virtual void GetExternalVars( SSArray & vars, + SSArray & funcs ) const = 0; + /// \ru Только для внутреннего использования! Степень функции по индексу переменной. \en For internal use only! Function degree by the index of variable. + virtual size_t GetPseudoOrderByPar ( size_t index ) const = 0; + /// \ru Область определения. \en Domain. + virtual bool GetDefRange( DefRange &, ItTreeVariable & var, + const std::vector & ) const = 0; + /// \ru Равны ли функции. \en Whether functions are equal. + virtual bool IsEqual ( const ItUserFunc & other ) const = 0; + /// \ru Равны ли функции. \en Whether functions are equal. + virtual bool IsEqual ( const MbUserFunc & other ) const = 0; + + /// \ru Операторы чтения, записи. \en Reading and writing operators. + DECLARE_PERSISTENT_OPS( ItUserFunc ); +}; + +#endif //__ITTREEVARS_H \ No newline at end of file diff --git a/C3d/Include/pars_user_function.h b/C3d/Include/pars_user_function.h new file mode 100644 index 0000000..4d01112 --- /dev/null +++ b/C3d/Include/pars_user_function.h @@ -0,0 +1,114 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пользовательская функция. + \en User-defined function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PARS_USER_FUNCTION_H +#define __PARS_USER_FUNCTION_H + + +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Пользовательская функция. + \en User-defined function. \~ + \details \ru Пользовательская функция. \n + \en User-defined function. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS MbUserFunc : public TapeBase, public ItUserFunc, public MbSyncItem +{ +protected: + c3d::string_t m_name; ///< \ru Имя пользовательской функции. \en A name of user-defined function. + c3d::string_t m_expression; ///< \ru Выражение. \en Expression. + BTreeNode * m_tree; ///< \ru Дерево разбора выражения (обязательно должно быть). \en A tree of expression parsing (it should be for sure). + IFC_Array m_vars; ///< \ru Формальные параметры функции. \en Formal parameters of function. + PArray m_intFuncs; ///< \ru Внутренние функции. \en Internal functions. + +public: + MbUserFunc( const c3d::string_t & name, const std::vector & pars ); ///< \ru Конструктор по имени функции и массиву аргументов. \en Constructor by function name and array of arguments. + MbUserFunc( const MbUserFunc & other ); ///< \ru Конструктор копирования. \en Copy-constructor. + MbUserFunc( const c3d::string_t & name ); ///< \ru Конструктор по имени функции. \en Constructor by function name. + virtual ~MbUserFunc(); + +public: + /// \ru Сделать копию. \en Create a copy. + virtual ItUserFunc & Duplicate() const { return *new MbUserFunc(*this); } + /// \ru Получить имя функции. \en Get function name. + virtual const c3d::string_t & GetName() const { return m_name; } + /// \ru Получить область определения функции. \en Get function domain. + virtual bool GetDefRange( DefRange &, ItTreeVariable & var, + const std::vector & ) const; + /// \ru Получить область определения функции. \en Get function domain. + bool GetDefRange( DefRange &, size_t ind, bool stopOnBreak ) const; + + /// \ru Количество аргументов (параметров). \en Parameters (arguments) count. + virtual size_t GetParsCount() const { return m_vars.Count(); } + /// \ru Внешние переменные. \en External variables. + virtual void GetExternalVars( SSArray & vars + , SSArray & funcs ) const; + + /// \ru Сравнить пользовательские функции. \en Compare symbolic (user-defined) functions. + virtual bool IsEqual( const ItUserFunc & other ) const { return other.IsEqual( *this ); } + /// \ru Сравнить пользовательские функции. \en Compare symbolic (user-defined) functions. + virtual bool IsEqual( const MbUserFunc & ) const; + /// \ru Вычислить значение функции в случае массива аргументов \en Calculate the value of a function in a case of arguments array + virtual EquTreeResCode GetValue( const SArray & params, double & v ) const; + /// \ru Вычислить значение функции и производные в случае массива аргументов \en Calculate the value of a function and derivatives in a case of arguments array + virtual EquTreeResCode GetDerivates( const SArray & params, + double & v, double & fd, + double & sd, double & td, + size_t dIndex = 0 ) const; + /// \ru Вычислить значение функции в случае одного аргумента \en Calculate the value of a function in a case of one argument + EquTreeResCode GetValue( double t, double & v ) const; + /// \ru Вычислить значение функции и производные в случае одного аргумента \en Calculate the value of a function and derivatives in a case of one argument + EquTreeResCode GetDerivates( double t, + double & v, double & fd, + double & sd, double & td ) const; + /// \ru Функция константная. \en Function is const. + bool IsConst() const; + /// \ru Функция линейная. \en Function is linear. + bool IsLine() const; + + /// \ru Установить выражение. \en Set expression. + EquTreeResCode SetExpression( const c3d::string_t & expr, const BTreeNode & tree ); + EquTreeResCode SetExpression( const TCHAR* expr, const BTreeNode & tree ); + /// \ru Получить выражение. \en Get expression. + const c3d::string_t & GetExpression() const { return m_expression; } + /// \ru Получить дерево разбора выражения \en Get expression parsing tree. + const BTreeNode & GetTree() const { return *m_tree; } + /// \ru Сравнение с пользовательской функцией. \en Comparison with user-defined function. + bool IsEqualValue( const MbUserFunc & other ) const; + /// \ru Получить массив параметров особых точек для данного аргумента, заданного индексом на заданном интервале. \en Get an array of parameters of singular points for the argument which is given by the index on the given interval. + bool GetExtremumPoints( size_t parIndex, std::pair interval, std::vector & points ); + /// \ru Получить массив параметров. \en Get array of parameters. + void GetPars ( RPArray & pars ) const; + /// \ru Получить аргумент по индексу. \en Get argument by index. + ItTreeVariable * GetPar( size_t i ) const { return i < m_vars.Count() ? m_vars[i] : NULL; } + /// \ru Поготовить объект к записи. \en Prepare an object for writing. + void WritingBeginEnd( bool begin ) { RegisterVars( begin ? registrable : noRegistrable ); } + /// \ru Оператор присваивания. \en Assignment operator. + const MbUserFunc & operator = ( const MbUserFunc & ); +private: + /// \ru Только для внутреннего использования! Порядок функции по номеру параметра. \en For internal use only! Degree of function by the number of parameter. + virtual size_t GetPseudoOrderByPar( size_t index ) const; + void RegisterVars( RegistrableRec ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbUserFunc ) +}; + +IMPL_PERSISTENT_OPS( MbUserFunc ) + +#endif // __PARS_USER_FUNCTION_H diff --git a/C3d/Include/pars_var.h b/C3d/Include/pars_var.h new file mode 100644 index 0000000..72f032e --- /dev/null +++ b/C3d/Include/pars_var.h @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Переменная. + \en Variable. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __VAR_H +#define __VAR_H + +#include +//#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Переменная. + \en Variable. \~ + \details \ru Переменная. \n + \en Variable. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS MbVar : public MbRefItem { +private: + const c3d::string_t _name; ///< \ru Имя переменной. \en A name of variable. + double _value; ///< \ru Значение переменной. \en A value of variable. + +public: + /// \ru Конструктор. \en Constructor. + MbVar( const c3d::string_t & name ); + /// \ru Деструктор. \en Destructor. + virtual ~MbVar(); + +public: + /// \ru Получить имя переменной. \en Get variable name. + const c3d::string_t & Name () const; + /// \ru Значение переменной. \en A value of variable. + double Value() const; + /// \ru Присвоить значение переменной. \en Assign a value to a variable. + void Assignment( double value ); + +OBVIOUS_PRIVATE_COPY( MbVar ) +}; + + +#endif // __VAR_H \ No newline at end of file diff --git a/C3d/Include/pars_variable.h b/C3d/Include/pars_variable.h new file mode 100644 index 0000000..67cedeb --- /dev/null +++ b/C3d/Include/pars_variable.h @@ -0,0 +1,100 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Переменная. + \en Variable. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MBVARIABLE_H +#define __MBVARIABLE_H + +#include +#include + + +//----------------------------------------------------------------------------- +/** \brief \ru Координата. + \en Coordinate. \~ + \details \ru Координата. \n + \en Coordinate. \n \~ + \ingroup Parser +*/ +// --- +class MbCoord : public ItCoord +{ +private: + double m_coord; // \ru Значение координаты. \en A value of coordinate. +public: + /// \ru Конструктор по значению. \en Constructor by the value. + MbCoord( double v ) : m_coord(v) {} + /// \ru Установить значение. \en Set value. + virtual void SetValue( double v ){ m_coord = v; } + /// \ru Получить значение. \en Get the value. + virtual double GetValue() const { return m_coord; } + /// \ru Вычислить размер координаты в байтах. \en Get size of coordinate in bytes. + size_t SizeOf() const { return sizeof(double);} + + /// \ru Операторы чтения, записи. \en Reading and writing operators. + KNOWN_OBJECTS_RW_REF_OPERATORS( MbCoord ); +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru Переменная. + \en Variable. \~ + \details \ru Переменная. \n + \en Variable. \n \~ + \ingroup Parser +*/ +// --- +class MATH_CLASS MbTreeVariable : public TapeBase, public ItTreeVariable +{ +private: + MbCoord m_coord; ///< \ru Координата. \en Coordinate. + c3d::string_t m_name; ///< \ru Имя переменной. \en A name of variable. + mutable size_t useCount; ///< \ru Количество использований. \en The number of uses. + +public: + /// \ru Конструктор по имени и значению. \en Constructor by the name and the value. + MbTreeVariable( const c3d::string_t & name, double v ); + virtual ~MbTreeVariable(); + +public: + /// \ru Получить имя. \en Get name. + virtual const c3d::string_t & GetName () const { return m_name; } + /// \ru Установить имя. \en Set name. + virtual void SetName ( const c3d::string_t & name ) { m_name = name; } + /// \ru Установить имя. Обработка нулевого указателяю \en Set name. Null pointer processing. + virtual void SetName( const TCHAR* s ) { m_name.assign( s ? s : _T("") ); }; + /// \ru Получение значение. \en Get value. + virtual double GetValue () const { return m_coord.GetValue(); } + /// \ru Установить значение. \en Set value. + virtual void SetValue ( double v ) { m_coord.SetValue( v ); } + /// \ru Получить координату. \en Get coordinate. + virtual const MbCoord & GetCoord () const { return m_coord; } + /// \ru Вычислить размер переменной в байтах. \en Get size of variable in bytes. + virtual size_t SizeOf () const { +#ifdef C3D_WINDOWS //_MSC_VER // method SizeOf() + return /*m_name.*/sizeof( m_name ) + sizeof( TCHAR ) * (m_name.length()) + m_coord.SizeOf(); +#else // C3D_WINDOWS + // \ru необходимо корректное вычилсение размера занимаемой памяти std::string \en there must be a correct calculation of size of memory allocated for std::string + return sizeof(m_name) + m_coord.SizeOf(); // \ru если данный SizeOf требуется для выделения памяти \en if the given SizeOf is required for the memory allocation + // \ru то все Ок, поскольку std::string сам разберется с выделением памяти себе. \en then everything is OK because std::string controls the memory allocation for itself. +#endif // C3D_WINDOWS + } + /// \ru Создать копию переменной. \en Create a copy of variable. + MbTreeVariable & Duplicate() const { return *new MbTreeVariable( GetName(), GetValue() ); } + /// \ru Увеличить счетчик использований. \en Increase a counter of uses. + virtual refcount_t AddRef () const { return ++useCount; } + /// \ru Уменьшить счетчик использований и удалить объект, если он никому уже не нужен. \en Decrease a counter of uses and delete an object if it is not used any more. + virtual refcount_t Release() const; + + /// \ru Операторы чтения, записи. \en Reading and writing operators. + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTreeVariable ); +}; + +IMPL_PERSISTENT_OPS( MbTreeVariable ) + +#endif // __MBVARIABLE_H \ No newline at end of file diff --git a/C3d/Include/pars_yacc.h b/C3d/Include/pars_yacc.h new file mode 100644 index 0000000..67993f0 --- /dev/null +++ b/C3d/Include/pars_yacc.h @@ -0,0 +1,181 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Алгоритм синтаксического разбора алгебраического выражения. + \en Algorithm of syntax parsing of algebraic expression. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __YACC_H +#define __YACC_H + +#include +#include +#include +#include + +class BTreeNode; +struct ItTreeVariable; +struct ItUserFunc; +struct ItIntervalTreeVariable; +class TreeIntervalNode; + +template class RPArray; + + +// \ru Максимальная длина переменной (BUG_20492) используется при создании переменной и при разборе уравнения в калькуляторе. \en Maximum length of variable (BUG_20492) is used when creating a variable and parsing of equation in calculator. + +/// \ru Максимальная длина переменной. \en Maximum length of variable. +#define MAX_VARIABLE_NAME_LENGTH 512 + +/// \ru Максимальная длина выражения. \en Maximum length of expression. +#define MAX_EQU_LENGTH 2048 + + +//------------------------------------------------------------------------------- +// +// --- +struct ItEquVarCreator +{ + virtual ~ItEquVarCreator() + { + } + + virtual ItTreeVariable * GetVariable( const c3d::string_t & name ) = 0; + virtual ItIntervalTreeVariable * GetIntervalVariable( const c3d::string_t & name ) = 0; + virtual ItUserFunc * GetFunc ( const c3d::string_t & name, size_t parCount ) = 0; + virtual bool CreateFunc ( const c3d::string_t & name, const std::vector & parNames ) = 0; + virtual bool CreateInterval( const c3d::string_t & name ) = 0; + virtual bool CreateVariable( const c3d::string_t & name ) = 0; + + virtual ItTreeVariable * GetVariable( const TCHAR* name ) = 0; + virtual ItIntervalTreeVariable * GetIntervalVariable( const TCHAR* name ) = 0; + virtual ItUserFunc * GetFunc ( const TCHAR* name, size_t parCount ) = 0; + virtual bool CreateInterval( const TCHAR* name ) = 0; + virtual bool CreateVariable( const TCHAR* name ) = 0; + virtual unsigned int GetUsedCoordsCount() const = 0; + virtual ItTreeVariable & CreateAuxVar() = 0; + + // \ru Использовались ли какие-либо переменные? \en Were any variables used? + virtual bool WereVarsUsed() const = 0; + // \ru Использовались ли несуществующие (новые) переменные? \en Were any not existed (new) variables used? + virtual bool WereNewVarsUsed() const = 0; +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать дерево уравнения (a = b + c) через параметрический калькулятор. + \en Create a tree of equations (a = b + c) by parametric calculator. \~ + \details \ru Создать дерево уравнения a = b + c) через параметрический калькулятор. \n + \en Create a tree of equations (a = b + c) by parametric calculator. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateBTreeForEquation( const c3d::string_t & equstr + , ItEquVarCreator & varsCreator + , std_unique_ptr & dRoot + ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать дерево выражения (b + c + d) через параметрический калькулятор. + \en Create a tree of equations (b + c + d) by parametric calculator. \~ + \details \ru Создать дерево выражения (b + c + d) через параметрический калькулятор. \n + \en Create a tree of equations (b + c + d) by parametric calculator. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateBTreeForExpression( const c3d::string_t & equstr + , ItEquVarCreator * varsCreator + , std_unique_ptr & root + , std_unique_ptr & iRoot + ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать переменную. + \en Create variable. \~ + \details \ru Создать переменную по строке. \n + \en Create variable by string. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateVariable( const c3d::string_t & expression, ItEquVarCreator & ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Является ли выражение неравенством. + \en Whether expression is inequation. \~ + \details \ru Является ли выражение неравенством. \n + \en Whether expression is inequation. \n \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(bool) IsInequality( const c3d::string_t & equstr ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать дерево уравнения (a = b + c) через параметрический калькулятор. + \en Create a tree of equations (a = b + c) by parametric calculator. \~ + \details \ru Создать дерево уравнения a = b + c) через параметрический калькулятор. \n + \en Create a tree of equations (a = b + c) by parametric calculator. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateBTreeForEquation( const TCHAR * equstr + , ItEquVarCreator & varsCreator + , std_unique_ptr & dRoot + ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать дерево выражения (b + c + d) через параметрический калькулятор. + \en Create a tree of equations (b + c + d) by parametric calculator. \~ + \details \ru Создать дерево выражения (b + c + d) через параметрический калькулятор. \n + \en Create a tree of equations (b + c + d) by parametric calculator. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateBTreeForExpression( const TCHAR * equstr + , ItEquVarCreator * varsCreator + , std_unique_ptr & root + , std_unique_ptr & iRoot + ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Создать переменную. + \en Create variable. \~ + \details \ru Создать переменную по строке. \n + \en Create variable by string. \n \~ + \return \ru Код результата операции. + \en Operation result code. \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(EquTreeResCode) CreateVariable( const TCHAR* expression, ItEquVarCreator & ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Является ли выражение неравенством. + \en Whether expression is inequation. \~ + \details \ru Является ли выражение неравенством. \n + \en Whether expression is inequation. \n \~ + \ingroup Parser +*/ +// --- +MATH_FUNC(bool) IsInequality( const TCHAR* equstr ); + + +#endif \ No newline at end of file diff --git a/C3d/Include/part_solid.h b/C3d/Include/part_solid.h new file mode 100644 index 0000000..d9f8ea0 --- /dev/null +++ b/C3d/Include/part_solid.h @@ -0,0 +1,465 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Идентификаторы частей тела. + \en Identifiers of the parts of the solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PART_SOLID_H +#define __PART_SOLID_H + + +#include +#include +#include + + +class MATH_CLASS MbSolid; + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификатор части тела. + \en Identifier of the part of the solid. \~ + \details \ru Идентификатор части тела с точкой привязки и другой информацией. \n + \en Identifier of solid part with the anchor point and other information. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbPartSolidIndex : public MbRefItem { + friend class MbPartSolidIndices; // \ru Владелец индексов. \en Owner of indices. + +protected: // \ru Данные класса \en Data of class + uint id; ///< \ru Идентификатор тела. \en Solid identifier. + MbPath path; ///< \ru Путь. \en Path. + ptrdiff_t ind; ///< \ru Индекс части тела. \en Index of the part of the solid. + MbCartPoint3D tiePnt; ///< \ru Точка привязки части тела. \en Anchor point of solid part. + double diag; ///< \ru Размер диагонали части тела. \en Diagonal size of the solid part. + MbCartPoint3D refPnt; ///< \ru Базовая точка тела из частей. \en Base point of the solid from parts. + ptrdiff_t allCnt; ///< \ru Общее количество частей тела. \en Total count of solid parts. +private: + mutable bool selected; ///< \ru Был ли выбран индекс. \en Whether index s selected. + mutable bool changed; ///< \ru Был ли изменен индекс части тела. \en Whether index of solid part is changed. + +public: // \ru Конструкторы \en Constructors + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPartSolidIndex() + : MbRefItem() + { + Reset(); + SetChanged( false ); + } + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по данным. + \en Constructor by data. \~ + \param[in] _id - \ru Идентификатор тела. + \en Solid identifier. \~ + \param[in] _path - \ru Путь. + \en Path. \~ + \param[in] _ind - \ru Индекс части тела. + \en Index of the part of the solid. \~ + \param[in] _tiePnt - \ru Точка привязки части тела. + \en Anchor point of solid part. \~ + \param[in] _diag - \ru Размер диагонали части тела. + \en Diagonal size of the solid part. \~ + \param[in] _refPnt - \ru Базовая точка тела из частей. + \en Base point of the solid from parts. \~ + \param[in] _allCount - \ru Общее количество частей тела. + \en Total count of solid parts. \~ + */ + MbPartSolidIndex( uint _id, + const MbPath & _path, + ptrdiff_t _ind, + const MbCartPoint3D & _tiePnt, + double _diag, + const MbCartPoint3D & _refPnt, + ptrdiff_t _allCount ) + : MbRefItem() + { + Init( _id, _path, _ind, _tiePnt, _diag, _refPnt, _allCount ); + SetChanged( false ); + } + /// \ru Деструктор. \en Destructor. + virtual ~MbPartSolidIndex(); + +public: // \ru Внешние функции. \en Eternal functions. + + /// \ru Корректен ли индекс. \en Whether index is correct. + bool IsValid() const; + /// \ru Использован ли индекс. \en Whether index is selected. + bool IsSelected() const { return selected; } + /// \ru Изменен ли индекс. \en Whether index is changed. + bool IsChanged() const { return changed; } + + /// \ru Получить идентификатор тела. \en Get solid identifier. + uint GetId() const { return id; } + /// \ru Получить путь. \en Get path. + const MbPath & GetPath() const { return path; } + + /// \ru Получить индекс части тела. \en Get index of the part of the solid. + ptrdiff_t GetIndex() const { return ind; } + /// \ru Получить точку привязки части тела. \en Get anchor point of solid part. + const MbCartPoint3D & GetTiePoint() const { return tiePnt; } + /// \ru Получить размер диагонали части тела. \en Get diagonal size of the solid part. + double GetDiag() const { return diag; } + /// \ru Получить точку привязки тела из частей. \en Get anchor point of solid from parts. + const MbCartPoint3D & GetRefPoint() const { return refPnt; } + /// \ru Получить общее количество частей тела. \en Get total count of solid parts. + ptrdiff_t GetAllCount() const { return allCnt; } + + /// \ru Сравнение индексов (по содержанию). \en Comparison of indices (by content). + bool operator == ( const MbPartSolidIndex & obj ) const; + +protected: // \ru Внутренние функции. \en Internal functions. + /// \ru Сброс данных в неопределённое состояние. \en Reset data to undefined state. + void Reset(); + + /** \brief \ru Инициализация. + \en Initialization. \~ + \details \ru Инициализация по данным. + \en Initialize by data. \~ + \param[in] _id - \ru Идентификатор тела. + \en Solid identifier. \~ + \param[in] _path - \ru Путь. + \en Path. \~ + \param[in] _ind - \ru Индекс части тела. + \en Index of the part of the solid. \~ + \param[in] _tiePnt - \ru Точка привязки части тела. + \en Anchor point of solid part. \~ + \param[in] _diag - \ru Размер диагонали части тела. + \en Diagonal size of the solid part. \~ + \param[in] _refPnt - \ru Базовая точка тела из частей. + \en Base point of the solid from parts. \~ + \param[in] _allCount - \ru Общее количество частей тела. + \en Total count of solid parts. \~ + */ + bool Init( uint _id, + const MbPath & _path, + ptrdiff_t _ind, + const MbCartPoint3D & _tiePnt, + double _diag, + const MbCartPoint3D & _refPnt, + ptrdiff_t _allCount ); + + /// \ru Инициализация по другом индексу. \en The initialization by another index. + bool Init( const MbPartSolidIndex & psInd ); + /// \ru Установить использованность. \en Set selected. + void SetSelected( bool b ) const { selected = b; } + /// \ru Установить измененность. \en Set modification. + void SetChanged ( bool b ) const { changed = b; } + +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbPartSolidIndex, MATH_FUNC_EX ) +DECLARE_NEW_DELETE_CLASS( MbPartSolidIndex ) +OBVIOUS_PRIVATE_COPY ( MbPartSolidIndex ) +}; + + +//------------------------------------------------------------------------------ +// \ru Проверка корректности. \en Check for correctness. +// --- +inline bool MbPartSolidIndex::IsValid() const +{ + return (ind > -1 && id != SYS_MAX_UINT32 && diag > METRIC_PRECISION && allCnt > 1); +} + + +//------------------------------------------------------------------------------ +// \ru Оператор сравнения (по содержанию). \en Comparison operator (by content). +// --- +inline bool MbPartSolidIndex::operator == ( const MbPartSolidIndex & obj ) const +{ + return ( id == obj.id && + ind == obj.ind && + path == obj.path && + tiePnt == obj.tiePnt && + diag == obj.diag && + refPnt == obj.refPnt && + allCnt == obj.allCnt ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по данным. \en Initialize by data. +// --- +inline +bool MbPartSolidIndex::Init( uint _id, + const MbPath & _path, + ptrdiff_t _ind, + const MbCartPoint3D & _tiePnt, + double _diag, + const MbCartPoint3D & _refPnt, + ptrdiff_t _allCnt ) +{ + if ( _ind > -1 && _id != SYS_MAX_UINT32 && ::fabs(_diag) > METRIC_PRECISION && _allCnt > 1 ) { + id = _id; + path = _path; + + ind = _ind; + tiePnt = _tiePnt; + diag = ::fabs(_diag); + + refPnt = _refPnt; + allCnt = _allCnt; + + selected = false; + changed = true; + return true; + } + + C3D_ASSERT_UNCONDITIONAL( false ); + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Инициализация по константной ссылке на другой объект. \en Initialization by constant reference to another object. +// --- +inline bool MbPartSolidIndex::Init( const MbPartSolidIndex & psInd ) +{ + if ( psInd.IsValid() ) { + id = psInd.id; + path = psInd.path; + + ind = psInd.ind; + tiePnt = psInd.tiePnt; + diag = psInd.diag; + + refPnt = psInd.refPnt; + allCnt = psInd.allCnt; + + selected = psInd.selected; + changed = true; + return true; + } + + C3D_ASSERT_UNCONDITIONAL( false ); + return false; +} + + +//------------------------------------------------------------------------------ +// \ru Сброс данных в неопределённое состояние. \en Reset data to undefined state. +// --- +inline void MbPartSolidIndex::Reset() +{ + id = SYS_MAX_UINT32; + path.Flush(); + + ind = -1; + tiePnt.SetZero(); + tiePnt.x = UNDEFINED_DBL; + diag = 0.0; + refPnt.SetZero(); + refPnt.x = UNDEFINED_DBL; + allCnt = 0; + + selected = false; + changed = true; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Идентификаторы частей тела. + \en Identifiers of the parts of the solid. \~ + \details \ru Множество идентификаторов частей тела. \n + \en Identifier set of the parts of the solid. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbPartSolidIndices : private PArray { +public: + /// \ru Состояние выбора. \en Selection state. + enum SelectionState { + ss_Undefined = 0, ///< \ru Состояние не определено. \en State is not defined. + ss_NoSelection, ///< \ru Не выбрано ни одного идентификатора. \en Identifiers are not selected. + ss_AllSelection, ///< \ru Выбраны все идентификаторы. \en All the identifiers are selected. + ss_AllMaxSizeSelection, ///< \ru Выбран идентификатор с самой большой частью. \en The identifier with the biggest part is selected. + // \ru Добавлять в конец! \en Add to the end! + }; + +protected: // \ru Данные класса. \en Data of class. + mutable SelectionState selState; ///< \ru Состояние выбора идентификаторов. \en State of identifiers selection. + mutable bool anyMulti; ///< \ru Рабочий флаг (наличие в наборе тел тела из частей). \en Working flag (solids from parts are in the set). + mutable bool editState; ///< \ru Рабочий флаг (режим редактирования тела). \en Working flag (mode of solid editing). + +public: // \ru Конструкторы, деструктор \en Constructors, destructor + /// \ru Пустой конструктор. \en Empty constructor. + MbPartSolidIndices(); + /// \ru Конструктор копирования копирует данные. \en Copy-constructor copies data. + MbPartSolidIndices( const MbPartSolidIndices & ); + virtual ~MbPartSolidIndices(); + +public: // \ru Открытые константные функции базового класса. \en Open constant functions of base class. +using PArray::Count; // \ru Количество идентификаторов. \en The count of identifiers. +using PArray::MaxIndex; // \ru Номер последнего идентификатора. \en Index of the last identifier. +using PArray::Reserve; // \ru Зарезервировать память. \en Reserve memory. +using PArray::Adjust; // \ru Очистить лишнюю память. \en Clear the unnecessary memory. +using PArray::IsExist; // \ru Существует ли объект? \en Is there the object? + +public: // \ru Внешние функции. \en External functions. + /// \ru Набор пуст? \en Whether set is empty? + bool IsEmpty() const { return Count() < 1; } + + /// \ru Корректен ли набор. \en Whether set is correct. + bool IsAllValid() const; + /// \ru Корректен ли k-й индекс части. \en Whether k-th index of part is correct. + bool IsValidIndex( size_t k ) const; + /// \ru Существует ли k-й индекс части. \en Whether k-th index of part exists. + bool IsExistIndex( size_t k ) const; + + /// \ru Выбраны ли все индексы. \en Whether all the indices are selected. + bool IsAllSelected() const; + /// \ru Установить состояние выбора всех индексов. \en Set the selection state for all the indices. + bool SetAllSelected( bool s ) const; + + /// \ru Выбран ли индекс. \en Whether index is selected. + bool IsSelected( size_t k ) const; + /// \ru Установить состояние выбора индекса. \en Set the selection state of index. + bool SetSelected( size_t k, bool s ) const; + + /// \ru Получить состояние выбора индексов. \en Get the selection state of indices. + SelectionState GetSelectionState() const { return selState; }; + /// \ru Установить состояние выбора индексов. \en Set the selection state of indices. + bool SetSelectionState( SelectionState selState ) const; + /// \ru Выставить общее состояние выбора по данным. \en Set total selection state from data. + bool CheckSelectionState() const; + + /// \ru Получить собственный индекс части тела. \en Get own index of the part of the solid. + ptrdiff_t GetOwnIndex( size_t k ) const; + /// \ru Получить макс. собственный индекс для частей тела в наборе. \en Get max own index of solid parts in the set. + ptrdiff_t GetMaxOwnIndex() const; + + /// \ru Получить идентификатор и путь для k-го индекса части. \en Get identifier and path for k-th index of part. + bool GetIdPath( size_t k, uint & id, MbPath & path ) const; + + /// \ru Получить копию индекса. \en Get a copy of the index. + bool GetPartIndex( size_t k, MbPartSolidIndex & partIndex ) const; + /// \ru Положить копию индекса. \en Add a copy of the index. + bool AddPartIndex( const MbPartSolidIndex & partIndex ); + /// \ru Отцепить индекс. \en Detach index. + MbPartSolidIndex * DetachPartIndex( size_t k ); + /// \ru Поглотить индекс. \en Absorb index. + bool AbsorbPartIndex( MbPartSolidIndex *& ); + + /// \ru Забрать индексы по идентификатору и пути. \en Detach indices by identifier and path. + bool DetachPartIndices( uint id, const MbPath & path, MbPartSolidIndices & ); + /// \ru Удалить индексы по идентификатору и пути. \en Delete indices by identifier and path. + bool DeletePartIndices( uint id, const MbPath & path ); + + /// \ru Положить копии индексов. \en Add copies of indices. + bool AddPartIndices( const MbPartSolidIndices & ); + ///< \ru Поглотить индексы. \en Absorb indices. + bool AbsorbPartIndices( MbPartSolidIndices & ); + + /// \ru Найти по адресу или содержанию. \en Find by address or content. + size_t Find( const MbPartSolidIndex & ) const; + /// \ru Найти по идентификаторам. \en Find by identifiers. + size_t Find( uint id, const MbPath & path, ptrdiff_t index ) const; + + /// \ru Удалить плохие индексы. \en Remove bad indices. + void RemoveBadIndices(); + /// \ru Удалить все индексы. \en Remove all the vertices. + void RemoveAllIndices(); + + /// \ru Удалить по существующему пути те индексы частей, которых нет в списке идентификаторов. \en Delete by existing path those indices of parts which are not contained in the list of identifiers. + void RemoveLostIndices( const MbPath & existPath, SArray & existIds ); + + /// \ru Получить флаг наличия в наборе тел из частей. \en Get flag (when solids from parts are in the set). + bool IsAnyMultiSolid() const { return anyMulti; } + /// \ru Установить флаг наличия в наборе тел из частей. \en Set flag (when solids from parts are in the set). + void SetAnyMultiSolid( bool anyMulit, bool setAny ) const; + + /// \ru Находимся в режиме редактирования? \en Is in the editing mode? + bool IsEditState() const { return editState; } + /// \ru Установить флаг, находимся ли в режиме редактирования. \en Set flag "Editing mode". + void SetEditState( bool b ) { editState = b; } + +private: // \ru Внутренние функции. \en Internal functions. + /// \ru Удалить не выбранные индексы (плохие тоже убирает). \en Remove unselected indices (also removes bad). + void RemoveUnselectedIndices(); + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbPartSolidIndices & ); + +KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbPartSolidIndices, MATH_FUNC_EX ) +DECLARE_NEW_DELETE_CLASS( MbPartSolidIndices ) +DECLARE_NEW_DELETE_CLASS_EX( MbPartSolidIndices ) +}; + + +//------------------------------------------------------------------------------ +// \ru Установить флаг наличия в наборе тел из частей (флаг устанавливается извне, объект им не управляет). \en Set flag of presence of solids from parts in the set (the flag is set from the outside, the object does not control it). +// --- +inline void MbPartSolidIndices::SetAnyMultiSolid( bool isMulti, bool setAny ) const +{ + if ( setAny ) + anyMulti = isMulti; + else if ( !anyMulti ) + anyMulti = isMulti; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Информация о части тела. + \en Information about the solid part. \~ + \details \ru Информация о части тела и его состоянии. \n + \en Information about the solid part and it state. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbPartSolidData { +public: + MbSolid * part; ///< \ru Часть тела. \en The part of the solid. + uint id; ///< \ru Идентификатор тела. \en Solid identifier. + ptrdiff_t ind; ///< \ru Номер части тела. \en Index of the solid part. + const MbPath & path; ///< \ru Путь. \en Path. + bool selected; ///< \ru Состояние выбора части. \en State of part selection. + +public: + /// \ru Конструктор по данным. \en Constructor by data. + MbPartSolidData( MbSolid * _part, + uint _id, + ptrdiff_t _ind, + const MbPath & _path, + bool _selected ) + : part ( _part ) + , id ( _id ) + , ind ( _ind ) + , path ( _path ) + , selected( _selected ) + {} +public: + /// \ru Проверить данные на корректность. \en Check data for correctness. + bool IsValid() const { return (part != NULL && ind > -1 && id != SYS_MAX_UINT32); } +private: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbPartSolidData(); + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without implementation of the copy-constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( MbPartSolidData ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать индексы частей тела. + \en Create indices of the parts of the solid. \~ + \details \ru При создании индексов частей тела предполагается, что тело состоит из отдельных частей. + Информационный массив должен соответствовать телу. + \en When creating indices of solid parts it is assumed that the solid consists of parts. + Information array must correspond to solid. \~ + \param[in] solid - \ru Состоящее из отдельных частей исходное тело. + \en The initial solid is consisting of separate parts. \~ + \param[in] partInfo - \ru Информация о частях тела. + \en Information about the solid parts. \~ + \param[out] partIndices - \ru Множество индексов частей тела. + \en Index set of the parts of the solid. \~ + \return \ru Cозданы ли индексы частей тела. + \en Whether indices of solid parts are created. \~ + \ingroup Algorithms_3D +*/ +MATH_FUNC (bool) CreatePartSolidIndices( const MbSolid & solid, + const SArray & partInfo, + MbPartSolidIndices & partIndices ); + + +#endif // __PART_SOLID_H diff --git a/C3d/Include/plane_instance.h b/C3d/Include/plane_instance.h new file mode 100644 index 0000000..d6211dc --- /dev/null +++ b/C3d/Include/plane_instance.h @@ -0,0 +1,197 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вставка двумерного объекта. + \en Instance of a two-dimensional object. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PLANE_INSTANCE_H +#define __PLANE_INSTANCE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbPlaneInstance; +namespace c3d // namespace C3D +{ +typedef SPtr PInstanceSPtr; +typedef SPtr ConstPInstanceSPtr; + +typedef std::vector PInstancesVector; +typedef std::vector ConstPInstancesVector; + +typedef std::vector PInstancesSPtrVector; +typedef std::vector ConstPInstancesSPtrVector; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вставка двумерных объектов эскиза. + \en Instance of a two-dimensional sketch objects. \~ + \details \ru Вставка позволяет работать с двумерными геометрическими объектами как с объектом геометрической модели. + Двумерные геометрические объекты MbPlaneItem располагаются в плоскости XOY локальной системы координат MbPlacement3D.\n + \en The instance allows to deal with two-dimensional geometric objects as with object of geometric model. + Two-dimensional MbPlaneItem geometric objects located in XOY-plane of MbPlacement3D local coordinate system.\n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbPlaneInstance : public MbItem { +protected : + MbPlacement3D place; ///< \ru Локальная система координат объекта. \en Local coordinate system of the object. + std::vector planeItems; ///< \ru Множество двумерных объектов эскиза. \en A set of two-dimensional sketch objects. + +protected : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbPlaneInstance( const MbPlaneInstance &, MbRegDuplicate * ); +public : + /// \ru Конструктор по локальной системе координат без двумерных объектов. \en Constructor by a local coordinate system without two-dimensional objects. + MbPlaneInstance( const MbPlacement3D & ); + /// \ru Конструктор по двумерному объекту (используется оригинал) и локальной системе координат. \en Constructor by two-dimensional object (original is used) and a local coordinate system. + MbPlaneInstance( const MbPlaneItem &, const MbPlacement3D & ); + /// \ru Конструктор по двумерным объектам (используются оригиналы) и локальной системе координат. \en Constructor by two-dimensional object (originals are used) and a local coordinate system. + template + MbPlaneInstance( const MbPlacement3D &, const PlaneItems & ); + /// \ru Деструктор \en Destructor + virtual ~MbPlaneInstance(); + +public : + VISITING_CLASS( MbPlaneInstance ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными? \en Are the objects similar? + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + // \ru Получить локальную систему координат объекта. \en Get the local coordinate system of an object. + virtual bool GetPlacement( MbPlacement3D & ) const; + // \ru Установить локальную систему координат объекта. \en Set the local coordinate system of an object. + virtual bool SetPlacement( const MbPlacement3D & ); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Найти объект по геометрическому объекту (MbPlaneItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbPlaneItem * s, MbPath & path, MbMatrix3D & from ) const; + + /** \ru \name Общие функции вставки двумерного объекта. + \en \name Common functions of instance of two-dimensional object. + \{ */ + /// \ru Выдать число двумерных геометрических объектов. \en Get number of two-dimensional geometric objects. + size_t PlaneItemsCount() const; + /// \ru Выдать двумерный геометрический объект. \en Get two-dimensional geometric object. + const MbPlaneItem * GetPlaneItem( size_t ind = 0 ) const; + /// \ru Выдать двумерный геометрический объект для возможного редактирования. \en Get two-dimensional object for possible editing. + MbPlaneItem * SetPlaneItem( size_t ind = 0 ); + /// \ru Заменить двумерный геометрический объект. \en Replace two-dimensional geometric object. + bool SetPlaneItem( MbPlaneItem * init, size_t ind = 0 ); + /// \ru Добавить двумерный геометрический объект. \en Add two-dimensional geometric object. The method returns the index of added or existing object in MbPlaneInstance (the method returns SYS_MAX_T if the object is NULL). + size_t AddPlaneItem( MbPlaneItem * init ); + /// \ru Метод возвращает индекс двумерного геометрического объекта. \en The method returns the index of two-dimensional geometric object in MbPlaneInstance (the method returns SYS_MAX_T if the object was not finded). + size_t GetIndex( MbPlaneItem * init ); + /// \ru Выдать локальную систему координат объекта. \en Get the local coordinate system of an object. + const MbPlacement3D & GetPlacement() const { return place; } + /// \ru Выдать локальную систему координат объекта для редактирования. \en Get the local coordinate system of an object for editing. + MbPlacement3D & SetPlacement() { return place; } + + /// \ru Преобразовать двумерный объект согласно матрице. \en Transform two-dimensional object according to the matrix. + void Transform( const MbMatrix &, MbRegTransform * iReg = NULL ); + /// \ru Сдвинуть двумерный объект вдоль вектора. \en Translate two-dimensional object along a vector. + void Move ( const MbVector &, MbRegTransform * iReg = NULL ); + /// \ru Повернуть двумерный объект вокруг точки на заданный угол. \en Rotate two-dimensional object at a given angle around an axis. + void Rotate ( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * iReg = NULL ); + /// \ru Повернуть двумерный объект вокруг точки на заданный угол. \en Rotate two-dimensional object at a given angle around an axis. + void Rotate ( const MbCartPoint & pnt, double angle, MbRegTransform * iReg = NULL ); + + /// \ru Удалить все объекты эскиза. \en Delete all the sketch items. + void DeleteItems(); + /// \ru Удалить объект эскиза. \en Delete the sketch item by index. + bool DeleteItem( size_t ind ); + /// \ru Удалить объект эскиза. \en Delete the sketch item by index. + MbPlaneItem * DetachItem( size_t ind ); + + /** \brief \ru Заменить объект. + \en Replace an item. \~ + \details \ru Заменить объект новым. + \en Replace an item by a new one. \~ + \param[in] item - \ru Заменяемый объект. + \en An item to be replaced. \~ + \param[in] newItem - \ru Новый объект. + \en A new item. \~ + \return \ru Возвращает true, если замена была выполнена. + \en Returns true if the replacement has been performed. \~ + */ + bool ReplaceItem( const MbPlaneItem & item, MbPlaneItem & newItem ); + + /// \ru Выдать все объекты. \en Get all the items. + template + void GetItems( PlaneItems & ) const; + + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPlaneInstance ) +OBVIOUS_PRIVATE_COPY( MbPlaneInstance ) +}; + +IMPL_PERSISTENT_OPS( MbPlaneInstance ); + +//------------------------------------------------------------------------------ +// Конструктор +// --- +template +inline MbPlaneInstance::MbPlaneInstance( const MbPlacement3D & p, const PlaneItems & inits ) + : MbItem ( ) + , place ( p ) + , planeItems( ) +{ + size_t addCnt = inits.size(); + planeItems.reserve( addCnt ); + for ( size_t k = 0; k < addCnt; ++k ) { + const MbPlaneItem * planeItem = inits[k]; + if ( planeItem != NULL ) { + planeItem->AddRef(); + planeItems.push_back( const_cast( planeItem ) ); + } + } + C3D_ASSERT( !planeItems.empty() ); +} + + +//------------------------------------------------------------------------------ +// дать все объекты +// --- +template +void MbPlaneInstance::GetItems( PlaneItems & items ) const +{ + size_t addCnt = planeItems.size(); + items.reserve( items.size() + addCnt ); + SPtr item_i; + for ( size_t i = 0; i < addCnt; ++i ) { + if ( planeItems[i] != NULL ) { + item_i = planeItems[i]; + items.push_back( item_i ); + } + } +} + + +#endif // __PLANE_INSTANCE_H diff --git a/C3d/Include/plane_item.h b/C3d/Include/plane_item.h new file mode 100644 index 0000000..4286009 --- /dev/null +++ b/C3d/Include/plane_item.h @@ -0,0 +1,401 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Геометрический объект в двумерном пространстве. + \en Geometric object in two-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __PLANE_ITEM_H +#define __PLANE_ITEM_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCartPoint; +class MATH_CLASS MbVector; +class MATH_CLASS MbDirection; +class MATH_CLASS MbMatrix; +class MATH_CLASS MbRect; +class MATH_CLASS MbSurface; +class MATH_CLASS MbProperties; +class MATH_CLASS MbProperty; +struct MATH_CLASS MbControlData; +class MbRegDuplicate; +class MbRegTransform; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы геометрических объектов в двумерном пространстве. + \en Types of geometric objects in two-dimensional space. \~ + \details \ru Геометрические объектыв группируются в семейства: + кривые, мультилиния, регион. + \en Geometric objects are grouped by families: + curves, multiline, region. \~ + \ingroup Geometric_Items +*/ +// --- +enum MbePlaneType { + + pt_Undefined = 0, ///< \ru Неизвестный объект. \en Unknown object. + pt_PlaneItem = 1, ///< \ru Произвольный двумерный объект. \en Arbitrary two-dimensional object. \n + + // \ru Типы кривых. \en Types of curves. + pt_Curve = 201, ///< \ru Произвольная кривая. \en Arbitrary curve. + pt_Line = 202, ///< \ru Прямая. \en Line. + pt_LineSegment = 203, ///< \ru Отрезок. \en Segment. + pt_Arc = 204, ///< \ru Окружность или эллипс или дуга окружности или дуга эллипсa. \en Circle or ellipse or arc of circle or arc of ellipse. + pt_Cosinusoid = 205, ///< \ru Кривая-косинусоида. \en Cosine curve. + pt_PolyCurve = 206, ///< \ru Сплайновая кривая. \en Spline curve. + pt_Polyline = 207, ///< \ru Полилиния. \en Polyline. + pt_Bezier = 208, ///< \ru Безье-сплайн. \en Bezier spline. + pt_Hermit = 209, ///< \ru Составной кубический сплайн Эрмита. \en Composite cubic Hermite spline. + pt_Nurbs = 210, ///< \ru NURBS кривая. \en NURBS-curve. + pt_CubicSpline = 211, ///< \ru Кубический сплайн. \en Cubic spline. + pt_TrimmedCurve = 212, ///< \ru Усеченная кривая. \en Trimmed curve. + pt_OffsetCurve = 213, ///< \ru Эквидистантная продленная кривая. \en Extended offset curve. + pt_ReparamCurve = 214, ///< \ru Репараметризованная кривая. \en Reparametrized curve. + pt_PointCurve = 215, ///< \ru Кривая - точка. \en Point-curve. + pt_CharacterCurve = 216, ///< \ru Кривая, координатные функции которой заданы в символьном виде. \en Functionally defined curve. + pt_ProjCurve = 217, ///< \ru Проекционная кривая. \en Projection curves. + pt_SweptImageCurve = 218, ///< \ru Образ трехмерной кривой на поверхности при движении по направляющей. \en Image of three-dimensional curve on surface while moving along a guide curve. + pt_TransformedCurve = 219, ///< \ru Трансформированная кривая. \en Transformed curve. + pt_ConeBendedCurve = 220, ///< \ru Кривая в параметрической области конуса, соответствующая кривой в параметрической области плоскости при коническом сгибе. \en Curve in parametric region of a cone corresponding to curve in parametric region of plane at a conic bend. + pt_ConeUnbendedCurve = 221, ///< \ru Кривая в параметрической области плоскости, соответствующая кривой в параметрической области конуса при коническом сгибе. \en Curve in parametric region of a plane corresponding to curve in parametric region of a cone at conic bend. + + // \ru Типы сложных кривых. \en Types of complex curves. + pt_Contour = 301, ///< \ru Контур - составная кривая. \en Contour - composite curve. + pt_ContourWithBreaks = 302, ///< \ru Контур с разрывами . \en Contour with discontinuities. + pt_FreeCurve = 400, ///< \ru Тип для кривых, созданных пользователем. \en User-defined curve. \n + + // \ru Типы сложных объектов. \en Types of complex objects. + pt_Multiline = 401, ///< \ru Мультилиния. \en Multiline. + + // \ru Типы других объектов. \en Types of other objects. + pt_Region = 501, ///< \ru Регион. \en Region. + + pt_FreeItem = 600, ///< \ru Тип для объектов, созданных пользователем. \en Type for the user-defined objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Геометрический объект в двумерном пространстве. + \en Geometric object in two-dimensional space. \~ + \details \ru Родительский класс геометрических объектов в двумерном пространстве. + Имеет счетчик ссылок. + Наследниками являются: кривая MbCurve, мультилиния MbMultiline, регион MbRegion. + \en Parent class of geometric objects in two-dimensional space. + Has reference counter. + Inheritors are: MbCurve curve, MbMultiline multiline, MbRegion region. \~ + \ingroup Geometric_Items +*/ +// --- +class MATH_CLASS MbPlaneItem : public TapeBase, public MbRefItem { +protected : + /// \ru Конструктор. \en Constructor. + MbPlaneItem(); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbPlaneItem(); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + /// \ru Получить регистрационный тип (для копирования, дублирования). \en Get the registration type (for copying, duplication). + virtual MbeRefType RefType() const; + /// \ru Получить тип объекта. \en Get the object type. + virtual MbePlaneType IsA() const = 0; + /// \ru Получить групповой тип объекта. \en Get the group type of the object. + virtual MbePlaneType Type() const = 0; + /// \ru Получить семейство объекта. \en Get family of object. + virtual MbePlaneType Family() const = 0; + + /** \brief \ru Создать копию. + \en Create a copy. \~ + \details \ru Создать копию объекта с использованием регистратора. + Регистратор используется для предотвращения многократного копирования объекта. + Если объект содержит ссылки на другие объекты, то вложенные объекты так же копируются. + Допустимо не передавать регистратор в функцию. Тогда будет создана новая копия объекта. + При копировании одиночного объекта или набора не связанных между собой объектов допустимо не использовать регистратор. + Регистратор необходимо использовать, если надо последовательно копировать несколько взаимосвязанных объектов. + Возможно, что связь объектов обусловлена наличием в них ссылок на общие объекты. + Тогда, при копировании без использования регистратора, можно получить набор копий, + содержащих ссылки на разные копии одного и того же вложенного объекта, что ведет к потере связи между копиями. + \en Create a copy of the object using the registrator. + The registrator is used for preventing multiple copying of an object. + If the object contains references to other objects, then the included objects are copied too. + It is allowed not to pass the registrator to a function. Then the new copy of the object will be created. + It is allowed not to use the registrator while copying a single object or a set of disconnected objects. + The registrator must be used to copy several correlated objects successively. + It is possible that the objects' connection means that the objects contain references to the common objects. + Then, while copying without using the registrator, one can get a set of copies + which contain references to the different copies of a single included object, what leads to loss of connection between the copies. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \return \ru Копия объекта. + \en Copy of the object. \~ + */ + virtual MbPlaneItem & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; + + /** \brief \ru Преобразовать согласно матрице. + \en Transform according to the matrix. \~ + \details \ru Преобразовать исходный объект согласно матрице c использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то вложенные объекты так же преобразуются согласно матрице. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих трансформации. + \en Transform the initial object according to the matrix using the registrator. + If the object contains references to the other geometric objects, then the nested objects are transformed according to the matrix. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to transformation. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \param[in] surface - \ru Новая базовая поверхность объекта + при условии, что matr - матрица преобразования из старой поверхности в новую. + Для трансформации проекционной кривой. + Не учитывается, если поверхность плоская. + \en New base surface of object + provided that 'matr' is a transformation matrix from the old surface to a new one. + For transformation of projection curve. + It isn't considered if the surface is planar. \~ + */ + virtual void Transform( const MbMatrix & matr, MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ) = 0; + + /** \brief \ru Сдвинуть вдоль вектора. + \en Translate along a vector. \~ + \details \ru Сдвинуть геометрический объект вдоль вектора с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция сдвига. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих сдвигу. + \en Translate a geometric object along the vector using the registrator. + If the object contains references to the other objects, then the translation operation is applied to the nested objects. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to translation. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \param[in] surface - \ru Новая базовая поверхность объекта + при условии, что matr - матрица преобразования из старой поверхности в новую. + Для трансформации проекционной кривой. + Не учитывается, если поверхность плоская. + \en New base surface of object + provided that 'matr' is a transformation matrix from the old surface to a new one. + For transformation of projection curve. + It isn't considered if the surface is planar. \~ + */ + virtual void Move ( const MbVector & to, MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ) = 0; + + /** \brief \ru Повернуть вокруг точки. + \en Rotate about a point. \~ + \details \ru Повернуть объект вокруг точки на заданный угол с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция поворота. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих повороту. + \en Rotate an object about a point by the given angle using the registrator. + If the object contains references to the other geometric objects, then the rotation operation is applied to the nested objects too. + The registrator is used for preventing multiple transformation of the object. + The function can be used without the registrator to transform a single object. + The registrator must be used to transform a set of interdependent objects to + prevent repeated transformation of the nested objects, since it is not ruled out + that several objects from the set contain references to one or several common objects subject to rotation. \~ + \param[in] pnt - \ru Неподвижная точка. + \en Fixed point. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \param[in] surface - \ru Новая базовая поверхность объекта + при условии, что matr - матрица преобразования из старой поверхности в новую. + Для трансформации проекционной кривой. + Не учитывается, если поверхность плоская. + \en New base surface of object + provided that 'matr' is a transformation matrix from the old surface to a new one. + For transformation of projection curve. + It isn't considered if the surface is planar. \~ + */ + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, + MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ) = 0; + + /** \brief \ru Повернуть вокруг точки. + \en Rotate about a point. \~ + \details \ru Повернуть объект вокруг точки на заданный угол с использованием регистратора. + \en Rotate an object about a point by the given angle using the registrator. \~ + \param[in] pnt - \ru Неподвижная точка. + \en Fixed point. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \param[in] surface - \ru Новая базовая поверхность объекта + при условии, что matr - матрица преобразования из старой поверхности в новую. + Для трансформации проекционной кривой. + Не учитывается, если поверхность плоская. + \en New base surface of object + provided that 'matr' is a transformation matrix from the old surface to a new one. + For transformation of projection curve. + It isn't considered if the surface is planar. \~ + */ + void Rotate( const MbCartPoint & pnt, double angle, + MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ); + + /** \brief \ru Определить, являются ли объекты равными. + \en Determine whether objects are equal. \~ + \details \ru Равными считаются однотипные объекты, все данные которых одинаковы (равны). + \en Objects of the same types with similar (equal) data are considered to be equal. \~ + \param[in] item - \ru Объект для сравнения. + \en Object for comparison. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. \~ + */ + virtual bool IsSame( const MbPlaneItem & item, double accuracy = LENGTH_EPSILON ) const = 0; + + /** \brief \ru Определить, являются ли объекты подобными. + \en Determine whether the objects are similar. \~ + \details \ru Подобными считаются однотипные объекты, данные которых можно приравнять или данные так же являются подобными (указатели). + Подобный объект можно инициализировать по данным подобного ему объекта (приравнять один другому без изменения адресов). + \en Objects of the same type are considered to be similar if data of the objects can be equated or the data are also similar (pointers). + Similar object can be initialized by data of object similar to it (equate one to another without changing of addresses). \~ + \param[in] item - \ru Объект для сравнения. + \en Object for comparison. \~ + \return \ru Подобны ли объекты. + \en Whether the objects are similar. \~ + */ + virtual bool IsSimilar( const MbPlaneItem & item ) const; + + /** \brief \ru Сделать объекты равным. + \en Make the objects equal. \~ + \details \ru Равными можно сделать только подобные объекты. + Подобный объект приравнивается присланному путем изменения численных данных. + \en It is possible to make equal only similar objects. + Similar object is equated to a given one by changing of numerical data. \~ + \param[in] item - \ru Объект для инициализации. + \en Object for initialization. \~ + \return \ru Сделан ли объект равным присланному. + \en Whether the object is made equal to the given one. \~ + */ + virtual bool SetEqual ( const MbPlaneItem & item ) = 0; + + /// \ru Расширить присланный габаритный прямоугольник так, чтобы он включал в себя данный объект. \en Extend the given bounding rectangle so that it encloses this object. + virtual void AddYourGabaritTo( MbRect & r ) const = 0; + + /** \brief \ru Определить видимость объекта в прямоугольнике. + \en Determine visibility of an object in rectangle. \~ + \details \ru Считается, что объект виден в прямоугольнике, если габариты объекта пересекаются с заданным прямоугольником + или (при повышенных требованиях к точности exact = true) в прямоугольник попадает хотя бы одна точка объекта. + \en It is considered that the object is visible in rectangle if bounds of an object is crossed with the given rectangle + or (high requirements to accuracy, exact = true) at least one point of object is in the rectangle. \~ + \param[in] rect - \ru Прямоугольник, попадание в который проверяется. + \en Rectangle to check getting to. \~ + \param[in] exact - \ru Точность проверки. При exact = true в прямоугольник должна попасть хотя бы одна точка объекта. + При exact = false - достаточно пересечения габарита объекта с прямоугольником. + \en Check accuracy. If exact = true, then at least one point of object gets to the rectangle. + if exact = false, it is sufficient to find intersection between rectangle and bounding box of an object. \~ + \return \ru true - объект виден в прямоугольнике, иначе - false. + \en true, if the object is visible in the rectangle, otherwise false. \~ + */ + virtual bool IsVisibleInRect( const MbRect & rect, bool exact = false ) const = 0; + + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual double DistanceToPoint( const MbCartPoint & to ) const = 0; + + /** \brief \ru Вычислить расстояние до точки. + \en Calculate the distance to a point. \~ + \details \ru Вычислить расстояние от объекта до заданной точки вблизи объекта. + Расстояние вычисляется и записывается в переменную d, если оно меньше исходного значения d. + Может быть получен выигрыш по времени выполнения по сравнению с функцией DistanceToPoint, + за счет того, что сначала проверяется расстояние от точки до габаритного куба, + и только если это расстояние не больше заданного, выполняются дальнейшие вычисления. + \en Calculate distance to object from a given point near the object. + Distance is calculated and stored to 'd' variable if it is less then initial value of 'd'. + There can be performance benefit in comparison with DistanceToPoint function + due to primarily checking the distance from point to bounding box + and performing the further calculations only if this distance is not greater than the given one. \~ + \param[in] to - \ru Tочка. + \en Point. \~ + \param[in, out] d - \ru На входе - заданная величина отступа от объекта. На выходе - расстояние от точки до объекта, если операция выполнена успешно. + \en Specified distance from object on input. Distance from point to object on output if operation succeeded. \~ + \return \ru true, если расстояние от точки до объекта меньше заданного, иначе - false. + \en True if distance from point to the object is less than the given one, otherwise false. \~ + */ + + /// \ru Рассчитать расстояние до точки и изменить его присланное значение, если расстояние окажется меньше присланного значения. \en Calculate the distance from a point and change the given value of distance if the distance is less than the given one. + virtual bool DistanceToPointIfLess( const MbCartPoint & to, double & d ) const = 0; + /// \ru Перевести все временные (mutable) данные объекта в неопределённое (исходное) состояние. \en Set all temporary (mutable) data of object to undefined (initial) state. + virtual void Refresh(); + + /// \ru Создать собственное свойство с заданием его имени. \en Create your own property with specified name. + virtual MbProperty & CreateProperty( MbePrompt name ) const = 0; + + /** \brief \ru Выдать свойства объекта. + \en Get properties of the object. \~ + \details \ru Выдать внутренние данные (свойства) объекта для их просмотра и модификации. + \en Get internal data (properties) of an object for viewing and modification. \~ + \param[in] properties - \ru Контейнер для внутренних данных объекта. + \en Container for internal data of an object. \~ + */ + virtual void GetProperties( MbProperties & properties ) = 0; + + /** \brief \ru Изменить свойства объекта. + \en Change properties of the object. \~ + \details \ru Изменение внутренних данных (свойств) объекта выполняется + копированием соответствующих значений из присланного объекта. + \en Change internal data (properties) of object is performed + by copying of corresponding values from the given object. \~ + \param[in] properties - \ru Контейнер для внутренних данных объекта. + \en Container for internal data of an object. \~ + */ + virtual void SetProperties( const MbProperties & properties ) = 0; + + /// \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void GetBasisPoints( MbControlData & ) const = 0; + /// \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void SetBasisPoints( const MbControlData & ) = 0; + /** \} */ + + /** \brief \ru Регистрация объекта. + \en Object registration. \~ + \details \ru Регистрация объекта для предотвращения его многократной записи. + Другие объекты могут содержать указатель на данный объект. + Функция взводит флаг, который позволяет записывать объект один раз, а в остальных записях ссылаться на записанный экземпляр. + Чтение так же выполняется один раз, а в остальных случаях чтения подставляется адрес уже прочитанного объекта. + \en Object registration for preventing its multiple writing. + Other objects may contain a pointer to the given object. + The function sets a flag that allow to write the object once and to use the references to the recorded instance in the other records. + Reading is performed once too, in other cases of reading the address of the already read object is used. \~ + */ + void PrepareWrite() { SetRegistrable( (GetUseCount() > 1) ? registrable : noRegistrable ); } + +DECLARE_PERSISTENT_CLASS( MbPlaneItem ) +OBVIOUS_PRIVATE_COPY( MbPlaneItem ) +}; // MbPlaneItem + +IMPL_PERSISTENT_OPS( MbPlaneItem ) + +#endif // __PLANE_ITEM_H diff --git a/C3d/Include/point3d.h b/C3d/Include/point3d.h new file mode 100644 index 0000000..6f37724 --- /dev/null +++ b/C3d/Include/point3d.h @@ -0,0 +1,101 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Пространственная точка со свойствами геометрического объекта. + \en Spatial point with properties of geometric object. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __POINT3D_H +#define __POINT3D_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Трёхмерная точка со свойствами геометрического объекта. + \en Three-dimensional point with properties of geometric object. \~ + \details \ru Точка cодержит трехмерную точку MbCartPoint3D и является + наследником геометрического объекта в пространстве.\n + \en The point contains three-dimensional point MbCartPoint3D and also is + the inheritor of a geometric object in space.\n \~ + \ingroup Point_3D +*/ +// --- +class MATH_CLASS MbPoint3D : public MbSpaceItem { +protected: + MbCartPoint3D point; ///< \ru Трехмерная точка. \en Three-dimensional point. + +private: + /// \ru Конструктор копирования. \en Copy-constructor. + MbPoint3D ( const MbPoint3D & ); +public: + /// \ru Конструктор. \en Constructor. + MbPoint3D (); + /// \ru Конструктор по точке. \en Constructor by point. + MbPoint3D ( const MbCartPoint3D & ); + /// \ru Конструктор по координатам. \en Constructor by coordinates. + MbPoint3D ( double x, double y, double z ); + /// \ru Деструктор. \en Destructor. + virtual ~MbPoint3D (); + +public: + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbeSpaceType Type() const; // \ru Групповой тип объекта. \en Group type of object. + virtual MbeSpaceType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равным. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \ru \name Функции точки. + \en \name Functions of point. + \{ */ + /// \ru Выдать декартову точку. \en Get Cartesian point. + void GetCartPoint( MbCartPoint3D & ) const; + /// \ru Выдать декартову точку. \en Get Cartesian point. + const MbCartPoint3D & GetCartPoint() const { return point; } + /// \ru Выдать декартову точку для возможного редактирования. \en Get Cartesian point for possible editing. + MbCartPoint3D & SetCartPoint() { return point; } + /// \ru Проверить равенство с другой точкой. \en Check for equality with another point. + bool operator == ( const MbPoint3D & ) const; + /// \ru Проверить на неравенство с другой точкой. \en Check for inequality with another point. + bool operator != ( const MbPoint3D & ) const; + /// \ru Инициализировать точку по другой точке. \en Initialize point by another point. + void Init( const MbPoint3D & init ) { point.Init(init.point); } + /// \ru Инициализировать точку по другой точке. \en Initialize point by another point. + void Init( const MbCartPoint3D & init ) { point.Init(init); } + /// \ru Инициализировать точку по координатам. \en Initialize point by coordinates. + void Init( double xx, double yy, double zz ) { point.Init(xx,yy,zz); } + /// \ru Обнуление координат. \en Set coordinates to zero. + void SetZero() { point.SetZero(); } + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const MbPoint3D & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPoint3D ) +}; // MbPoint3D + +IMPL_PERSISTENT_OPS( MbPoint3D ) + +#endif // __POINT3D_H diff --git a/C3d/Include/point_frame.h b/C3d/Include/point_frame.h new file mode 100644 index 0000000..4d9894e --- /dev/null +++ b/C3d/Include/point_frame.h @@ -0,0 +1,162 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Точечный каркас. + \en Point-frame. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __POINT_FRAME_H +#define __POINT_FRAME_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbPointFrame; + + +namespace c3d // namespace C3D +{ +typedef SPtr PointFrameSPtr; +typedef SPtr ConstPointFrameSPtr; + +typedef std::vector PointFramesVector; +typedef std::vector ConstPointFramesVector; + +typedef std::vector PointFramesSPtrVector; +typedef std::vector ConstPointFramesSPtrVector; +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Точечный каркас. + \en Point-frame. \~ + \details \ru Точечный каркас состоит из множества декартовых точек, представленных в виде вершин MbVertex. \n + \en The point frame consists of set of Cartesian points represented as MbVertex vertices. \n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbPointFrame : public MbItem { +protected: + c3d::VerticesVector vertices; ///< \ru Множество вершин каркаса. \en Set frame vertices. + +protected: + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbPointFrame( const MbPointFrame &, MbRegDuplicate * ); +public: + /// \ru Конструктор. \en Constructor. + MbPointFrame(); + /// \ru Конструктор по вершине и флагу использования этого объекта, а не его копии. \en Constructor by vertex and by flag of use of this object instead of its copy. + explicit MbPointFrame( const MbVertex &, bool same ); + /// \ru Конструктор по точке. \en Constructor by point. + explicit MbPointFrame( const MbCartPoint3D & ); + /// \ru Конструктор по координатам. \en Constructor by coordinates. + MbPointFrame( double x, double y, double z ); + /// \ru Конструктор по массиву вершин и флагу использования этих объектов, а не их копий. \en Constructor by array of vertices and by flag of use of these objects instead of their copies. + template + MbPointFrame( const VerticesVector & verts, bool same ) + : MbItem() + , vertices() + { + size_t vertsCnt = verts.size(); + vertices.reserve( vertsCnt ); + for ( size_t k = 0; k < vertsCnt; ++k ) { + if ( verts[k] != NULL ) + AddVertex( const_cast( *verts[k] ), same ); + } + } + /// \ru Конструктор по массиву точек. \en Constructor by array of points. + template + MbPointFrame( const PointsVector & pnts ) + : MbItem () + , vertices() + { + size_t vertsCnt = pnts.size(); + vertices.reserve( vertsCnt ); + for ( size_t k = 0; k < vertsCnt; ++k ) + AddVertex( pnts[k] ); + } + /// \ru Деструктор. \en Destructor. + virtual ~MbPointFrame(); + +public: + VISITING_CLASS( MbPointFrame ); + + // \ru Общие функции геометрического объекта \en Common functions of a geometric object + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbeSpaceType Type() const; // \ru Групповой тип объекта. \en Group type of object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными? \en Are the objects similar? + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать объекты равным. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Перестроить объект по журналу построения. \en Reconstruct object according to the history tree. + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + + /** \ru \name Общие функции каркаса. + \en \name Common functions of a frame. + \{ */ + + /// \ru Выдать количество вершин. \en Get count of vertices. + size_t GetVerticesCount() const { return vertices.size(); } + /// \ru Получить вершину по индексу. \en Get vertex by an index. + const MbVertex * GetVertex( size_t k ) const { return ((k < vertices.size()) ? vertices[k] : NULL ); } + /// \ru Получить вершину по индексу для модификации. \en Get vertex by an index for modification. + MbVertex * GetVertex( size_t k ) { return ((k < vertices.size()) ? vertices[k] : NULL ); } + /// \ru Добавить вершину по точке. \en Add vertex by point. + void AddVertex( const MbCartPoint3D & ); + /// \ru Добавить вершину или ее копию, что определяется флагом использования самого объекта. \en Add vertex or its copy (defined by flag of use of object). + void AddVertex( const MbVertex &, bool same ); + /// \ru Вставить вершину по номеру и точке. \en Insert vertex by index and point. + void InsertVertex( size_t k, const MbCartPoint3D & ); + /// \ru Вставить по номеру вершину или ее копию, что определяется флагом использования самого объекта. \en Insert vertex or its copy (defined by flag of use of object) by index. + void InsertVertex( size_t k, const MbVertex &, bool same ); + /// \ru Удалить вершину с заданным номером. \en Delete vertex by given index. + bool DeleteVertex( size_t k ); + /// \ru Удалить все вершины. \en Delete all vertices. + void DeleteVertices(); + + /// \ru Дать декартову точку начальной вершины. \en Get Cartesian point of the first vertex. + bool GetCartPoint( MbCartPoint3D & ) const; + /// \ru Дать декартову точку вершины с заданным номером. \en Get Cartesian point of vertex by a given index. + bool GetCartPoint( size_t k, MbCartPoint3D & ) const; + /// \ru Проверка на равенство с каркасом. \en Check for equality with frame. + bool operator == ( const MbPointFrame & ) const; + /// \ru Проверка на неравенство с каркасом. \en Check for inequality with frame. + bool operator != ( const MbPointFrame & ) const; + /** \} */ + /// \ru Установить заданный флаг измененности для всех вершин. \en Set flag of changes for all vertices. + void SetOwnChangedThrough( MbeChangedType ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPointFrame ) +OBVIOUS_PRIVATE_COPY( MbPointFrame ) +}; + +IMPL_PERSISTENT_OPS( MbPointFrame ) + +#endif // __POINT_FRAME_H diff --git a/C3d/Include/position_data.h b/C3d/Include/position_data.h new file mode 100644 index 0000000..efd0f69 --- /dev/null +++ b/C3d/Include/position_data.h @@ -0,0 +1,188 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Данные для размеров операции. + \en Data for operation dimensions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __POSITION_DATA_H +#define __POSITION_DATA_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbCurveEdge; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные для размеров операции. + \en Data for operation dimensions. \~ + \details \ru Данные для позиционирования размеров операции скругления и фаски рёбер. \n + \en Data for positioning dimensions of operations of fillet and chamfer of edges. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbPositionData { +public: + MbCartPoint3D point1; ///< \ru Опорная точка размера. \en Support point of dimension. + MbCartPoint3D point2; ///< \ru Опорная точка размера. \en Support point of dimension. + MbCartPoint3D origin; ///< \ru Начальна точка или центр. \en Start point or center. + MbVector3D normal; ///< \ru Нормаль плоскости размера. \en Plane normal of dimension. + double param; ///< \ru Положение размера в процентах длины ребра. \en Position of dimension in percentage of edge length. + MbName itemName; ///< \ru Имя объекта. \en A name of an object. + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbPositionData() + : point1() + , point2() + , origin() + , normal( 0.0, 0.0, 1.0 ) + , param (0.5) + , itemName() + {} + /// \ru Конструктор по толщинам и замкнутости. \en Constructor by thicknesses and closedness. + MbPositionData( const MbCartPoint3D & p1, const MbCartPoint3D & p2, const MbCartPoint3D & _or, + const MbVector3D & nor, double t, const MbName & n ) + : point1( p1 ) + , point2( p2 ) + , origin( _or ) + , normal( nor ) + , param ( t ) + , itemName( n ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbPositionData( const MbPositionData & other ) + : point1( other.point1 ) + , point2( other.point2 ) + , origin( other.origin ) + , normal( other.normal ) + , param ( other.param ) + , itemName( other.itemName ) + {} + /// \ru Деструктор. \en Destructor. + ~MbPositionData() {} + /// \ru Функция копирования данных. \en Copy function of data. + void Init( const MbPositionData & other ) { + point1 = other.point1; + point2 = other.point2; + origin = other.origin; + normal = other.normal; + param = other.param; + itemName.SetName( other.itemName ); + } + + /// \ru Первая контрольная точка. \en The first control point. + const MbCartPoint3D & GetPoint1() const { return point1; } + /// \ru Вторая контрольная точка. \en The second control point. + const MbCartPoint3D & GetPoint2() const { return point2; } + /// \ru Начальная точка. \en The starting point. + const MbCartPoint3D & GetOrigin() const { return origin; } + /// \ru Нормаль плоскости размера. \en Plane normal of dimension. + const MbVector3D & Normal() const { return normal; } + /// \ru Положение размера в процентах длины ребра. \en Position of dimension in percentage of edge length. + const double & GetParam() const { return param; } + /// \ru Имя объекта. \en A name of an object. + const MbName & GetName() const { return itemName; } + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const MbPositionData & other ) { + point1 = other.point1; + point2 = other.point2; + origin = other.origin; + normal = other.normal; + param = other.param; + itemName.SetName( other.itemName ); + } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbPositionData, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbPositionData, MATH_FUNC_EX ); + DECLARE_NEW_DELETE_CLASS( MbPositionData ) + DECLARE_NEW_DELETE_CLASS_EX( MbPositionData ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Последовательность рёбер. + \en Sequence of edges. \~ + \details \ru Последовательность гладко стыкующихся рёбер, скругляемых одновременно. \n + \en Sequence of smooth mating edges rounded at the same time. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbEdgeSequence { +public: + RPArray edges; ///< \ru Рёбра последовательности. \en Edges of sequence. + SArray sense; ///< \ru Направленность рёбер в последовательности. \en Direction of edges in the sequence. + bool closed; ///< \ru Замкнутость последовательности. \en Closedness of sequence. + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbEdgeSequence() + : edges( 0, 1 ) + , sense( 0, 1 ) + , closed( false ) + {} + /// \ru Конструктор по толщинам и замкнутости. \en Constructor by thicknesses and closedness. + MbEdgeSequence( const MbCurveEdge & edge, bool s, bool c ) + : edges( 1, 1 ) + , sense( 1, 1 ) + , closed( c ) + { + edges.Add( &edge ); + sense.Add( s ); + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbEdgeSequence( const MbEdgeSequence & other ) + : edges( other.edges.Count(), 1 ) + , sense( other.sense ) + , closed( other.closed ) + { + edges.AddArray( other.edges ); + } + /// \ru Деструктор. \en Destructor. + ~MbEdgeSequence() {} + /// \ru Функция копирования данных. \en Copy function of data. + void Init( const MbEdgeSequence & other ) { + edges.DetachAll(); + sense.Flush(); + edges.AddArray( other.edges ); + sense = other.sense; + closed = other.closed; + } + /// \ru Зарезервировать место под столько элементов. \en Reserve space for a given count of elements. + void Reserve( size_t count ) { + edges.Reserve( count ); + sense.Reserve( count ); + } + /// \ru Добавить ребро. \en Add an edge. + void AddEdge( const MbCurveEdge & edge, bool s ) { + edges.Add( &edge ); + sense.Add( s ); + } + /// \ru Добавить в последовательность все гладко стыкующиеся с ней ребра. \en Add all smooth mating edges to a sequence. + bool CollectEdges( double epsilon ); + /// \ru Установить замкнутость. \en Set closedness. + void SetClosed( bool c ) { closed = c; } + + const MbCurveEdge * Edge ( size_t i ) const { return ( i < edges.Count() ) ? edges[i] : NULL; } + const bool Sense( size_t i ) const { return ( i < sense.Count() ) ? sense[i] : false; } + size_t Count() const { return edges.Count(); } + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const MbEdgeSequence & other ) { + Init( other ); + } + + KNOWN_OBJECTS_RW_REF_OPERATORS_EX( MbEdgeSequence, MATH_FUNC_EX ); + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbEdgeSequence, MATH_FUNC_EX ); + DECLARE_NEW_DELETE_CLASS( MbEdgeSequence ) + DECLARE_NEW_DELETE_CLASS_EX( MbEdgeSequence ) +}; + + +#endif // __POSITION_DATA_H diff --git a/C3d/Include/reference_item.h b/C3d/Include/reference_item.h new file mode 100644 index 0000000..9dbe037 --- /dev/null +++ b/C3d/Include/reference_item.h @@ -0,0 +1,1021 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Счетчик ссылок (владельцев объекта). + \en Reference counter (of an object owners). \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __REFERENCE_ITEM_H +#define __REFERENCE_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Типы объекта со счетчиком ссылок. + \en Types of object with reference counter. \~ + \details \ru Тип несёт информацию об объекте-наследнике. \n + \en Type has an information of inheritor object. \n \~ + \ingroup Geometric_Items +*/ +// --- +enum MbeRefType +{ + rt_RefItem = 0, ///< \ru Некоторый объект. \en Some object. + rt_PlaneItem, ///< \ru Двумерный геометрически объект. \en Two-dimensional geometric object. + rt_SpaceItem, ///< \ru Трехмерный геометрический объект. \en Three-dimensional geometric object. + rt_TopItem, ///< \ru Топологический объект. \en A topological object. + rt_Creator, ///< \ru Строитель объекта. \en Object constructor + rt_Attribute, ///< \ru Атрибут объекта. \en Attribute of an object. + rt_Primitive, ///< \ru Элемент полигонального объекта. \en Element of polygonal object. + // \ru В конец можно добавлять новые нужные \en It is possible to add new necessary ones to the end +}; + + +class MATH_CLASS MbRefItem; +namespace c3d // namespace C3D +{ +typedef SPtr RefItemSPtr; +typedef SPtr ConstRefItemSPtr; + +typedef std::vector RefItemsVector; +typedef std::vector ConstRefItemsVector; + +typedef std::vector RefItemsSPtrVector; +typedef std::vector ConstRefItemsSPtrVector; +} + +//---------------------------------------------------------------------------------------- +/** \brief \ru Объект с подсчетом ссылок. + \en Reference-counted object. \~ + \details \ru Объект, считающий количество своих владельцев. \n + Используется в качестве одного из родительских классов геометрических объектов. \n + Если наследник данного класса захватывается другим объектом или алгоритмом,то другой + объект или алгоритм должен увеличить счетчик ссылок на единицу методом AddRef(). + При отказе от использования наследника данного класса другим объектом (например, при деструктурировании) + или алгоритмом другой объект или алгоритм должны уменьшить счетчик ссылок на единицу + методом Release(). Такое правило позволяет использовать одного и того же наследника + данного класса несколькими другим объектами или алгоритмами одновременно и гарантирует, + что объект будет удалён, когда он станет никому не нужен.\n + + \en Object counting number of its owners. \n + Is used as one of parent classes of geometric objects. \n + If inheritor of current class is captured by other object or algorithm, then the other + object or algorithm has to increase reference counter by one by AddRef() method. + At refusal of use of the successor of this class by other object (for example at destruction) + or by algorithm, the other object or algorithm has to decrease reference counter + by one by Release() method. Such rule allows to use the same inheritor of current + class simultaneously by several other objects or algorithms and guarantees that the + object will be removed when it becomes unnecessary.\n \~ + + \note \ru Рекомендуется применение автоматических указателей типа SPtr к экземплярам + данного класса. Это упростит работу с кодом, где нужно позаботится об автоматической + сборке мусора. + \en It is recommended to use smart pointers of type SPtr to instances of + this class. This will simplify the work with the code where you want to take care of + the automatic garbage collection. \~ + \sa #SPtr + \ingroup Geometric_Items +*/ +// --- +class MATH_CLASS MbRefItem { +private: + mutable use_count_type useCount; ///< \ru Счетчик ссылок на объект, изменяемый владельцами объекта. \en A counter of references to an object modifiable by owners of object. +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbRefItem(); +protected: + virtual ~MbRefItem(); + +public: + /** \ru \name Функции регистрации ссылок на геометрический объект владельцами объекта. + \en \name Functions for registration of references to geometric object by owners of object. + \{ */ + /// \ru Выдать количество ссылок (выдать количество владельцев объекта). \en Get count of references (get count of owners of an object). + refcount_t GetUseCount() const; + /// \ru Увеличить количество ссылок на единицу. \en Increase count of references by one. + refcount_t AddRef() const; + /// \ru Уменьшить количество ссылок на единицу. \en Decrease count of references by one. + refcount_t DecRef() const; + /// \ru Уменьшить количество ссылок на единицу и, если количество ссылок стало равным нулю, удалить себя. \en Decrease count of references by one and if count of references became zero, then remove itself. + refcount_t Release() const; + /** \} */ +public: + /// \ru Регистрационный тип (для копирования, дублирования). \en Registration type (for copying, duplication). + virtual MbeRefType RefType() const; + +OBVIOUS_PRIVATE_COPY( MbRefItem ) +}; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Шаблон класса сериализации (порядковой нумерации создаваемых объектов). + \en Serialization class template (ordinal numbering of created objects). \~ + \details \ru Шаблон класса сериализации (порядковой нумерации создаваемых объектов). \n + Применение: наследовать от данного класса. + Аргумент шаблона позволяет иметь несколько сериализаций одновременно: \n + если нужна сериализация объектов класса T, можно записать class T: virtual public MbSerialItem \n + если объекты U должны иметь ту же сериализацию, можно записать class U: virtual public MbSerialItem \n + или же создать пустой класс для сериализации типа class MbBasicSerializer {} + и наследоваться от MbSerialItem. \n + + \en Serialization class template (ordinal numbering of created objects). \n + How to use: inherit from this class. \n + The template argument allows multiple serializations at the same time: \n + if you need serialization of objects of class T, you can write class T: virtual public MbSerialItem \n + if U objects must have the same serialization, you can write a class U: virtual public MbSerialItem \n + or you can create an empty class to serialize the class type MbBasicSerializer \n + and inherit it from MbSerialItem . \n \~ + + \ingroup Geometric_Items +*/ +// --- +template class MbSerialItem { +private: + static serial_type serialLast; ///< \ru Индекс последнего созданного объекта (0 в случае отсутствия объектов). \en Index of the last object created (0 if there are no objects). + static serial_type serialCount; ///< \ru Счетчик объектов. \en Counter of objects. + serial_type serialThis; ///< \ru Уникальный порядковый номер объекта, выдается при создании. В дальнейшем не меняется. \en The unique sequence number of the object, issued at creation. In the future it is not changed. +public: + MbSerialItem(); ///< \ru Конструктор. \en Constructor. +protected: + virtual ~MbSerialItem(); ///< \ru Деструктор. \en Destructor. +public: + size_t GetSerial() const { return SerialTypeValue( serialThis ); } ///< \ru Выдать порядковый номер объекта. \en Get object serial identifier. + +OBVIOUS_PRIVATE_COPY( MbSerialItem ) +}; + + +// \ru Инициализация статических переменных шаблона класса сериализации. \en Initializing static variables of the serialization class template. +template serial_type MbSerialItem::serialLast = 0; +template serial_type MbSerialItem::serialCount = 0; + + +//----------------------------------------------------------------------------- +// \ru Конструктор. \en Constructor. +// --- +template MbSerialItem::MbSerialItem() +{ // Set the serial number and promote the counters + PRECONDITION( serialLast != SYS_MAX_T ); // number overflow + serialThis = ++serialLast; + ++serialCount; +} + + +//----------------------------------------------------------------------------- +// \ru Деструктор. \en Destructor. +// --- +template MbSerialItem::~MbSerialItem() +{ + PRECONDITION( SerialTypeValue( serialCount ) != 0 ); // If it equals 0 then it means that the counter is damaged. + if ( --serialCount == 0 ) // The case when the last of the instantiated objects is deleted + serialLast = 0; // Set serialization to zero - at the subsequent creation of objects the numbering will start again (serially since 1). +} + + + +//------------------------------------------------------------------------------ +/// \ru Удалить объект без ссылок. \en Delete an object without references. +//--- +template +inline void DeleteMatItem( Type *& item ) +{ + if ( item != NULL ) { + delete item; + item = NULL; + } +} + + +//------------------------------------------------------------------------------ +/// \ru Удалить объекты без ссылок. \en Delete objects without references. +// --- +template +void DeleteMatItems( Vector & items ) +{ + for ( size_t k = 0, itemsCnt = items.size(); k < itemsCnt; ++k ) + ::DeleteMatItem( items[k] ); + items.clear(); +} + + +//------------------------------------------------------------------------------ +/// \ru Сделать копию, если объект используется, иначе вернуть оригинал. \en Create a copy if object is used, otherwise return original. +// --- +template +Type & DuplicateIfUsed( Type & item ) +{ + Type * resItem = &item; + if ( item.GetUseCount() > 0 ) // \ru Если оригинал, то делаем копию. \en If there is original, then make a copy. + resItem = static_cast( &item.Duplicate() ); + + return *resItem; +} + + +//------------------------------------------------------------------------------ +/// \ru Сделать копию, если объект используется, иначе вернуть оригинал. \en Create a copy if object is used, otherwise return original. +// --- +template +Type & DuplicateIfUsed( Type & item, RegType * iReg ) +{ + Type * resItem = &item; + if ( item.GetUseCount() > 0 ) // \ru Если оригинал, то делаем копию. \en If there is original, then make a copy. + resItem = static_cast( &item.Duplicate( iReg ) ); + + return *resItem; +} + + +//------------------------------------------------------------------------------ +/// \ru Сделать копию, если объект используется, иначе вернуть оригинал. \en Create a copy if object is used, otherwise return original. +// --- +template +Type * DuplicateIfUsed( SPtr & item ) +{ + if ( item == NULL ) + return NULL; + Type * resItem = item.get(); + if ( item->GetUseCount() > 1 ) // \ru Если оригинал, то делаем копию. \en If there is original, then make a copy. + resItem = static_cast( &item->Duplicate() ); + + return resItem; +} + + +//------------------------------------------------------------------------------ +/// \ru Сделать копию, если объект используется, иначе вернуть оригинал. \en Create a copy if object is used, otherwise return original. +// --- +template +Type * DuplicateIfUsed( SPtr & item, RegType * iReg ) +{ + if ( item == NULL ) + return NULL; + Type * resItem = item.get(); + if ( item->GetUseCount() > 1 ) // \ru Если оригинал, то делаем копию. \en If there is original, then make a copy. + resItem = static_cast( &item->Duplicate( iReg ) ); + + return resItem; +} + +//------------------------------------------------------------------------------ +/// \ru Удалить объект, если он больше никому не нужен. \en Delete an object if it is unnecessary. +// --- +template +void DeleteItem( Type *& item ) +{ + if ( item != NULL ) { + if ( item->GetUseCount() < 1 ) + delete item; + item = NULL; + } +} + +//------------------------------------------------------------------------------ +/// \ru Освободить ссылку на объект. \en Release the reference to object. +// --- +template +void ReleaseItem( Type *& item ) +{ + if ( item != NULL ) { + item->Release(); + item = NULL; + } +} + +//------------------------------------------------------------------------------ +/// \ru Захватить объект. \en Catch an object. +// --- +template +void AddRefItem( const Type * item ) +{ + if ( item != NULL ) + item->AddRef(); +} + +//------------------------------------------------------------------------------ +/// \ru Отпустить объект без удаления. \en Detach an object without removing. +// --- +template +void DecRefItem( const Type * item ) +{ + if ( item != NULL ) + item->DecRef(); +} + + +//------------------------------------------------------------------------------ +/// \ru Захватить объекты. \en Catch objects. +// --- +template +void AddRefItems( const Vector & items ) +{ + for ( size_t k = 0, itemsCnt = items.size(); k < itemsCnt; ++k ) { + if ( items[k] != NULL ) + items[k]->AddRef(); + } +} + + +//------------------------------------------------------------------------------ +/// \ru Отпустить объекты без удаления. \en Detach objects without removing. +// --- +template +void DecRefItems( const Vector & items ) +{ + for ( size_t k = 0, itemsCnt = items.size(); k < itemsCnt; ++k ) { + if ( items[k] != NULL ) + items[k]->DecRef(); + } +} + + +//------------------------------------------------------------------------------ +/// \ru Удалить никому не нужные объекты. \en Remove unnecessary objects. +// --- +template +void DeleteItems( Vector & items ) +{ + for ( size_t k = 0, itemsCnt = items.size(); k < itemsCnt; ++k ) + ::DeleteItem( items[k] ); + items.clear(); +} + + +//------------------------------------------------------------------------------ +/// \ru Отпустить объекты с возможным удалением. \en Detach objects with possible removing. +// --- +template +void ReleaseItems( Vector & items ) +{ + for ( size_t k = 0, itemsCnt = items.size(); k < itemsCnt; ++k ) + ::ReleaseItem( items[k] ); + items.clear(); +} + + +//------------------------------------------------------------------------------ +/// \ru Удалить никому не нужные объекты. \en Remove unnecessary objects. +// --- +template +void DeleteItems( Vector & items, SArray & coItems ) +{ + size_t itemsCnt = items.size(); + if ( itemsCnt > 0 ) { + for ( size_t k = 0; k < itemsCnt; ++k ) + ::DeleteItem( items[k] ); + items.clear(); + coItems.clear(); + } +} + + +//------------------------------------------------------------------------------ +/// \ru Отпустить объекты с возможным удалением. \en Detach objects with possible removing. +// --- +template +void ReleaseItems( Vector & items, SArray & coItems ) +{ + size_t itemsCnt = items.size(); + if ( itemsCnt > 0 ) { + for ( size_t k = 0; k < itemsCnt; ++k ) + ::ReleaseItem( items[k] ); + items.clear(); + coItems.clear(); + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefItems( const TypeVector & srcItems, bool same, RPArray & dstItems ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast( &srcItems ) != reinterpret_cast( &dstItems ) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate() ); + dstItem->AddRef(); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefItems( const TypeVector & srcItems, bool same, std::vector< SPtr > & dstItems ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast(&srcItems) != reinterpret_cast(&dstItems) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; k++ ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + SPtr dstItem; + dstItem = same ? srcItem : static_cast( &srcItem->Duplicate() ); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefItems( const TypeVector & srcItems, bool same, std::vector & dstItems ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast( &srcItems ) != reinterpret_cast( &dstItems ) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate() ); + dstItem->AddRef(); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefRegItems( const TypeVector & srcItems, bool same, RPArray & dstItems, RegType * iReg ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast(&srcItems) != reinterpret_cast(&dstItems) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItem->AddRef(); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefRegItems( const TypeVector & srcItems, bool same, std::vector< SPtr > & dstItems, RegType * iReg ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast(&srcItems) != reinterpret_cast(&dstItems) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + SPtr dstItem; + dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Переложить элементы с захватом и возможным копированием. \en Put elements with capturing and with possible copying. +// --- +template +void AddRefRegItems( const TypeVector & srcItems, bool same, std::vector & dstItems, RegType * iReg ) +{ + if ( (srcItems.size() > 0) && reinterpret_cast(&srcItems) != reinterpret_cast(&dstItems) ) { + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + if ( srcItems[k] != NULL ) { + Type * srcItem = &const_cast(*srcItems[k]); + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItem->AddRef(); + dstItems.push_back( dstItem ); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. +// --- +template +bool IsItemSame( const Item * item1, const Item * item2, double accuracy ) +{ + if ( (item1 == NULL) && (item2 == NULL) ) + return true; + else if ( (item1 != NULL) && (item2 != NULL) && item1->IsSame( *item2, accuracy ) ) + return true; + return false; +} + + +//------------------------------------------------------------------------------ +/// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. +// --- +template +bool AreItemsSame( const Vector & items1, const Vector & items2, double accuracy ) +{ + bool areEqual = false; + + const size_t cnt = items1.size(); + if ( cnt == items2.size() ) { + areEqual = true; + for ( size_t k = 0; k < cnt; ++k ) { + if ( (items1[k] == NULL) || (items2[k] == NULL) || !items1[k]->IsSame( *items2[k], accuracy ) ) { + areEqual = false; + break; + } + } + } + + return areEqual; +} + + +//------------------------------------------------------------------------------ +/// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. +// --- +template +bool AreObjectsSame( const Vector & items1, const Vector & items2, double accuracy ) +{ + bool areEqual = false; + + const size_t cnt = items1.size(); + if ( cnt == items2.size() ) { + areEqual = true; + for ( size_t k = 0; k < cnt; ++k ) { + if ( !items1[k].IsSame( items2[k], accuracy ) ) { + areEqual = false; + break; + } + } + } + + return areEqual; +} + + +//------------------------------------------------------------------------------ +/// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. +// --- +template +bool AreItemsSimilar( const Vector & items1, const Vector & items2 ) +{ + bool areEqual = false; + + const size_t cnt = items1.size(); + if ( cnt == items2.size() ) { + areEqual = true; + for ( size_t k = 0; k < cnt; ++k ) { + if ( (items1[k] == NULL) || (items2[k] == NULL) || !items1[k]->IsSimilar( *items2[k] ) ) { + areEqual = false; + break; + } + } + } + + return areEqual; +} + + +//------------------------------------------------------------------------------ +/// \ru Сделать равными. \en Make equal. +// --- +template +bool SetItemsEqual( const Vector & srcItems, Vector & dstItems ) +{ + bool setEqual = false; + + size_t cnt = srcItems.size(); + if ( cnt == dstItems.size() ) { + setEqual = ::AreItemsSimilar( srcItems, dstItems ); + + if ( setEqual ) { + for ( size_t k = 0; k < cnt; ++k ) { + if ( srcItems[k] == NULL || dstItems[k] == NULL || !dstItems[k]->SetEqual( *srcItems[k] ) ) { + setEqual = false; + break; + } + } + } + } + + return setEqual; +} + + +//------------------------------------------------------------------------------ +/// \ru Дублировать c регистратором (опционально переложить оригиналы). \en Duplicate with registrator (optionally put originals). +// --- +template +void DuplicateItems( const TypeVector & srcItems, RegType * iReg, bool same, RPArray & dstItems ) +{ + C3D_ASSERT( dstItems.size() < 1 ); + dstItems.Reserve( srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + Type * srcItem = srcItems[k]; + if ( srcItem != NULL ) { + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItems.push_back( dstItem ); + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Дублировать c регистратором (опционально переложить оригиналы). \en Duplicate with registrator (optionally put originals). +// --- +template +void DuplicateItems( const TypeVector & srcItems, RegType * iReg, bool same, std::vector< SPtr > & dstItems ) +{ + C3D_ASSERT( dstItems.size() < 1 ); + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + Type * srcItem = srcItems[k]; + if ( srcItem != NULL ) { + SPtr dstItem; + dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItems.push_back( dstItem ); + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Дублировать c регистратором (опционально переложить оригиналы). \en Duplicate with registrator (optionally put originals). +// --- +template +void DuplicateItems( const TypeVector & srcItems, RegType * iReg, bool same, std::vector & dstItems ) +{ + C3D_ASSERT( dstItems.size() < 1 ); + dstItems.reserve( dstItems.size() + srcItems.size() ); + for ( size_t k = 0, cnt = srcItems.size(); k < cnt; ++k ) { + Type * srcItem = srcItems[k]; + if ( srcItem != NULL ) { + Type * dstItem = same ? srcItem : static_cast( &srcItem->Duplicate( iReg ) ); + dstItems.push_back( dstItem ); + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Преобразовать элементы согласно матрице. \en Transform elements according to the matrix. +// --- +template +void TransformItems( Array & items, const Matrix & matr, RegType * iReg ) +{ + for ( size_t k = 0, cnt = items.size(); k < cnt; ++k ) { + if ( items[k] != NULL ) + items[k]->Transform( matr, iReg ); + } +} + +//------------------------------------------------------------------------------ +/// \ru Преобразовать элементы согласно матрице. \en Transform elements according to the matrix. +// --- +template +void TransformObjects( Array & objects, const Matrix & matr ) +{ + for ( size_t k = 0, cnt = objects.size(); k < cnt; ++k ) + objects[k].Transform( matr ); +} + + +//------------------------------------------------------------------------------ +/// \ru Сдвинуть вдоль объекты вектора. \en Translate objects along a vector. +// --- +template +void MoveItems( Array & items, const Vector & to, RegType * iReg ) +{ + for ( size_t k = 0, cnt = items.size(); k < cnt; ++k ) { + if ( items[k] != NULL ) + items[k]->Move( to, iReg ); + } +} + +//------------------------------------------------------------------------------ +/// \ru Сдвинуть вдоль объекты вектора. \en Translate objects along a vector. +// --- +template +void MoveObjects( Array & objects, const Vector & to ) +{ + for ( size_t k = 0, cnt = objects.size(); k < cnt; ++k ) + objects[k].Move( to ); +} + + +//------------------------------------------------------------------------------ +/// \ru Повернуть вокруг оси. \en Rotate about an axis. +// --- +template +void RotateItems( Array & items, const Axis & axis, double angle, RegType * iReg ) +{ + for ( size_t k = 0, cnt = items.size(); k < cnt; ++k ) { + if ( items[k] != NULL ) + items[k]->Rotate( axis, angle, iReg ); + } +} + +//------------------------------------------------------------------------------ +/// \ru Повернуть вокруг оси. \en Rotate about an axis. +// --- +template +void RotateObjects( Array & objects, const Axis & axis, double angle ) +{ + for ( size_t k = 0, cnt = objects.size(); k < cnt; ++k ) + objects[k].Rotate( axis, angle ); +} + + +//------------------------------------------------------------------------------ +/// \ru Запись объектов в поток. \en Write objects to the stream. +// --- +template +void WriteRefItems( const Vector & items, Writer & out ) +{ + size_t k, cnt = items.size(); + + for ( k = 0; k < cnt; ++k ) { + if ( items[k] == NULL ) + cnt--; + } + + WriteCOUNT( out, cnt ); + + if ( out.good() ) { + for ( k = 0; k < cnt; ++k ) { + if ( items[k] != NULL ) { + items[k]->PrepareWrite(); + out << &(*items[k]); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Запись объекты в поток. \en Write objects to the stream. +// --- +template +void WriteRefItems( const std::vector< SPtr > & items, Writer & out ) +{ + size_t k, cnt = items.size(); + + for ( k = 0; k < cnt; ++k ) { + if ( items[k] == NULL ) + cnt--; + } + + WriteCOUNT( out, cnt ); + + if ( out.good() ) { + for ( k = 0; k < cnt; ++k ) { + if ( items[k] != NULL ) { + items[k]->PrepareWrite(); + out << items[k].get(); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Чтение массива объектов из потока с захватом. \en Read an array of objects with capturing from the stream. +// --- +template +void ReadRefItems( Reader & in, RPArray & items ) +{ + size_t cnt = ReadCOUNT( in ); + + if ( in.good() && cnt > 0 ) { + items.reserve( items.size() + cnt ); + + for ( size_t i = 0; i < cnt; ++i ) { + Type * item = NULL; + in >> item; + if ( item != NULL ) { + items.push_back( item ); + item->AddRef(); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Чтение массива объектов из потока с захватом. \en Read an array of objects with capturing from the stream. +// --- +template +void ReadRefItems( Reader & in, std::vector & items ) +{ + size_t cnt = ReadCOUNT( in ); + + if ( in.good() && cnt > 0 ) { + for ( size_t i = 0; i < cnt; ++i ) { + Type * item = NULL; + in >> item; + if ( item != NULL ) { + items.push_back( item ); + item->AddRef(); + } + } + } +} + + +//------------------------------------------------------------------------------ +/// \ru Чтение массива объектов из потока с захватом. \en Read an array of objects with capturing from the stream. +// --- +template +void ReadRefItems( Reader & in, std::vector< SPtr > & items ) +{ + size_t cnt = ReadCOUNT( in ); + + if ( in.good() && cnt > 0 ) { + for ( size_t i = 0; i < cnt; ++i ) { + Type * item = NULL; + in >> item; + if ( item != NULL ) + items.push_back( SPtr(item) ); + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Отцепить от массива и уменьшить счетчик ссылок. + \en Detach from array and decrease reference counter. \~ + \details \ru Отцепить от массива и уменьшить счетчик ссылок без проверок.\n + \en Detach from array and decrease reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] index - \ru Номер элемента. Не проверяется на корректность. + \en Index of element. Isn't checked for correctness. \~ +*/ +// --- +template +void ReleaseAndDetachItem_( Vector & items, size_t index ) +{ + items[index]->Release(); + items.erase( items.begin() + index ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить объект и увеличить счетчик ссылок. + \en Add an object and increase reference counter. \~ + \details \ru Добавить объект и увеличить счетчик ссылок без проверок.\n + \en Add an object and increase reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] newItem - \ru Новый элемент. + \en New element. \~ +*/ +// --- +template +void AddRefAndAddItem_( Vector & items, Type * newItem ) +{ + newItem->AddRef(); + items.push_back( newItem ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить объект и увеличить счетчик ссылок. + \en Add an object and increase reference counter. \~ + \details \ru Добавить объект и увеличить счетчик ссылок без проверок.\n + \en Add an object and increase reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] newItem - \ru Новый элемент. + \en New element. \~ + \param[in] index - \ru Номер элемента. Не проверяется на корректность. + \en Index of element. Isn't checked for correctness. \~ +*/ +// --- +template +void AddRefAndAddAtItem_( Vector & items, Type * newItem, size_t index ) +{ + newItem->AddRef(); + items.insert( index, newItem ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Отцепить от массива и уменьшить счетчик ссылок. + \en Detach from array and decrease reference counter. \~ + \details \ru Отцепить от массива и уменьшить счетчик ссылок без проверок.\n + \en Detach from array and decrease reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] index - \ru Номер элемента. Не проверяется на корректность. + \en Index of element. Isn't checked for correctness. \~ +*/ +// --- +template +void ReleaseAndDetachItem_( std::vector > & items, size_t index ) +{ + items[index].reset(); + items.erase( items.begin() + index ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить объект и увеличить счетчик ссылок. + \en Add an object and increase reference counter. \~ + \details \ru Добавить объект и увеличить счетчик ссылок без проверок.\n + \en Add an object and increase reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] newItem - \ru Новый элемент. + \en New element. \~ +*/ +// --- +template +void AddRefAndAddItem_( std::vector > & items, Type * newItem ) +{ + items.push_back( SPtr(newItem) ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить объект и увеличить счетчик ссылок. + \en Add an object and increase reference counter. \~ + \details \ru Добавить объект и увеличить счетчик ссылок без проверок.\n + \en Add an object and increase reference counter without checks.\n \~ + \param[in,out] items - \ru Множество элементов. + \en An array of elements. \~ + \param[in] newItem - \ru Новый элемент. + \en New element. \~ + \param[in] index - \ru Номер элемента. Не проверяется на корректность. + \en Index of element. Isn't checked for correctness. \~ +*/ +// --- +template +void AddRefAndAddAtItem_( std::vector > & items, Type * newItem, size_t index ) +{ + items.insert( items.begin() + index, SPtr(newItem) ); +} + + +//------------------------------------------------------------------------------ +/// \ru Отцепить объект из владеющего указателя. \en Detach object from owning pointer. +// --- +template +inline Type * DetachItem( SPtr & itemOwner ) +{ + return itemOwner.detach(); +} + + +//------------------------------------------------------------------------------ +/// \ru Заменить объект на копию. \en Replace object by copy. +// --- +template +void ReplaceByCopy( Type *& item ) +{ + if ( item != NULL ) { + Type * temp = (Type *)&item->Duplicate(); + ::DeleteItem( item ); + item = temp; + } +} + + +//------------------------------------------------------------------------------ +/// \ru Включить габариты объектов массива в общий габарит. \en Include bounding boxes of an array of objects in a common bounding box. +//--- +template +void AddYourGabaritTo( Objects & objects, Gab & gab ) +{ + for ( size_t k = 0, cnt = objects.size(); k < cnt; ++k ) { + if ( objects[k] ) + objects[k]->AddYourGabaritTo( gab ); + } +} + + +#endif // __REFERENCE_ITEM_H diff --git a/C3d/Include/region.h b/C3d/Include/region.h new file mode 100644 index 0000000..8cde1e6 --- /dev/null +++ b/C3d/Include/region.h @@ -0,0 +1,312 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерный регион. + \en Two-dimensional region. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __REGION_H +#define __REGION_H + +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерный регион. + \en Two-dimensional region. \~ + \details \ru Регион состоит из набора замкнутых составных кривых (контуров) MbContour. \n + Регион представляет собой связное множество точек двумерного пространства, границы которого описывают контуры. + Контуры региона замкнуты и не имеют самопересечений (но могут иметь самокасания). + В произвольном регионе обязан быть один (и только один) внешний контур (положительный + обход внешнего контура осуществляется против часовой стрелки) и несколько + внутренних контуров (положительный обход внутреннего контура осуществляется по часовой + стрелке), которые полностью лежат внутри внешнего контура (или могут его касаться). + В массиве contours первым всегда лежит внешний контур. + Над регионами можно выполнять булевы операции. + \en A region consists of a set of closed composite curves (contours) MbContour. \n + A region represents a connected set of two-dimensional points, which boundaries are described by contours. + Contours of region are closed and do not have self-intersections (but there may be self-contacts). + In arbitrary region should be one (and only one) external contour (positive + traverse of external contour is performed counterclockwise) and several + internal contour (positive traverse of internal contour is performed clockwise) + which are completely located inside external contour (or may contact it). + In the array 'contours' external contour is always the first. + Boolean operations may be performed with regions. \~ + \ingroup Region_2D +*/ +// --- +class MATH_CLASS MbRegion : public MbPlaneItem { +private: + RPArray contours; ///< \ru Контуры региона. \en Region contour. + mutable ThreeStates setCorrect; ///< \ru Результат проверки корректности. \en Correctness check result. + +public: + MbRegion(); ///< \ru Пустой регион. \en Empty region. + MbRegion( const MbContour &, bool same ); ///< \ru Регион с одним внешним контуром. \en Region with one external contour. + MbRegion( const SPtr &, bool same ); ///< \ru Регион с одним внешним контуром. \en Region with one external contour. + MbRegion( const RPArray &, bool same ); ///< \ru Регион с несколькими контурами. \en Region with several contours. + MbRegion( const std::vector< SPtr > &, bool same ); ///< \ru Регион с несколькими контурами. \en Region with several contours. + MbRegion( const MbRegion &, bool same, MbRegDuplicate * iReg = NULL ); ///< \ru Конструктор копии. \en Copy-constructor. +public: + virtual ~MbRegion(); + +public: + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbePlaneType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbePlaneType Type() const; // \ru Групповой тип объекта. \en Group type of object. + virtual MbePlaneType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbPlaneItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию. \en Create a copy + virtual void Transform( const MbMatrix & matr, MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector & to, MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * iReg = NULL, const MbSurface * newSurface = NULL ); + virtual bool IsSame ( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool SetEqual ( const MbPlaneItem & item ); // \ru Сделать объекты равным. \en Make objects equal. + virtual void AddYourGabaritTo( MbRect & r ) const; // \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + virtual bool IsVisibleInRect( const MbRect & r, bool exact = false ) const; // \ru Виден ли объект в заданном прямоугольнике. \en Whether the object is visible in the given rectangle + virtual double DistanceToPoint( const MbCartPoint & to ) const; // \ru Вычислить расстояние до точки to. \en Calculate the distance to a point 'to'. + virtual bool DistanceToPointIfLess( const MbCartPoint & to, + double & distance ) const; // \ru Вычислить расстояние до точки to, если оно меньше d. \en Calculate the distance to the point 'to' if it is less than d. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + + virtual MbProperty & CreateProperty( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + /**\ru \name Функции инициализации. + \en \name Initialization functions. + \{ */ + /// \ru Инициализация. \en Initialization. + void Init( const MbContour &, bool same ); + /// \ru Инициализация. \en Initialization. + void Init( const RPArray &, bool same ); + /// \ru Инициализация. \en Initialization. + void Init( const std::vector< SPtr > &, bool same ); + /** \} */ + /**\ru \name Функции доступа к данным. + \en \name Functions for access to data. + \{ */ + size_t GetContoursCount() const { return contours.size(); } ///< \ru Выдать количество контуров региона. \en Get the number of contours of region. + const MbContour * GetContour( size_t k ) const { return contours[k]; } ///< \ru Выдать контур с индексом index. \en Get contour with the given index. + const MbContour * GetOutContour() const; ///< \ru Выдать внешний контур. \en Get external contour. + /** \} */ + /**\ru \name Функции изменения данных. + \en \name Functions for changing data + \{ */ + MbContour * SetContour( size_t k ) { setCorrect = ts_neutral; return contours[k]; } ///< \ru Выдать контур с индексом index. \en Get contour with the given index. + + /// \ru Отсоединить используемые контуры и удалить остальные. \en Detach used contours and delete other. + void DeleteContours(); + /// \ru Отцепить все контуры региона без удаления. \en Detach all region contours without deletion. + void DetachContours( RPArray & ); + + /// \ru Сделать регион корректным (если это нужно и возможно). \en Make region correct (if this is possible). + bool SetCorrect(); + /// \ru Состояние проверки корректности региона. \en A state of region validation. + ThreeStates GetCorrectState() const { return setCorrect; } + + /// \ru Определить положение точки относительно региона. \en Define the point location relative to the region. + MbeItemLocation PointClassification( const MbCartPoint &, double metricAcc /*= Math::LengthEps*/ ) const; + /// \ru Есть ли в контуре криволинейный сегмент. \en Whether the contour has a curved segment. + bool IsAnyCurvilinear() const; + /// \ru Одинаковы ли регионы геометрически. \en Whether regions are space same. + bool IsSpaceSame( const MbRegion & ) const; + /// \ru Рассчитать и добавить массивы отрисовочных точек с заданной стрелкой прогиба. \en Calculate and add arrays of drawn points with a given sag. + void CalculatePolygons( double sag, RPArray & polygons ) const; + /// \ru Удалить внутренние контуры. \en Remove internal contours. + void DeleteInnerContours(); + + /** \brief \ru Удалить внутренний контур. + \en Remove internal contour. \~ + \details \ru Удалить внутренний контур по индексу. Индекс проверяется на корректность. + \en Remove internal contour by index. An index is validated for correctness. \~ + \param[in] index - \ru Индекс внутреннего контура. Должен быть больше нуля, но меньше количества контуров. + \en An index of internal contour. It should be more than null and less than the number of contours. \~ + \return \ru true Если контур был удален. + \en True if the contour has been deleted. \~ + */ + bool DeleteInnerContour( size_t index ); + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRegion ) +OBVIOUS_PRIVATE_COPY( MbRegion ) +}; // MbRegion + +IMPL_PERSISTENT_OPS( MbRegion ) + +//------------------------------------------------------------------------------- +/** \brief \ru Получить набор регионов. + \en Get a set of regions. \~ + \details \ru Получить набор корректных регионов из произвольного набора контуров.\n + Из присланных контуров отбираются те, которые подходят для построения + региона - замкнутые несамопересекающиеся и без разрывов. + \en Get a set of correct regions from arbitrary set of regions. \n + From sent contours there are selected such contours which are suitable for construction + of region - closed, without self-intersections and discontinuities. \~ + \param[in] contours - \ru Набор контуров. + \en A set of contours. \~ + \param[in] sameContours - \ru Флаг использования оригиналов контуров при создании регионов. + \en A flag of using of contours originals when creating regions. \~ + \param[out] regions - \ru Результат - набор регионов. + \en The result is a set of points. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) GetCorrectRegions( const RPArray & contours, bool sameContours, + RPArray & regions ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Разбить набор контуров на группы и построить по ним регионы. + \en Divide a set of regions into groups and construct regions. \~ + \details \ru Разбить произвольный набор контуров на связные группы контуров и построить по ним регионы.\n + Для любого контура, принадлежащего связной группе, этой же группе + принадлежат все контуры:\n + 1) совпадающие с данным контуром\n + 2) пересекающие данный контур\n + 3) содержащие данный контур\n + 4) содержащиеся в данном контуре\n + Группы возвращаются в виде регионов (возможно, некорректных). + \en Divide arbitrary set of contours into connected groups of contours and construct regions.\n + For any contour belonging to connected group, this group + contain all contours:\n + 1) which coincide with the given contour\n + 2) which intersect the given contour\n + 3) which contain the given contour\n + 4) which are contained in the given contour\n + Groups are returned in regions form (perhaps, incorrect). \~ + \param[in] contours - \ru Набор контуров для разбиения на группы. + \en A set of contours for dividing into groups. \~ + \param[in] useSelfIntCntrs - \ru Если true, то самопересекающиеся контуры образуют + отдельные группы (некорректные регионы), иначе - такие контуры + вообще не используются. + \en If true then self-intersected contours form + separate groups (incorrect regions), otherwise - such contours + are not used at all. \~ + \param[in] sameContours - \ru Флаг использования оригиналов контуров при создании регионов. + \en A flag of using of contours originals when creating regions. \~ + \param[out] regions - \ru Результат - набор регионов. + \en The result is a set of points. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (void) MakeRegions( RPArray & contours, + bool useSelfIntCntrs, + bool sameContours, + RPArray & regions ); + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры булевой операции над регионами. + \en Boolean operation parameters over regions. + \~ + \details \ru Параметры булевой операции над регионами.\n + \en Boolean operation parameters over regions. \n + \~ + \ingroup Region_2D +*/ +// --- +struct MATH_CLASS MbRegionBooleanParams { +protected: + RegionOperationType operType; ///< \ru Тип булевой операции. \en А Boolean operation type. + bool allowSelfTouch; ///< \ru Допустимость самокасаний в результате. \en Admissibility of self-touches as a result.. + bool mergeCurves; ///< \ru Объединять подобные сегменты кривых. \en Merge similar segments of curves. +public: + MbRegionBooleanParams( RegionOperationType type, bool selfTouch = true, bool mergeCrvs = true ) : operType( type ), allowSelfTouch( selfTouch ), mergeCurves( mergeCrvs ) {} + MbRegionBooleanParams( const MbRegionBooleanParams & p ) : operType( p.operType ), allowSelfTouch( p.allowSelfTouch ), mergeCurves( p.mergeCurves ) {} +public: + RegionOperationType OperationType() const { return operType; } + void OperationType( RegionOperationType type ) { operType = type; } + + bool MergeCurves() const { return mergeCurves; } + void MergeCurves( bool b ) { mergeCurves = b; } + + bool AllowSelfTouch() const { return allowSelfTouch; } + void AllowSelfTouch( bool b ) { allowSelfTouch = b; } + + const MbRegionBooleanParams & operator = ( const MbRegionBooleanParams & p ) { operType = p.operType; allowSelfTouch = p.allowSelfTouch; mergeCurves = p.mergeCurves; return *this; } +private: + MbRegionBooleanParams(); +}; + + +//------------------------------------------------------------------------------- +/** \brief \ru Выполнить булеву операцию над регионами. + \en Perform boolean operation with regions. \~ + \details \ru Выполнить булеву операцию над двумя регионами, заданными массивами контуров. \n + Ломаную нежелательно использовать как сегмент контура. Ее нужно преобразовать на набор отрезков. + \en Perform boolean operation with two regions, which are set by the contours array. \n + Polyline is undesirable as a contour segment. It needs to be converted to a set of segments. \~ + \param[in] contours1 - \ru Первый набор контуров. + \en First set of contours. \~ + \param[in] contours2 - \ru Второй набор контуров. + \en Second set of contours. \~ + \param[in] operParams - \ru Параметры булевой операции. + \en A Boolean operation parameters. \~ + \param[out] regions - \ru Результат - набор регионов. + \en The result is a set of points. \~ + \param[out] resInfo - \ru Код результата операции. + \en Operation result code. \~ + \return \ru true в случае успеха операции. + \en Returns true if the operation succeeded. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) CreateBooleanResultRegions( RPArray & contours1, RPArray & contours2, + const MbRegionBooleanParams & operParams, RPArray & regions, + MbResultType * resInfo = NULL ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Выполнить булеву операцию над регионами. + \en Perform boolean operation with regions. \~ + \details \ru Выполнить булеву операцию над двумя регионами. + \en Perform boolean operation with two regions. \~ + \param[in] region1 - \ru Первый регион. + \en First region. \~ + \param[in] region2 - \ru Второй регион. + \en Second region. \~ + \param[in] operParams - \ru Параметры булевой операции. + \en A Boolean operation parameters. \~ + \param[out] regions - \ru Результат - набор регионов. + \en The result is a set of points. \~ + \param[out] resInfo - \ru Код результата операции. + \en Operation result code. \~ + \return \ru true в случае успеха операции. + \en Returns true if the operation succeeded. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) CreateBooleanResultRegions( MbRegion & region1, MbRegion & region2, + const MbRegionBooleanParams & operParams, RPArray & regions, + MbResultType * resInfo = NULL ); + + +//------------------------------------------------------------------------------- +/** \brief \ru Выполнить объединение регионов. + \en Perform union of regions. \~ + \details \ru Выполнить объединение регионов. + \en Perform union of regions. \~ + \param[in,out] regions - \ru Начальные и конечные регионы. + \en Initial and resulting regions. \~ + \param[in] allowSelfTouch - \ru Допустимость самокасаний в результате. + \en Admissibility of self-touches as a result. \~ + \param[in] mergeCurves - \ru Объединять подобные сегменты кривых. + \en Merge similar segments of curves. \~ + \return \ru true, если какие-то регионы были объединены. + \en Returns true if a pair of regions has been united. \~ + \ingroup Algorithms_2D +*/ +// --- +MATH_FUNC (bool) MakeUnionRegions( RPArray & regions, bool allowSelfTouch = true, bool mergeCurves = true ); + + +#endif // __REGION_H \ No newline at end of file diff --git a/C3d/Include/sheet_metal_param.h b/C3d/Include/sheet_metal_param.h new file mode 100644 index 0000000..da57f9b --- /dev/null +++ b/C3d/Include/sheet_metal_param.h @@ -0,0 +1,1907 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cтруктуры параметров для листовых операций. + \en Structures of parameters for sheet operation. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SHEET_METAL_PARAM_H +#define __SHEET_METAL_PARAM_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbFace; + + +//------------------------------------------------------------------------------ +/** \brief \ru Способ освобождения углов. + \en Way of freeing angles. \~ + \ingroup Build_Parameters +*/ +// --- +enum MbeReleaseType { + rt_No = 0, ///< \ru Без освобождения углов. \en Without freeing angles. + rt_Only, ///< \ru Только сгиб. \en Only bend. + rt_Bend, ///< \ru Сгиб и его продолжение. \en Bend and its extension. + rt_All, ///< \ru Все сгибы. \en All the bends. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры сгиба. + \en The bend parameters. \~ + \details \ru При k = 0.0 внутренняя грань сгиба разгибается без деформаций, при k = 1.0 - внешняя.\n + Параметр radius равен радиусу внутренней цилиндрической грани сгиба, для конического сгиба не определён.\n + Угол сгиба angle используется при создании цилиндрических сгибов в операциях "сгиб по ребру" и "сгиб по линии".\n + Параметр coneAngle равен 0.0 для цилиндрического сгиба и больше 0.0 для конического.\n + \en If k=0.0, then internal face of bend is unbend without deformation, if k = 1.0 - external.\n + The parameter "radius" is equal to radius of inner cylindrical face of bend for conic bend is undefined.\n + Bend angle "angle" is used in the creation of cylindrical bends in the operations of "bend by an edge" and "bend by a line".\n + The parameter coneAngle is equal to 0.0 for cylindrical bend and greater than 0.0 for conical.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbBendValues { +public: + double k; ///< \ru Коэффициент, определяющий положение нейтрального слоя. \en Coefficient determining the position of the neutral layer. + double radius; ///< \ru Внутренний радиус сгиба. \en The internal radius of the bend. + double angle; ///< \ru Угол сгиба. \en The bend angle. + double coneAngle; ///< \ru Угол между осью и боковой образующей конуса. \en The angle between the axis and the side of the cone. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbBendValues() : k( 0.0 ), radius( 0.0 ), angle( 0.0 ), coneAngle( 0.0 ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbBendValues( double coef, double rad, double ang, double coneAng ) : + k ( coef ), + radius ( rad ), + angle ( ang ), + coneAngle( coneAng ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbBendValues( const MbBendValues & other ) : + k ( other.k ), + radius ( other.radius ), + angle ( other.angle ), + coneAngle( other.coneAngle ) { + } + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( double coef, double rad, double ang, double coneAng ) { + k = coef; + radius = rad; + angle = ang; + coneAngle = coneAng; + } + /// \ru Инициализировать по другой структуре. \en Initialize by another structure. + void Init( const MbBendValues & other ) { + k = other.k; + radius = other.radius; + angle = other.angle; + coneAngle = other.coneAngle; + } + /// \ru Оператор присваивания. \en Assignment operator. + const MbBendValues & operator = ( const MbBendValues & other ) { + k = other.k; + radius = other.radius; + angle = other.angle; + coneAngle = other.coneAngle; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbBendValues & other, double accuracy ) const { + bool isSame = false; + + if ( ::fabs( k - other.k ) < accuracy && + ::fabs( radius - other.radius ) < accuracy && + ::fabs( angle - other.angle ) < accuracy && + ::fabs( coneAngle - other.coneAngle ) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbBendValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры построения тела из листового материала. + \en Parameters of solid construction from sheet material. \~ + \details \ru Параметры построения тела из листового материала для операций + "Листовое тело", "Пластина", "Отверстие", "Вырез". \n + Параметр thickness - это толщина листа при выдавливании незамкнутого контура.\n + Глубина выдавливания задаётся в параметрах side1 или side2, в зависимости от направления выдавливания. + Коэффициент нейтрального слоя k нужен для построения листового тела по незамкнутому контуру в разогнутом виде.\n + Параметр radius - это внутренний радиус цилиндрического сгиба, который формируется в месте негладкой стыковки + двух прямолинейных сегментов незамкнутого контура. + \en Parameters of solid construction from sheet material for operation + "Sheet solid", "Plate", "Hole", "Cut". \n + The thickness parameter - is thickness of sheet when extruded of an open contour.\n + Depth of extrusion is given in the parameters side1 and side2 depending on the direction of extrusion. + Coefficient of neutral layer k is necessary for construction of sheet solid by open contour in unbent state.\n + The radius parameter - is inner radius of cylindrical bend which is formed in a non-smooth connection + of two straight segments of open contour. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSheetMetalValues { +public: + double thickness; ///< \ru Толщина. \en The thickness. + double k; ///< \ru Коэффициент, определяющий положение нейтрального слоя. \en Coefficient determining the position of the neutral layer. + double radius; ///< \ru Внутренний радиус сгиба. \en The internal radius of the bend. + MbSweptSide side1; ///< \ru Параметры для стороны, лежащей в направлении нормали к эскизу. \en Parameters for side lying along the direction of normal to the sketch. + MbSweptSide side2; ///< \ru Параметры для противоположной стороны. \en Parameters for the opposite side. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSheetMetalValues() : thickness( 0.0 ), k( 0.0 ), radius( 0.0 ), side1(), side2() {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbSheetMetalValues( const MbSheetMetalValues &other ) : thickness( other.thickness ), k( other.k ), radius( other.radius ), + side1( other.side1 ), side2( other.side2 ) {} + /// \ru Оператор присваивания. \en Assignment operator. + MbSheetMetalValues & operator = ( const MbSheetMetalValues &other ) { + thickness = other.thickness; + k = other.k; + radius = other.radius; + side1 = other.side1; + side2 = other.side2; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSheetMetalValues & other, double accuracy ) const { + bool isSame = false; + + if ( ::fabs( thickness - other.thickness ) < accuracy && + ::fabs( k - other.k ) < accuracy && + ::fabs( radius - other.radius ) < accuracy && + side1.IsSame( other.side1, accuracy ) && + side2.IsSame( other.side2, accuracy ) ) + isSame = true; + + return isSame; + } + + /** \ru \name Функции работы с поверхностями, до которых выдавливать. + \en \name Functions for working with surfaces to which extrude. + \{ */ + /// \ru Получить ограничивающую поверхность в направлении нормали. \en Get bounding surface in direction of normal. + MbSurface * GetSurface1() const { return side1.GetSurface(); } + /// \ru Получить ограничивающую поверхность в противоположном направлении. \en Get bounding surface along the opposite direction. + MbSurface * GetSurface2() const { return side2.GetSurface(); } + + /// \ru Установить ограничивающую поверхность в направлении нормали. \en Set bounding surface along the direction of normal. + void SetSurface1( MbSurface *s ) { side1.SetSurface( s ); } + /// \ru Установить ограничивающую поверхность в противоположном направлении. \en Set bounding surface along the opposite direction. + void SetSurface2( MbSurface *s ) { side2.SetSurface( s ); } + /// \ru Поменять местами ограничивающие выдавливание поверхности. \en Swap bounding extrusions of surfaces. + void ExchangeSurfaces() { + MbSurface *s = side1.GetSurface(); + MbSweptWay w = side1.way; + double d = side1.distance; + if (s!=NULL) + s->AddRef(); + side1.SetSurface( side2.GetSurface() ); + side1.way = side2.way; + side1.distance = side2.distance; + side2.SetSurface( s ); + side2.way = w; + side2.distance = d; + if (s!=NULL) + s->DecRef(); + } + /** \} */ + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbSheetMetalValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры разгрузки сгиба. + \en The parameters of stress relieving of bending. \~ + \details \ru Разгрузка сгиба - это вырезы в базовом листе по обе стороны от места крепления сгиба. \n + Радиус скругления разгрузки задаёт скругление углов этого выреза, находящихся внутри базового листа.\n + \en Unloading of bend - is cuts in the base sheet on both sides of attachment points of bend. \n + Fillet radius of unloading sets fillet of angles of this cut located inside base sheet.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSlotValues { +public: + double width; ///< \ru Ширина разгрузки сгиба. \en The width of bend unloading. + double depth; ///< \ru Глубина разгрузки сгиба. \en The depth of bend unloading. + double radius; ///< \ru Радиус скругления разгрузки. \en The fillet radius of unloading. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSlotValues() : width( 0 ), depth( 0 ), radius( 0 ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbSlotValues( double w, double d, double r ) : width( w ), depth( d ), radius( r ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbSlotValues( const MbSlotValues &other ) : + width ( other.width ), + depth ( other.depth ), + radius( other.radius ) + {} + /// \ru Инициализировать по конкретным параметрам \en Initialize by specific parameters + void Init( double w, double d, double r ) { + width = w; + depth = d; + radius = r; + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbSlotValues &other ) { + width = other.width; + depth = other.depth; + radius = other.radius; + } + /// \ru Оператор присваивания. \en Assignment operator. + const MbSlotValues & operator = ( const MbSlotValues &other ) { + width = other.width; + depth = other.depth; + radius = other.radius; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSlotValues & other, double accuracy ) const { + bool isSame = false; + + if ( ::fabs( width - other.width ) < accuracy && + ::fabs( depth - other.depth ) < accuracy && + ::fabs( radius - other.radius ) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbSlotValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры построения сгиба по линии для операции "Сгиб по линии". + \en The parameter of bend construction by line for operation "Bend by a line". \~ + \details \ru Смещение сгиба определяет величину отступа начала сгиба от прямолинейного эскиза + в одну или другую сторону вдоль сгибаемой поверхности в зависимости от знака.\n + Параметр leftFixed определяет с какой стороны от прямолинейного эскиза будет лежать несгибаемая часть листа.\n + \en Displacement of bending determines value of indent of beginning of bend from a straight sketch + to one side or other along a bendable surface depending on the sign. \n + LeftFixed parameter determines which side of the straight sketch will lie unbendable part of the sheet.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbBendOverSegValues : public MbBendValues { +public: + double displacement; ///< \ru Смещение сгиба. \en The displacement of bending. + bool leftFixed; ///< \ru Неподвижная часть грани. \en The fixed part of face. + MbeReleaseType type; ///< \ru Способ освобождения углов. \en Way of freeing angles. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbBendOverSegValues() : MbBendValues(), displacement( 0.0 ), leftFixed( true ), type( rt_No ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbBendOverSegValues( double coef, double rad, double ang, double coneAng, double displ, bool left, MbeReleaseType tp ) : + MbBendValues( coef, rad, ang, coneAng ), + displacement( displ ), + leftFixed( left ), + type( tp ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbBendOverSegValues( const MbBendOverSegValues &other ) : + MbBendValues( other ), + displacement( other.displacement ), + leftFixed( other.leftFixed ), + type( other.type ) + {} + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( double coef, double rad, double ang, double coneAng, double displ, bool left, MbeReleaseType tp ) { + MbBendValues::Init( coef, rad, ang, coneAng ); + displacement = displ; + leftFixed = left; + type = tp; + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbBendOverSegValues &other ) { + MbBendValues::Init( other ); + displacement = other.displacement; + leftFixed = other.leftFixed; + type = other.type; + } + /// \ru Оператор присваивания. \en Assignment operator. + MbBendOverSegValues & operator = ( const MbBendOverSegValues &other ) { + MbBendValues::Init( other ); + displacement = other.displacement; + leftFixed = other.leftFixed; + type = other.type; + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbBendOverSegValues & other, double accuracy ) const { + bool isSame = false; + + if ( leftFixed == other.leftFixed && + type == other.type && + ::fabs( displacement - other.displacement ) < accuracy && + MbBendValues::IsSame( other, accuracy ) ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbBendOverSegValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры для операции "подсечка". + \en The parameters for operation "undercutting". \~ + \details \ru Высота подсечки - это расстояние от неподвижной части сгибаемой поверхности до её подвижной части после выполнения операции.\n + При включенном режиме добавления материала подсечка выполняется методом штамповки + листа с неизменной длиной проекции детали на плоскость неподвижной грани. + В разогнутом состоянии такая деталь будет тем длиннее, чем больше высота подсечки. + При выключенном режиме добавления материала подсечка выполняется двумя сгибами, + и соответственно проекция детали на плоскость неподвижной грани укорачивается. + Параметр byInnerSide влияет на способ добавления материала. + \en Height of undercutting - is distance from fixed part of unbendable surface to its movable part after operation.\n + If the addition mode of material is enabled, then undercutting is performed by method of stamping + of sheet with a constant length of the part projection on the plane of the fixed face. + In unbent state this detail will be longer as the greater height of undercutting. + If the addition mode of material isn't enabled, then undercutting is performed by two methods, + and accordingly the detail projection on the plane of fixed face is shortened. + The byInnerSide parameter affects the way of adding material. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbJogValues : public MbBendOverSegValues { + double elevation; ///< \ru Высота подсечки. \en A jog height. + bool addMaterial; ///< \ru Вкл./откл. режим добавления материала. \en On/off mode of material adding. + bool byInnerSide; ///< \ru Линия подсечки находится внутри/снаружи первого сгиба. \en Jog line is inside/outside of the first bend. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbJogValues() : MbBendOverSegValues(), elevation( 0.0 ), addMaterial( true ), byInnerSide( true ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbJogValues( double coef, double rad, double ang, double displ, bool left, MbeReleaseType tp, double elev, bool addMat, bool byInner ) : + MbBendOverSegValues( coef, rad, ang, 0.0/*coneAng*/, displ, left, tp ), + elevation( elev ), + addMaterial( addMat ), + byInnerSide( byInner ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbJogValues( const MbJogValues &other ) : + MbBendOverSegValues( other ), + elevation( other.elevation ), + addMaterial( other.addMaterial ), + byInnerSide( other.byInnerSide ) + {} + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( double coef, double rad, double ang, double displ, bool left, MbeReleaseType tp, double elev, bool addMat, bool byInner ) { + MbBendOverSegValues::Init( coef, rad, ang, 0.0/*coneAng*/, displ, left, tp ); + elevation = elev; + addMaterial = addMat; + byInnerSide = byInner; + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbJogValues &other ) { + MbBendOverSegValues::Init( other ); + elevation = other.elevation; + addMaterial = other.addMaterial; + byInnerSide = other.byInnerSide; + } + /// \ru Оператор присваивания. \en Assignment operator. + MbJogValues & operator = ( const MbJogValues &other ) { + MbBendOverSegValues::Init( other ); + elevation = other.elevation; + addMaterial = other.addMaterial; + byInnerSide = other.byInnerSide; + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbJogValues & other, double accuracy ) const { + bool isSame = false; + + if ( addMaterial == other.addMaterial && + byInnerSide == other.byInnerSide && + ::fabs( elevation - other.elevation ) < accuracy && + MbBendOverSegValues::IsSame( other, accuracy ) ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbJogValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры замыкания сгиба. + \en The bend closure parameters. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbClosedCornerValues { + /** \brief \ru Cпособ построения. + \en Way of construction. \~ + \ingroup Build_Parameters + */ + enum MbeCloseCornerWay { + ccRip, ///< \ru Замыкание встык. \en Closing butt. + ccOverlap, ///< \ru Замыкание с перекрытием. \en Closing with overlapping. + ccTight ///< \ru Плотное замыкание. \en Dense closure. + }; + + /** \brief \ru Обработка углов. + \en Processing of angles. \~ + \ingroup Build_Parameters + */ + enum MbeCloseBendsWay { + cbNone, ///< \ru Без обработки. \en Without processing. + cbChord, ///< \ru По хорде. \en By chord. + cbEdge, ///< \ru По кромке. \en By fillet. + cbCircle ///< \ru Круговая обработка. \en Circular processing. + }; + + /** \brief \ru Размещение отверстия (при круговой обработке углов). + \en Disposition of the circle (for circular processing of angles). \~ + \ingroup Build_Parameters + */ + enum MbeCloseBendsCirclePos { + cpBend, ///< \ru По центру сгиба. \en At bends center. + cpAngle, ///< \ru По точке угла. \en At angle point. + cpPoint ///< \ru Через точку угла. \en Through angle point. + }; + + MbeCloseCornerWay cornerWay; ///< \ru Способ построения. \en Way of construction. + std::vector bendsWay; ///< \ru Обработка углов. \en Processing of angles. + MbeCloseBendsCirclePos circlePos; ///< \ru Размещение отверстия (при круговой обработке углов). \en Disposition of the circle (for circular processing of angles). + double gap; ///< \ru Зазор. \en Gap. + double diameter; ///< \ru Диаметр отверстия (при круговой обработке углов). \en Diameter of the circle (for circular processing of angles). + double shift; ///< \ru Сдвиг отверстия (при круговой обработке углов). \en Shift of the circle (for circular processing of angles). + double kPlus; ///< \ru Коэффициент нейтрального слоя для сгиба, лежащего слева от ребра. \en Neutral layer coefficient for bend lying on the left of the edge. + double kMinus; ///< \ru Коэффициент нейтрального слоя для сгиба, лежащего справа от ребра. \en Neutral layer coefficient for bend lying on the right of the edge. + double angle; ///< \ru Угол замыкания для обработки только с одной стороны. \en Closure angle for processing only one side. + bool plus; ///< \ru Перекрывающая часть находится слева от общего ребра (для способа ccOverlap). \en Overlapping part is on the left side of the common edge (for the method ccOverlap). + bool prolong; ///< \ru С продолжением. \en With continuation. + bool acrossBend; ///< \ru Замыкание через сгиб (для замыкания с одной стороны). \en Closure by bend (for closing on one side). + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbClosedCornerValues() + : cornerWay( ccRip ), bendsWay(), circlePos( cpBend ), gap( 0.0 ), diameter( 0.0 ), shift( 0.0 ), kPlus( 0.5 ), kMinus( 0.5 ), + angle( M_PI_2 ), plus( true ), prolong( false ), acrossBend( false ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbClosedCornerValues( MbeCloseCornerWay cc, MbeCloseBendsWay cb, MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool ab ) + : cornerWay( cc ), bendsWay(), circlePos( cp ), gap( g ), diameter( dm ), shift( sh ), + kPlus( kP ), kMinus( kM ), angle( ang ), plus( pl ), prolong( pr ), acrossBend( ab ) { bendsWay.clear(); bendsWay.push_back(cb); } + /// \ru Конструктор копирования. \en Copy-constructor. + MbClosedCornerValues( const MbClosedCornerValues &other ) + : cornerWay( other.cornerWay ), bendsWay( other.bendsWay ), circlePos( other.circlePos ), + gap( other.gap ), diameter( other.diameter ), shift( other.shift ), + kPlus( other.kPlus ), kMinus( other.kMinus ), angle( other.angle), + plus( other.plus ), prolong( other.prolong ), acrossBend( other.acrossBend ) {} + + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( MbeCloseCornerWay cc, MbeCloseBendsWay cb, MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool ab ) { + cornerWay = cc; + bendsWay.clear(); + bendsWay.push_back( cb ); + circlePos = cp; + gap = g; + diameter = dm; + shift = sh; + kPlus = kP; + kMinus = kM; + angle = ang; + plus = pl; + prolong = pr; + acrossBend = ab; + } + + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbClosedCornerValues &other ) { + cornerWay = other.cornerWay; + bendsWay = other.bendsWay; + circlePos = other.circlePos; + gap = other.gap; + diameter = other.diameter; + shift = other.shift; + kPlus = other.kPlus; + kMinus = other.kMinus; + angle = other.angle; + plus = other.plus; + prolong = other.prolong; + acrossBend = other.acrossBend; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbClosedCornerValues & operator = ( const MbClosedCornerValues &other ) { Init( other ); return *this; } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbClosedCornerValues & other, double accuracy ) const { + bool isSame = false; + + if ( plus == other.plus && + prolong == other.prolong && + acrossBend == other.acrossBend && + cornerWay == other.cornerWay && + circlePos == other.circlePos && + ::fabs( gap - other.gap ) < accuracy && + ::fabs( diameter - other.diameter ) < accuracy && + ::fabs( shift - other.shift ) < accuracy && + ::fabs( kPlus - other.kPlus ) < accuracy && + ::fabs( kMinus - other.kMinus ) < accuracy && + ::fabs( angle - other.angle ) < accuracy && + bendsWay == other.bendsWay ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbClosedCornerValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры замыкания сгиба с флагом выполнения. + \en The bend closure parameters with the performing closure flag. \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbMiterValues : public MbClosedCornerValues { + bool allow; ///< \ru Флаг выполнения замыкания. \en Flag of performing closure. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbMiterValues() : MbClosedCornerValues(), allow( false ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbMiterValues( MbeCloseCornerWay cc, MbeCloseBendsWay cb, MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool al, bool ab ) + : MbClosedCornerValues( cc, cb, cp, g, dm, sh, kP, kM, ang, pl, pr, ab ), allow( al ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbMiterValues( const MbMiterValues & other ) + : MbClosedCornerValues( other ), allow( other.allow ) {} + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( MbeCloseCornerWay cc, MbeCloseBendsWay cb, MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool al, bool ab ) { + MbClosedCornerValues::Init( cc, cb, cp, g, dm, sh, kP, kM, ang, pl, pr, ab ); + allow = al; + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init ( const MbMiterValues & other ) { + MbClosedCornerValues::Init( other ); + allow = other.allow; + } + /// \ru Оператор присваивания. \en Assignment operator. + MbMiterValues & operator = ( const MbMiterValues & other ) { Init( other ); return *this; } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbMiterValues & other, double accuracy ) const { + bool isSame = false; + + if ( allow == other.allow && + MbClosedCornerValues::IsSame( other, accuracy ) ) + isSame = true; + + return isSame; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры построения сгиба для операции "Сгиб по ребру". + \en The parameter of bend construction for operation "Bend by an edge". \~ + \details \ru Положительные значения увеличивают "тело" сгиба.\n + \en Positive values increase the "solid" of bend.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbBendByEdgeValues : public MbBendValues { +public: + /** \brief \ru Параметры одного края сгиба. + \en Parameters of one boundary of bend. \~ + \details \ru Положительные значения увеличивают "тело" сгиба. + \en Positive values increase the "solid" of bend. \~ + \ingroup Build_Parameters + */ + struct MATH_CLASS MbSide { + public: + double distance; ///< \ru Отступ от края ребра. \en Distance from boundary of edge. + double angle; ///< \ru Угол уклона края сгиба. \en Draft angle of bend boundary. + double deviation; ///< \ru Угол уклона продолжения (плоской части) сгиба. \en Draft angle of bend extension (the planar part). + double widening; ///< \ru Расширение продолжения (плоской части) сгиба. \en Expanding of bend extension (the planar part). + double length; ///< \ru Длина продолжения (плоской части) сгиба. \en Length of bend extension (the planar part). + + public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSide() : distance( 0 ), angle( 0 ), deviation( 0 ), widening( 0 ), length ( 0 ) {} + /// \ru Конструктор по длине продолжения. \en Default by length of extension. + MbSide( double len ) : distance( 0 ), angle( 0 ), deviation( 0 ), widening( 0 ), length ( len ) {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbSide( const MbSide &other ) : + distance( other.distance ), angle( other.angle ), deviation( other.deviation ), widening( other.widening ), length ( other.length ) + {} + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( double dis, double a, double dev, double w, double l ) { + distance = dis; angle = a; deviation = dev; widening = w; length = l; + } + /// \ru Оператор присваивания. \en Assignment operator. + const MbSide & operator = ( const MbSide &other ) { + distance = other.distance; + angle = other.angle; + deviation = other.deviation; + widening = other.widening; + length = other.length; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSide & other, double accuracy ) const { + bool isSame = false; + + if ( ::fabs( distance - other.distance ) < accuracy && + ::fabs( angle - other.angle ) < accuracy && + ::fabs( deviation - other.deviation ) < accuracy && + ::fabs( widening - other.widening ) < accuracy && + ::fabs( length - other.length ) < accuracy ) + isSame = true; + + return isSame; + } + }; // \ru Параметры одного края сгиба \en Parameters of one boundary of bend + +public: + double deepness; ///< \ru Смещение сгиба (расстояние от ребра до начала сгиба). \en Displacement of bend (the distance from the edge to the start of the bend). + MbSide sideLeft; ///< \ru Параметры левого края сгиба. \en Parameters of the left boundary of bend. + MbSide sideRight; ///< \ru Параметры правого края сгиба. \en Parameters of the first boundary of bend. + MbMiterValues miterBegin; ///< \ru Параметры края в начале. \en The parameters of boundary at the beginning. + MbMiterValues miterEnd; ///< \ru Параметры края в конце. \en The parameters of boundary at the end. + MbMiterValues miterMiddle; ///< \ru Параметры замыкания углов. \en The enclosure parameters of angles. + MbSlotValues slot; ///< \ru Разгрузкa сгиба. \en Bend unloading. + MbeReleaseType type; ///< \ru Способ освобождения углов. \en Way of freeing angles. + +public: + /// \ru Конструктор по-умолчанию. \en Default constructor. + MbBendByEdgeValues() : MbBendValues(), deepness( 0 ), sideLeft(), sideRight(), miterBegin(), miterEnd(), miterMiddle(), slot(), type( rt_No ) {} + /// \ru Конструктор по конкретным параметрам (правая и левая стороены края продолжения одной длины). \en Constructor by specific parameters. + MbBendByEdgeValues( double coef, double rad, double ang, double coneAng, double len, double d, MbeReleaseType tp ) : + MbBendValues( coef, rad, ang, coneAng ), + deepness ( d ), + sideLeft ( len ), + sideRight ( len ), + miterBegin (), + miterEnd (), + miterMiddle(), + slot (), + type ( tp ) { + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbBendByEdgeValues( double coef, double rad, double ang, double coneAng, double lenL, double lenR, double d, MbeReleaseType tp ) : + MbBendValues( coef, rad, ang, coneAng ), + deepness ( d ), + sideLeft ( lenL ), + sideRight ( lenR ), + miterBegin (), + miterEnd (), + miterMiddle(), + slot (), + type ( tp ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbBendByEdgeValues( const MbBendByEdgeValues &other ) : + MbBendValues( other ), + deepness ( other.deepness ), + sideLeft ( other.sideLeft ), + sideRight ( other.sideRight ), + miterBegin ( other.miterBegin ), + miterEnd ( other.miterEnd ), + miterMiddle( other.miterMiddle ), + slot ( other.slot ), + type ( other.type ) { + } + /// \ru Инициализировать параметры сгиба. \en Initialize the parameters of bend. + void SheetMetalInit( double coef, double rad, double ang, double coneAng ) { + MbBendValues::Init( coef, rad, ang, coneAng ); + } + /// \ru Инициализировать длину, смещение и тип освобождения сгиба. \en Initialize the length, shift and type of freeing bend. + void BendInit( double len, double d, MbeReleaseType tp ) { + sideLeft.length = len; + sideRight.length = len; + + deepness = d; + type = tp; + } + /// \ru Инициализировать левую сторону сгиба. \en Initialize the left side of bend. + void SideLeftInit( double dis, double a, double dev, double w ) { + sideLeft.Init( dis, a, dev, w, sideLeft.length ); + } + /// \ru Инициализировать правую сторону сгиба. \en Initialize the first side of bend. + void SideRightInit( double dis, double a, double dev, double w ) { + sideRight.Init( dis, a, dev, w, sideRight.length ); + } + /// \ru Инициализировать левую сторону сгиба. \en Initialize the left side of bend. + void SideLeftInit( double dis, double a, double dev, double w, double l ) { + sideLeft.Init( dis, a, dev, w, l ); + } + /// \ru Инициализировать правую сторону сгиба. \en Initialize the first side of bend. + void SideRightInit( double dis, double a, double dev, double w, double l ) { + sideRight.Init( dis, a, dev, w, l ); + } + /// \ru Инициализировать параметры разгрузки сгиба. \en Initialize the parameters of bend unloading. + void SlotInit( double w, double d, double r ) { + slot.Init( w, d, r ); + } + /// \ru Инициализировать замыкание угла в начале цепочки рёбер. \en Initialize corner closing at the beginning of the chain of edges. + void MiterBeginInit( MbClosedCornerValues::MbeCloseCornerWay cc, MbClosedCornerValues::MbeCloseBendsWay cb, MbClosedCornerValues::MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool al, bool ab ) { + miterBegin.Init( cc, cb, cp, g, dm, sh, kP, kM, ang, pl, pr, al, ab ); + } + /// \ru Инициализировать замыкание угла в конце цепочки рёбер. \en Initialize corner closing at the end of the chain of edges. + void MiterEndInit( MbClosedCornerValues::MbeCloseCornerWay cc, MbClosedCornerValues::MbeCloseBendsWay cb, MbClosedCornerValues::MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool al, bool ab ) { + miterEnd.Init( cc, cb, cp, g, dm, sh, kP, kM, ang, pl, pr, al, ab ); + } + /// \ru Инициализировать замыкание угла в середине цепочки рёбер. \en Initialize corner closing in the middle of the chain of edges. + void MiterMiddleInit( MbClosedCornerValues::MbeCloseCornerWay cc, MbClosedCornerValues::MbeCloseBendsWay cb, MbClosedCornerValues::MbeCloseBendsCirclePos cp, double g, double dm, double sh, + double kP, double kM, double ang, bool pl, bool pr, bool al, bool ab ) { + miterMiddle.Init( cc, cb, cp, g, dm, sh, kP, kM, ang, pl, pr, al, ab ); + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbBendByEdgeValues &other ) { + MbBendValues::Init( other ); + deepness = other.deepness; + sideLeft = other.sideLeft; + sideRight = other.sideRight; + miterBegin = other.miterBegin; + miterEnd = other.miterEnd; + miterMiddle = other.miterMiddle; + slot = other.slot; + type = other.type; + } + /// \ru Оператор присваивания. \en Assignment operator. + const MbBendByEdgeValues & operator = ( const MbBendByEdgeValues &other ) { + MbBendValues::Init( other ); + deepness = other.deepness; + sideLeft = other.sideLeft; + sideRight = other.sideRight; + miterBegin = other.miterBegin; + miterEnd = other.miterEnd; + miterMiddle = other.miterMiddle; + slot = other.slot; + type = other.type; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbBendByEdgeValues & other, double accuracy ) const { + bool isSame = false; + + if ( type == other.type && + MbBendValues::IsSame( other, accuracy ) && + ::fabs( deepness - other.deepness ) < accuracy && + sideLeft.IsSame( other.sideLeft, accuracy ) && + sideRight.IsSame( other.sideRight, accuracy ) && + miterBegin.IsSame( other.miterBegin, accuracy ) && + miterEnd.IsSame( other.miterEnd, accuracy ) && + miterMiddle.IsSame( other.miterMiddle, accuracy ) && + slot.IsSame( other.slot, accuracy ) ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbBendByEdgeValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры комбинированного сгиба. + \en The parameters of combined bend. \~ + \details \ru Параметры комбинированного сгиба (сгиба по эскизу). \n + Положительные значения параметров distanceBegin и distanceEnd увеличивают "тело" сгиба, а отрицательные - уменьшают.\n + \en The parameters of combined bend (bend by sketch). \n + Positive values of parameters distanceBegin and distanceEnd increase the "solid" of bend and negative - decrease.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbJointBendValues : public MbBendValues { + double distanceBegin; ///< \ru Отступ от начала ориентированного ребра, принадлежащего листовой грани. \en Distance from beginning of the oriented edge owned sheet face. + double distanceEnd; ///< \ru Отступ от конца ориентированного ребра, принадлежащего листовой грани. \en Distance from end of the oriented edge owned sheet face. + MbMiterValues miterBegin; ///< \ru Параметры края в начале. \en The parameters of boundary at the beginning. + MbMiterValues miterEnd; ///< \ru Параметры края в конце. \en The parameters of boundary at the end. + MbMiterValues miterMiddle; ///< \ru Параметры замыкания углов. \en The enclosure parameters of angles. + MbSlotValues slotValues; ///< \ru Разгрузкa сгиба. \en Bend unloading. + MbeReleaseType releaseType; ///< \ru Способ освобождения углов. \en Way of freeing angles. + + /// \ru Конструктор по-умолчанию. \en Default constructor. + MbJointBendValues() + : MbBendValues (), + distanceBegin( 0.0 ), + distanceEnd ( 0.0 ), + miterBegin (), + miterEnd (), + miterMiddle (), + slotValues (), + releaseType ( rt_No ) { + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbJointBendValues( double coef, double bendRad, double distBeg, double distEnd, bool plus, + MbClosedCornerValues::MbeCloseCornerWay ccb, MbClosedCornerValues::MbeCloseBendsWay cbb, MbClosedCornerValues::MbeCloseBendsCirclePos cpb, + double gapb, double dmb, double shb, double angb, bool alb, bool abb, + MbClosedCornerValues::MbeCloseCornerWay cce, MbClosedCornerValues::MbeCloseBendsWay cbe, MbClosedCornerValues::MbeCloseBendsCirclePos cpe, + double gape, double dme, double she, double ange, bool ale, bool abe, + MbClosedCornerValues::MbeCloseCornerWay ccm, MbClosedCornerValues::MbeCloseBendsWay cbm, MbClosedCornerValues::MbeCloseBendsCirclePos cpm, + double gapm, double dmm, double shm, bool alm, + double width, double depth, double relRad, MbeReleaseType rt ) + : MbBendValues ( coef, bendRad, 0.0/*angle*/, 0.0/*coneAng*/ ), + distanceBegin( distBeg ), + distanceEnd ( distEnd ), + miterBegin ( ccb, cbb, cpb, gapb, dmb, shb, coef, coef, angb, plus, true/*prolong*/, alb, abb ), + miterEnd ( cce, cbe, cpe, gape, dme, she, coef, coef, ange, plus, true/*prolong*/, ale, abe ), + miterMiddle ( ccm, cbm, cpm, gapm, dmm, shm, coef, coef, 0.0, plus, true/*prolong*/, alm, false/*acrossBend*/ ), + slotValues ( width, depth, relRad ), + releaseType ( rt ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbJointBendValues( const MbJointBendValues & other ) + : MbBendValues ( other ), + distanceBegin( other.distanceBegin ), + distanceEnd ( other.distanceEnd ), + miterBegin ( other.miterBegin ), + miterEnd ( other.miterEnd ), + miterMiddle ( other.miterMiddle ), + slotValues ( other.slotValues ), + releaseType ( other.releaseType ) { + } + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbJointBendValues & other ) { + MbBendValues::Init( other ); + distanceBegin = other.distanceBegin; + distanceEnd = other.distanceEnd; + miterBegin = other.miterBegin; + miterEnd = other.miterEnd; + miterMiddle = other.miterMiddle; + slotValues = other.slotValues; + releaseType = other.releaseType; + } + /// \ru Оператор присваивания. \en Assignment operator. + MbJointBendValues & operator = ( const MbJointBendValues & other ) { + Init( other ); + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbJointBendValues & other, double accuracy ) const { + bool isSame = false; + + if ( releaseType == other.releaseType && + MbBendValues::IsSame( other, accuracy ) && + ::fabs( distanceBegin - other.distanceBegin ) < accuracy && + ::fabs( distanceEnd - other.distanceEnd ) < accuracy && + miterBegin.IsSame( other.miterBegin, accuracy ) && + miterEnd.IsSame( other.miterEnd, accuracy ) && + miterMiddle.IsSame( other.miterMiddle, accuracy ) && + slotValues.IsSame( other.slotValues, accuracy ) ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbJointBendValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры штамповки. + \en The parameters of stamping. \~ + \details \ru Эскиз штамповки задаёт конфигурацию её донышка. Штамповка строится по замкнутому или незамкнутому контуру. + Замкнутый контур может целиком лежать внутри листовой грани, а может частично выходить за её пределы. + Оба конца незамкнутого контура обязаны лежать за пределами штампуемой листовой грани.\n + В зависимости от параметра wallInside боковые стенки штамповки располагаются внутри или снаружи от эскиза.\n + Высота штамповки - это расстояние от плоскости листа до соответствующей ей выдавленной части штамповки.\n + Параметр angle - это угол отклонения боковых стенок штамповки от вертикали в радианах.\n + Параметр leftFixed указывает сторону эскиза, которая будет выштамповываться, а reverse - направление штамповки - по нормали к плоской грани или против.\n + В случае открытой штамповки лист пробивается насквозь.\n + \en Sketch of stamping sets the configuration of its bottom. Stamping is constructed by open or closed contour. + Closed closed can lie entirely inside sheet face and can partially go out of its bounds. + Both ends of open contour must lie outside of the stamped sheet face.\n + Depending on the parameter wallInside the stamping sidewalls are located inside or outside from sketch.\n + Height of stamping - is distance from plane of sheet to corresponding extruded part of stamping.\n + The angle parameter - is the angle of sidewalls deviation of stamping from the vertical in radians.\n + The leftFixed parameter indicates the side of the sketch which will be stamped and "reverse" - the direction of stamping along the normal to the planar face or along opposite to the normal. \n + If stamping is open, then sheet makes its way through and through.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbStampingValues { + double hight; ///< \ru Высота штамповки. \en Stamping height. + double angle; ///< \ru Угол наклона боковых стенок штамповки. \en Slope angle of stamping sidewalls. + double sketchFilletRadius; ///< \ru Радиус скругления эскиза (отрицательное значение запрещает скругление). \en Fillet radius of sketch (negative value prohibits fillet). + double baseFilletRadius; ///< \ru Радиус скругления основания (отрицательное значение запрещает скругление). \en Fillet radius of base (negative value prohibits fillet). + double bottomFilletRadius; ///< \ru Радиус скругления дна (отрицательное значение запрещает скругление). \en Fillet radius of bottom (negative value prohibits fillet). + bool wallInside; ///< \ru Боковая стенка внутри. \en The sidewall is inside. + bool leftFixed; ///< \ru Изменяется геометрия справа от эскиза. \en Geometry changes to the right of the sketch. + bool reverse; ///< \ru Направление построения штамповки. \en Direction of stamping construction. + bool open; ///< \ru Открытая штамповка. \en Open stamping. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbStampingValues() : + hight ( 0.0 ), + angle ( 0.0 ), + sketchFilletRadius( 0.0 ), + baseFilletRadius ( 0.0 ), + bottomFilletRadius( 0.0 ), + wallInside ( true ), + leftFixed ( true ), + reverse ( false ), + open ( true ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbStampingValues( const MbStampingValues &other ) : + hight ( other.hight ), + angle ( other.angle ), + sketchFilletRadius( other.sketchFilletRadius ), + baseFilletRadius ( other.baseFilletRadius ), + bottomFilletRadius( other.bottomFilletRadius ), + wallInside ( other.wallInside ), + leftFixed ( other.leftFixed ), + reverse ( other.reverse ), + open ( other.open ) { + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbStampingValues( double h, double ang, double sketchRad, double baseRad, double bottomRad, + bool inside, bool left, bool rev, bool op ) : + hight ( h ), + angle ( ang ), + sketchFilletRadius( sketchRad ), + baseFilletRadius ( baseRad ), + bottomFilletRadius( bottomRad ), + wallInside ( inside ), + leftFixed ( left ), + reverse ( rev ), + open ( op ) { + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbStampingValues & operator = ( const MbStampingValues &other ) { Init( other ); return *this; } + /// \ru Инициализация по другому объекту. \en Initialization by another object. + void Init( const MbStampingValues &other ) { + hight = other.hight; + angle = other.angle; + sketchFilletRadius = other.sketchFilletRadius; + baseFilletRadius = other.baseFilletRadius; + bottomFilletRadius = other.bottomFilletRadius; + wallInside = other.wallInside; + leftFixed = other.leftFixed; + reverse = other.reverse; + open = other.open; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbStampingValues & other, double accuracy ) const { + bool isSame = false; + + if ( wallInside == other.wallInside && + leftFixed == other.leftFixed && + reverse == other.reverse && + open == other.open && + ::fabs( hight - other.hight ) < accuracy && + ::fabs( angle - other.angle ) < accuracy && + ::fabs( sketchFilletRadius - other.sketchFilletRadius ) < accuracy && + ::fabs( baseFilletRadius - other.baseFilletRadius ) < accuracy && + ::fabs( bottomFilletRadius - other.bottomFilletRadius ) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbStampingValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры буртика. + \en The bead parameters. \~ + \details \ru Буртик строится по замкнутому или незамкнутому контуру. На концах незамкнутого контура строятся законцовки, + форма которых определяется параметром endType. Форма самого буртика определяется параметром beadType.\n + Высота буртика - это расстояние от плоской грани, на которой он строится, до самой дальней от неё точки буртика.\n + Параметор bottomWidth определяет ширину донышка U-образного буртика.\n + Параметр angle определяет угол отклонения боковых стенок от вертикали в радианах. Если высота, радиус скругления + дна и основания таковы, что боковые стенки отсутствуют, параметр angle игнорируется.\n + Параметр reverse определяет направление построения - по нормали к плоской грани в случае false или против в случае true.\n + \en Bead is constructed by open or closed contour. Tips are constructed at the ends of open contour, + shape of which is defined by endType parameter. Shape of the bead is defined by beadType parameter.\n + Height of the bead - is the distance from planar face on which it is constructed to the farthest point of bead.\n + The bottomWidth parameter defines the bottom width of U-shaped bead.\n + The angle parameter defines the deviation angle of sidewalls from the vertical in radians. If the height, fillet radius + of the bottom and the base such that the sidewalls are absent, then angle parameter is ignored. \n + The reverse parameter determines the direction of construction - along the normal to planar face if false or along opposite to the normal if true.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbBeadValues { + /** \brief \ru Тип буртика. + \en Type of the bead. \~ + \ingroup Build_Parameters + */ + enum MbeBeadType { + btRound = 0, ///< \ru Круглый. \en Circular. + btVType, ///< \ru V-образный. \en V-shaped. + btUType, ///< \ru U-образный. \en U-shaped. + btHalfRound ///< \ru Полукруглый (для вытянутых жалюзи). \en Semicircular (for elongated jalousie). + }; + + /** \brief \ru Тип законцовки буртика. + \en Type of bead tip. \~ + \ingroup Build_Parameters + */ + enum MbeBeadEndType { + betClosed, ///< \ru Закрытый. \en Closed. + betChopped, ///< \ru Рубленый. \en Chopped. + }; + + double hight; ///< \ru Высота буртика. \en Height of the bead. + double bottomWidth; ///< \ru Ширина выпуклой части. \en Width of the convex part. + double baseFilletRadius; ///< \ru Радиус скругления основания. \en Fillet radius of the base. + double bottomFilletRadius; ///< \ru Радиус скругления дна. \en Fillet radius of the bottom. + double angle; ///< \ru Угол уклона боковых стенок. \en Draft angle of sidewalls. + double gap; ///< \ru Зазор рубленой законцовки. \en Gap of chopped tip. + bool reverse; ///< \ru Направление построения буртика. \en Direction of the bead construction. + MbeBeadType beadType; ///< \ru Тип буртика. \en Type of the bead. + MbeBeadEndType endType; ///< \ru Тип законцовки. \en Type of tip. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbBeadValues() + : hight ( 0.0 ), + bottomWidth ( 0.0 ), + baseFilletRadius ( 0.0 ), + bottomFilletRadius( 0.0 ), + angle ( 0.0 ), + gap ( 0.0 ), + reverse ( false ), + beadType ( btRound ), + endType ( betClosed ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbBeadValues( const MbBeadValues & other ) + : hight ( other.hight ), + bottomWidth ( other.bottomWidth ), + baseFilletRadius ( other.baseFilletRadius ), + bottomFilletRadius( other.bottomFilletRadius ), + angle ( other.angle ), + gap ( other.gap ), + reverse ( other.reverse ), + beadType ( other.beadType ), + endType ( other.endType ) { + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbBeadValues( double h, double bottomW, double baseR, double bottomR, + double ang, double g, bool rev, MbeBeadType bt, MbeBeadEndType bet ) + : hight ( h ), + bottomWidth ( bottomW ), + baseFilletRadius ( baseR ), + bottomFilletRadius( bottomR ), + angle ( ang ), + gap ( g ), + reverse ( rev ), + beadType ( bt ), + endType ( bet ) { + } + + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbBeadValues & other ) { + hight = other.hight; + bottomWidth = other.bottomWidth; + baseFilletRadius = other.baseFilletRadius; + bottomFilletRadius = other.bottomFilletRadius; + angle = other.angle; + gap = other.gap; + reverse = other.reverse; + beadType = other.beadType; + endType = other.endType; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbBeadValues & operator = ( const MbBeadValues & other ) { Init( other ); return *this; } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbBeadValues & other, double accuracy ) const { + bool isSame = false; + + if ( reverse == other.reverse && + beadType == other.beadType && + endType == other.endType && + ::fabs( hight - other.hight ) < accuracy && + ::fabs( bottomWidth - other.bottomWidth ) < accuracy && + ::fabs( baseFilletRadius - other.baseFilletRadius ) < accuracy && + ::fabs( bottomFilletRadius - other.bottomFilletRadius ) < accuracy && + ::fabs( angle - other.angle ) < accuracy && + ::fabs( gap - other.gap ) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbBeadValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры жалюзи. + \en The parameters of jalousie. \~ + \details \ru Жалюзи строятся по одному или нескольким отрезкам.\n + Если параметр stretching имеет значение false - жалюзи строятся в виде отогнутой пластины, иначе - с полукруглым профилем.\n + Высота жалюзи - это расстояние от плоской грани до самой верхней точки жалюзи. Ширина - это поперечный размер вырубаемого в листе выреза + без учёта радиуса скругления.\n + Коэффициент нейтрального слоя k учитывается при расчёте поперечного размера отогнутого жалюзи.\n + При значении параметра reverse - false, жалюзи строятся в направлении нормали листовой грани, true - в противоположном направлении.\n + Параметр normToThick определяет форму конца отогнутых жалюзи, при значении true - законцовка строится вдоль нормали к отогнутой пластине, + при значении false - вдоль нормали к базовой листовой грани.\n + \en Jalousie are built from one or more segments.\n + If stretching parameter has value false - jalousie is built in the form of the bent plate, otherwise - with a semicircular profile.\n + Height of jalousie - is the distance from planar face to the uppermost of jalousie point. Width - is transverse size of cut in the sheet + without taking into account the fillet radius.\n + Coefficient of neutral layer-k is taken into account when calculating the transverse size of the deflected jalousie.\n + If reverse = false, then jalousie is built along the normal direction of sheet face, true - along the opposite direction.\n + The normToThick parameter defines the shape of end of the deflected jalousie, if true - the tip is built along the normal to the deflected plate, + if false - along the normal to the base sheet face.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbJalousieValues { + double width; ///< \ru Ширина. \en Width. + double hight; ///< \ru Высота. \en Height. + double filletRadius; ///< \ru Радиус скругления. \en The fillet radius. + double k; ///< \ru Коэффициент, определяющий положение нейтрального слоя. \en Coefficient determining the position of the neutral layer. + bool reverse; ///< \ru Направление построения жалюзи. \en Direction of jalousie construction. + bool leftSide; ///< \ru Сторона отрезка, по которой строятся жалюзи. \en The segment side which jalousie are constructed by. + bool stretching; ///< \ru Вытяжка. \en Stretch. + bool normToThick; ///< \ru По нормали к толщине. \en Along the normal to thickness. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbJalousieValues() + : width ( 0.0 ), + hight ( 0.0 ), + filletRadius( 0.0 ), + k ( 0.0 ), + reverse ( false ), + leftSide ( false ), + stretching ( false ), + normToThick ( false ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbJalousieValues( const MbJalousieValues & other ) + : width ( other.width ), + hight ( other.hight ), + filletRadius( other.filletRadius ), + k ( other.k ), + reverse ( other.reverse ), + leftSide ( other.leftSide ), + stretching ( other.stretching ), + normToThick ( other.normToThick ) { + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbJalousieValues( double wid, double high, double radius, double coef, + bool rev, bool left, bool stretch, bool norm ) + : width ( wid ), + hight ( high ), + filletRadius( radius ), + k ( coef ), + reverse ( rev ), + leftSide ( left ), + stretching ( stretch ), + normToThick ( norm ) { + } + + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbJalousieValues & other ) { + width = other.width; + hight = other.hight; + filletRadius = other.filletRadius; + k = other.k; + reverse = other.reverse; + leftSide = other.leftSide; + stretching = other.stretching; + normToThick = other.normToThick; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbJalousieValues & operator = ( const MbJalousieValues & other ) { + Init( other ); + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbJalousieValues & other, double accuracy ) const { + bool isSame = false; + + if ( reverse == other.reverse && + leftSide == other.leftSide && + stretching == other.stretching && + normToThick == other.normToThick && + ::fabs( width - other.width ) < accuracy && + ::fabs( hight - other.hight ) < accuracy && + ::fabs( filletRadius - other.filletRadius ) < accuracy && + ::fabs( k - other.k ) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbJalousieValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры обечайки. + \en A ruled shell parameters. \~ + \details \ru Обечайка строится по одному или двум эскизам. + В случае одного эскиза, второй расчитывается по параметрам height и slopeAngle. \n + Зазор расчитывается оп следующему правилу: в зависимости от типа смещения зазора расчитывается точка на эскизе, + в ней вычисляется нормаль, прямая проходящая вдоль этой нормали через расчитанную точку + на эскизе смещается влево и вправо на половину величины gapValue. + Получившиеся прямые определяют границы зазора.\n + \en Shell ring is constructed by one or two sketches. + In the case of one sketch the second parameter is calculated from height and slopeAngle. \n + Gap is calculated by the following rule: depending on the type of gap shift the point is calculated on the sketch, + normal is calculated in its, line passing along this normal through calculated point + on the sketch shifted to the left and right at the half value gapValue. + Resulting straight lines define boundaries of the gap.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbRuledSolidValues { + /** \brief \ru Тип смещения зазора. + \en A displacement type of the gap. \~ + \details \ru За начало отсчёта принимается начальная точка контура. Угол отмеряется против часовой стрелки, + а длина по направлению от начальной точки контура к конечной точке. + \en Starting point of contour is taken as the origin. The angle is measured counterclockwise, + and the length along the direction from the starting point of contour to the endpoint. \~ + \ingroup Build_Parameters + */ + enum MbeGapShiftType { + gsAngle = 0, ///< \ru По углу. \en By angle. + gsLength, ///< \ru По метрической длине. \en By metric length. + gsRatio, ///< \ru В процентах от метрической длины. \en Percentage of the metric length. + gsSegmentRatio ///< \ru В формате 1.3, где 1 - номер сегмента, а .3 - доля его метрической длины. \en In form 1.3 where 1 is a segment number and .3 is a ratio of its metric length. + }; + + MbPlacement3D placement1; ///< \ru Локальная система координат первого контура. \en The local coordinate system of the first contour. + MbContour contour1; ///< \ru Первый контур. \en The first contour. + DPtr< SArray > breaks1; ///< \ru Параметры разбивки первого контура. \en The fragmentation parameters of the first contour. + DPtr placement2; ///< \ru Локальная система координат второго контура. \en The local coordinate system of the second contour. + SPtr contour2; ///< \ru Второй контур. \en The second contour. + DPtr< SArray > breaks2; ///< \ru Параметры разбивки второго контура. \en The fragmentation parameters of the second contour. + double thickness; ///< \ru Толщина листа. \en The sheet thickness. + double radius; ///< \ru Радиус скругления эскизов. \en The fillet radius of sketch. + double slopeAngle; ///< \ru Угол уклона (для создания по одному эскизу). \en Draft angle (for creating by one sketch). + double height; ///< \ru Высота обечайки (для создания по одному эскизу). \en Height of shell ring (for creating by one sketch). + double gapValue; ///< \ru Величина зазора. \en Gap value. + double gapAngle; ///< \ru Угол уклона зазора. \en Gap draft angle (for creating by one sketch). + double gapShift; ///< \ru Смещение зазора. \en Shift of the gap. + MbeGapShiftType shiftType; ///< \ru Тип смещения зазора. \en A displacement type of the gap. + bool guideSidesByNorm; ///< \ru Направляющие боковины по нормали к линейчатой поверхности. \en Guide sides along normal to the ruled surface. + bool generSidesByNorm; ///< \ru Образующие боковины по нормали к линейчатой поверхности. \en Generating sides along normal to the ruled surface. + bool cylindricBends; ///< \ru Формировать сгибы с постоянным радиусом. \en Create bend with permanent radius. + bool joinByVertices; ///< \ru Соединять контура через вершины. \en Join contour through vertices. + double surfDistance; ///< \ru Расстояние от поверхности surface. \en Distance from the surface "surface". + SPtr surface; ///< \ru Поверхность, до которой выдавливать. \en Surface to extrude up to which. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbRuledSolidValues() + : placement1 ( ), + contour1 ( ), + breaks1 ( NULL ), + placement2 ( NULL ), + contour2 ( NULL ), + breaks2 ( NULL ), + thickness ( 0.0 ), + radius ( 0.0 ), + slopeAngle ( 0.0 ), + height ( 0.0 ), + gapValue ( 0.0 ), + gapAngle ( 0.0 ), + gapShift ( 0.0 ), + shiftType ( gsAngle ), + guideSidesByNorm( false ), + generSidesByNorm( false ), + cylindricBends ( false ), + joinByVertices ( true ), + surfDistance ( 0.0 ), + surface ( NULL ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbRuledSolidValues( const MbRuledSolidValues & other ) + : placement1 ( other.placement1 ), + contour1 (), + breaks1 ( (other.breaks1 != NULL) ? new SArray(*other.breaks1) : NULL ), + placement2 ( (other.placement2 != NULL) ? new MbPlacement3D(*other.placement2) : NULL ), + contour2 ( (other.contour2 != NULL) ? new MbContour() : NULL ), + breaks2 ( (other.breaks2 != NULL) ? new SArray(*other.breaks2) : NULL ), + thickness ( other.thickness ), + radius ( other.radius ), + slopeAngle ( other.slopeAngle ), + height ( other.height ), + gapValue ( other.gapValue ), + gapAngle ( other.gapAngle ), + gapShift ( other.gapShift ), + shiftType ( other.shiftType ), + guideSidesByNorm( other.guideSidesByNorm ), + generSidesByNorm( other.generSidesByNorm ), + cylindricBends ( other.cylindricBends ), + joinByVertices ( other.joinByVertices ), + surfDistance ( other.surfDistance ), + surface ( (other.surface != NULL) ? static_cast(&other.surface->Duplicate()) : NULL ) { + contour1.Init( other.contour1 ); + if ( contour2 != NULL && other.contour2 != NULL ) + contour2->Init( *other.contour2 ); + } + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbRuledSolidValues( const MbPlacement3D & place1, const MbContour & cntr1, const SArray * brks1, + const MbPlacement3D * place2, const MbContour * cntr2, const SArray * brks2, + const double thick, const double rad, const double sAngle, const double h, + const double gap, const double shift, const MbeGapShiftType type, + const bool guideByNorm, const bool generByNorm, const bool cylBends, const bool joinByVert, + const double surfDist, const MbSurface * surf ) + : placement1( place1 ), + contour1(), + breaks1( (brks1 != NULL) ? new SArray(*brks1) : NULL ), + placement2( (place2 != NULL) ? new MbPlacement3D(*place2) : NULL ), + contour2( (cntr2 != NULL) ? new MbContour() : NULL ), + breaks2( (brks2 != NULL) ? new SArray(*brks2) : NULL ), + thickness( thick ), + radius( rad ), + slopeAngle( sAngle ), + height( h ), + gapValue( gap ), + gapAngle( 0.0 ), + gapShift( shift ), + shiftType( type ), + guideSidesByNorm( guideByNorm ), + generSidesByNorm( generByNorm ), + cylindricBends( cylBends ), + joinByVertices( joinByVert ), + surfDistance( surfDist ), + surface( (surf != NULL) ? static_cast(&surf->Duplicate()) : NULL ) { + contour1.Init( cntr1 ); + if ( (contour2 != NULL) && (cntr2 != NULL) ) + contour2->Init( *cntr2 ); + } + + /// \ru Инициализировать по другому объекту. \en Initialize by another object. + void Init( const MbRuledSolidValues & other ) { + placement1.Init( other.placement1 ); + contour1.Init( other.contour1 ); + + if ( other.breaks1 != NULL ) { + if ( breaks1 != NULL ) + ((SArray &)*breaks1) = *other.breaks1; + else + breaks1 = new SArray( *other.breaks1 ); + } + else + breaks1 = NULL; + + if ( other.placement2 != NULL ) { + if ( placement2 != NULL ) + placement2->Init( *other.placement2 ); + else + placement2 = new MbPlacement3D( *other.placement2 ); + } + else + placement2 = NULL; + + if ( other.contour2 != NULL ) { + if ( contour2 == NULL ) + contour2 = new MbContour(); + contour2->Init( *other.contour2 ); + } + else + contour2 = NULL; + + if ( other.breaks2 != NULL ) { + if ( breaks2 != NULL ) + ((SArray &)*breaks2) = *other.breaks2; + else + breaks2 = new SArray( *other.breaks2 ); + } + else + breaks1 = NULL; + + thickness = other.thickness; + radius = other.radius; + slopeAngle = other.slopeAngle; + height = other.height; + gapValue = other.gapValue; + gapAngle = other.gapAngle; + gapShift = other.gapShift; + shiftType = other.shiftType; + guideSidesByNorm = other.guideSidesByNorm; + generSidesByNorm = other.generSidesByNorm; + cylindricBends = other.cylindricBends; + joinByVertices = other.joinByVertices; + surfDistance = other.surfDistance; + + if ( other.surface != NULL ) + surface = static_cast( &other.surface->Duplicate() ); + else + surface = NULL; + } + + /// \ru Инициализировать контуры. \en Initialize contours. + void Init( const MbPlacement3D & place1, const MbContour & cntr1, const SArray * brks1, + const MbPlacement3D * place2, const MbContour * cntr2, const SArray * brks2 ) { + placement1.Init( place1 ); + contour1.Init( cntr1 ); + + if ( brks1 != NULL ) { + if ( breaks1 != NULL ) + ((SArray &)*breaks1) = *brks1; + else + breaks1 = new SArray( *brks1 ); + } + else + breaks1 = NULL; + + if ( place2 != NULL ) { + if ( placement2 != NULL ) + placement2->Init( *place2 ); + else + placement2 = new MbPlacement3D( *place2 ); + } + else + placement2 = NULL; + + if ( cntr2 != NULL ) { + if ( contour2 == NULL ) + contour2 = new MbContour(); + contour2->Init( *cntr2 ); + } + else + contour2 = NULL; + + if ( brks2 != NULL ) { + if ( breaks2 != NULL ) + ((SArray &)*breaks2) = *brks2; + else + breaks2 = new SArray( *brks2 ); + } + else + breaks1 = NULL; + } + + /// \ru Оператор присваивания. \en Assignment operator. + MbRuledSolidValues & operator = ( const MbRuledSolidValues & other ) { + Init( other ); + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbRuledSolidValues & other, double accuracy ) const { + size_t i, cnt; + bool isSame = false; + + if ( shiftType == other.shiftType && + guideSidesByNorm == other.guideSidesByNorm && + generSidesByNorm == other.generSidesByNorm && + cylindricBends == other.cylindricBends && + joinByVertices == other.joinByVertices && + placement1.IsSame( other.placement1, accuracy ) && + contour1.IsSame( other.contour1, accuracy ) && + ::fabs( thickness - other.thickness ) < accuracy && + ::fabs( radius - other.radius ) < accuracy && + ::fabs( slopeAngle - other.slopeAngle ) < accuracy && + ::fabs( height - other.height ) < accuracy && + ::fabs( gapValue - other.gapValue ) < accuracy && + ::fabs( gapAngle - other.gapAngle ) < accuracy && + ::fabs( gapShift - other.gapShift ) < accuracy && + ::fabs( surfDistance - other.surfDistance ) < accuracy ) { + + bool isBreaks1 = breaks1 != NULL; + bool isOtherBreaks1 = other.breaks1 != NULL; + bool isPlacement2 = placement2 != NULL; + bool isOtherPlacement2 = other.placement2 != NULL; + bool isContour2 = contour2 != NULL; + bool isOtherContour2 = other.contour2 != NULL; + bool isBreaks2 = breaks2 != NULL; + bool isOtherBreaks2 = other.breaks2 != NULL; + bool isSurf = surface != NULL; + bool isOtherSurf = other.surface != NULL; + + if ( isBreaks1 == isOtherBreaks1 && + isPlacement2 == isOtherPlacement2 && + isContour2 == isOtherContour2 && + isBreaks2 == isOtherBreaks2 && + isSurf == isOtherSurf ) { + isSame = true; + if ( isSame && isBreaks1 && isOtherBreaks1 ) { + if ( breaks1->Count() != other.breaks1->Count() ) + isSame = false; + + for ( i = 0, cnt = breaks1->Count(); i < cnt && isSame; i++ ) + if ( ::fabs( (*breaks1)[i] - (*other.breaks1)[i] ) >= accuracy ) { + isSame = false; + break; + } + } + + if ( isSame && isPlacement2 && isOtherPlacement2 && !placement2->IsSame( *other.placement2, accuracy ) ) + isSame = false; + + if ( isSame && isContour2 && isOtherContour2 && !contour2->IsSame( *other.contour2, accuracy ) ) + isSame = false; + + if ( isSame && isBreaks2 && isOtherBreaks2 ) { + if ( breaks2->Count() != other.breaks2->Count() ) + isSame = false; + + for ( i = 0, cnt = breaks2->Count(); i < cnt && isSame; i++ ) + if ( ::fabs( (*breaks2)[i] - (*other.breaks2)[i] ) >= accuracy ) { + isSame = false; + break; + } + } + + if ( isSame && isSurf && isOtherSurf && !surface->IsSame( *other.surface, accuracy ) ) + isSame = false; + } + } + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbRuledSolidValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры операции упрощения углов в развёртке листового тела. + \en Parameters of the simplification corners operation.\n \~ + \details \ru Параметры операции упрощения углов в развёртке листового тела.\n + \en Parameters of the simplification corners operation.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSimplifyFlatPatternValues { + bool uniteFaces; ///< \ru Флаг слияния подобных граней. \en The merger faces flag. + bool cornerTreatment; ///< \ru Флаг упрощения углов развёртки. \en The simplification corners flag. + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSimplifyFlatPatternValues() : uniteFaces( false ), cornerTreatment( true ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbSimplifyFlatPatternValues( bool uFaces, bool cTreatment ) : + uniteFaces ( uFaces ), + cornerTreatment( cTreatment ) { + } + /// \ru Конструктор копирования. \en Copy-constructor. + MbSimplifyFlatPatternValues( const MbSimplifyFlatPatternValues & other ) : + uniteFaces ( other.uniteFaces ), + cornerTreatment( other.cornerTreatment ) { + } + /// \ru Инициализировать по конкретным параметрам. \en Initialize by specific parameters. + void Init( bool uFaces, bool cTreatment ) { + uniteFaces = uFaces; + cornerTreatment = cTreatment; + } + /// \ru Инициализировать по другой структуре. \en Initialize by another structure. + void Init( const MbSimplifyFlatPatternValues & other ) { + uniteFaces = other.uniteFaces; + cornerTreatment = other.cornerTreatment; + } + /// \ru Оператор присваивания. \en Assignment operator. + const MbSimplifyFlatPatternValues & operator = ( const MbSimplifyFlatPatternValues & other ) { + uniteFaces = other.uniteFaces; + cornerTreatment = other.cornerTreatment; + + return *this; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSimplifyFlatPatternValues & other ) const { + bool isSame = false; + + if ( (!uniteFaces == !other.uniteFaces) && (!cornerTreatment == !other.cornerTreatment) ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbSimplifyFlatPatternValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры и имена элементов сгиба. + \en Parameters and names of bend's elements. \~ + \details \ru Параметры сгиба. Имена внешней и внутренней граней сгиба, а также имена сегментов контура, между которыми строится сгиб. + Используются для построения листовых тел выдавливанием эскизов. Дополнительное имя в операциях построения не используется.\n + \en The bend parameters. Names of the outer and inner faces of the bend, and names of contour segments between which bend is built. + Used to construct sheet solids by sketches extrusion. Additional name in operations of construction is not used.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSMBendNames : public MbBendValues { +public: + SimpleName segName1; ///< \ru Имя первого из двух смежных сегментов контура. \en Name of the first of two adjacent segments of the contour. + SimpleName segName2; ///< \ru Имя второго из двух смежных сегментов контура. \en Name of the second of two adjacent segments of the contour. + SimpleName extraName; ///< \ru Дополнительное имя. \en Additional name. + uint groupNumber; ///< \ru Номер группы одновременно сгибаемых/разгибаемых сгибов. \en Group number of simultaneously bent/unbent bends. + MbName innerFaceName; ///< \ru Имя внутренней грани сгиба. \en Name of interior face of bend. + MbName outerFaceName; ///< \ru Имя внешней грани сгиба. \en Name of exterior face of bend. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSMBendNames() : MbBendValues(), + segName1 ( SimpleName(SIMPLENAME_MAX) ), + segName2 ( SimpleName(SIMPLENAME_MAX) ), + extraName( SimpleName(SIMPLENAME_MAX) ), + groupNumber( SYS_MAX_UINT ), + innerFaceName(), + outerFaceName() {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbSMBendNames( double coef, double rad, double ang, SimpleName sn1, SimpleName sn2, SimpleName exn = -1, uint groupNumber = SYS_MAX_UINT ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSMBendNames( const MbSMBendNames &init ) + : MbBendValues( init ), + segName1 ( init.segName1 ), + segName2 ( init.segName2 ), + extraName ( init.extraName ), + groupNumber ( init.groupNumber ), + innerFaceName( init.innerFaceName ), + outerFaceName( init.outerFaceName ) + { + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSMBendNames & other, double accuracy ) const { + bool isSame = false; + + if ( segName1 == other.segName1 && + segName2 == other.segName2 && + extraName == other.extraName && + groupNumber == other.groupNumber && + innerFaceName == other.innerFaceName && + outerFaceName == other.outerFaceName && + MbBendValues::IsSame( other, accuracy ) ) + isSame = true; + + return isSame; + } + +private: + MbSMBendNames & operator = ( const MbSMBendNames & ); // \ru Не реализовано \en Not implemented + + KNOWN_OBJECTS_RW_PTR_OPERATORS_EX( MbSMBendNames, MATH_FUNC_EX ) // \ru Для работы с указателями класса \en For working with pointers of class +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Внешняя и внутренняя грани сгиба с параметрами. + \en Outer and inner faces of bend with parameters. \~ + \details \ru Внешняя и внутренняя грани сгиба с внутренним радиусом и коэффициентом нейтрального слоя. + Полностью определяет сгиб и связывает его с параметрами.\n + \en Outer and inner faces of bend with inner radius and neutral layer coefficient. + Completely determines the bend and associates it with parameters.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbSheetMetalBend : public MbBendValues { +public: + RPArray innerFaces; ///< \ru Указатели на внутренние грани сгиба. \en Pointers to interior faces of bend. + RPArray outerFaces; ///< \ru Указатели на внешние грани сгиба. \en Pointers to exterior faces of bend. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbSheetMetalBend() : MbBendValues(), innerFaces( 1, 1 ), outerFaces( 1, 1 ) {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbSheetMetalBend( MbFace * inner, MbFace * outer, const double k, const double radius, const double angle, const double coneAngle ) + : MbBendValues( k, radius, angle, coneAngle ), innerFaces( 1, 1 ), outerFaces( 1, 1 ) { + innerFaces.Add( inner ); + outerFaces.Add( outer ); + } + MbSheetMetalBend( const RPArray & inners, const RPArray & outers, const double k, const double radius, const double angle, const double coneAngle ) + : MbBendValues( k, radius, angle, coneAngle ), innerFaces( inners.Count(), 1 ), outerFaces( outers.Count(), 1 ) { + innerFaces.AddArray( inners ); + outerFaces.AddArray( outers ); + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbSheetMetalBend & other, double accuracy ) const { + bool isSame = false; + + if ( MbBendValues::IsSame( other, accuracy ) && + innerFaces.Count() == other.innerFaces.Count() && + outerFaces.Count() == other.outerFaces.Count() ) { + isSame = true; + + size_t i, cnt; + for ( i = 0, cnt = innerFaces.Count(); i < cnt && isSame; i++ ) + if ( innerFaces[i] == NULL || other.innerFaces[i] == NULL || !innerFaces[i]->IsSame( *other.innerFaces[i], accuracy ) ) { + isSame = false; + break; + } + + for ( i = 0, cnt = outerFaces.Count(); i < cnt && isSame; i++ ) + if ( outerFaces[i] == NULL || other.outerFaces[i] == NULL || !outerFaces[i]->IsSame( *other.outerFaces[i], accuracy ) ) { + isSame = false; + break; + } + } + + return isSame; + } + +private: + MbSheetMetalBend( const MbSheetMetalBend & ); // \ru Не реализовано \en Not implemented + MbSheetMetalBend & operator = ( const MbSheetMetalBend & ); // \ru Не реализовано \en Not implemented +}; + + +//------------------------------------------------------------------------------ +// Индексы внешних и внутренних граней сгиба с параметрами. +// --- +struct MATH_CLASS MbBendIndices : public MbBendValues { +public: + SArray innerFacesIndices; ///< Индексы внутренних граней сгиба. + SArray outerFacesIndices; ///< Индексы внешних граней сгиба. + + /// Конструктор по умолчанию. + MbBendIndices() : MbBendValues(), innerFacesIndices( 0, 1 ), outerFacesIndices( 0, 1 ) {} + MbBendIndices( const MbBendIndices & other ) + : MbBendValues( other ), innerFacesIndices( other.innerFacesIndices ), outerFacesIndices( other.outerFacesIndices ) {} + + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D & matr ) { + matr.TransformLength( radius ); + for ( size_t innerFaceIndex = innerFacesIndices.Count(); innerFaceIndex--; ) + innerFacesIndices[innerFaceIndex].Transform( matr ); + for ( size_t outerFaceIndex = outerFacesIndices.Count(); outerFaceIndex--; ) + outerFacesIndices[outerFaceIndex].Transform( matr ); + } + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move( const MbVector3D & to ) { + for ( size_t innerFaceIndex = innerFacesIndices.Count(); innerFaceIndex--; ) + innerFacesIndices[innerFaceIndex].Move( to ); + for ( size_t outerFaceIndex = outerFacesIndices.Count(); outerFaceIndex--; ) + outerFacesIndices[outerFaceIndex].Move( to ); + } + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate( const MbAxis3D & axis, double ang ) { + for ( size_t innerFaceIndex = innerFacesIndices.Count(); innerFaceIndex--; ) + innerFacesIndices[innerFaceIndex].Rotate( axis, ang ); + for ( size_t outerFaceIndex = outerFacesIndices.Count(); outerFaceIndex--; ) + outerFacesIndices[outerFaceIndex].Rotate( axis, ang ); + } + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbBendIndices & other, double accuracy ) const { + bool isSame = false; + + if ( MbBendValues::IsSame( other, accuracy ) && + innerFacesIndices.Count() == other.innerFacesIndices.Count() && + outerFacesIndices.Count() == other.outerFacesIndices.Count() ) { + isSame = true; + + size_t i, cnt; + for ( i = 0, cnt = innerFacesIndices.Count(); i < cnt && isSame; i++ ) + if ( !innerFacesIndices[i].IsSame( other.innerFacesIndices[i], accuracy ) ) { + isSame = false; + break; + } + + for ( i = 0, cnt = outerFacesIndices.Count(); i < cnt && isSame; i++ ) + if ( !outerFacesIndices[i].IsSame( other.outerFacesIndices[i], accuracy ) ) { + isSame = false; + break; + } + } + + return isSame; + } + +private: + MbBendIndices & operator = ( const MbBendIndices & ); // не реализовано + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbBendIndices ) // для работы со ссылками и объектами класса +}; + + +//------------------------------------------------------------------------------ +// Параметры нелистового сгиба. +// --- +struct MATH_CLASS MbAnyBend { +public: + MbCartPoint origin; + MbVector vector; + double wideness; + double neutralRadius; + + /// Конструктор по умолчанию. + MbAnyBend() : origin(), vector(), wideness( 0.0 ), neutralRadius( 0.0 ) {} + MbAnyBend( const MbAnyBend & other ) + : origin( other.origin ), vector( other.vector ), wideness( other.wideness ), neutralRadius( other.neutralRadius ) {} + + void Transform( const MbMatrix3D & matr ) { matr.TransformLength( wideness ); matr.TransformLength( neutralRadius ); } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbAnyBend & other, double accuracy ) const { + bool isSame = false; + + if ( c3d::EqualPoints( origin, other.origin, accuracy ) && + c3d::EqualVectors( vector, other.vector, accuracy ) && + ::fabs( wideness - other.wideness ) < accuracy && + ::fabs( neutralRadius - other.neutralRadius ) < accuracy ) + isSame = true; + + return isSame; + } + +private: + MbAnyBend & operator = ( const MbAnyBend & ); // не реализовано + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbAnyBend ) // для работы со ссылками и объектами класса +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры штамповки телом-инструментом. + \en The parameters of stamping by a tool solid. \~ + \details \ru Параметры шатмповки телом-инструментом определяют толщину формованной части и радиус скругления основания.\n + \en The parameters of stamping by a tool solid is specified a thickness of a stamped part and fillet radius of stamping base.\n \~ + \ingroup Build_Parameters +*/ +// --- +struct MATH_CLASS MbUserStampingValues { + double baseFilletRadius; ///< \ru Радиус скругления основания (отрицательное значение запрещает скругление). \en Fillet radius of base (negative value prohibits fillet). + double stampThickness; ///< \ru Толщина формованной части. \en Thickness of a stamped part. + + /// \ru Конструктор по умолчанию. \en Default constructor. + MbUserStampingValues() : + baseFilletRadius ( 0.0 ), + stampThickness ( 0.0 ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbUserStampingValues( const MbUserStampingValues & other ) : + baseFilletRadius ( other.baseFilletRadius ), + stampThickness ( other.stampThickness ) + {} + /// \ru Конструктор по конкретным параметрам. \en Constructor by specific parameters. + MbUserStampingValues( double baseRad, double thick ) : + baseFilletRadius ( baseRad ), + stampThickness ( thick ) + {} + + /// \ru Оператор присваивания. \en Assignment operator. + MbUserStampingValues & operator = ( const MbUserStampingValues &other ) { Init( other ); return *this; } + /// \ru Инициализация по другому объекту. \en Initialization by another object. + void Init( const MbUserStampingValues & other ) { + baseFilletRadius = other.baseFilletRadius; + stampThickness = other.stampThickness; + } + + ///\ru Являются ли объекты равными? \en Determine whether an object is equal? + bool IsSame( const MbUserStampingValues & other, double accuracy ) const { + bool isSame = false; + + if ( ::fabs(baseFilletRadius - other.baseFilletRadius) < accuracy && + ::fabs(stampThickness - other.stampThickness) < accuracy ) + isSame = true; + + return isSame; + } + + KNOWN_OBJECTS_RW_REF_OPERATORS( MbUserStampingValues ) // \ru Для работы со ссылками и объектами класса \en For treatment of references and objects of the class +}; + +#endif // __SHEET_METAL_PARAM_H \ No newline at end of file diff --git a/C3d/Include/shell_history.h b/C3d/Include/shell_history.h new file mode 100644 index 0000000..5fddebc --- /dev/null +++ b/C3d/Include/shell_history.h @@ -0,0 +1,64 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru История граней. + \en Faces history. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SHELL_HISTORY_H +#define __SHELL_HISTORY_H + + +#include + + +class MATH_CLASS MbFaceShell; + + +//------------------------------------------------------------------------------ +/** \brief \ru История граней. + \en Faces history. \~ + \details \ru История граней содержит два синхронных множества граней: + исходных граней и их копий. \n + История используется после операции для замены в результирующей оболочке + неизменённых операцией копий гриней их оригиналами. \n + \en Faces history contains two synchronous sets of faces: + initial faces and their copies. \n + A faces history is used after the operation of replacement in a result shell + of unchanged faces copies by their originals. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbShellHistory { +private: + RPArray originFaces; ///< \ru Множество исходных граней. \en A set of initial faces. + RPArray copyFaces; ///< \ru Множество копий граней. \en A set of faces copies. +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbShellHistory(); + /// \ru Деструктор. \en Destructor. + ~MbShellHistory(); + +public: + /// \ru Очистить массивы для повторного использования. \en Clear arrays for reuse. + void Clear(); + /// \ru Запомнить оригиналы. \en Save originals. + void InitOrigins( const RPArray & origin ); + /// \ru Выдать контейнер оригиналов для заполнения. \en Get container of originals for filling. + RPArray & SetOriginFaces() { return originFaces; } + /// \ru Выдать контейнер копий для заполнения. \en Get container of copies for filling. + RPArray & SetCopyFaces() { return copyFaces; } + /// \ru Заменить в shell неизменённые copy-объекты на origin-объекты. \en Replace in 'shell' the unchanged 'copy'-objects by the 'origin'-objects. + void SetOrigins ( MbFaceShell & shell ); + +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbShellHistory( const MbShellHistory & ); // \ru Не реализовано \en Not implemented + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbShellHistory & ); // \ru Не реализовано \en Not implemented +}; + + +#endif // __SHELL_HISTORY_H diff --git a/C3d/Include/solid.h b/C3d/Include/solid.h new file mode 100644 index 0000000..2ceecc6 --- /dev/null +++ b/C3d/Include/solid.h @@ -0,0 +1,451 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Твердое тело. + \en Solid solid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SOLID_H +#define __SOLID_H + +#include +#include + + +class MATH_CLASS MbSolid; +namespace c3d // namespace C3D +{ +typedef SPtr SolidSPtr; +typedef SPtr ConstSolidSPtr; + +typedef std::vector SolidsVector; +typedef std::vector ConstSolidsVector; + +typedef std::vector SolidsSPtrVector; +typedef std::vector ConstSolidsSPtrVector; + +typedef std::set SolidsSet; +typedef SolidsSet::iterator SolidsSetIt; +typedef SolidsSet::const_iterator SolidsSetConstIt; +typedef std::pair SolidsSetRet; + +typedef std::set SolidsSPtrSet; +typedef SolidsSPtrSet::iterator SolidsSPtrSetIt; +typedef SolidsSPtrSet::const_iterator SolidsSPtrSetConstIt; +typedef std::pair SolidsSPtrSetRet; + +typedef std::set ConstSolidsSet; +typedef ConstSolidsSet::iterator ConstSolidsSetIt; +typedef ConstSolidsSet::const_iterator ConstSolidsSetConstIt; +typedef std::pair ConstSolidsSetRet; + +typedef std::set ConstSolidsSPtrSet; +typedef ConstSolidsSPtrSet::iterator ConstSolidsSPtrSetIt; +typedef ConstSolidsSPtrSet::const_iterator ConstSolidsSPtrSetConstIt; +typedef std::pair ConstSolidsSPtrSetRet; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Твердое тело. + \en Solid solid. \~ + \details \ru Твердое тело, или тело, является объектом геометрической модели. + Тело состоит из множества граней MbFaceShell.\n + Структура данных тела содержит указатель на набор граней outer и тип связности тела #multiState. + Тело может описывать одно или несколько связных множеств точек. Тип связности #multiState сообщает о том, + что тело описывает одно связное множество точек, или, что тело описывает несколько связных множеств точек + и может быть разбито на несколько тел.\n + Набор граней тела #outer->faceSet описывает одну или несколько однородных оболочек. + В зависимости от признака #outer->closed замкнутости оболочек тело может описывать + два принципиально разных множества точек.\n + Если все оболочки тела замкнутые, то тело описывает множество точек, располагающихся с + внутренней стороны одной внешней и нескольких внутренних оболочек, расположенных внутри + внешней оболочки, в совокупности с точками этих оболочек.\n + Если оболочки тела незамкнутые, то тело описывает множество точек, принадлежащих граням этих оболочек.\n + В зависимости от замкнутости оболочек тело будем называть замкнутым или незамкнутым. + В частном случае, когда все оболочки являются замкнутыми, получим замкнутое тело. + В общем случае оболочки тела могут быть незамкнутыми, тогда получим незамкнутое тело.\n + Замкнутое тело и незамкнутое тело оперируют разными множествами точек и это различие влияет на булевы и другие операции с телами. \n + Над телами можно выполнять определённый набор действий. + Эти действия записываются в журнал построения тела, элементами которого являются строители оболочек MbCreator.\n + Тело может иметь атрибуты MbAttribute.\n + \en Solid solid or solid is object of geometric model. + Solid consists of face set MbFaceShell. \n + Data structure of solid contains pointer to face set outer and type of solid connectivity #multiState. + The solid can describe one or more sets of points. Connection type #multiState informs + that the solid describes one connected set of points or that the solid describes some connected sets of points + and can be split into multiple solids.\n + Face set of solid #outer->faceSet describes one or some homogeneous shells. + Depending on the attribute of #outer->closed shell closedness the solid can describe + two principally different sets of points.\n + If all the shells of solid are closed, then the solid describes a set of points which are located on + the inside of one external and several internal shells located inside + outer shell in combination with points of these shells.\n + If shells of solid are closed, then the solid describes a set of points belonging to the faces of these shells.\n + Depending on the closedness of shells the solid is called closed or non-closed. + In the special case when all the shells are closed, the solid is closed. + In the general case shells of solid can be unclosed, the solid is unclosed. \n + Closed solid and unclosed solid operate with different sets of points and this difference affects on boolean other operations with solids. \n + Certain set of actions can be performed with solids. + These actions are recorded to history tree of solid, elements of which are creators of shells MbCreator. \n + Solid can have attributes MbAttribute.\n \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbSolid : public MbItem { +public: + /** \brief \ru Тип связности тела. + \en The solid connection type. \~ + \details \ru Тело может состоять из одного или нескольких связных множеств точек. + \en The solid can consist of one or several connected sets of points. \~ + */ + enum MultiState { + ms_Undefined = 0, ///< \ru Связность тела не определена. \en Connectivity of solid is undefined. + ms_Single, ///< \ru Тело описывает одно связное множество точек. \en The solid describes one connected set of points. + ms_Multiple, ///< \ru Тело описывает несколько связных множеств точек и может быть разбито на несколько связных частей. \en The solid describes several connected set of points and can be split into multiple connected parts. + }; +protected: + MbFaceShell * outer; ///< \ru Оболочка тела. \en Shell of solid. + mutable MultiState multiState; ///< \ru Тип связности тела. \en The solid connection type. +//#ifdef _MSC_VER +//CRITICAL_SECTION itemLock_; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object. +//#ifdef _MSC_VER + +private: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbSolid( const MbSolid & other ); + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbSolid( const MbSolid & other, MbRegDuplicate * iReg ); +public : + /// \ru Конструктор по оболочке и строителю. \en Constructor by shell and creator. + explicit MbSolid( MbFaceShell * shell, MbCreator * creator ); + /// \ru Конструктор по оболочке и строителю. \en Constructor by shell and creator. + explicit MbSolid( MbFaceShell & shell, MbCreator & creator ); + /// \ru Конструктор по оболочке и набору строителей, флагу копирования строителей и регистратору дублирования объектов. \en Constructor by shell and set of creators, flag of creators copying and registrator of objects duplicating. + MbSolid( MbFaceShell & shell, RPArray & creators, bool sameCreators, MbRegDuplicate * iReg ); // BUG_40923 + /// \ru Конструктор по оболочке и набору строителей, флагу копирования строителей и регистратору дублирования объектов. \en Constructor by shell and set of creators, flag of creators copying and registrator of objects duplicating. + MbSolid( MbFaceShell & shell, c3d::CreatorsSPtrVector & creators, bool sameCreators, MbRegDuplicate * iReg ); // BUG_40923 + /// \ru Конструктор по оболочке, телу, у которого берутся строители, и строителю. \en Constructor by shells, creator and solid which has creators. + MbSolid( MbFaceShell & shell, const MbSolid & solid, MbCreator & creator ); + /// \ru Конструктор по оболочке, телу, у которого берутся строители, и строителю. \en Constructor by shells, creator and solid which has creators. + MbSolid( MbFaceShell & shell, const MbSolid & solid, MbCreator * creator ); + /// \ru Деструктор. \en Destructor. + virtual ~MbSolid(); + +public : + VISITING_CLASS( MbSolid ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * iReg = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * iReg = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * iReg = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual bool IsSame ( const MbSpaceItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными? \en Determine whether objects are similar. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить свой габарит в куб. \en Add own bounding box into a cube. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Выдать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Перестроить объект по журналу построения. \en Reconstruct object according to the history tree. + virtual bool RebuildItem( MbeCopyMode copyMode, RPArray * items, IProgressIndicator * progInd ); + // \ru Достроить тело для последней невыполненной операции в журнале построения. \en Build a body by the last kept operation in the build log. + virtual bool FinishItem(); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + + /** \ru \name Функции тела. + \en \name Functions of solid. + \{ */ + + /** \brief \ru Рассчитать габарит. + \en Calculate bounding box. \~ + \details \ru Рассчитать габарит тела. + \en Calculate bounding box of solid. \~ + \param[out] cube - \ru Рассчитанный габарит. + \en Calculated bounding box. \~ + */ + virtual void CalculateGabarit( MbCube & cube ) const; + + /** \brief \ru Получить габарит. + \en Get bounding box. \~ + \details \ru Получить габарит тела. + \en Get bounding box of solid. \~ + \return \ru Габарит. + \en Bounding box. \~ + */ + const MbCube GetCube() const; + + /** \brief \ru Добавить свои строители в присланный массив. + \en Add your own creators to the given array. \~ + \details \ru При отсутствии строителей создает строитель без истории + и добавляет его в присланный контейнер и в пустой журнал построения. + \en If there are no creators, then creates a creator without history + and adds it to the given container and to empty history tree. \~ + \param[out] creators - \ru Контейнер для добавления своих строителей. + \en Container for adding of its creators. \~ + \return \ru Добавлены ли строители. + \en Whether creators are added. \~ + */ + virtual bool GetCreators( RPArray & creators ) const; + /** \brief \ru Добавить свои строители в присланный массив. + \en Add your own creators to the given array. \~ + \details \ru При отсутствии строителей создает строитель без истории + и добавляет его в присланный контейнер и в пустой журнал построения. + \en If there are no creators, then creates a creator without history + and adds it to the given container and to empty history tree. \~ + \param[out] creators - \ru Контейнер для добавления своих строителей. + \en Container for adding of its creators. \~ + \return \ru Добавлены ли строители. + \en Whether creators are added. \~ + */ + virtual bool GetCreators( c3d::CreatorsSPtrVector & creators ) const; + + /** \brief \ru Построить полигональную копию тела и положить её данные в присланный объект. + \en Create a polygonal copy of the solid and put its data to the given object. \~ + \details \ru Полигональная копия тела строится только путём триангуляции граней. + \en Polygonal copy of the solid is created only by triangulating the faces. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[out] mesh - \ru Полигональная копия объекта. + \en Polygonal copy of the object. \~ + */ + void CalculateGrid( const MbStepData & stepData, MbMesh & mesh ) const; + + /// \ru Заменить оболочку тела на присланную. \en Replace the shell of the solid by the given one. + void SetShell( MbFaceShell * shell ); + /// \ru Отцепить оболочку. \en Detach the shell. + MbFaceShell * DetachShell(); + /// \ru Выдать оболочку. \en Get the shell. + MbFaceShell * GetShell() const; + /// \ru Имеется ли оболочка? \en Is there a shell? + bool IsShellBuild() const; + /// \ru Переустановить в ребрах указатели на соединяемые ими грани. \en Reinstall pointers to mating faces in edges. + void MakeRight(); + /// \ru Верно ли установлены в ребра указатели на соединяемые ими грани? \en Are the pointers in edges to the faces connected by them set correctly? + bool IsRight() const; + /// \ru Выдать количество граней. \en Get the count of faces. + size_t GetFacesCount() const; + /// \ru Заполнить контейнер вершинами тела. \en Fill container by solid vertices. + template + void GetVertices( VerticesVector & vertices ) const { if ( outer != NULL ) { outer->GetVertices( vertices ); } } + /// \ru Заполнить контейнер ориентированными ребрами тела. \en Fill container by oriented edges of the solid. + template + void GetEdges( EdgesVector & edges ) const { if ( outer != NULL ) { outer->GetEdges( edges ); } } + /// \ru Заполнить контейнеры вершинами и ребрами тела. \en Fill containers by vertices and edges of the solid. + template + void GetItems( VerticesVector & vertices, EdgesVector & edges ) const { if ( outer != NULL ) { outer->GetItems( vertices, edges ); } } + /// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. + template + void GetFaces ( FacesVector & faces ) const { if ( outer != NULL ) { outer->GetFaces( faces ); } } + /// \ru Заполнить контейнер гранями тела. \en Fill container by solid faces. + template + void GetFacesSet( FacesSet & faces ) const { if ( outer != NULL ) { outer->GetFacesSet( faces ); } } + + /// \ru Заполнить контейнер вершинами, ребрами и гранями тела. \en Fill container by vertices, edges and faces of the solid. + void GetItems ( RPArray & ) const; + /// \ru Выдать вершину по её номеру. \en Get vertex by its index. + MbVertex * GetVertex( size_t index ) const; + /// \ru Выдать ребро по его номеру. \en Get edge by its index. + MbCurveEdge * GetEdge ( size_t index ) const; + /// \ru Выдать грань по её номеру. \en Get face by its index. + MbFace * GetFace ( size_t index ) const; + /// \ru Выдать номер вершины. \en Get the vertex index. + size_t GetVertexIndex( const MbVertex & ) const; + /// \ru Выдать номер ребра. \en Get the edge index. + size_t GetEdgeIndex ( const MbCurveEdge & ) const; + /// \ru Выдать номер грани. \en Get the face index. + size_t GetFaceIndex ( const MbFace & ) const; + /// \ru Выдать количество связных оболочек тела. \en Get the count of connected shells of the solid. + size_t GetShellCount() const; + /// \ru Вывернуть тело наизнанку - переориентировать все грани. \en Revert the solid - reorientation of the whole set of faces. + bool Reverse(); + + /** \brief \ru Классифицировать точку. + \en Classify point. \~ + \details \ru Классификация заключается в определении положения точки относительно тела. + \en Classification consists in determining the point position relative to the solid. \~ + \param[in] p - \ru Классифицируемая точка. + \en Classified point. \~ + \param[in] epsilon - \ru Точность классификации. + \en Classification tolerance. \~ + \return \ru #iloc_InItem (+1) - Точка лежит внутри тела.\n + #iloc_OutOfItem (-1) - Точка лежит вне тела.\n + #iloc_OnItem ( 0) - Точка лежит на поверхности тела. + \en #iloc_InItem (+1) - Point is inside the solid.\n + #iloc_OutOfItem (-1) - Point is outside the solid.\n + #iloc_OnItem ( 0) - Point is on the surface of the solid. \~ + */ + MbeItemLocation PointClassification( const MbCartPoint3D & p, double epsilon = Math::metricRegion ) const; + + /** \brief \ru Классифицировать тело. + \en Classify solid. \~ + \details \ru Классификация заключается в определении положения присланного тела относительно данного тела. + \en Classification consists in determining a solid position relative to the this solid. \~ + \param[in] solid - \ru Классифицируемое тело. + \en Classified solid. \~ + \param[in] epsilon - \ru Точность классификации. + \en Classification tolerance. \~ + \return \ru #iloc_OutOfItem (-1) - Классифицируемое тело лежит вне данного тела.\n + #iloc_OnItem ( 0) - Классифицируемое тело пересекает данного тело.\n + #iloc_InItem (+1) - Классифицируемое тело лежит внутри данного тела.\n + #iloc_ByItem (+2) - Данное тело лежит внутри классифицируемого тела.\n + #iloc_Undefined (-3) - Классификация не выполнялась.\n + \en #iloc_OutOfItem (-1) - Classified solid is outside the this solid.\n + #iloc_OnItem ( 0) - Classified solid intersects the this solid.\n + #iloc_InItem (+1) - Classified solid is inside the this solid.\n + #iloc_ByItem (+2) - This solid is inside the classified solid.\n + #iloc_Undefined (-3) - Solid is not classified.\n \~ + */ + MbeItemLocation SolidClassification( const MbSolid & solid, double epsilon = Math::metricRegion ) const; + + /** \brief \ru Найти номера граней. + \en Find indices of faces. \~ + \details \ru Найти номера граней и заполнить второй контейнер в соответствии с первым. + \en Find indices of faces and fill the second container in accordance with the first. \~ + \param[in] faces - \ru Множество граней. + \en A set of faces. \~ + \param[out] indices - \ru Найденное множество номеров этих граней в теле. + \en Found set of indices of these faces in the solid. \~ + \return \ru Найдены ли все номера? + \en Whether all the indices are found? \~ + */ + bool FindFacesIndexByFaces( RPArray & faces, SArray & indices ) const; + + /** \brief \ru Найти номера ребер и соединяемых ими граней. + \en Find indices of edges and faces connected by them. \~ + \details \ru Найти номера ребер и заполнить второй контейнер в соответствии с первым. + \en Find indices of edges and fill the second container in accordance with the first. \~ + \param[in] edges - \ru Множество ребер. + \en A set of edges. \~ + \param[out] indices - \ru Найденное множество комбинированных номеров ребер и соединяемых ими граней. + \en Found set of combined indices of edges and faces connected by them. \~ + \return \ru Найдены ли номера? + \en Whether indices are found? \~ + */ + bool FindFacesIndexByEdges( RPArray & edges, SArray & indices ) const; + + /// \ru Выдать ближайшую к точке вершину. \en Get the nearest vertex to point. + const MbVertex * FindNearestVertex( const MbCartPoint3D & p ) const; + + /** \brief \ru Найти стыкующиеся в вершине ребра тела. + \en Find mating edges of the solid at the vertex. \~ + \details \ru Найти ребра тела, для которых данная вершина является начальной или конечной. + \en Find edges of the solid for which this vertex is start or end. \~ + \param[in] vertex - \ru Вершина. + \en Vertex. \~ + \param[out] findEdges - \ru Стыкующиеся в вершине рёбра. + \en Mating edges at the vertex. \~ + */ + void FindEdgesForVertex( const MbVertex & vertex, RPArray & findEdges ) const; + + /** \brief \ru Найти стыкующиеся в вершине грани тела. + \en Find mating faces of the solid at the vertex. \~ + \details \ru Найти грани тела, для ребер которых данная вершина является конечной. + \en Find edges of the solid for which this vertex is end. \~ + \param[in] vertex - \ru Вершина. + \en Vertex. \~ + \param[out] findFaces - \ru Стыкующиеся в вершине грани. + \en Mating faces at the vertex. \~ + */ + void FindFacesForVertex( const MbVertex & vertex, RPArray & findFaces ) const; + + /** \brief \ru Найти для ребра его номер грани, номер цикла и номер ребра в цикле. + \en Find a face index for the edge, loop index and edge index in the loop. \~ + \details \ru Для ребра найти номер грани, номер цикла и номер ребра в цикле. + Если номера не найдены, то номера сохраняют исходные значения. + \en Find face index for the edge, loop index and edge index in the loop. + If the indices are not found, then indices remain the same. \~ + \param[in] edge - \ru Ребро. + \en Edge. \~ + \param[out] faceN - \ru Найденный номер грани. + \en Found face index. \~ + \param[out] loopN - \ru Найденный номер цикла грани. + \en Found index of face loop. \~ + \param[out] edgeN - \ru Найденный номер ребра в цикле. + \en Found index of the edge in the loop. \~ + \return \ru Найдены ли номера? + \en Whether indices are found? \~ + */ + bool FindEdgeNumbers ( const MbCurveEdge & edge, size_t & faceN, size_t & loopN, size_t & edgeN ) const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + const MbVertex * FindVertexByName( const MbName & ) const; + /// \ru Найти ребро по имени. \en Find edge by name. + const MbCurveEdge * FindEdgeByName ( const MbName & ) const; + /// \ru Найти грань по имени. \en Find face by name. + const MbFace * FindFaceByName ( const MbName & ) const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + MbVertex * FindVertexByName( const MbName & ); + /// \ru Найти ребро по имени. \en Find edge by name. + MbCurveEdge * FindEdgeByName ( const MbName & ); + /// \ru Найти грань по имени. \en Find face by name. + MbFace * FindFaceByName ( const MbName & ); + + /// \ru Создать именователь тела. \en Create name-maker of solid. + MbSNameMaker GetYourName() const; + + /// \ru Установить заданный флаг измененности для всех граней, рёбер и вершин. \en Set flag of changes for all the faces, edges and vertices. + void SetOwnChangedThrough( MbeChangedType ); + /// \ru Замкнуто ли тело (не имеет края)? \en Is solid closed (it has not boundary)? + bool IsClosed() const; + + /// \ru Является ли тело многочастным? \en Is a solid composed of several parts (is a multibody solid)? + bool IsMultiSolid() const; + /** \brief \ru Установить флаг многочастности с минимальной проверкой. + \en Set flag of multibody with minimal checks. \~ + \details \ru Установить флаг многочастности с минимальной проверкой. + Неправильная установка флага может привести к непредсказуемым последствиям в операциях с телом. + \en Set flag of multibody with minimal checks. + Improper flag setting can lead to unpredictable results after operations with the solid. \~ + \param[in] ms - \ru При ms == true полагается, что тело является многочастностным. + \en Assumed that solid is multibody if ms==true. \~ + \param[in] setDirectly - \ru Установить без каких-либо проверок. + \en Set without any checks. \~ + \return \ru Установлен ли флаг? + \en Whether flag was set? \~ + */ + bool SetMultiSolidState( bool ms, bool setDirectly = false ) const; + /// \ru Сбросить флаг многочастности в неопределённое состояние. \en Reset flag of multibody solid. + void ResetMultiSolidState() const { multiState = ms_Undefined; } + /// \ru Получить фактическое состояние флага многочастности. \en Get current state of multibody flag. + MultiState GetMultiSolidState() const { return multiState; } + + /// \ru Рассчитать габарит относительно локальной системы координат, заданной матрицей преобразования в неё. \en Calculate bounding box relative to the local coordinate system which is given by the matrix 'matrToLocal ' of transformation to it. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; + /// \ru Рассчитать габарит относительно локальной системы координат. \en Calculate bounding box relative to the local coordinate system. + void CalculateLocalGabarit( const MbPlacement3D & localPlace, MbCube & cube ) const; + /// \ru Выдать базовые объекты журнала построения. \en Get the base objects of history tree. + void BreakToBasisItem( size_t c, RPArray & s ); + /// \ru Присвоить свой указатель глобальной переменной Math::selectSolid = this (для отладки). \en Assign the pointer to global variable Math::selectSolid = this (for debugging). + void Math3DSelectSolid() const; + /** \} */ + +public: + friend MbResultType MakeIngot( RPArray &, bool, const MbSNameMaker &, MbSolid *& ); + +private: + void SetMultiSolidStateDirectly( bool ms ) const { multiState = ms ? ms_Multiple : ms_Single; } + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbSolid & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSolid ); +}; + +IMPL_PERSISTENT_OPS( MbSolid ) + + +#endif // __SOLID_H diff --git a/C3d/Include/space_instance.h b/C3d/Include/space_instance.h new file mode 100644 index 0000000..cf887f5 --- /dev/null +++ b/C3d/Include/space_instance.h @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вставка трёхмерного объекта. + \en Instance of three-dimensional object. \~ + +*/ +////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPACE_INSTANCE_H +#define __SPACE_INSTANCE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbLegend; +class MATH_CLASS MbPoint3D; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbSurface; + + +class MATH_CLASS MbSpaceInstance; +namespace c3d // namespace C3D +{ +typedef SPtr SInstanceSPtr; +typedef SPtr ConstSInstanceSPtr; + +typedef std::vector SInstancesVector; +typedef std::vector ConstSInstancesVector; + +typedef std::vector SInstancesSPtrVector; +typedef std::vector ConstSInstancesSPtrVector; +} + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Вставка трёхмерного объекта. + \en Instance of three-dimensional object. \~ + \details \ru Вставка позволяет работать с трёхмерным геометрическим объектом, как с + объектом геометричекой модели. Вставка позволяет использовать в геометричекой + модели любые другие объекты MbSpaceItem, например, резьбу и условные обозначения. + \en Instance allows to deal with three-dimensional object as with object of + geometric model. Instance allows to use any objects inherited from MbSpaceItem + such as thread and conventional notations in geometric model. \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbSpaceInstance : public MbItem { +protected : + MbSpaceItem * spaceItem; ///< \ru Трёхмерный геометрический объект. \en Three-dimensional geometric object. + +protected : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbSpaceInstance( const MbSpaceInstance &, MbRegDuplicate * ); +public : + /// \ru Конструктор по вспомогательному объекту. \en Constructor by auxiliary item. + MbSpaceInstance( MbLegend & ); + /// \ru Конструктор по точке. \en Constructor by point. + MbSpaceInstance( MbPoint3D & ); + /// \ru Конструктор по кривой. \en Constructor by curve. + MbSpaceInstance( MbCurve3D & ); + /// \ru Конструктор по поверхности. \en Constructor by surface. + MbSpaceInstance( MbSurface & ); + /// \ru Деструктор. \en Destructor. + virtual ~MbSpaceInstance(); + +public : + VISITING_CLASS( MbSpaceInstance ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en A type of an object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * iReg = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * iReg = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * iReg = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными? \en Are the objects similar? + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & r ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt n ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + // \ru Найти объект по геометрическому объекту (MbSpaceItem). \en Find the object by a geometric object (MbSpaceItem). + virtual const MbItem * FindItem( const MbSpaceItem * s, MbPath & path, MbMatrix3D & from ) const; + // \ru Дать все объекты указанного типа. \en Get all objects by type. \~ + virtual bool GetItems( MbeSpaceType type, const MbMatrix3D & from, + RPArray & items, SArray & matrs ); + // \ru Дать все уникальные объекты указанного типа. \en Get all unique objects by type . \~ + virtual bool GetUniqItems( MbeSpaceType type, CSSArray & items ) const; + + /** \ru \name Общие функции вставки трёхмерного объекта. + \en \name Common functions of instance of three-dimensional object. + \{ */ + /// \ru Выдать трёхмерный геометрический объект. \en Get three-dimensional geometric object. + const MbSpaceItem * GetSpaceItem() const; + /// \ru Выдать трёхмерный геометрический объект для модификации. \en Get three-dimensional geometric object for modification. + MbSpaceItem * SetSpaceItem(); + /// \ru Заменить геометрический объект. \en Replace geometric object. + void SetSpaceItem( MbSpaceItem * init ); + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSpaceInstance ) +OBVIOUS_PRIVATE_COPY( MbSpaceInstance ) +}; + +IMPL_PERSISTENT_OPS( MbSpaceInstance ) + +#endif // __SPACE_INSTANCE_H diff --git a/C3d/Include/space_item.h b/C3d/Include/space_item.h new file mode 100644 index 0000000..a89a3ab --- /dev/null +++ b/C3d/Include/space_item.h @@ -0,0 +1,463 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Геометрический объект в трехмерном пространстве. + \en Geometrical object in three-dimensional space. + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPACE_ITEM_H +#define __SPACE_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbVector3D; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCube; +class MATH_CLASS MbProperty; +class MATH_CLASS MbProperties; +class MATH_CLASS MbMesh; +struct MATH_CLASS MbControlData3D; +class MATH_CLASS MbStepData; +class MbRegTransform; +class MbRegDuplicate; + + +class MATH_CLASS MbSpaceItem; +namespace c3d // namespace C3D +{ +typedef SPtr SpaceItemSPtr; ///< \ru Умный указатель на геометрический объект. \en Smart pointer of an geometrical object. +typedef SPtr ConstSpaceItemSPtr; ///< \ru Умный указатель на геометрический объект. \en Smart pointer of an geometrical object. +typedef std::pair SpaceItemPair; ///< \ru Пара геометрических объектов. \en Pair of geometrical objects. + +typedef std::vector SpaceItemsVector; ///< \ru Вектор геометрических объектов. \en Vector of geometrical objects. +typedef std::vector ConstSpaceItemsVector; ///< \ru Вектор геометрических объектов. \en Vector of geometrical objects. + +typedef std::vector SpaceItemsSPtrVector; ///< \ru Вектор геометрических объектов. \en Vector of geometrical objects. +typedef std::vector ConstSpaceItemsSPtrVector; ///< \ru Вектор геометрических объектов. \en Vector of geometrical objects. +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы геометрических объектов в трёхмерном пространстве. + \en Types of spatial geometric objects. \~ + \details \ru Геометрические объекты группируются в семейства: + точки, кривые, поверхности объекты модели и вспомогательные объекты. + \en Geometric objects are grouped into families: + points, curves, surfaces, model objects and ancillary facilities. \~ + \ingroup Geometric_Items +*/ +// --- +enum MbeSpaceType { + + st_Undefined = 0, ///< \ru Неизвестный объект. \en Unknown object. + st_SpaceItem = 1, ///< \ru Геометрический объект. \en Geometric object. \n + + // \ru Типы точек. \en Point types. + st_Point3D = 101, ///< \ru Точка. \en Point. + st_FreePoint3D = 200, ///< \ru Тип для точек, созданных пользователем. \en Type for the user-defined points. \n + + // \ru Типы кривых. \en Curve types. + st_Curve3D = 201, ///< \ru Кривая. \en Curve. + st_Line3D = 202, ///< \ru Прямая. \en Line. + st_LineSegment3D = 203, ///< \ru Отрезок прямой. \en Line segment. + st_Arc3D = 204, ///< \ru Окружность, эллипс, дуга. \en Circle, ellipse, arc. + st_Spiral = 205, ///< \ru Спираль. \en Spiral. + st_ConeSpiral = 206, ///< \ru Коническая спираль. \en Conical spiral. + st_CurveSpiral = 207, ///< \ru Спираль по образующей кривой. \en Spiral curve constructed by generatrix. + st_CrookedSpiral = 208, ///< \ru Спираль по направляющей кривой. \en Spiral along the guide curve. + st_PolyCurve3D = 209, ///< \ru Кривая, построенная по точкам. \en Curve constructed by points. + st_Polyline3D = 210, ///< \ru Полилиния. \en Polyline. + st_Nurbs3D = 211, ///< \ru NURBS кривая. \en NURBS curve. + st_Bezier3D = 212, ///< \ru Кривая Безье. \en Bezier curve. + st_Hermit3D = 213, ///< \ru Составной кубический сплайн Эрмита. \en Composite Hermit cubic spline. + st_CubicSpline3D = 214, ///< \ru Кубический сплайн. \en Cubic spline. + st_PlaneCurve = 215, ///< \ru Плоская кривая в пространстве. \en Plane curve in space. + st_OffsetCurve3D = 216, ///< \ru Эквидистантная кривая. \en Offset curve. + st_TrimmedCurve3D = 217, ///< \ru Усеченная кривая. \en Truncated curve. + st_ReparamCurve3D = 218, ///< \ru Репараметризованная кривая. \en Reparametrized curve. + st_BridgeCurve3D = 219, ///< \ru Кривая-мостик, соединяющая две кривые. \en Curve as a bridge connecting two curves. + st_CharacterCurve3D = 220, ///< \ru Кривая, координатные функции которой заданы в символьном виде. \en Functionally defined curve. + st_ContourOnSurface = 221, ///< \ru Контур на поверхности. \en Contour on the surface. + st_ContourOnPlane = 222, ///< \ru Контур на плоскости. \en Contour on the plane. + st_SurfaceCurve = 223, ///< \ru Кривая на поверхности. \en Curve on the surface. + st_SilhouetteCurve = 224, ///< \ru Силуэтная кривая. \en Silhouette curve. + st_SurfaceIntersectionCurve = 225, ///< \ru Кривая пересечения поверхностей. \en Curve as intersection of surfaces. + st_BSpline = 226, ///< \ru В-сплайн. \en B-spline. + st_Contour3D = 227, ///< \ru Контур. \en Contour. + st_CoonsDerivative = 228, ///< \ru Кривая производных поверхности Кунса. \en Curve of Coons surface derivetives. + st_FreeCurve3D = 300, ///< \ru Тип для кривых, созданных пользователем. \en Type for the user-defined curves. \n + + // \ru Типы поверхностей. \en Surface types. + st_Surface = 301, ///< \ru Поверхность. \en Surface. + st_ElementarySurface = 302, ///< \ru Элементарная поверхность. \en Elementary surface. + st_Plane = 303, ///< \ru Плоскость. \en Plane. + st_ConeSurface = 304, ///< \ru Коническая поверхность. \en Conical surface. + st_CylinderSurface = 305, ///< \ru Цилиндрическая поверхность. \en Cylindrical surface. + st_SphereSurface = 306, ///< \ru Сфера. \en Sphere. + st_TorusSurface = 307, ///< \ru Тор. \en Torus. + st_SweptSurface = 308, ///< \ru Поверхность движения. \en Swept surface. + st_ExtrusionSurface = 309, ///< \ru Поверхность перемещения. \en Extrusion surface. + st_RevolutionSurface = 310, ///< \ru Поверхность вращения. \en Revolution surface. + st_EvolutionSurface = 311, ///< \ru Поверхность заметания. \en Swept surface with guide curve. + st_ExactionSurface = 312, ///< \ru Поверхность заметания с поворотными торцами. \en Swept surface with rotating ends. + st_ExpansionSurface = 313, ///< \ru Плоскопараллельная поверхность. \en Plane-parallel swept surfaces. + st_SpiralSurface = 314, ///< \ru Спиральная поверхность. \en Spiral surface. + st_RuledSurface = 315, ///< \ru Линейчатая поверхность. \en Ruled surface. + st_SectorSurface = 316, ///< \ru Секториальная поверхность. \en Sectorial surface. + st_PolySurface = 317, ///< \ru Поверхность, определяемая точками. \en Surface constructed by points. + st_HermitSurface = 318, ///< \ru Hermit поверхность, определяемая точками. \en Hermit surface. + st_SplineSurface = 319, ///< \ru NURBS поверхность, определяемая точками. \en NURBS surface. + st_GridSurface = 320, ///< \ru Поверхность, определяемая точками. \en Surface defined by points. + st_TriBezierSurface = 321, ///< \ru Треугольная Bezier поверхность, определяемая точками. \en Triangular Bezier surface. + st_TriSplineSurface = 322, ///< \ru Треугольная NURBS поверхность, определяемая точками. \en Triangular NURBS surface. + st_OffsetSurface = 323, ///< \ru Эквидистантная поверхность. \en Offset surface. + st_DeformedSurface = 324, ///< \ru Деформированная поверхность. \en Deformed surface. + st_NurbsSurface = 325, ///< \ru NURBS поверхность, определяемая кривыми. \en NURBS surface defined by curves. + st_CornerSurface = 326, ///< \ru Поверхность по трем кривым. \en The surface based on three curves. + st_CoverSurface = 327, ///< \ru Поверхность по четырем кривым. \en The surface based on the four curves. + st_CoonsPatchSurface = 328, ///< \ru Бикубическая поверхность Кунса по четырем кривым. \en Bicubic Coons surface constructed by four curves. + st_GregoryPatchSurface = 329, ///< \ru Поверхность Грегори по четырем кривым. \en Gregory surface constructed by four curves. + st_LoftedSurface = 330, ///< \ru Поверхность, проходящая через заданное семейство кривых. \en Lofted surface. + st_ElevationSurface = 331, ///< \ru Поверхность, проходящая через заданное семейство кривых, с направляющей. \en Lofted surface with the guide. + st_MeshSurface = 332, ///< \ru Поверхность на сетке кривых. \en The surface constructed by the grid curves. + st_GregorySurface = 333, ///< \ru Поверхность на ограничивающем контуре. \en The surface on the bounding contour. + st_SmoothSurface = 334, ///< \ru Поверхность сопряжения. \en Conjugation surface. + st_ChamferSurface = 335, ///< \ru Поверхность фаски. \en The surface of the bevel. + st_FilletSurface = 336, ///< \ru Поверхность скругления. \en Fillet surface. + st_ChannelSurface = 337, ///< \ru Поверхность скругления с переменным радиусом. \en Fillet surface with variable radius. + st_FullFilletSurface = 338, ///< \ru Поверхность полного скругления. \en Full fillet surface. + st_JoinSurface = 339, ///< \ru Поверхность соединения. \en The surface of the joint. + st_CurveBoundedSurface = 340, ///< \ru Ограниченная кривыми поверхность. \en The surface bounded by curves. + st_BendedUnbendedSurface = 341, ///< \ru Поверхность, полученная сгибом/разгибом. \en Surface constructed by fold / unbending. + st_CylindricBendedSurface = 342, ///< \ru Поверхность, полученная цилиндрическим сгибом. \en Surface constructed by cylindrical fold. + st_CylindricUnbendedSurface = 343, ///< \ru Поверхность, полученная цилиндрическим разгибом. \en Surface constructed by cylindrical unbending. + st_ConicBendedSurface = 344, ///< \ru Поверхность, полученная коническим сгибом. \en Surface constructed by conical fold. + st_ConicUnbendedSurface = 345, ///< \ru Поверхность, полученная коническим разгибом. \en Surface constructed by conical unbending. + st_GregoryRibbonPatchSurface= 346, ///< \ru Поверхность Грегори с граничными условиями. \en Gregory patch surface with ribbons. + st_ExplorationSurface = 347, ///< \ru Поверхность заметания с масштабированием и поворотом образующей кривой. \en Swept surface with scaling and winding of generating curve. + st_FreeSurface = 400, ///< \ru Тип для поверхностей, созданных пользователем. \en Type for the user-defined surfaces. \n + + // \ru Типы вспомогательных объектов. \en Helper object types. + st_Legend = 401, ///< \ru Вспомогательный объект. \en The helper object. + st_Marker = 402, ///< \ru Точка и двойка ортонормированных векторов (применяется в сопряжениях, в кинематике). \en Point and two orthonormal vectors. + st_Thread = 403, ///< \ru Резьба. \en Thread. + st_Symbol = 404, ///< \ru Условное обозначение. \en Symbol. + st_PointsSymbol = 405, ///< \ru Условное обозначение на базовых точках. \en Symbol on the basic points. + st_Rough = 406, ///< \ru Обозначение шероховатости. \en Designation of roughness. + st_Leader = 407, ///< \ru Обозначение линии выноски. \en Designation of the leader line. + st_Dimension3D = 408, ///< \ru Размер. \en Dimension + st_LinearDimension3D = 409, ///< \ru Линейный размер. \en Linear dimension. + st_DiameterDimension3D = 410, ///< \ru Диаметральный размер. \en Diameter dimension. + st_RadialDimension3D = 411, ///< \ru Радиальный размер. \en Radial dimension. + st_AngularDimension3D = 412, ///< \ru Угловой размер. \en Angular dimension. + st_FreeLegend = 500, ///< \ru Тип для вспомогательных объектов, созданных пользователем. \en Type for the user helper objects. \n + + // \ru Типы объектов модели геометрического ядра с журналом построения и атрибутами. \en Model object types with history tree and attributes. + st_Item = 501, ///< \ru Геометрический объект модели. \en Model object. + st_AssistedItem = 502, ///< \ru Локальная система координат. \en The local coordinate system. + st_PointFrame = 503, ///< \ru Точечный каркас. \en Point frame. + st_WireFrame = 504, ///< \ru Проволочный каркас. \en Wire frame. + st_Solid = 505, ///< \ru Твердое тело. \en Solid. + st_Instance = 506, ///< \ru Объект модели в локальной системе координат. \en The model object in the local coordinate system. + st_Assembly = 507, ///< \ru Сборочная единица объектов модели. \en Assembly unit of model objects. + st_Mesh = 508, ///< \ru Полигональный объект в виде точек, ломаных и пластин. \en Polygonal form of an object as a set of points, polylines, and plates. + st_SpaceInstance = 509, ///< \ru Обертка над геометрическим объектом MbSpaceItem. \en Wrapper over a geometry MbSpaceItem. + st_PlaneInstance = 510, ///< \ru Обертка над плоским объектом MbPlaneItem. \en Wrapper over a flat object MbPlaneItem. + st_Collection = 511, ///< \ru Коллекция элементов. \en Collection of elements. \n + + st_FreeItem = 600, ///< \ru Тип для объектов, созданных пользователем. \en Type for the user-defined objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Геометрический объект в трехмерном пространстве. + \en Geometrical object in three-dimensional space. \~ + \details \ru Родительский класс геометрических объектов в трехмерном пространстве. + Наследниками являются: точка MbPoint3D, кривая MbCurve3D, поверхность MbSurface, + объект геометрической модели MbItem и другие вспомогательные объекты.\n + Объект имеет счетчик ссылок и умеет записываться и читаться. + \en The parent class of geometric objects in three dimensions. + Heirs are: point MbPoint3D, curve MbCurve3D, surface MbSurface, + geometric object model and MbItem other ancillary facilities.\n + The object has a reference count and can be written and read.\n \~ + \ingroup Geometric_Items +*/ +// --- +class MATH_CLASS MbSpaceItem : public TapeBase, public MbRefItem { +protected : + /// \ru Конструктор без параметров. \en Default constructor. + MbSpaceItem(); +public : + /// \ru Деструктор. \en Destructor. + virtual ~MbSpaceItem(); + + /** \ru \name Общие функции геометрического объекта. + \en \name General functions of a geometric object. + \{ */ + /// \ru Получить регистрационный тип (для копирования, дублирования). \en Get a registration type (for copying, duplication). + virtual MbeRefType RefType() const; + /// \ru Получить тип объекта. \en Get the type of the object. + virtual MbeSpaceType IsA() const = 0; + /// \ru Получить групповой тип объекта. \en Get the group object type. + virtual MbeSpaceType Type() const = 0; + /// \ru Получить семейство объекта. \en Get family of objects. + virtual MbeSpaceType Family() const = 0; + + /// \ru Принадлежит ли объект к регистрируемому семейству. \en Whether the object belongs to a registrable family. + virtual bool IsFamilyRegistrable() const; + + /** \brief \ru Создать копию объекта. + \en Create a copy of the object. \~ + \details \ru Создать копию объекта с использованием регистратора. + Регистратор используется для предотвращения многократного копирования объекта. + Если объект содержит ссылки на другие объекты, то вложенные объекты так же копируются. + Допустимо не передавать регистратор в функцию. Тогда будет создана новая копия объекта. + При копировании одиночного объекта или набора не связанных между собой объектов допустимо не использовать регистратор. + Регистратор необходимо использовать, если надо последовательно копировать несколько взаимосвязанных объектов. + Возможно, что связь объектов обусловлена наличием в них ссылок на общие объекты. + Тогда, при копировании без использования регистратора, можно получить набор копий, + содержащих ссылки на разные копии одного и того же вложенного объекта, что ведет к потере связи между копиями. + \en Create a copy of an object using the registrator. + Registrator is used to prevent multiple copy of the object. + If the object contains references to the other objects, then nested objects are copied as well. + It is allowed not to pass registrator into the function. Then new copy of object will be created. + While copying of single object or set of not connected objects, it is allowed not to use registrator. + Registrator should be used if it is required to copy several connected objects. + It is possible, that objects connection is based on the references to common objects. + Then, while copying without using of registrator, it is possible to obtain set of copies, + that contain references to the different copies of the same nested object, that leads to loss of connection between copies.\~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \return \ru Копия объекта. + \en A copy of the object. + */ + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const = 0; + + /** \brief \ru Преобразовать объект согласно матрице. + \en Convert the object according to the matrix. \~ + \details \ru Преобразовать исходный объект согласно матрице c использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то вложенные объекты так же преобразуются согласно матрице. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих трансформации. + \en Convert the original object according to the matrix using the registrator. + If object contains references to the other geometric objects, then nested objects are transformed according to the matrix. + Registrator is needed to prevent multiple object copying. + It is allowed to use function without registrator, if it is needed to transform single object. + If it is needed to transform a set of connected objects, then one should use registrator + to prevent repeating transformation of nested objects, because of the possible situation + when several objects contain references to the same common objects, that require to be transformed.\~ + \param[in] matr - \ru Матрица преобразования. + \en Transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. + */ + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Сдвинуть объект вдоль вектора. + \en Move an object along a vector. \~ + \details \ru Сдвинуть геометрический объект вдоль вектора с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция сдвига. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих сдвигу. + \en Move an object along a geometric vector using the registrator. + If object contains references to the other geometric objects then the move operation is applied to the nested objects. + Registrator is needed to prevent multiple copying of the object. + It is allowed to use function without registrator, if it is needed to transform a single object. + If it is needed to transform a set of connected objects, then one should use registrator + to prevent repeating transformation of nested objects, because of the possible situation + when several objects contain references to the same common objects, that require to be moved.\~ + \param[in] to - \ru Вектор сдвига. + \en Shift vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. + */ + virtual void Move ( const MbVector3D & to, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Повернуть объект вокруг оси на заданный угол. + \en Rotate an object around an axis at a given angle. \~ + \details \ru Повернуть объект вокруг оси на заданный угол с использованием регистратора. + Если объект содержит ссылки на другие геометрические объекты, то к вложенным объектам так же применяется операция поворота. + Регистратор служит для предотвращения многократного преобразования объекта. + Допустимо использовать функцию без регистратора, если надо преобразовать одиночный объект. + Если надо преобразовать набор взаимосвязанных объектов, необходимо использовать регистратор для + предотвращения повторного преобразования вложенных объектов, поскольку не исключена ситуация, + когда несколько объектов из набора содержат ссылки на один или несколько общих объектов, подлежащих повороту. + \en Rotate an object around an axis at a given angle with the registrator. + If object contains references to the other geometric objects then the rotation operation is applied to the nested objects. + Registrator is needed to prevent multiple copying of the object. + It is allowed to use function without registrator, if it is needed to transform a single object. + If it is needed to transform a set of connected objects, then one should use registrator + to prevent repeating transformation of nested objects, because of the possible situation + when several objects contain references to the same common objects, that require to be rotated.\~ + \param[in] axis - \ru Ось поворота. + \en The axis of rotation. \~ + \param[in] angle - \ru Угол поворота. + \en Rotation. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. + */ + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Определить, являются ли объекты равными. + \en Determine whether an object is equal. \~ + \details \ru Равными считаются однотипные объекты, все данные которых одинаковы (равны). + \en Still considered objects of the same type, all data is the same (equal). \~ + \param[in] item - \ru Объект для сравнения. + \en The object to compare. \~ + \param[in] accuracy - \ru Точность сравнения. + \en The accuracy to compare. \~ + \return \ru Равны ли объекты. + \en Whether the objects are equal. + */ + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; + + /** \brief \ru Определить, являются ли объекты подобными. + \en Determine whether an object is similar. \~ + \details \ru Подобными считаются однотипные объекты, данные которых можно приравнять или данные так же являются подобными (указатели). + Подобный объект можно инициализировать по данным подобного ему объекта (приравнять один другому без изменения адресов). + \en Such are considered the same objects whose data are similar. \~ + \param[in] item - \ru Объект для сравнения. + \en The object to compare. \~ + \return \ru Подобны ли объекты. + \en Whether the objects are similar. + */ + virtual bool IsSimilar( const MbSpaceItem & item ) const; + + /** \brief \ru Сделать объекты равным, если они подобны. + \en Make objects equal if they are similar. \~ + \details \ru Равными можно сделать только подобные объекты. + Подобный объект приравнивается присланному путем изменения численных данных. + \en You can still make only a similar objects. \~ + \param[in] item - \ru Объект для инициализации. + \en The object to initialize. \~ + \return \ru Сделан ли объект равным присланному. + \en Object is changed. + */ + virtual bool SetEqual ( const MbSpaceItem & item ) = 0; + + /** \brief \ru Определить расстояние до точки. + \en Determine the distance to the point. \~ + \details \ru Определить расстояние до точки. + \en Determine the distance to the point. \~ + \param[in] point - \ru Точка. + \en Point. \~ + \return \ru Расстояние от объекта до точки. + \en Distance to point + */ + virtual double DistanceToPoint ( const MbCartPoint3D & point ) const = 0; + + /** \brief \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. + \en Expand sent bounding box (a.k.a. gabarit), so that it included the object. \~ + \details \ru Расширить присланный габаритный куб так, чтобы он включал в себя данный объект. + \en Expand sent bounding box, so that it included the object. \~ + \param[in, out] cube - \ru Принимающий габаритный куб с информацией по габаритам. + \en The bounding box to expand. + */ + virtual void AddYourGabaritTo( MbCube & cube ) const = 0; + + /** \brief \ru Рассчитать габарит в локальной системы координат. + \en To compute bounding box in a local coordinate system\~ + \details \ru Для получения габарита объекта относительно локальной системы координат, + присланный куб делается пустым. Затем вычисляются габариты объекта в локальной системе координат + и сохраняются в кубе cube. + \en To obtain bounding box of object with regar to a local coordinate system, + sent box is made to be empty. Then it is computed bounding box of object in a local coordinate system \ + and it is stored in box 'cube' \~ + \param[in] into - \ru Матрица перехода от текущей для объекта системы координат к локальной системе координат. + \en Transformation matrix from object's current coordinate system to a local coordinate system \~ + \param[in, out] cube - \ru Куб с информацией по габаритам. + \en Information on bounding box \~ + */ + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const = 0; + + /// \ru Перевести все временные (mutable) данные объекта в неопределённое (исходное) состояние. \en Translate all the time (mutable) data objects in an inconsistent (initial) state. + virtual void Refresh(); + + /// \ru Создать собственное свойство с заданием его имени. \en Create your own property with the name. + virtual MbProperty & CreateProperty( MbePrompt name ) const = 0; + + /** \brief \ru Выдать свойства объекта. + \en Outstanding properties of the object. \~ + \details \ru Выдать внутренние данные (свойства) объекта для их просмотра и модификации. + \en Issue internal data (properties) of the object for viewing and modification. \~ + \param[in] properties - \ru Контейнер для внутренних данных объекта. + \en Container for the internal data of the object. + */ + virtual void GetProperties( MbProperties & properties ) = 0; + + /** \brief \ru Изменить свойства объекта. + \en Change the properties of an object. \~ + \details \ru Изменение внутренних данных (свойств) объекта выполняется копированием соответствующих значений из присланного объекта. + \en Changing the internal data (properties) of the object you are copying the corresponding values from the sent object. \~ + \param[in] properties - \ru Контейнер для внутренних данных объекта. + \en Container for the internal data of the object. + */ + virtual void SetProperties( const MbProperties & properties ) = 0; + + /** \brief \ru Построить полигональную копию mesh. + \en Build polygonal copy mesh. \~ + \details \ru Построить полигональную копию данного объекта, представленную полигонами, или/и плоскими пластинами. + \en Build a polygonal copy of the object that is represented by polygons or/and fasets. \~ + \param[in] stepData - \ru Данные для вычисления шага при построении полигонального. + \en Data for еру step calculation for polygonal object. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[in, out] mesh - \ru Построенный полигональный объект. + \en The builded polygonal object. + */ + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const = 0; + void CalculateWire( const MbStepData & stepData, MbMesh & mesh ) const // The method deprecated. It will be removed at 2019. Use CalculateMesh( stepData, MbFormNote(true, false), mesh ); \~ + { CalculateMesh( stepData, MbFormNote(true, false), mesh ); } + void CalculateWire( double sag, MbMesh & mesh ) const // The method deprecated. It will be removed at 2018. Use CalculateMesh( MbStepData(ist_SpaceStep,sag), MbFormNote(true, false), mesh ); \~ + { CalculateMesh( MbStepData(ist_SpaceStep,sag), MbFormNote(true, false), mesh ); } + + /// \ru Выдать базовые объекты в присланный контейнер. \en Outstanding reference objects in a container sent. + virtual void GetBasisItems ( RPArray & ); + /// \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void GetBasisPoints( MbControlData3D & ) const; + /// \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void SetBasisPoints( const MbControlData3D & ); + /** \} */ + /** \brief \ru Регистрация объекта. + \en Register object. \~ + \details \ru Регистрация объекта для предотвращения его многократной записи. + Другие объекты могут содержать указатель на данный объект. + Функция взводит флаг, который позволяет записывать объект один раз, + а в остальных записях ссылаться на записанный экземпляр. + Чтение так же выполняется один раз, а в остальных случаях чтения подставляется адрес уже прочитанного объекта. + \en Register object to prevent its rewritable. + Other objects may contain a pointer to the given object. + Function sets a flag to 'true', which allows to write object for one time, + and make a reference to the written instance of the other records. + Reading is performed once, and there is substitution of already read object for all the remaining reading cases. + */ + void PrepareWrite() { SetRegistrable( (GetUseCount() > 1) ? registrable : noRegistrable ); } + +DECLARE_PERSISTENT_CLASS( MbSpaceItem ) +OBVIOUS_PRIVATE_COPY( MbSpaceItem ) +}; + +IMPL_PERSISTENT_OPS( MbSpaceItem ) + + +#endif // __SPACE_ITEM_H diff --git a/C3d/Include/surf_chamfer_surface.h b/C3d/Include/surf_chamfer_surface.h new file mode 100644 index 0000000..c7c09a0 --- /dev/null +++ b/C3d/Include/surf_chamfer_surface.h @@ -0,0 +1,229 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность-фаска. + \en Chamfer surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CHAMFER_SURFACE_H +#define __SURF_CHAMFER_SURFACE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность фаски. + \en Chamfer surface. \~ + \details \ru Поверхность фаски является линейчатой поверхностью, + построенной по двут кривым на сопрягаемых поверхностях: curve1 и curve2. + Первый параметр поверхности совпадает с параметром кривых curve1 и curve2. + Второй параметр изменяется от нуля (точки совпадают с curve1) до единицы (точки совпадают с curve2). + В отличие от других поверхностей функции PointOn и Derive... поверхность фаски не корректирует + первый параметр при выходе его за пределы области определения. + Сечение поверхности вдоль её второго параметра будет отрезком прямой. + \en Chamfer surface is ruled surface + constructed from two curves on the mating surfaces: curve1 and curve2. + The first surface parameter coincides with the parameter of curves curve1 and curve2. + The second parameter is changed from zero (points coincide with curve1) to unit (points coincide with curve2). + In contrast to other surfaces functions PointOn and Derive ... chamfer surface does not correct + the first parameter when it is out of domain bounds. + Section of surface along its second parameter is a line segment. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbChamferSurface : public MbSmoothSurface { + +public: + /** \brief \ru Конструктор по двум кривым, катетам и типу сопряжения. + \en Constructor by two curves, cathetuses and type of mate. \~ + \details \ru Конструктор по двум кривым, катетам и типу сопряжения. + \en Constructor by two curves, cathetuses and type of mate. \~ + \param[in] curv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface \~ + \param[in] curv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface \~ + \param[in] d1 - \ru Катет(или угол в зависимости от типа сопряжения) со знаком для поверхности кривой curv1 + \en Cathetus(or angle according to the type of mate) with the sign for surface of curve curv1 \~ + \param[in] d2 - \ru Катет(или угол в зависимости от типа сопряжения) со знаком для поверхности кривой curv2 + \en Cathetus(or angle according to the type of mate) with the sign for surface of curve curv2 \~ + \param[in] fm - \ru Тип сопряжения: + st_Chamfer - фаска с заданными катетами + st_Slant1 - фаска по катету и углу + st_Slant2 - фаска по углу и катету + \en Mate type: + st_Chamfer - chamfer with given cathetuses + st_Slant1 - chamfer by cathetus and angle + st_Slant2 - chamfer by angle and cathetus \~ + */ + MbChamferSurface( MbSurfaceCurve & curv1, MbSurfaceCurve & curv2, double d1, double d2, MbeSmoothForm fm ); + + /** \brief \ru Конструктор по двум кривым, катетам и типу сопряжения. + \en Constructor by two curves, cathetuses and type of mate. \~ + \details \ru Конструктор по двум кривым, катетам и типу сопряжения. + \en Constructor by two curves, cathetuses and type of mate. \~ + \param[in] surf1 - \ru Первая поверхность + \en The first surface \~ + \param[in] curv1 - \ru Кривая в параметрах первой поверхности + \en Curve in parameters of the first surface \~ + \param[in] surf2 - \ru Вторая поверхность + \en The second surface \~ + \param[in] curv2 - \ru Кривая в параметрах второй поверхности + \en Curve in parameters of the second surface \~ + \param[in] d1 - \ru Катет(или угол в зависимости от типа сопряжения) со знаком для поверхности кривой curv1 + \en Cathetus(or angle according to the type of mate) with the sign for surface of curve curv1 \~ + \param[in] d2 - \ru Катет(или угол в зависимости от типа сопряжения) со знаком для поверхности кривой curv2 + \en Cathetus(or angle according to the type of mate) with the sign for surface of curve curv2 \~ + \param[in] fm - \ru Тип сопряжения: + st_Chamfer - фаска с заданными катетами + st_Slant1 - фаска по катету и углу + st_Slant2 - фаска по углу и катету + \en Mate type: + st_Chamfer - chamfer with given cathetuses + st_Slant1 - chamfer by cathetus and angle + st_Slant2 - chamfer by angle and cathetus \~ + */ + MbChamferSurface( MbSurface & surf1, MbCurve & curv1, + MbSurface & surf2, MbCurve & curv2, double d1, double d2, MbeSmoothForm fm ); + +protected: + MbChamferSurface( const MbChamferSurface &, MbRegDuplicate * ); + MbChamferSurface( const MbChamferSurface * ); // \ru Конструктор копирования с теми же опорными поверхностями для CurvesDuplicate(). \en Copy constructor with the same support surfaces for CurvesDuplicate(). + +private: + MbChamferSurface( const MbChamferSurface & ); // \ru Не реализовано. \en Not implemented. + +public: + virtual ~MbChamferSurface (); + +public: + VISITING_CLASS( MbChamferSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + virtual void Init0( double wmin, double wmax, bool insertPoints = true ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента. \en Make a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Cделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems( RPArray &s ); // \ru Дать базовые поверхности. \en Get base surfaces. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр при его выходе за пределы определения параметров. + \en \name Functions for working at domain of surface + Functions PointOn and Derive...of smooth surfaces don't correct + the first parameter when it is out of domain bounds. + \{ */ + virtual void PointOn ( double &u, double &v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double &u, double &v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double &u, double &v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double &u, double &v, MbVector3D & ) const; + virtual void DeriveUUV( double &u, double &v, MbVector3D & ) const; + virtual void DeriveUVV( double &u, double &v, MbVector3D & ) const; + virtual void DeriveVVV( double &u, double &v, MbVector3D & ) const; + virtual void Normal ( double &u, double &v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalV ( double &u, double &v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature along v. + + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Creation of an offset surface. + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru Построить NURBS копию поверхности. \en Construct a NURBS copy of the surface. + + virtual MbCurve3D * CurveV( double u, MbRect1D *pRrn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + virtual bool GetCylinderAxis( MbAxis3D &axis ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + + virtual void ChangeCarrier( const MbSpaceItem &item, MbSpaceItem &init ); // \ru Изменение носителя. \en Changing of carrier. + virtual bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); // \ru Изменение носимых элементов. \en Change carrier elements. + virtual double GetSmoothRadius() const; // \ru Дать радиус. \en Get radius. + virtual void GetDistances( double u, double &d1, double &d2 ) const; // \ru Дать радиусы со знаком. \en Get radii with a sign. + virtual double GetDistance( bool s ) const; // \ru Дать радиус со знаком. \en Get radius with a sign. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether a surface is planar. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric domain to the parametric domain of surf. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons along u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons along v. + + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives along V are equal to zero. + /** \} */ + /** \ru \name Функции поверхности сопряжения + \en \name Functions of smooth surface + \{ */ + virtual MbSmoothSurface & CurvesDuplicate() const; // \ru Копия с теми же опорными поверхностями. \en Copy with the same support surfaces. + // \ru Объединить поверхности путём включения поверхности init в данную поверхность. \en Unite surface by inclusion of 'init' surface to the given surface. + virtual bool SurfacesCombine( const MbSurfaceIntersectionCurve & edge, + const MbSurface & init, bool add, MbMatrix & matr, + const MbSurfaceIntersectionCurve * seam ); + //virtual void InsertPointsToCurves( double u ); // \ru Добавить точки в опорные кривые поверхности. \en Add points to support curves of surface. + + /** \} */ +private: + void operator = ( const MbChamferSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbChamferSurface ) +}; + +IMPL_PERSISTENT_OPS( MbChamferSurface ) + +#endif // __SURF_CHAMFER_SURFACE_H diff --git a/C3d/Include/surf_channel_surface.h b/C3d/Include/surf_channel_surface.h new file mode 100644 index 0000000..27c8a1c --- /dev/null +++ b/C3d/Include/surf_channel_surface.h @@ -0,0 +1,275 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность скругления с переменным радиусом обычная или с сохранением кромки. + \en Fillet surface with variable radius is normal or with preservation of edges. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CHANNEL_SURFACE_H +#define __SURF_CHANNEL_SURFACE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность скругления с переменным радиусом обычная или с сохранением кромки. + \en Fillet surface with variable radius is normal or with preservation of edges. \~ + \details \ru Поверхность скругления с переменным радиусом является NURBS-поверхностью, + построенной по трём кривым: curve1, curve0, curve2. + Первый параметр поверхности совпадает с параметром кривых curve1, curve0, curve2. + Второй параметр изменяется от нуля (точки совпадают с curve1) до единицы (точки совпадают с curve2). + Функция function определяет изменение радиуса и равна отношению текущего радиуса к заданному для поверхности радиусу. + Параметр функции радиуса совпадает с параметром кривых curve1, curve0, curve2. + Если коэффициент формы conic = _ARC_ ( 0 ), то вес каждой точки кривой curve0 задаётся функцией weights0 и + вычислен так, что сечение поверхности вдоль её второго параметра будет дугой окружности, + то есть при любом параметре u три точки curve1(u), curve0(u), curve2(u) определяют NURBS-кривую в форме дуги окружности. + Если коэффициент формы conic != _ARC_, то вес каждой точки кривой curve0 равен conic / ( 1.0 - conic ). + При conic = 0.5 сечение поверхности вдоль её второго параметра будет параболой. \n + \en Fillet surface with variable radius is NURBS-surface + constructed on three curves: curve1, curve0, curve2. + The first surface parameter coincides with the parameter of curve1, curve0, curve2 curves. + The second parameter is changed from zero (points coincide with curve1) to unit (points coincide with curve2). + Function "function" determines the change of the radius and equals the ratio of the current radius to given for surface. + The parameter of radius function coincides with the parameter of curves curve1, curve0, curve2. + If coefficient of shape conic = _ARC_ ( 0 ), then the weight of each point of the curve0 curve determined by the function weights0 and + calculated so that the section of surface along its second parameter is a circular arc + i.e. for any parameter u three points of curve1(u), curve0(u), curve2(u) determine the NURBS-curve with the shape of a circular arc. + If coefficient of shape conic != _ARC_, then the weight of each point of the curve0 curve is equal to conic / ( 1.0 - conic ). + If conic = 0.5, then the surface section along its second parameter is parabola. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbChannelSurface : public MbFilletSurface { +private: + MbFunction * function; ///< \ru Функция изменения радиуса (переменный коэффициент). \en Function of change of the radius (variable coefficient). + +public: + + /** \brief \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and type of mate. \~ + \details \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and type of mate. \~ + \param[in] curv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface \~ + \param[in] curv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой crve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой crve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой \n + st_Fillet - скругление с заданными радиусами + \en Mate type: \n + st_Span - fillet with a given chord \n + st_Fillet - fillet with given radii. \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0.5 - дуга окружности) + \en Coefficient of shape is changed from 0.05 to 0.95 (if 0.5 - circular arc) \~ + \param[in] func - \ru Функция изменения радиуса + \en Function of change of the radius \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Uniform parametrization by arc or not \~ + */ + MbChannelSurface( MbSurfaceCurve & curv1, MbSurfaceCurve & curv2, + double d1, double d2, MbeSmoothForm fm, double cn, MbFunction & func, bool ev ); + + /** \brief \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and type of mate. \~ + \details \ru Конструктор поверхности с сохранением кромки по двум кривым и типу сопряжения. + \en Constructor of surface with preservation of edges by two curves and mate type. \~ + \param[in] curv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface \~ + \param[in] curv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой crve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой crve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой \n + st_Fillet - скругление с заданными радиусами + \en Mate type: \n + st_Span - fillet with a given chord \n + st_Fillet - fillet with given radii. \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0.5 - дуга окружности) + \en Coefficient of shape is changed from 0.05 to 0.95 (if 0.5 - circular arc) \~ + \param[in] func - \ru Функция изменения радиуса + \en Function of change of the radius \~ + \param[in] byFirst - \ru true - кривая curve2 является кромкой, false - кривая curve1 является кромкой + \en True - curve2 curve is edge, false - curve1 curve is edge \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Uniform parametrization by arc or not \~ + */ + MbChannelSurface( MbSurfaceCurve & curv1, MbSurfaceCurve & curv2, + double d1, double d2, MbeSmoothForm fm, double cn, MbFunction & func, bool byFirst, bool ev ); + + /** \brief \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and type of mate. \~ + \details \ru Конструктор поверхности с сохранением кромки по двум кривым и типу сопряжения. + \en Constructor of surface with preservation of edges by two curves and mate type. \~ + \param[in] surf1 - \ru Первая поверхность + \en First surface \~ + \param[in] curv1 - \ru Опорная кривая в параметрах первой поверхности + \en Support curve at parameters of the first surface \~ + \param[in] surf2 - \ru Вторая поверхность + \en Second surface \~ + \param[in] curv2 - \ru Опорная кривая в параметрах второй поверхности + \en Support curve at parameters of the second surface \~ + \param[in] curv0 - \ru Кривая пересеченния касательных к поверхностям + \en Intersection curve of tangents to surfaces \~ + \param[in] weig0 - \ru Функция изменения веса. + \en Function of change of the weights. \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой crve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой crve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой \n + st_Fillet - скругление с заданными радиусами + \en Mate type: \n + st_Span - fillet with a given chord \n + st_Fillet - fillet with given radii. \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0.5 - дуга окружности) + \en Coefficient of shape is changed from 0.05 to 0.95 (if 0.5 - circular arc) \~ + \param[in] func - \ru Функция изменения радиуса. + \en Function of change of the radius. \~ + \param[in] byFirst - \ru true - кривая curve2 является кромкой, false - кривая curve1 является кромкой + \en True - curve2 curve is edge, false - curve1 curve is edge \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Uniform parametrization by arc or not \~ + */ + MbChannelSurface( MbSurface & surf1, MbCurve & curv1, + MbSurface & surf2, MbCurve & curv2, + MbCurve3D & curv0, MbFunction & weig0, + double d1, double d2, MbeSmoothForm fm, double cn, MbFunction & func, bool ev ); + +protected: + MbChannelSurface( const MbChannelSurface &, MbRegDuplicate * ); + MbChannelSurface( const MbChannelSurface * ); // \ru Конструктор копирования с теми же опорными поверхностями для CurvesDuplicate() \en Copy constructor with the same support surfaces for CurvesDuplicate() + +private: + MbChannelSurface( const MbChannelSurface & ); // \ru Не реализовано. \en Not implemented. + +public: + virtual ~MbChannelSurface (); + +public: + VISITING_CLASS( MbChannelSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Creation of an offset surface. + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; + /** \} */ + /** \ru \name Функции поверхности сопряжения + \en \name Functions of smooth surface + \{ */ + virtual MbSmoothSurface & CurvesDuplicate() const; // \ru Копия с теми же опорными поверхностями. \en Copy with the same support surfaces. + virtual double GetSmoothRadius() const; // \ru Дать радиус. \en Get radius. + virtual double DistanceRatio( bool firstCurve, MbCartPoint3D & p, double distance ) const; + /** \} */ + /** \ru \name Функции поверхности скругления с переменным радиусом обычная или с сохранением кромки + \en \name Functions of fillet surface with variable radius is normal or with preservation of edges + \{ */ + + /** \brief \ru Добавить точку в опорные кривые границы. + \en Add a point to the support curves of the boundary. \~ + \details \ru Добавить точку в опорные кривые границы.\n + Точка будет добавлена в кривую, если она имеет тип pt_LineSegment, pt_CubicSpline или pt_Hermit. + \en Add a point to the support curves of the boundary.\n + A point will be added into a curve if it has a type pt_LineSegment, pt_CubicSpline or pt_Hermit. \~ + \param[out] t1 - \ru Параметр точки на первой кривой (если add1 = true) + \en Parameter of a point on the first curve (if add1 equals true) \~ + \param[in] p1 - \ru Точка на первой кривой + \en Point on the first curve \~ + \param[in] add1 - \ru Нужно ли добавлять точку в первую кривую + \en Whether to add a point to the first curve \~ + \param[out] t2 - \ru Параметр точки на второй кривой (если add2 = true) + \en Parameter of a point on the second curve (if add2 equals true) \~ + \param[in] p2 - \ru Точка на второй кривой + \en Point on the second curve \~ + \param[in] add2 - \ru Нужно ли добавлять точку во вторую кривую + \en Whether to add a point to the second curve \~ + */ + virtual bool InsertPoints( double & t1, const MbCartPoint & p1, bool add1, + double & t2, const MbCartPoint & p2, bool add2 ); + + /** \brief \ru Проверить наличие полюса. + \en Check pole availability. \~ + \details \ru Проверить наличие полюса. + \en Check pole availability. \~ + \param[in] u - \ru Начальное приближение параметра по U для поиска полюса + \en Initial approximation of parameter U to search pole \~ + \param[in] bModify - \ru Флаг модификации поверхности \n + если true, то поверхность корректирует свои параметры по U + и соответственно им опорные кривые curve1 и curve2 + \en Flag of surface modification \n + if true, then the surface corrects its parameters along U + and according to them the support curves curve1 and curve2 \~ + \return \ru true - если нашли полюс + \en True - if pole has been found \~ + */ + bool CheckPole( double & u, bool bModify = true ); + /// \ru Получить функцию изменения радиуса. \en Get a function of radius changing. + const MbFunction & GetFunction() const { return *function; } + /// \ru Получить функцию изменения радиуса. \en Get a function of radius changing. + MbFunction & SetFunction() { return *function; } + /// \ru Заменить функцию изменения радиуса. \en Set a function of radius changing. + void SetFunction( MbFunction & funcNew ); // \ru (новая функция должна быть корректна) \en (new function must be correct) + + /** \} */ +protected: + void CalculateCurves( bool insertPoints ); + +private: + // \ru Дать коэффициент для радиуса \en Get coefficient for radius + virtual double FunctionValue( double u ) const; + void CheckPole(); // \ru Проверить полюса \en Check poles + // \ru Добавить точку в опорные кривые границы поверхности с постоянной хордой. \en Add a point to the support curves of the boundary of surface with constant chord. \~ + bool InsertForSpan( double & t1, const MbCartPoint & p1, bool add1, + double & t2, const MbCartPoint & p2, bool add2 ); + void operator = ( const MbChannelSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbChannelSurface ) +}; + +IMPL_PERSISTENT_OPS( MbChannelSurface ) + +//------------------------------------------------------------------------------ +// \ru Создать поверхность переменного радиуса \en Create surface with variable radius +// --- +MbSmoothSurface * CreateChannelSurface( const MbSurface & surface1, SArray & points1, + const MbSurface & surface2, SArray & points2, + MbeSmoothForm form, double distance1, double distance2, double conic, + SArray & dFactor, SArray & dTendency, + bool even ); + + +//------------------------------------------------------------------------------ +// \ru Создать поверхность переменного радиуса с сохранением кромки \en Create surface with variable radius with preservation of edges +// --- +MbSmoothSurface * CreateKerbChannelSurface( const MbSurface & surface1, SArray & points1, + const MbSurface & surface2, SArray & points2, + MbeSmoothForm form, double distance1, double distance2, double conic, + const MbSurfaceIntersectionCurve & guideCurve, SArray & params, + SArray & dFactor, + bool byFirstSurface, bool even ); + + +#endif // __SURF_CHANNEL_SURFACE_H + diff --git a/C3d/Include/surf_cone_surface.h b/C3d/Include/surf_cone_surface.h new file mode 100644 index 0000000..6a982c8 --- /dev/null +++ b/C3d/Include/surf_cone_surface.h @@ -0,0 +1,479 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Kоническая поверхность. + \en Conical surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CONE_SURFACE_H +#define __SURF_CONE_SURFACE_H + + +#include +#include + + +class MATH_CLASS MbLine3D; +class MATH_CLASS MbLineSegment3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Kоническая поверхность. + \en Conical surface. \~ + \details \ru Коническая поверхность описывается радиусом radius, высотой height и углом конусности angle, заданными в локальной системе координат position. \n + Первый параметр поверхности отсчитывается по дуге от оси position.axisX в направлении оси position.axisY. + Первый параметр поверхности u принимает значения на отрезке: umin<=u<=umax. + Значения u=0 и u=2pi соответствуют точке на плоскости XZ локальной системы координат. + Поверхность может быть замкнутой по первому параметру. + У замкнутой поверхности umax-umin=2pi, у не замкнутой поверхности umax-umin<2pi. \n + Второй параметр поверхности отсчитывается по прямой вдоль оси position.axisZ. + Второй параметр поверхности v принимает значения на отрезке: vmin<=v<=vmax. + Значение v=0 соответствует точке плоскости XY локальной системы координат, + а значение v=1 соответствует точке на расстоянии height от плоскости XY локальной системы координат поверхности. \n + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + ((radius + height v tg(angle)) (cos(u) position.axisX + sin(u) position.axisY)) + (height v position.axisZ). \n + Полюсу поверхности соответствует значение второго параметра v=–radius / (height tg(angle)). + Граничные параметры vmax и vmin принимают такие значения, при которых поверхность располагается с одной стороны от полюса. \n + Локальная система координат position может быть как правой, так и левой. + Если локальная система координат правая, то нормаль направлена в сторону выпуклости поверхности (от оси position.axisZ), + если локальная система координат левая, то нормаль направлена в сторону вогнутости поверхности (в сторону оси position.axisZ).\n + \en Conical surface is described by 'radius' radius, 'height' height and 'angle' angle of conicity given in 'position' local coordinate system. \n + The first parameter of surface is measured along arc from position.axisX axis in the direction of position.axisY axis. + The first parameter u of surface possesses the values in the range: umin<=u<=umax. + Values u=0 and u=2pi correspond to point on XZ plane of local coordinate system. + Surface can be closed by first parameter. + In case of closed surface: umax-umin=2pi; in case of open surface: umax-umin<2pi. \n + Second parameter of surface is measured by line along position.axisZ axis. + Second parameter v of surface possesses the values in the range: vmin<=v<=vmax. + Value v=0 corresponds to point on XY plane of local coordinate system, + but value v=1 corresponds to point at 'height' distance from XY plane of local coordinate system of surface. \n + Radius-vector of surface is described by the vector function \n + r(u,v) = position.origin + ((radius + height v tg(angle)) (cos(u) position.axisX + sin(u) position.axisY)) + (height v position.axisZ). \n + Value of second parameter v=-radius / (height tg(angle)) corresponds to pole of surface. + Boundary parameters vmax and vmin possess such values which the surface is placed on the one side from a pole at. \n + Local coordinate system 'position' can be both right and left. + If local coordinate system is right then normal is directed to the side of convexity of surface (from position.axisZ axis), + If local coordinate system is left then normal is directed to the side of concavity of surface (to position.axisZ axis).\n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbConeSurface : public MbElementarySurface { +private: + double radius; ///< \ru Радиус в плоскости XY локальной системы координат. \en Radius in the XY plane of a local coordinate system. + double angle; ///< \ru Угол между осью position.axisZ и боковой образующей. \en Angle between position.axisZ axis and lateral generatrix. + double height; ///< \ru Высота конуса. \en Height of cone. + double tgAngleH; ///< \ru Вспомогательная величина height*tan(angle). \en Auxiliary value height*tan(angle). + bool uclosed; ///< \ru Признак замкнутости по первому параметру. \en Attribute of closedness by first parameter. + +protected: + explicit MbConeSurface( const MbConeSurface & init ); +public: + /// \ru Конструктор по локальной системе координат, радиусу, углу и высоте. \en Constructor by a local coordinate system, radius, angle and height. + explicit MbConeSurface( const MbPlacement3D & pl, double r, double a, double h ); + + /** \brief \ru Конструктор по радиусу, углу, высоте, локальной системе координат, минимальному и максимальному параметрам по V. + \en Constructor by radius, angle, height, local coordinate system, minimal and maximal parameters by V. \~ + \details \ru Конструктор по радиусу, углу, высоте, локальной системе координат, минимальному и максимальному параметрам по V. + \en Constructor by radius, angle, height, local coordinate system, minimal and maximal parameters by V. \~ + \warning \ru Используется только в конвертерах. + \en Used only in converters. \~ + */ + explicit MbConeSurface( double r, double a, double h, const MbPlacement3D & pl, double v1, double v2 ); + + /** \brief \ru Конструктор по радиусу, высоте, локальной системе координат, тангенсу угла, минимальному и максимальному параметрам по V. + \en Constructor by radius, height, local coordinate system, tangent of angle, minimal and maximal parameters by V. \~ + \details \ru Конструктор по радиусу, высоте, локальной системе координат, тангенсу угла, минимальному и максимальному параметрам по V. + \en Constructor by radius, height, local coordinate system, tangent of angle, minimal and maximal parameters by V. \~ + \warning \ru Используется только в конвертерах. + \en Used only in converters. \~ + */ + explicit MbConeSurface( double r, double h, const MbPlacement3D & pl, double tgAngle, double v1, double v2 ); // \ru Используется только в конверторах \en Used only in converters + + /** \brief \ru Конструктор по трем точкам. + \en Constructor by three points. \~ + \details \ru Конструктор по трем точкам.\n + Вектор из точки point0 в точку point1 определяет ось Z.\n + Вектор из точки point0 в точку point2 определяет направление оси X.\n + Радиус в начале локальной системы координат равен нулю.\n + Угол point1 point0 point2 - полуугол конуса. + \en Constructor by three points.\n + Vector from point0 point to point1 point determines Z-axis.\n + Vector from point0 point to point2 point determines direction of X-axis.\n + Radius at origin of local coordinate system is equal to zero.\n + Angle point1 point0 point2 - semi-angle of cone. \~ + */ + explicit MbConeSurface( const MbCartPoint3D & point0, const MbCartPoint3D & point1, const MbCartPoint3D & point2 ); + + /** \brief \ru Конструктор по отрезку и точке. + \en Constructor by segment and point. \~ + \details \ru Конструктор по отрезку и точке.\n + Ось конуса определяется отрезком seg.\n + Высота конуса равна длине отрезка seg.\n + Конус проходит через точку point.\n + \en Constructor by segment and point.\n + Axis of cone is determined by 'seg' segment.\n + Height of cone is equal to length of 'seg' segment.\n + Cone passes through 'point' point.\n \~ + */ + explicit MbConeSurface( const MbLineSegment3D & seg, const MbCartPoint3D & point ); + +public: + virtual ~MbConeSurface(); + +public: + VISITING_CLASS( MbConeSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /// \ru Инициализация по конической поверхности. \en Initialization by conical surface. + void Init( const MbConeSurface & init ); + /// \ru Инициализация по локальной системе координат, радиусу, высоте и углу. \en Initialization by a local coordinate system, radius, height and angle. + void Init( const MbPlacement3D & plane, double r, double h, double a ); + /// \ru Инициализация по прямой, радиусу, высоте и углу. \en Initialization by a line, radius, height and angle. + void Init( const MbLine3D & line, double r, double h, double a ); + + /** \brief \ru Инициализация по отрезку и точке. + \en Initialization by segment and point. \~ + \details \ru Инициализация по отрезку и точке.\n + Ось конуса определяется отрезком seg.\n + Высота конуса равна длине отрезка seg.\n + Конус проходит через точку point.\n + \en Initialization by segment and point.\n + Axis of cone is determined by 'seg' segment.\n + Height of cone is equal to length of 'seg' segment.\n + Cone passes through 'point' point.\n \~ + */ + void Init( const MbLineSegment3D & seg, const MbCartPoint3D & point ); + + /** \brief \ru Инициализация по прямой и отрезку. + \en Initialization by a line and a segment. \~ + \details \ru Инициализация по прямой и отрезку.\n + В случае успеха получим конус, являющийся поверхностью вращения\n + отрезка seg вокруг прямой line. + \en Initialization by a line and a segment.\n + In case of success will be obtained a cone being a surface of rotation\n + of 'seg' segment around 'line' line. \~ + */ + bool Init( const MbLine3D & line, const MbLineSegment3D & seg ); + + /** \brief \ru Инициализация по локальной системе координат и отрезку. + \en Initialization by a local coordinate system and a segment. \~ + \details \ru Инициализация по локальной системе координат и отрезку.\n + В случае успеха получим конус, являющийся поверхностью вращения\n + отрезка seg вокруг оси Z локальной системы координат plane. + \en Initialization by a local coordinate system and a segment.\n + In case of success will be obtained a cone being a surface of rotation\n + of 'seg' segment around Z-axis of 'plane' local coordinate system. \~ + */ + bool Init( const MbPlacement3D & plane, const MbLineSegment3D & seg ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA () const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & init ); // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; + virtual bool IsVClosed() const; + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for closed function. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for closed function. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void TangentU ( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + virtual void _TangentU ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке. \en Values of derivatives at point. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна вдоль u. \en Curvature along u. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature along v. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность. \en Create a shifted surface. + + virtual MbCurve3D * CurveU ( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV ( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + virtual MbCurve3D * CurveUV( const MbLineSegment &, bool bApprox = true ) const; // \ru Пространственная копия линии по параметрической линии. \en Spatial copy of line by parametric line. + + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Пересечение с кривой. \en Intersection with curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D & axis ) const ; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether the surface is convex. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual void CalculateGabarit( MbCube & ) const; // \ru Рассчитать габарит поверхности. \en Calculate bounding box of surface. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + + virtual void IncludePoint( double u, double v ); // \ru Включить точку в область определения. \en Include point into domain. + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether there is pole on boundary of parametric region of spline curve. + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is special. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives by V higher the first one are equal to zero. + + // \ru Является ли объект смещением. \en Is the object is a shift? + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + + virtual double GetRadius() const; // \ru Дать максимальный физический радиус объекта или ноль, если это невозможно. \en Get the maximum physical radius of the object or null if it impossible. + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces + \{ */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /** \} */ + /** \ru \name Функции конической поверхности + \en \name Functions of conical surface + \{ */ + /// \ru Получить внутренний радиус основания. \en Get internal radius of base. + double GetR() const { return radius; } + /// \ru Получить текущий внутренний радиус для параметра v без ограничений vmin, vmax. \en Get current internal radius for v parameter without constraints of vmin, vmax. + double GetR( double v ) const { return radius + tgAngleH * v; } + /// \ru Получить физический радиус. \en Get physical radius. + double GetRadius( double v ) const; + /// \ru Получить внутренний радиус для параметра v, равного 1.0. \en Get internal radius for v parameter equal to 1.0. + double GetUpperR() const { return radius + tgAngleH; } + /// \ru Установить внутренний радиус. \en Set an internal radius. + void SetR( double r ) { radius = r; } + + /// \ru Установить угол. \en Set an angle. + void SetAngle ( const double & a ) { angle = a; tgAngleH = ( height * ::tan(a ) ); } + /// \ru Установить внутреннюю высоту. \en Set internal height. + void SetHeight( const double & h ) { height = h; tgAngleH = ( h * ::tan(angle) ); C3D_ASSERT( ::fabs(height) > LENGTH_EPSILON ); } + /// \ru Угол. \en Angle. + double GetAngle () const { return angle; } + /** \brief \ru Внутренняя высота. + \en Internal height. \~ + \details \ru Внутренняя высота. \n + Чтобы получить физическую высоту нужно внутреннюю высоту умножить + на параметрическую длину по V и + длину оси Z ЛСК поверхности. \n + \en Internal height. \n + To obtain the physical height you need to multiply the internal height + by the parametric length along V and + the length of the Z axis of the local coordinate system of the surface. \~ + */ + double GetHeight() const { return height; } + /// \ru Выдать физисечкую высоту. \en Get physical height. \~ + double GetRealHeight() const { return ( height * (vmax - vmin) * position.GetAxisZ().Length() ); } + /// \ru Тангенс угла, умноженный на внутреннюю высоту. \en Tangent of the angle multiplied by internal height. + double GetTgAngleH() const { return tgAngleH; } + + /** \brief \ru Проверка параметра v по отношению к полюсу. + \en Check v parameter against pole. \~ + \details \ru Проверка параметра v по отношению к полюсу. + \en Check v parameter against pole. \~ + \return \ru true, если параметр v был изменен, чтобы не уйти за полюс. + \en True if v parameter was changed not to leave out of pole. \~ + */ + inline bool CheckVParam( double & v ) const; + /** \brief \ru Получить v-параметр полюса. + \en Get v parameter of pole. \~ + \details \ru Получить v-параметр полюса.\n + Может быть вне области определения. + \en Get v-parameter of pole.\n + Can be outside of domain. \~ + */ + inline double GetVPole() const; + + /** \brief \ru Находится ли полюс внутри диапазона (v1,v2). + \en Whether pole is inside range (v1,v2). \~ + \details \ru Находится ли полюс внутри диапазона (v1,v2). \n + \en Whether pole is inside range (v1,v2).\n \~ + */ + inline bool IsVPoleInside( double v1, double v2, double metricAcc ) const; + + /** \} */ + +private: + inline void CheckParam( double & u, double & v ) const; // \ru Проверка параметров. \en Check parameters. + // \ru Пересечение с прямолинейной кривой. \en Intersection with rectilinear curve. + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, bool ext0, bool ext ) const; + void operator = ( const MbConeSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbConeSurface ) +}; // MbConeSurface + +IMPL_PERSISTENT_OPS( MbConeSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверка параметров \en Check parameters +// --- +inline +void MbConeSurface::CheckParam( double & u, double & v ) const +{ + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) + u -= ::floor( (u - umin) * Math::invPI2 ) * M_PI2; + else if ( u < umin ) + u = umin; + else if ( u > umax ) + u = umax; + } + if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +//------------------------------------------------------------------------------ +// \ru Проверка параметра v по отношению к полюсу \en Check v parameter against pole +// --- +inline +bool MbConeSurface::CheckVParam( double & v ) const +{ + bool res = true; + + if ( v < vmin || v > vmax ) { + double vPole = GetVPole(); + if ( ((v < vPole - EXTENT_EPSILON) && (vmin > vPole - EXTENT_EPSILON)) || + ((v > vPole + EXTENT_EPSILON) && (vmax < vPole + EXTENT_EPSILON)) ) { + v = vPole; + res = false; // \ru Изменили параметр v, чтобы не уйти за полюс \en V parameter was changed not to leave out of pole + } + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru Получить v-параметр полюса \en Get v parameter of pole +// --- +inline +double MbConeSurface::GetVPole() const { + return -radius/tgAngleH; +} + + +//------------------------------------------------------------------------------ +// \ru Получить v-параметр полюса \en Get v parameter of pole +// --- +inline +bool MbConeSurface::IsVPoleInside( double v1, double v2, double vAcc ) const +{ + bool res = false; + if ( v1 > v2 ) + std::swap( v1, v2 ); + double vPole = GetVPole(); + if ( vPole > v1 + vAcc && vPole < v2 - vAcc ) + res = true; + return res; +} + + +#endif // __SURF_CONE_SURFACE_H diff --git a/C3d/Include/surf_coons_surface.h b/C3d/Include/surf_coons_surface.h new file mode 100644 index 0000000..97e72f4 --- /dev/null +++ b/C3d/Include/surf_coons_surface.h @@ -0,0 +1,523 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Бикубическая поверхность Кунса на четырех кривых и их поперечных производных. + \en Bicubic Coons surface on four curves and its transverse derivatives. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_COONS_SURFACE_H +#define __SURF_COONS_SURFACE_H + + +#include +#include +#include + + +class MATH_CLASS MbCurve; + + +#define COONS_COUNT 4 ///< \ru Число кривых, используемых для построения поверхности Кунса \en Count of curves used to construct Coons surface. + + +//------------------------------------------------------------------------------ +/** \brief \ru Способ расчёта поверхности Кунса. +\en Type of calculation of Coons surface. \~ +\details \ru Способ расчёта поверхности Кунса. \n +\en Type of calculation of Coons surface. \n \~ +\ingroup Surfaces +*/ +// --- +enum MbeCoonsSurfaceCalcType { + cst_DefaultType = 0, ///< \ru Способ по умолчанию. \en Default type. + cst_SurfaceType, ///< \ru Точный способ по кривым на поверхностях. \en Exact type by Curves on surfaces. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность Кунса на четырех кривых. + \en Coons surface on four curves. \~ + \details \ru Бикубическая поверхность Кунса определяется четырьмя кривыми и + производными поверхности на этих кривых в поперечном к кривым направлениях. + Поверхность проходит через определяющие её кривые и + имеет заданные производные на этих кривых в поперечном к кривым направлениях. \n + \en Bicubic Coons surface is determined by four curves and + surface derivatives on these curves in transverse directions to curves. + Surface passes through its determining curves and + has specified derivatives on this curves in transverse directions to curves. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbCoonsPatchSurface : public MbSurface { + +// curve2V +// t2min curve2 t2max +// P3 ______________________ P2 +// t3max | | t1max +// | | +// | | +// curve3 | | curve1 +// curve3U | | curve1U +// t0=t0min*(1-u)+t0max*u | | +// t1=t1min*(1-v)+t1max*v | | +// t2=t2min*(1-u)+t2max*u t3min |______________________| t1min +// t3=t3min*(1-v)+t3max*v P0 P1 +// t0min curve0 t0max +// curve0V +// \ru Не переименовывать в MbCoonsSurface - хэш совпал с существующим объектом (BUG_60351). \en No renaming to MbCoonsSurface - hash was coincided with existing object (BUG_60351). + +private: + MbCurve3D * curve0; ///< \ru Кривая 0. \en Curve 0. + MbCurve3D * curve1; ///< \ru Кривая 1. \en Curve 1. + MbCurve3D * curve2; ///< \ru Кривая 2. \en Curve 2. + MbCurve3D * curve3; ///< \ru Кривая 3. \en Curve 3. + MbCurve3D * curve0V; ///< \ru Производная по v вдоль кривой 0. \en Derivative by v along curve 0. + MbCurve3D * curve1U; ///< \ru Производная по u вдоль кривой 1. \en Derivative by u along curve 1. + MbCurve3D * curve2V; ///< \ru Производная по v вдоль кривой 2. \en Derivative by v along curve 2. + MbCurve3D * curve3U; ///< \ru Производная по u вдоль кривой 3. \en Derivative by u along curve 3. + MbCartPoint3D vertex[COONS_COUNT]; ///< \ru Вершины. \en Vertices. + MbCartPoint3D vertexU[COONS_COUNT]; ///< \ru Производная по u в вершинах. \en Derivative by u at vertices. + MbCartPoint3D vertexV[COONS_COUNT]; ///< \ru Производная по v в вершинах. \en Derivative by v at vertices. + MbCartPoint3D vertexUV[COONS_COUNT]; ///< \ru Производная по uv в вершинах. \en Derivative by uv at vertices. + double t0min; ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double t0max; ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double t1min; ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double t1max; ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double t2min; ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double t2max; ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + double t3min; ///< \ru Минимальное значение параметра на кривой 3. \en Minimal value of parameter on curve 3. + double t3max; ///< \ru Максимальное значение параметра на кривой 3. \en Maximal value of parameter on curve 3. + bool uclosed; ///< \ru Замкнутость по u. \en Closeness by u. + bool vclosed; ///< \ru Замкнутость по v. \en Closeness by v. + bool poleUMin; ///< \ru Полюс в начале. \en Pole at the beginning. + bool poleUMax; ///< \ru Полюс в конце. \en Pole at the end. + bool poleVMin; ///< \ru Полюс в начале. \en Pole at the beginning. + bool poleVMax; ///< \ru Полюс в конце. \en Pole at the end. + MbeCoonsSurfaceCalcType calcType; ///< \ru Версия реализации определяет способ расчёта поверхности. \en Version of implementation determines a type of calculation of surface. + +protected: + /** \brief \ru Конструктор поверхности Кунса. + \en Constructor of Coons surface. \~ + \details \ru Конструктор поверхности Кунса по набору кривых и производных вдоль кривых. + \en Constructor of Coons surface by set of curves and derivatives along curves. \~ + \param[in] initCurve0 - \ru Кривая 0. + \en Curve 0. \~ + \param[in] initCurve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] initCurve2 - \ru Кривая 2. + \en Curve 2. \~ + \param[in] initCurve3 - \ru Кривая 3. + \en Curve 3. \~ + \param[in] derVCurve0 - \ru Производная по v вдоль кривой 0. + \en Derivative by v along curve 0. \~ + \param[in] derUCurve1 - \ru Производная по u вдоль кривой 1. + \en Derivative by u along curve 1. \~ + \param[in] derVCurve2 - \ru Производная по v вдоль кривой 2. + \en Derivative by v along curve 2. \~ + \param[in] derUCurve3 - \ru Производная по u вдоль кривой 3. + \en Derivative by u along curve 3. \~ + */ + MbCoonsPatchSurface ( MbCurve3D & initCurve0, MbCurve3D & initCurve1, MbCurve3D & initCurve2, MbCurve3D & initCurve3, + MbCurve3D & derVCurve0, MbCurve3D & derUCurve1, MbCurve3D & derVCurve2, MbCurve3D & derUCurve3, + double w0min, double w0max, double w1min, double w1max, double w2min, double w2max, double w3min, double w3max, + MbeCoonsSurfaceCalcType calcType = cst_DefaultType ); +private: + MbCoonsPatchSurface( const MbCoonsPatchSurface & ); // \ru Не реализовано. \en Not implemented. + MbCoonsPatchSurface( const MbCoonsPatchSurface &, MbRegDuplicate * ); ///< \ru Конструктор копирования. \en Copy-constructor. +public: + virtual ~MbCoonsPatchSurface( void ); + +public: + VISITING_CLASS( MbCoonsPatchSurface ); + + /// \ru Создание поверхности Кунса заданным кривым на поверхностях. \en Creation of Coons surface by curves on surfaces. + static MbCoonsPatchSurface * Create( const MbCurve3D & curve0, + const MbCurve3D & curve1, + const MbCurve3D & curve2, + const MbCurve3D & curve3, + MbResultType & resType ); + + /// \ru Инициализация поверхности Кунса заданной поверхностью Кунса. \en Initialization of Coons surface by specified Coons surface. + void Init( const MbCoonsPatchSurface & ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента \en Make a copy of element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray &s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности \en Point on the extended surface + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU( double u, double v, double sag ) const; // \ru Вычисление шага параметра u по по величине прогиба \en Calculation of parameter u step by the value of sag + virtual double StepV( double u, double v, double sag ) const; // \ru Вычисление шага параметра v по по величине прогиба \en Calculation of parameter v step by the value of sag + virtual double DeviationStepU( double u, double v, double ang ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double ang ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const \en Spatial copy of 'v = const'-line + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const \en Spatial copy of 'u = const'-line + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + // \ru Существует ли полюс на границе параметрической области \en Whether there is pole on boundary of parametric region + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the count of polygons by u + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + /// \ru Получить кривую 0. \en Get curve 0. + const MbCurve3D & GetCurve0() const { return *curve0; } + /// \ru Получить кривую 1. \en Get curve 1. + const MbCurve3D & GetCurve1() const { return *curve1; } + /// \ru Получить кривую 2. \en Get curve 2. + const MbCurve3D & GetCurve2() const { return *curve2; } + /// \ru Получить кривую 3. \en Get curve 3. + const MbCurve3D & GetCurve3() const { return *curve3; } + /// \ru Получить кривую производной в трансверсальном направлении к кривой 0. \en Get derivative curve transversal to curve 0. + const MbCurve3D & GetDerCurve0() const { return *curve0V; } + /// \ru Получить кривую производной в трансверсальном направлении к кривой 1. \en Get derivative curve transversal to curve 1. + const MbCurve3D & GetDerCurve1() const { return *curve1U; } + /// \ru Получить кривую производной в трансверсальном направлении к кривой 2. \en Get derivative curve transversal to curve 2. + const MbCurve3D & GetDerCurve2() const { return *curve2V; } + /// \ru Получить кривую производной в трансверсальном направлении к кривой 3. \en Get derivative curve transversal to curve 3. + const MbCurve3D & GetDerCurve3() const { return *curve3U; } + /// \ru Получить кривую по индексу. \en Get curve by an index. + const MbCurve3D * GetCurve( size_t ind ) const; + /// \ru Получить количество кривых. \en Get count of curves. + size_t GetCurvesCount() const { return COONS_COUNT; } //-V112 + const MbCartPoint3D * GetVertex() const { return vertex; } ///< \ru Выдать вершины P0, P1, P2. \en Get vertices P0, P1, P2. + /** \} */ + double GetT0Min() const { return t0min; } ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double GetT0Max() const { return t0max; } ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double GetT1Min() const { return t1min; } ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double GetT1Max() const { return t1max; } ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double GetT2Min() const { return t2min; } ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double GetT2Max() const { return t2max; } ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + double GetT3Min() const { return t3min; } ///< \ru Минимальное значение параметра на кривой 3. \en Minimal value of parameter on curve 3. + double GetT3Max() const { return t3max; } ///< \ru Максимальное значение параметра на кривой 3. \en Maximal value of parameter on curve 3. + + /** \brief \ru Получить образующую кривую по индексу, если она точно совпадает с соответствующим краем поверхности. + \en Get exact curve by index, if it coincides with the corresponding border of the surface. \~ + \details \ru Совпадение кривой с краем поверхности определяется по крайним точкам кривой. + \en Coincidence of the curve with the border of the surface is determined by the end points of the curve. \~ + \param[in] k - \ru Индекс кривой. + \en Index of the curve. \~ + \param[out] sense - \ru Флаг совпадения направленности кривой с рисунком, приведенным выше. + \en Flag that indicates the coincidence of the curve with the picture shown above.\~ + \return - \ru Указатель на кривую или NULL. + \en Pointer to the curve or NULL. \~ + */ + const MbCurve3D * GetExactCurve( size_t k, bool & sense ) const; + + /** \brief \ru Проверка полюсов на кривых. + \en Check poles on curves. \~ + \details \ru Определяет, есть ли полюс на границе области определения по длине кривой, определяющей границу.\n + Результат вычислений можно получить с помощью функций GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax. + \en Determines whether the pole at domain boundary by curve length determining boundary.\n + Result of calculations can be obtained with help of GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax functions. \~ + */ + void CheckPole(); + +private: + void operator = ( const MbCoonsPatchSurface & ); // \ru Не реализовано. \en Not implemented. + void Setup(); + void CheckParams( double & u, double & v ) const; // \ru Проверить и изменить при необходимости параметры. \en Check and correct parameters. + // \ru Определение местных координат. \en Determination of local coordinates. + void CalculateCoordinate( double & u, double & v, + double & t0, double & t1, double & t2, double & t3 ) const; + void CalculatePoint ( double & u, double & v, + MbCartPoint3D * point, MbCartPoint3D * pointUV ) const; + void CalculateFirst ( double & u, double & v, + MbCartPoint3D * point, MbVector3D * first, + MbCartPoint3D * pointUV, MbVector3D * firstUV ) const; + void CalculateThird ( double & u, double & v, + MbCartPoint3D * point, MbVector3D * third, + MbCartPoint3D * pointUV, MbVector3D * thirdUV ) const; + void CalculateExplore( double & u, double & v, + MbCartPoint3D * point, MbVector3D * first, MbVector3D * second, + MbCartPoint3D * pointUV, MbVector3D * firstUV, MbVector3D * secondUV ) const; + // \ru Производные. \en Derivatives with respect to u and to v. + void Derivatives( double & u, double & v, MbVector3D & uDer, MbVector3D & vDer ) const; + // \ru Нормаль. \en Calculate surface normal with refinement on borders. + void Normal( double u, double v, MbVector3D & derU, MbVector3D & derV, MbVector3D & norm ) const; + inline void ParamPoint ( double w, double * t ) const; + inline void ParamFirst ( double w, double * t ) const; + inline void ParamSecond( double w, double * t ) const; + inline void ParamThird ( double w, double * t ) const; + // \ru Добавить матрицу поверхности. \en Add the matrix of the surface. + inline void AddMatrix ( double * uu, double * vv, MbVector3D & p ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCoonsPatchSurface ) +}; // MbCoonsSurface + + +IMPL_PERSISTENT_OPS( MbCoonsPatchSurface ) + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметра точки \en Determination of array of degrees of point parameter +// --- +inline void MbCoonsPatchSurface::ParamPoint ( double w, double * t ) const { + t[0] = 1.0 - 3.0 * w * w + 2.0 * w * w * w; //*/ 1.0 - 10.0 * w * w * w + 15.0 * w * w * w * w - 6.0 * w * w * w * w * w; + t[1] = 3.0 * w * w - 2.0 * w * w * w; //*/ 10.0 * w * w * w - 15.0 * w * w * w * w + 6.0 * w * w * w * w * w; + t[2] = w - 2.0 * w * w + w * w * w; //*/ 0.0; + t[3] = - w * w + w * w * w; //*/ 0.0; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметра производной \en Determination of array of degrees of derivative parameter +// --- +inline void MbCoonsPatchSurface::ParamFirst ( double w, double * t ) const { + t[0] = - 6.0 * w + 6.0 * w * w; //*/ -30.0 * w * w + 60.0 * w * w * w - 30.0 * w * w * w * w; + t[1] = 6.0 * w - 6.0 * w * w; //*/ 30.0 * w * w - 60.0 * w * w * w + 30.0 * w * w * w * w; + t[2] = 1.0 - 4.0 * w + 3.0 * w * w; //*/ 0.0; + t[3] = - 2.0 * w + 3.0 * w * w; //*/ 0.0; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметра второй производной \en Determination of array of degrees of second derivative parameter +// --- +inline void MbCoonsPatchSurface::ParamSecond( double w, double * t ) const { + t[0] = - 6.0 + 12.0 * w; //*/ -60.0 * w + 180.0 * w * w - 120.0 * w * w * w; + t[1] = 6.0 - 12.0 * w; //*/ 60.0 * w - 180.0 * w * w + 120.0 * w * w * w; + t[2] = - 4.0 + 6.0 * w; //*/ 0.0; + t[3] = - 2.0 + 6.0 * w; //*/ 0.0; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметра третьей производной \en Determination of array of degrees of third derivative parameter +// --- +inline void MbCoonsPatchSurface::ParamThird ( double /*w*/, double * t ) const { + t[0] = 12.0; //*/ -60.0 + 360.0 * w - 360.0 * w * w; + t[1] = -12.0; //*/ 60.0 - 360.0 * w + 360.0 * w * w; + t[2] = 6.0; //*/ 0.0; + t[3] = 6.0; //*/ 0.0; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить матрицу поверхности. \en Add the matrix of the surface. +// --- +inline void MbCoonsPatchSurface::AddMatrix( double * uu, double * vv, MbVector3D & p ) const { + p.Add( vertex[0], -uu[0]*vv[0], vertex[1], -uu[1]*vv[0], vertex[2], -uu[1]*vv[1], vertex[3], -uu[0]*vv[1] ); + p.Add( vertexU[0], -uu[2]*vv[0], vertexU[1], -uu[3]*vv[0], vertexU[2], -uu[3]*vv[1], vertexU[3], -uu[2]*vv[1] ); + p.Add( vertexV[0], -uu[0]*vv[2], vertexV[1], -uu[1]*vv[2], vertexV[2], -uu[1]*vv[3], vertexV[3], -uu[0]*vv[3] ); + p.Add( vertexUV[0], -uu[2]*vv[2], vertexUV[1], -uu[3]*vv[2], vertexUV[2], -uu[3]*vv[3], vertexUV[3], -uu[2]*vv[3] ); +} + + +//------------------------------------------------------------------------------ +// \ru Получить кривую по индексу \en Get curve by an index +// --- +inline const MbCurve3D * MbCoonsPatchSurface::GetCurve( size_t ind ) const +{ + if ( ind >= COONS_COUNT ) + ind = ind % COONS_COUNT; + switch ( ind ) { + case 0 : { return curve0; } + case 1 : { return curve1; } + case 2 : { return curve2; } + case 3 : { return curve3; } + } + return NULL; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// Вспомогательные объекты бикубической поверхности Кунса. +// Auxiliary objects for bicubic Coons surface. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +// \ru Кривая производных, обслуживающаяя точную бикубическую поверхность Кунса, построенная кривой на поверхности. +// \en The curve of derivetives serving the exact bicubic Coons surface, constructed by a curve on the surface. \~ +// --- +class MATH_CLASS MbCoonsDerivative : public MbCurve3D { +protected : + MbSurfaceCurve * curve; ///< \ru Кривая на поверхности (всегда не NULL). \en Curve on surface (always not NULL). + double param1; ///< \ru Параметр первой точки кривой. \en The first point parameter of curve. + double param2; ///< \ru Параметр второй точки кривой. \en The second point parameter of curve. + MbVector rail1; ///< \ru Вектор для вычисления поперечной производной в первой точке кривой. \en The vector for calculatiob of the transverse derivative in first point of curve. + MbVector rail2; ///< \ru Вектор для вычисления поперечной производной во второй точке кривой. \en The vector for calculatiob of the transverse derivative in second point of curve. + double turner; ///< \ru Угол поворота векторов на единицу изменения параметра. \en The angle of rotation of vectors per unit of parameter change. + +public : + /// \ru Конструктор кривой на поверхности. \en Constructor of curve on surface. + MbCoonsDerivative( MbSurfaceCurve & c, double t1, const MbVector & r1, double t2, const MbVector & r2 ); +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbCoonsDerivative( const MbCoonsDerivative &, MbRegDuplicate * ); +private: + MbCoonsDerivative( const MbCoonsDerivative & ); // \ru Не реализовано!!! \en Not implemented!!! + +public : + virtual ~MbCoonsDerivative(); + +public: + /// \ru Реализация функции, инициирующей посещение объекта. \en Implementation of a function initializing a visit of an object. + VISITING_CLASS( MbCoonsDerivative ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + + virtual MbeSpaceType IsA() const; // \ru Дать тип элемента. \en Get element type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Определить, являются ли объекты одинаковыми. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Определить, являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + /** \} */ + /** \ru \name Общие функции кривой. + \en \name Common functions of curve. + \{ */ + + virtual double GetTMin() const; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + virtual double GetTMax() const; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + virtual bool IsClosed() const; // \ru Проверить замкнутость кривой. \en Check for curve closedness. + virtual double GetPeriod() const; // \ru Вернуть период периодической кривой. \en Get period of a periodic curve. + + // \ru Функции для работы в области определения. \en Functions for working in the definition domain. + virtual void PointOn ( double & t, MbCartPoint3D & ) const; // \ru Вычислить точку на кривой. \en Calculate a point on the curve. + virtual void FirstDer ( double & t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void SecondDer( double & t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void ThirdDer ( double & t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Функции для работы вне области определения. \en Functions for working outside of definition domain. + virtual void _PointOn ( double t, MbCartPoint3D & ) const; // \ru Вычислить точку на расширенной кривой. \en Calculate a point on the extended curve. + virtual void _FirstDer ( double t, MbVector3D & ) const; // \ru Вычислить первую производную. \en Calculate the first derivative. + virtual void _SecondDer( double t, MbVector3D & ) const; // \ru Вычислить вторую производную. \en Calculate the second derivative. + virtual void _ThirdDer ( double t, MbVector3D & ) const; // \ru Вычислить третью производную по t. \en Calculate the third derivative by t. + // \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore ( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const; + + virtual void Inverse( MbRegTransform * iReg = NULL ); // \ru Изменить направление. \en Change the direction. + + virtual double Step ( double t, double sag ) const; // \ru Вычисление шага по стрелке прогиба. \en Calculation of parameter step by the sag. + virtual double DeviationStep( double t, double angle ) const; // \ru Вычисление шага по углу отклонения нормали. \en Calculation of parameter step by the deviation angle. + + virtual void ChangeCarrier ( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменить носитель. \en Change the carrier. + virtual bool ChangeCarrierBorne( const MbSpaceItem &, MbSpaceItem &, const MbMatrix & matr ); // \ru Изменить носимые элементы. \en Change a carrier elements. + + /** \} */ + + /// \ru Вычислить нормаль к поверхности. \en Calculate surface normal. + void SurfaceNormal( double & t, MbVector3D & n ) const { curve->SurfaceNormal( t, n ); } + /// \ru Заменить кривую. \en Replace curve. + bool ChangeCurve( MbSurfaceCurve & ); + /// \ru Дать кривую. \en Get curve. + const MbSurfaceCurve * GetSurfaceCurve() const { return curve; } + /// \ru Дать кривую. \en Get curve. + MbSurfaceCurve * SetSurfaceCurve() { return curve; } + +protected: + void CheckParam ( double & t ) const; // \ru Проверить и изменить при необходимости параметр. \en Check and correct parameter. + +private: + // \ru Объявить оператор приравнивания по ссылке. \en Declare operator of assignment by reference. + void operator = ( const MbCoonsDerivative & ); // \ru Не реализовано!!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCoonsDerivative ) + +}; + +IMPL_PERSISTENT_OPS( MbCoonsDerivative ) + + +#endif // __SURF_COONS_SURFACE_H diff --git a/C3d/Include/surf_corner_surface.h b/C3d/Include/surf_corner_surface.h new file mode 100644 index 0000000..c456ccf --- /dev/null +++ b/C3d/Include/surf_corner_surface.h @@ -0,0 +1,346 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Треугольная поверхность на сетке из трех кривых. + \en Triangular surface on grid of three curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CORNER_SURFACE_H +#define __SURF_CORNER_SURFACE_H + + +#include + + +#define CORNER_COUNT 3 ///< \ru Число кривых, нужных для построения треугольной поверхности. \en Count of curves used to construct triangular surface. +#define VECT_CNT CORNER_COUNT + + +class MATH_CLASS MbContour3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Треугольная поверхность на кривых. + \en Triangular surface on curves. \~ + \details \ru Треугольная поверхность на сетке из трех кривых. + Кривые должны попарно пересекаться или иметь точки скрещения. + Если кривые попарно пересекаются, то поверхность проходит через определяющиее её кривые. \n + \en Triangular surface on grid of three curves. + Curves have to be intersected pairwise or have crossing points. + If curves are intersected pairwise then surface passes through its determining curves. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbCornerSurface : public MbSurface { +// P2 +// t1max ^* t0min +// R(s0,s1,s2) = / * +// (curve2(1-s1)+curve1(s2)-P0)*s0+ / * +// (curve0(1-s2)+curve2(s0)-P1)*s1+ / * +// (curve1(1-s0)+curve0(s1)-P2)*s2 curve1 / * curve0 +// / R * +// s0(u,v) + s1(u,v) + s2(u,v) = 1 / * +// R(0,s1,s2) = curve0(s1) / * +// R(s0,0,s2) = curve1(s2) t1min <----------------v t0max +// R(s0,s1,0) = curve2(s0) P0 P1 +// t2max curve2 t2min +// +// \ru s0,s1,s2 - Барицентрические (треугольные) координаты, \en S0,s1,s2 - Baricentric (triangular) coordinates. +// \ru P0 - полюс \en P0 - pole +private: + MbCurve3D * curve0; ///< \ru Кривая 0. \en Curve 0. + MbCurve3D * curve1; ///< \ru Кривая 1. \en Curve 1. + MbCurve3D * curve2; ///< \ru Кривая 2. \en Curve 2. + MbCartPoint3D vertex[CORNER_COUNT]; ///< \ru Вершины P0, P1, P2. \en Vertices P0, P1, P2. + double t0min; ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double t0max; ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double t1min; ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double t1max; ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double t2min; ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double t2max; ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + +public: + /** \brief \ru Конструктор треугольной поверхности. + \en Constructor of triangular surface. \~ + \details \ru Конструктор треугольной поверхности по набору кривых. + \en Constructor of triangular surface by set of curves. \~ + \param[in] initCurve0 - \ru Кривая 0. + \en Curve 0. \~ + \param[in] initCurve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] initCurve2 - \ru Кривая 2. + \en Curve 2. \~ + */ + MbCornerSurface ( const MbCurve3D & initCurve0, const MbCurve3D & initCurve1, const MbCurve3D & initCurve2 ); +private: + MbCornerSurface( const MbCornerSurface & ); // \ru Не реализовано. \en Not implemented. + MbCornerSurface( const MbCornerSurface & init, MbRegDuplicate * ); +public: + virtual ~MbCornerSurface( void ); + +public: + VISITING_CLASS( MbCornerSurface ); + + /// \ru Инициализация треугольной поверхности заданной треугольной поверхностью. \en Initialization of triangular surface by given triangular surface. + void Init( const MbCornerSurface &init ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента \en Make a copy of element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void CalculateSurfaceWire( const MbStepData & stepData, size_t beg, MbMesh & mesh, + size_t uMeshCount = c3d::WIRE_MAX, size_t vMeshCount = c3d::WIRE_MAX ) const; + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void TangentV ( double & u, double & v, MbVector3D & p ) const; + virtual void Normal ( double & u, double & v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; // \ru Точка на расширенной поверхности \en Point on the extended surface + virtual void _DeriveU ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _TangentV ( double u, double v, MbVector3D & p ) const; + virtual void _Normal ( double u, double v, MbVector3D & p ) const; // \ru Нормаль \en Normal + virtual void _NormalV ( double u, double v, MbVector3D & p ) const; // \ru Производная нормали \en Derivative of normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по U \en Calculation of the approximation step with consideration of the curvature radius by U + virtual double StepV( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по V \en Calculation of the approximation step with consideration of the curvature radius by V + virtual double DeviationStepU( double u, double v, double ang ) const; ///< \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double ang ) const; ///< \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool doApprox = true ) const; // \ru Пространственная копия линии v = const \en Spatial copy of 'v = const'-line + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool doApprox = true ) const; // \ru Пространственная копия линии u = const \en Spatial copy of 'u = const'-line + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + // \ru Существует ли полюс на границе параметрической области \en Whether there is pole on boundary of parametric region + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the count of polygons by u + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + /// \ru Получить кривую 0. \en Get curve 0. + const MbCurve3D & GetCurve0() const { return *curve0; } + /// \ru Получить кривую 1. \en Get curve 1. + const MbCurve3D & GetCurve1() const { return *curve1; } + /// \ru Получить кривую 2. \en Get curve 2. + const MbCurve3D & GetCurve2() const { return *curve2; } + /// \ru Получить кривую по индексу. \en Get curve by an index. + const MbCurve3D * GetCurve( size_t ind ) const; + /// \ru Получить количество кривых. \en Get count of curves. + size_t GetCurvesCount() const { return 3; } //-V112 + const MbCartPoint3D * GetVertex() const { return vertex; } ///< \ru Выдать вершины P0, P1, P2. \en Get vertices P0, P1, P2. + double GetT0Min() const { return t0min; } ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double GetT0Max() const { return t0max; } ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double GetT1Min() const { return t1min; } ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double GetT1Max() const { return t1max; } ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double GetT2Min() const { return t2min; } ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double GetT2Max() const { return t2max; } ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + double GetTMin( size_t ind ) const; ///< \ru Минимальное значение параметра на кривой с индексом ind. \en Get The minimal value of parameter on curve by index. + double GetTMax( size_t ind ) const; ///< \ru Максимальное значение параметра на кривой с индексом ind. \en Get The maximal value of parameter on curve by index. + /** \} */ + +private: + void Init(); + inline void CalculateCoordinate( double & u, double & v, bool ext, + double & s0, double & s1, double & s2, + double & c0, double & c1, double & c2, + double & t0, double & t1, double & t2 ) const; + void CalculatePoint ( double & u, double & v, bool ext, + MbCartPoint3D & point ) const; + void CalculateFirst ( double & u, double & v, bool ext, + MbVector3D * first ) const; + void CalculateSecond( double & u, double & v, bool ext, + MbVector3D * second ) const; + void CalculateThird ( double & u, double & v, bool ext, + MbVector3D * second, MbVector3D * third ) const; + void CalculateExplore( double & u, double & v, bool ext, + MbCartPoint3D * point, MbVector3D * first, MbVector3D * second ) const; + bool GetNormalFactor( MbVector3D & norm ) const; // \ru Нормаль в точке с параметрами u=0. \en Normal at u=0. + void Derivatives( double u, double v, bool ext, MbVector3D & uDer, MbVector3D & vDer ) const; // \ru Ппроизводные. \en Derivatives with respect to u and to v. + void operator = ( const MbCornerSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCornerSurface ) +}; // MbCornerSurface + +IMPL_PERSISTENT_OPS( MbCornerSurface ) + +//------------------------------------------------------------------------------ +// \ru Определение местных координат \en Determination of local coordinates +// --- +inline void MbCornerSurface::CalculateCoordinate( double & u, double & v, bool ext, + double & s0, double & s1, double & s2, + double & c0, double & c1, double & c2, + double & t0, double & t1, double & t2 ) const +{ + if ( !ext ) { + if ( v <-1.0 ) v =-1.0; + if ( u > 1.0 ) u = 1.0; + if ( v > 1.0 ) v = 1.0; + } + if (u < 0.0) + u = 0.0; // \ru Нельзя заходить за полюс. \en Is impossible to go behind a pole + + s0 = 1.0 - u; + s1 = 0.5 * (u - u*v); + s2 = 0.5 * (u + u*v); +// \ru Пересчет параметров u,v в параметры a,b,c \en Recalculation of u,v parameters to a,b,c parameters +// +// v c=1 +// +1 | /| +// | / | +// curve1 / | curve0 +// |/ | +// a=1+----+--> u +// |\ |1 +// curve2 \ | +// | \ | +// -1 | \| +// | b=1 +// + c0 = t0min*(1.0-s1) + t0max*s1; + c1 = t1min*(1.0-s2) + t1max*s2; + c2 = t2min*(1.0-s0) + t2max*s0; + t0 = t0min*s2 + t0max*(1.0-s2); + t1 = t1min*s0 + t1max*(1.0-s0); + t2 = t2min*s1 + t2max*(1.0-s1); + + //if ( u < PARAM_EPSILON ) { + // if ( vc> PARAM_EPSILON && v> PARAM_EPSILON ) + // v = 1.0; + // else + // if ( vc<-PARAM_EPSILON && v<-PARAM_EPSILON ) + // v =-1.0; + //} +} + + +//------------------------------------------------------------------------------ +// \ru Получить кривую по индексу \en Get curve by an index +// --- +inline const MbCurve3D * MbCornerSurface::GetCurve( size_t ind ) const +{ + if ( ind >= CORNER_COUNT ) + ind = ind % CORNER_COUNT; + switch ( ind ) { + case 0 : { return curve0; } + case 1 : { return curve1; } + case 2 : { return curve2; } + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru Минимальное значение параметра на кривой с индексом ind. \en Get The minimal value of parameter on curve by index. +// --- +inline double MbCornerSurface::GetTMin( size_t ind ) const +{ + if ( ind >= CORNER_COUNT ) + ind = ind % CORNER_COUNT; + switch ( ind ) { + case 0 : { return t0min; } + case 1 : { return t1min; } + case 2 : { return t2min; } + } + return UNDEFINED_DBL; +} + + +//------------------------------------------------------------------------------ +// \ru Максимальное значение параметра на кривой с индексом ind. \en Get The maximal value of parameter on curve by index. +// --- +inline double MbCornerSurface::GetTMax( size_t ind ) const +{ + if ( ind >= CORNER_COUNT ) + ind = ind % CORNER_COUNT; + switch ( ind ) { + case 0 : { return t0max; } + case 1 : { return t1max; } + case 2 : { return t2max; } + } + return UNDEFINED_DBL; +} + + +#endif // __SURF_CORNER_SURFACE_H diff --git a/C3d/Include/surf_cover_surface.h b/C3d/Include/surf_cover_surface.h new file mode 100644 index 0000000..9d19032 --- /dev/null +++ b/C3d/Include/surf_cover_surface.h @@ -0,0 +1,364 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Билинейная поверхность на четырех кривых. + \en Bilinear surface on four curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_COVER_SURFACE_H +#define __SURF_COVER_SURFACE_H + + +#include + + +#define COVER_COUNT 4 ///< \ru Число кривых, используемых для построения билинейной поверхности. \en Count of curves used to construct bilinear surface. + + +//------------------------------------------------------------------------------ +/** \brief \ru Четырёхугольная поверхность на кривых. + \en Quadrangular surface on curves. \~ + \details \ru Билинейная поверхность на четырех кривых. \n + Кривые должны попарно пересекаться или иметь точки скрещения. + Если кривые попарно пересекаются, то поверхность проходит через определяющиее её кривые. \n + \en Bilinear surface on four curves. \n + Curves have to be intersected pairwise or have crossing points. + If curves are intersected pairwise then surface passes through its determining curves. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbCoverSurface : public MbSurface { + +// t2min curve2 t2max +// R(u,v) = P3 ______________________ P2 +// (curve0(t0) - P0*(1-u)) *(1-v)+ t3max | | t1max +// (curve1(t1) - P1*(1-v)) * u + | | +// (curve2(t2) - P2* u ) * v + | | +// (curve3(t3) - P3* v ) *(1-u) curve3 | R | curve1 +// t0=t0min*(1-u)+t0max*u | | +// t1=t1min*(1-v)+t1max*v | | +// t2=t2min*(1-u)+t2max*u t3min |______________________| t1min +// t3=t3min*(1-v)+t3max*v P0 P1 +// t0min curve0 t0max + +private: + MbCurve3D * curve0; ///< \ru Кривая 0. \en Curve 0. + MbCurve3D * curve1; ///< \ru Кривая 1. \en Curve 1. + MbCurve3D * curve2; ///< \ru Кривая 2. \en Curve 2. + MbCurve3D * curve3; ///< \ru Кривая 3. \en Curve 3. + + MbCartPoint3D vertex[COVER_COUNT]; ///< \ru Вершины \en Vertices + double t0min; ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double t0max; ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double t1min; ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double t1max; ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double t2min; ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double t2max; ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + double t3min; ///< \ru Минимальное значение параметра на кривой 3. \en Minimal value of parameter on curve 3. + double t3max; ///< \ru Максимальное значение параметра на кривой 3. \en Maximal value of parameter on curve 3. + bool uclosed; ///< \ru Замкнутость поверхности по u. \en Closedness of surface by u. + bool vclosed; ///< \ru Замкнутость поверхности по v. \en Closedness of surface by v. + bool poleUMin; ///< \ru Полюс в начале. \en Pole at the beginning. + bool poleUMax; ///< \ru Полюс в конце. \en Pole at the end. + bool poleVMin; ///< \ru Полюс в начале. \en Pole at the beginning. + bool poleVMax; ///< \ru Полюс в конце. \en Pole at the end. + +public: + /** \brief \ru Конструктор билинейной поверхности. + \en Constructor of bilinear surface. \~ + \details \ru Конструктор билинейной поверхности по набору кривых. + \en Constructor of bilinear surface by set of curves. \~ + \param[in] initCurve0 - \ru Кривая 0. + \en Curve 0. \~ + \param[in] initCurve1 - \ru Кривая 1. + \en Curve 1. \~ + \param[in] initCurve2 - \ru Кривая 2. + \en Curve 2. \~ + \param[in] initCurve3 - \ru Кривая 3. + \en Curve 3. \~ + */ + MbCoverSurface ( const MbCurve3D & initCurve0, const MbCurve3D & initCurve1, + const MbCurve3D & initCurve2, const MbCurve3D & initCurve3 ); +private: + MbCoverSurface( const MbCoverSurface & ); // \ru Не реализовано. \en Not implemented. + MbCoverSurface( const MbCoverSurface &, MbRegDuplicate * ); +public: + virtual ~MbCoverSurface( void ); + +public: + VISITING_CLASS( MbCoverSurface ); + + /// \ru Инициализация билинейной поверхности заданной билинейной поверхностью. \en Initialization of bilinear surface by given bilinear surface. + void Init( const MbCoverSurface & ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента \en Make a copy of element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + // \ru Существует ли полюс на границе параметрической области \en Whether there is pole on boundary of parametric region + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void Normal ( double & u, double & v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; // \ru Точка на расширенной поверхности \en Point on the extended surface + virtual void _DeriveU ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _Normal ( double u, double v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; +/** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU( double u, double v, double sag ) const; // \ru Вычисление шага параметра u по по величине прогиба \en Calculation of parameter u step by the value of sag + virtual double StepV( double u, double v, double sag ) const; // \ru Вычисление шага параметра v по по величине прогиба \en Calculation of parameter v step by the value of sag + virtual double DeviationStepU( double u, double v, double ang ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double ang ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool doApprox = true ) const; // \ru Пространственная копия линии v = const \en Spatial copy of 'v = const'-line + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool doApprox = true ) const; // \ru Пространственная копия линии u = const \en Spatial copy of 'u = const'-line + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the count of polygons by u + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + /// \ru Получить кривую 0. \en Get curve 0. + const MbCurve3D & GetCurve0() const { return *curve0; } + /// \ru Получить кривую 1. \en Get curve 1. + const MbCurve3D & GetCurve1() const { return *curve1; } + /// \ru Получить кривую 2. \en Get curve 2. + const MbCurve3D & GetCurve2() const { return *curve2; } + /// \ru Получить кривую 3. \en Get curve 3. + const MbCurve3D & GetCurve3() const { return *curve3; } + /// \ru Получить кривую по индексу. \en Get curve by an index. + const MbCurve3D * GetCurve( size_t ind ) const; + /// \ru Получить количество кривых. \en Get count of curves. + size_t GetCurvesCount() const { return 4; } //-V112 + const MbCartPoint3D * GetVertex() const { return vertex; } ///< \ru Выдать вершины P0, P1, P2. \en Get vertices P0, P1, P2. + double GetT0Min() const { return t0min; } ///< \ru Минимальное значение параметра на кривой 0. \en Minimal value of parameter on curve 0. + double GetT0Max() const { return t0max; } ///< \ru Максимальное значение параметра на кривой 0. \en Maximal value of parameter on curve 0. + double GetT1Min() const { return t1min; } ///< \ru Минимальное значение параметра на кривой 1. \en Minimal value of parameter on curve 1. + double GetT1Max() const { return t1max; } ///< \ru Максимальное значение параметра на кривой 1. \en Maximal value of parameter on curve 1. + double GetT2Min() const { return t2min; } ///< \ru Минимальное значение параметра на кривой 2. \en Minimal value of parameter on curve 2. + double GetT2Max() const { return t2max; } ///< \ru Максимальное значение параметра на кривой 2. \en Maximal value of parameter on curve 2. + double GetT3Min() const { return t3min; } ///< \ru Минимальное значение параметра на кривой 3. \en Minimal value of parameter on curve 3. + double GetT3Max() const { return t3max; } ///< \ru Максимальное значение параметра на кривой 3. \en Maximal value of parameter on curve 3. + double GetTMin( size_t ind ) const; ///< \ru Минимальное значение параметра на кривой с индексом ind. \en Get The minimal value of parameter on curve by index. + double GetTMax( size_t ind ) const; ///< \ru Максимальное значение параметра на кривой с индексом ind. \en Get The maximal value of parameter on curve by index. + + /** \brief \ru Получить образующую кривую по индексу, если она точно совпадает с соответствующим краем поверхности. + \en Get exact curve by index, if it coincides with the corresponding border of the surface. \~ + \details \ru Совпадение кривой с краем поверхности определяется по крайним точкам кривой. + \en Coincidence of the curve with the border of the surface is determined by the end points of the curve. \~ + \param[in] k - \ru Индекс кривой. + \en Index of the curve. \~ + \param[out] sense - \ru Флаг совпадения направленности кривой с рисунком, приведенным выше. + \en Flag that indicates the coincidence of the curve with the picture shown above.\~ + \return - \ru Указатель на кривую или NULL. + \en Pointer to the curve or NULL. \~ + */ + const MbCurve3D * GetExactCurve( size_t k, bool &sense ) const; + + /** \brief \ru Проверка полюсов на кривых. + \en Check poles on curves. \~ + \details \ru Определяет, есть ли полюс на границе области определения по длине кривой, определяющей границу.\n + Результат вычислений можно получить с помощью функций GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax. + \en Determines whether the pole at domain boundary by curve length determining boundary.\n + Result of calculations can be obtained with help of GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax functions. \~ + */ + void CheckPole(); + /** \brief \ru Корректировка параметров. + \en Correct parameters. \~ + \details \ru Загоняет параметры, выходящие за область определения в область определения,\n + если поверхность замкнута по соответствующему параметру или параметр лежит за полюсом. + \en Drives parameters leaving out of domain into domain\n + if the surface is closed by corresponding parameter or parameter lies behind a pole. \~ + */ + inline void CheckParam( double & u, double & v ) const; + +private: + void operator = ( const MbCoverSurface & ); // \ru Не реализовано. \en Not implemented. + void Init(); + // \ru Определение местных координат. \en Determination of local coordinates. + void CalculateCoordinate( double & u, double & v, bool ext, + double & t0, double & t1, double & t2, double & t3 ) const; + void CalculatePoint ( double & u, double & v, bool ext, MbCartPoint3D * point ) const; + void CalculateFirst ( double & u, double & v, bool ext, MbCartPoint3D * point, MbVector3D * first ) const; + void CalculateSecond( double & u, double & v, bool ext, MbVector3D * second ) const; + void CalculateThird ( double & u, double & v, bool ext, MbVector3D * third ) const; + void CalculateExplore( double & u, double & v, bool ext, + MbCartPoint3D * point, MbVector3D * first, MbVector3D * second ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCoverSurface ) +}; // MbCoverSurface + + +IMPL_PERSISTENT_OPS( MbCoverSurface ) + + +//------------------------------------------------------------------------------ +// \ru Получить кривую по индексу \en Get curve by an index +// --- +inline const MbCurve3D * MbCoverSurface::GetCurve( size_t ind ) const +{ + if ( ind >= COVER_COUNT ) + ind = ind % COVER_COUNT; + switch ( ind ) { + case 0 : { return curve0; } + case 1 : { return curve1; } + case 2 : { return curve2; } + case 3 : { return curve3; } + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru Минимальное значение параметра на кривой с индексом ind. \en Get The minimal value of parameter on curve by index. +// --- +inline double MbCoverSurface::GetTMin( size_t ind ) const +{ + if ( ind >= COVER_COUNT ) + ind = ind % COVER_COUNT; + switch ( ind ) { + case 0 : { return t0min; } + case 1 : { return t1min; } + case 2 : { return t2min; } + case 3 : { return t3min; } + } + return UNDEFINED_DBL; +} + + +//------------------------------------------------------------------------------ +// \ru Максимальное значение параметра на кривой с индексом ind. \en Get The maximal value of parameter on curve by index. +// --- +inline double MbCoverSurface::GetTMax( size_t ind ) const +{ + if ( ind >= COVER_COUNT ) + ind = ind % COVER_COUNT; + switch ( ind ) { + case 0 : { return t0max; } + case 1 : { return t1max; } + case 2 : { return t2max; } + case 3 : { return t3max; } + } + return UNDEFINED_DBL; +} + + +//------------------------------------------------------------------------------ +// \ru Корректировка параметров \en Correct parameters +// --- +inline void MbCoverSurface::CheckParam( double &u, double &v ) const +{ + double umin = 0; + double umax = 1; + double vmin = 0; + double vmax = 1; + if ( uclosed ) { + if ( (u < umin) || (u > umax ) ) { + double tmp = umax - umin; + u -= ::floor((u - umin) / tmp) * tmp; + } + } + else { + if ( poleUMin && uumax ) + u = umax; + } + if ( vclosed ) { + if ( (v < vmin) || (v > vmax ) ) { + double tmp = vmax - vmin; + v -= ::floor((v - vmin) / tmp) * tmp; + } + } + else { + if ( poleVMin && vvmax ) + v = vmax; + } +} + + +#endif // __SURF_COVER_SURFACE_H diff --git a/C3d/Include/surf_curve_bounded_surface.h b/C3d/Include/surf_curve_bounded_surface.h new file mode 100644 index 0000000..3d72a12 --- /dev/null +++ b/C3d/Include/surf_curve_bounded_surface.h @@ -0,0 +1,570 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность произвольной криволинейной границей и возможными вырезами внутри. + \en The surface with an arbitrary curved boundary and possible cuts inside. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CURVE_BOUNDED_SURFACE_H +#define __SURF_CURVE_BOUNDED_SURFACE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbRect; +class MATH_CLASS MbRect2D; +class MbContoursSearchTree; + + +//------------------------------------------------------------------------------ +/** \brief \ru Ограниченная кривыми поверхность. + \en The surface bounded by curves. \~ + \details \ru Поверхность, ограниченная замкнутыми контурами на поверхности MbContourOnSurface, + представляет собой общий случай поверхности. \n + Областью определения параметров такой поверхности является + связный кусок двумерной плоскости, который описывается + одним внешним двумерным контуром и некоторым числом внутренних контуров. \n + Контур представляет собой составную замкнутую двумерную кривую. + Каждый двумерный контур в совокупности с базовой поверхностью образует контур на поверхности MbContourOnSurface, + который проходит по одному из краёв поверхности. + Каждый контур описывает одну замкнутую границу поверхности. \n + Первый контур контейнера curves описывает внешнюю границу и содержит внутри все остальные контуры, + которые описывают внутренние вырезы в поверхности. \n + Внутренние контуры не могут быть вложены друг в друга. + Внутренние контуры лежат внутри внешнего контура. \n + В случае отсутствия вырезов внутри поверхности внутренние контуры отсутствуют. + Контуры не пересекают друг друга и сами себя. \n + Контуры, описывающие область определения поверхности, + могут выходить за область определения базовой поверхности basisSurface. + При выходе за пределы области определения базовая поверхность basisSurface продолжается + по своему закону изменения, как, например, элементарные поверхности, или - по касательной в общем случае. \n + Для правильной работы метода, определяющего положение параметров относительно границ поверхности, + контуры должны быть ориентированы (метод NormalizeCurvesOrientation()). + Если смотреть навстречу нормали поверхности с ориентированными контурами, то + внешний контур на поверхности ориентирован против часовой стрелки, + а внутренние контуры на поверхности ориентированы по часовой стрелке. \n + Ограниченная кривыми поверхность считается не замкнутой по обоим параметрам. + Для периодической базовой поверхности область определения периодического параметра + ограниченной кривыми поверхности может превышать период базовой поверхности. + Базовой поверхностью для ограниченной кривыми поверхности не может служить другая ограниченная кривыми поверхность. + В подобной ситуации выполняется переход к первичной базовой поверхности. + Поверхность используется для построения граней тел в общем случае. + \en The surface bounded by closed contours on surface MbContourOnSurface + represents the general case of a surface. \n + Domain of parameters of such surface is the + connected piece of the two-dimensional plane which is described by + one external two-dimensional contour and some internal contours. \n + Contour is composite closed two-dimensional curve. + Each two-dimensional contour together with base surface forms a contour on surface MbContourOnSurface + which passes through one of surface edges. + Each contour describes one closed boundary of surface. \n + First contour of 'curves' container describes external boundary and contains inside all the other contours + describing internal cuts of a surface. \n + Internal contours can not be enclosed each other. + Internal loops lie inside the external loop. \n + In case of absence of cuts inside surfaces internal contours are absent. + Loops don't intersect each other and themselves. \n + Contours describing the surface domain + can exceed the domain of base surface basisSurface. + When it is out of domain bounds base surface basisSurface is extended + according to its law of change as elementary surfaces for example or by tangent generally. \n + For the correct work of the method determining the position of parameters relative to surface boundary + contours have to be oriented (NormalizeCurvesOrientation() method). + If look towards to a surface normal with the oriented contours then + the external contour of surface is oriented counterclockwise + but internal contours of surface are oriented clockwise. \n + The surface bounded by curves is considered to be open by both parameters. + For a periodic base surface the domain of periodic parameter of + the surface bounded by curves can exceed the period of a base surface. + Another surface bounded by curves can't be the base surface for surface bounded by curves. + In this situation it changes to the initial base surface. + The surface is used for creation of faces of solids in general case. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbCurveBoundedSurface : public MbSurface, public MbNestSyncItem { +private: + MbSurface * basisSurface; ///< \ru Базовая поверхность. \en Base surface. + RPArray curves; ///< \ru Множество контуров на поверхности, определяющих её края. \en Set of contours on surface determining surface boundary. + /// \ru Габариты области определения параметров. \en Bounds of parameter domain. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + + mutable MbContoursSearchTree * searchTree; ///< \ru Дерево габаритов для ускорения поиска. \en A tree of bounding boxes for search acceleration. + +public : + /// \ru Конструктор без установки пределов по u, v. \en Constructor without setting the u, v limits. + MbCurveBoundedSurface( MbSurface & initSurface ); + /// \ru Конструктор с установкой пределов по u, v. \en Constructor with setting the u, v limits. + MbCurveBoundedSurface( MbSurface & initSurface, double uin, double uax, double vin, double vax ); + /// \ru Конструктор с установкой пределов по u, v. \en Constructor with setting the u, v limits. + MbCurveBoundedSurface( MbSurface & initSurface, const MbRect & rect ); + /// \ru Конструктор с установкой пределов по u, v. \en Constructor with setting the u, v limits. + MbCurveBoundedSurface( MbSurface & initSurface, const MbRect2D & rect ); + /// \ru Конструктор с массивом контуров на поверхности. \en Constructor with array of contours on surface. + MbCurveBoundedSurface( MbSurface & initSurface, RPArray & initCurves, bool sameContours ); + /// \ru Конструктор с массивом контуров на плоскости (двумерных контуров). \en Constructor with array of contours on plane (two-dimensional contours). + MbCurveBoundedSurface( MbSurface & initSurface, RPArray & initCurves, bool sameContours ); + /// \ru Конструктор с массивом контуров на плоскости (двумерных контуров). \en Constructor with array of contours on plane (two-dimensional contours). + MbCurveBoundedSurface( MbSurface & initSurface, std::vector< SPtr > & initCurves, bool sameContours ); + /// \ru Конструктор для поверхности c габаритом при чтении грани. \en Constructor for surface with bounding box at face reading. + MbCurveBoundedSurface( MbSurface & initSurface, RPArray & initCurves, MbCube & gab ); + /// \ru Конструктор по контурам, берет за базовую поверхность поверхность первого контура. \en Constructor by contours, uses the surface of first contour as base surface. + MbCurveBoundedSurface( MbContourOnSurface & init1, MbContourOnSurface * init2 = NULL ); + /// \ru Конструктор-копия на новую базовую поверхность. \en Copy-constructor for new base surface. + MbCurveBoundedSurface( const MbCurveBoundedSurface & init, MbSurface & newBaseSurface, bool calculateGabarit = true ); + +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbCurveBoundedSurface( const MbCurveBoundedSurface & init, MbRegDuplicate * ); + /// \ru Конструктор копирования контуров с той же поверхностью (для CurvesDuplicate()). \en Copy-constructor of contours with the same surface (for CurvesDuplicate()). + MbCurveBoundedSurface( const MbCurveBoundedSurface * init ); +private : + MbCurveBoundedSurface( const MbCurveBoundedSurface & ); // \ru Не реализовано !!! \en Not implemented !!! +public : + virtual ~MbCurveBoundedSurface(); + +public : + VISITING_CLASS( MbCurveBoundedSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые поверхности. \en Get base surfaces. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; // \ru Минимальное значение параметра u. \en Minimal value of parameter u. + virtual double GetVMin() const; // \ru Минимальное значение параметра v. \en Minimal value of parameter v. + virtual double GetUMax() const; // \ru Максимальное значение параметра u. \en Maximal value of parameter u. + virtual double GetVMax() const; // \ru Максимальное значение параметра v. \en Maximal value of parameter v. + + virtual bool IsUClosed() const; // \ru Замкнута ли гладко поверхность по параметру u без учета граничного контура. \en Whether the surface is smoothly closed by parameter u without regard to the boundary contour. + virtual bool IsVClosed() const; // \ru Замкнута ли гладко поверхность по параметру v без учета граничного контура. \en Whether the surface is smoothly closed by parameter v without regard to the boundary contour. + virtual bool IsUTouch() const; // \ru Замкнута ли фактически поверхность по параметру u независимо от гладкости. \en Whether the surface is actually closed by parameter u regardless of the smoothness. + virtual bool IsVTouch() const; // \ru Замкнута ли фактически поверхность по параметру v независимо от гладкости. \en Whether the surface is actually closed by parameter v regardless of the smoothness. + virtual bool IsUPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру u. \en Whether the surface is smoothly closed by parameter u. + virtual bool IsVPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру v. \en Whether the surface is smoothly closed by parameter v. + virtual double GetUPeriod() const; // \ru Период для замкнутой поверхности или 0. \en Period for closed surface or 0. + virtual double GetVPeriod() const; // \ru Период для замкнутой поверхности или 0. \en Period for closed surface or 0. + + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по u. \en The third derivative with respect to u. + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по v. \en The third derivative with respect to v. + virtual void TangentU ( double & u, double & v, MbVector3D & ) const; // \ru Касательный вектор. \en Tangent vector. + virtual void TangentV ( double & u, double & v, MbVector3D & ) const; // \ru Касательный вектор. \en Tangent vector. + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали по u. \en The derivative of normal with respect to u. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали по v. \en The derivative of normal with respect to v. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + // \ru Значения производных в точке \en Values of derivatives at point + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; // \ru Количество разбиений по параметру u для проверки событий. \en Count of splittings by parameter u to check for events. + virtual size_t GetVCount() const; // \ru Количество разбиений по параметру v для проверки событий. \en Count of splittings by parameter v to check for events. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual const MbSurface & GetSurface() const; // \ru Дать базовую поверхность. \en Get the base surface. + virtual const MbSurface & GetBasisSurface() const; // \ru Дать базовую поверхность. \en Get the base surface. + virtual MbSurface & SetSurface() ; // \ru Дать базовую поверхность. \en Get the base surface. + virtual MbSurface & SetBasisSurface(); // \ru Дать базовую поверхность. \en Get the base surface. + + // \ru Выдать граничную точку \en Get the boundary point + virtual void GetLimitPoint( ptrdiff_t num, MbCartPoint3D & ) const; // \ru Выдать граничную трехмерную точку. \en Get the three-dimensional boundary point. + virtual void GetLimitPoint( ptrdiff_t num, MbCartPoint & ) const; // \ru Выдать граничную двумерную точку (граничные параметры). \en Get the two-dimensional boundary point (boundary parameters). + + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии u. \en Curvature of u-line. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v-line. + + virtual bool IsSameBase( const MbSurface & ) const; // \ru Является ли базовая поверхность копией базовой поверхности данного объекта. \en Whether the base surface is a duplicate of base surface of current object. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual double GetFilletRadius( const MbCartPoint3D & ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual bool GetCylinderAxis( MbAxis3D & ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + + virtual void ChangeCarrier ( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + virtual bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); // \ru Изменение носимых элементов. \en Change a carrier elements. + + virtual MbSplineSurface * NurbsSurface( double u1, double u2, double v1, double v2, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + virtual MbCurve3D * CurveUV( const MbLineSegment &, bool bApprox = true ) const; // \ru Пространственная копия линии по параметрической линии. \en Spatial copy of line by parametric line. + + virtual MbeItemLocation PointClassification( const MbCartPoint &, bool ignoreClosed = false ) const; // \ru Находится ли точка в области, принадлежащей поверхности. \en Whether the point is in region belonging to the surface. + virtual double DistanceToBorder ( const MbCartPoint &, double & eps ) const; // \ru Параметрическое расстояние до ближайшей границы. \en Parametric distance to the nearest boundary. + + // \ru Определение точек пересечения кривой с контурами поверхности. \en Determine intersection points of a curve with the contours on the surface. + virtual size_t CurveClassification( const MbCurve & curve, SArray & tcurv, SArray & dir ) const; + /** \brief \ru Определить точки пересечения с двумерной кривой. + \en Determine points of intersection with two-dimensional uv-curve. \~ + \details \ru Определить точки пересечения плоской кривой и плоских контуров поверхности. \n + \en Determine intersection points of a planar curve and contours. \n \~ + \param[in] pCurve - \ru Кривая. + \en A curve. \~ + \param[out] curveParams - \ru Массив параметров на кривой. + \en An array of parameters on the curve. \~ + \return \ru Количество точек пересечения. + \en The number of points. \~ + */ + size_t SegmentIntersection( const MbCurve & pCurve, SArray & curveParams, double epsilon = Math::metricEpsilon ) const; + + // \ru Найти ближайшую проекцию точки на поверхность. \en Find the nearest projection of a point onto the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Вce точки пересечения поверхности и кривой. \en All the points of intersection of a surface and a curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + // \ru Уточнение параметров точки линии очерка поверхности. \en Refinement of parameters of point of isocline curve of the surface. + virtual MbeNewtonResult SilhouetteNewton( const MbVector3D & eye, bool perspective, const MbAxis3D * axis, MbeParamDir switchPar, + double funcEpsilon, size_t iterLimit, double & u, double & v, bool ext ) const; + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Изменение носимых двумерных кривых (точек) поверхности путем проецирования на совпадающую поверхность. \en Change a carrier two-dimensional curves (points) of surface by projecting onto the coinciding surface. + virtual bool ProjectCurveOnSimilarSurface( const MbCurve3D & spaceCurve, const MbCurve & curve, const MbSurface & surfNew, MbCurve *& curveNew ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether the surface is convex. + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + // \ru Расчёт площади области определения параметров. \en Calculate area of parameter domain. + virtual double ParamArea() const; + + virtual size_t GetUPairs( double v, SArray & u ) const; // \ru Вычислить U-пары от V. \en Calculate U-pairs by V. + virtual size_t GetVPairs( double u, SArray & v ) const; // \ru Вычислить V-пары от U. \en Calculate V-pairs by U. + + virtual void CalculateGabarit( MbCube & ) const; // \ru Рассчитать габарит поверхности. \en Calculate bounding box of surface. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); // \ru Установить пределы. \en Set limits. + virtual void IncludePoint( double u, double v ); // \ru Расширить параметрические границы поверхности. \en Extend parametric bounds of surface. + + virtual double GetParamDelta() const; // \ru Дать максимальное приращение параметра. \en Get the maximal increment of parameter. + virtual double GetParamPrice() const; // \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + virtual void CalculateSurfaceWire( const MbStepData & stepData, size_t beg, MbMesh & mesh, + size_t uMeshCount = c3d::WIRE_MAX, size_t vMeshCount = c3d::WIRE_MAX ) const; // \ru Рассчитать сетку. \en Calculate mesh. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If true, then all the derivatives by U higher the first one are equal to zero. + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives by V higher the first one are equal to zero. + + virtual MbContour & MakeContour( bool sense ) const; // \ru Выдать граничных двумерный контур. \en Get the two-dimensional boundary contour. + virtual MbCurve & MakeSegment( size_t i, bool sense ) const; // \ru Дать граничную двумерную кривую. \en Get the two-dimensional boundary curve. + /// \ru Аппроксимация поверхности треугольными пластинами. \en Approximation of a surface by triangular plates. + virtual void CalculateSurfaceGrid( const MbStepData & stepData, bool sense, MbGrid & grid ) const; + /** \} */ + /** \ru \name Функции поверхности MbCurveBoundSurface + \en \name Functions of MbCurveBoundSurface surface + \{ */ + + /** \brief \ru Дать граничную двумерную кривую. + \en Get the two-dimensional boundary curve. \~ + \details \ru Делает копию кривой. + \en Makes a copy of a curve. \~ + \param[in] number - \ru Номер кривой + \en Index of curve \~ + \param[in] i - \ru Индекс сегмента + \en Index of segment \~ + \param[in] sense - \ru Признак совпадения направления кривой + \en Attribute of coincidence of curve direction \~ + */ + MbCurve & MakeSegment( size_t number, size_t i, bool sense ) const; + /** \brief \ru Дать граничную двумерную кривую. + \en Get the two-dimensional boundary curve. \~ + \details \ru Дать граничную двумерную кривую. + \en Get the two-dimensional boundary curve. \~ + \param[in] number - \ru Номер кривой + \en Index of curve \~ + \param[in] i - \ru Индекс сегмента + \en Index of segment \~ + */ + const MbCurve * GetSegment ( size_t number, size_t i ) const; + /** \brief \ru Дать граничную двумерную кривую. + \en Get the two-dimensional boundary curve. \~ + \details \ru Дать граничную двумерную кривую. + \en Get the two-dimensional boundary curve. \~ + \param[in] number - \ru Номер кривой + \en Index of curve \~ + \param[in] i - \ru Индекс сегмента + \en Index of segment \~ + */ + MbCurve * SetSegment ( size_t number, size_t i ); + + /// \ru Выдать число контуров. \en Get the count of contours. + size_t GetCurvesCount() const { return curves.Count(); } + /// \ru Выдать число сегментов в контуре с номером i \en Get the count of segments of i-th contour + size_t GetSegmentsCount( size_t i ) const; + + /** \brief \ru Добавить контур. + \en Add a contour. \~ + \details \ru Создает контур, ограничивающий поверхность, если число контуров = 0 + \en Creates a contour bounding a surface if count of contours is equal to 0 \~ + */ + void AddOuterContour(); + /** \brief \ru Удалить контур. + \en Remove contour. \~ + \details \ru Удаляет указанный контур. + \en Removes the specified contour. \~ + \param[in] cntr - \ru Удаляемый контур + \en Contour to remove \~ + */ + void DeleteContour( MbContourOnSurface * cntr ); + /** \brief \ru Заменить контур. + \en Replace contour. \~ + \details \ru Заменить контур. + \en Replace contour. \~ + \param[in] index - \ru Индекс изменяемого контура + \en Index of contour to change \~ + \param[in] cntr - \ru Новый контур + \en New contour \~ + */ + bool ChangeContour( size_t index, MbContourOnSurface * cntr ); + /// \ru Заменить базовую поверхность. \en Replace base surface. + bool ChangeSurface( MbSurface & newsurf ); + /// \ru Заменить базовую поверхность на ее копию. \en Replace base surface with its copy. + void NewBasisSurface(); + /// \ru Вычислить параметрические границы поверхности без сброса габарита. \en Calculate parametric bounds of surface without resetting the bounding box. + void CalculateUVLimitsOnly(); + /// \ru Вычислить параметрические границы поверхности с пересчетом габарита. \en Calculate parametric bounds of surface with recalculation of the bounding box. + void CalculateUVLimits(); + /** + \brief \ru Расширить параметрические границы базовой поверхности. + \en Extend parametric bounds of base surface. \~ + \details \ru Если это возможно, параметрические границы базовой поверхности расширяются так, \n + чтобы параметрические границы поверхности, ограниченной кривыми, находились внутри них. + \en If it is possible, then parametric bounds of base surface are extended so\n + that the parametric bounds of surface bounded by curves are inside of them. \~ + */ + void SetBasisSurfaceUVLimits(); + /** + \brief \ru Проверить, входят ли параметры в параметрические границы поверхности. + \en Check, whether the parameters are in parametric bounds of surface. \~ + \details \ru Параметры проверяются на вхождение в область допустимых значений параметров для данной поверхности. \n + Если параметр выходит за эту область, ему присваивается максимально или минимально допустимое значение. + \en Parameters are checked for occurrence in region of permissible values of parameters for current surface. \n + If parameter is out of this region, then maximum or minimum permissible value is assigned to it. \~ + */ + inline void CheckParam( double & u, double & v ) const; + + /** \brief \ru Ориентировать ограничивающие контуры. + \en Orient bounding contours. \~ + \details \ru Ориентирует внешний контур против часовой стрелки, внутренние контуры - по часовой стрелки. + \en External contour is oriented counterclockwise, internal contours - clockwise. \~ + \return \ru Возвращает площадь параметрической области поверхности. + \en Returns area of parametric region of surface. \~ + \warning \ru В конструкторах не вызывается, так как предполагается, что на вход поступает правильный набор контуров, \n + а сама функция ориентирования требует много времени на ее выполнение. + \en In constructors isn't called as it is supposed that given the correct set of contours,\n + but function of orientation needs a lot of time for its execution. \~ + + */ + double NormalizeCurvesOrientation(); + + // \ru Не используется \en Not used \~ bool SetCurveEqual( const MbSpaceItem & ); // Сделать равными контуры. \en Make contours equal. + // \ru Не используется \en Not used \~ bool IsCurveEqual ( const MbSpaceItem & ) const; // Являются ли объекты подобными. \en Whether the objects are equal. + /// \ru Удалить все контуры. \en Remove all the contours. + void DeleteCurves(); + /** \brief \ru Добавить контур. + \en Add a contour. \~ + \details \ru Добавить контур. После добавления нужно вызвать CalculateUVLimits(). + \en Add a contour. After addition it is necessary to call CalculateUVLimits(). \~ + */ + void AddCurve( MbContourOnSurface & contour ); + /** \brief \ru Добавить контур. + \en Add a contour. \~ + \details \ru Добавить контур. После добавления нужно вызвать CalculateUVLimits(). + \en Add a contour. After addition it is necessary to call CalculateUVLimits(). \~ + */ + void AddCurve( MbContour & contour ); + /** \brief \ru Добавить контур. + \en Add a contour. \~ + \details \ru Добавить контур. После добавления не нужно вызвать CalculateUVLimits(). + \en Add a contour. After addition it isn't necessary to call CalculateUVLimits(). \~ + */ + void AddContour( MbContour & contour ) { AddCurve( contour ); CalculateUVLimits(); } + + /** \brief \ru Дать контур, ограничивающий поверхность, по его индексу. + \en Get contour bounding surface by its index. \~ + \details \ru Дать контур, ограничивающий поверхность, по его индексу. С проверкой индекса. + \en Get contour bounding surface by its index. With index checking. \~ + */ + const MbContourOnSurface * GetCurve ( size_t ind ) const { return ( ind < curves.Count() ) ? curves[ind] : NULL; } + /** \brief \ru Дать контур, ограничивающий поверхность, по его индексу. + \en Get contour bounding surface by its index. \~ + \details \ru Дать контур, ограничивающий поверхность, по его индексу. Без проверки индекса. + Рекомендуется использовать функцию GetCurve с проверкой индекса. + \en Get contour bounding surface by its index. Without index checking. + It is recommended to use the GetCurve function with index checking. \~ + */ + const MbContourOnSurface *_GetCurve ( size_t ind ) const { return curves[ind]; } + /** \brief \ru Дать контур, ограничивающий поверхность, по его индексу. + \en Get contour bounding surface by its index. \~ + \details \ru Дать контур, ограничивающий поверхность, по его индексу. С проверкой индекса. + \en Get contour bounding surface by its index. With index checking. \~ + */ + MbContourOnSurface * SetCurve ( size_t ind ) { return ( ind < curves.Count() ) ? curves[ind] : NULL; } + /** \brief \ru Дать контур, ограничивающий поверхность, по его индексу. + \en Get contour bounding surface by its index. \~ + \details \ru Дать контур, ограничивающий поверхность, по его индексу. Без проверки индекса. + Рекомендуется использовать функцию SetCurve с проверкой индекса. + \en Get contour bounding surface by its index. Without index checking. + It is recommended to use the SetCurve function with index checking. \~ + */ + MbContourOnSurface *_SetCurve ( size_t ind ) { return curves[ind]; } + /// \ru Переместить кривую с индексом ind в нулевую позицию массива. \en Move a curve with the 'ind' index to a zero position of the array. + void ReplaceOuterCurveBy( size_t ind ); + /// \ru Найти двумерную кривую и заменить ее на другую. \en Find two-dimensional curve and replace it with another one. + bool ChangeCurve2D( MbCurve & oldCrv, MbCurve * newCrv ); + /// \ru Слить двумерные сегменты в контурах. \en Merge two-dimensional segments in contours. + void MergeSegments( double eps = Math::LengthEps ); + /// \ru Копия объекта со старой базовой поверхностью. \en Copy of object with old base surface. + MbCurveBoundedSurface & CurvesDuplicate() const; + /// \ru Проверить на замкнутость по u или v по внешнему контуру. \en Check closeness by u or v using outer contour. + bool CheckTouchByContour( bool byU ) const; + /** \} */ + +protected: + bool CreateRectTree() const; ///< \ru Создать и инициализировать дерево поиска. \en Create and initialize the search tree. + void DeleteRectTree() const; ///< \ru Удалить дерево поиска. \en Delete search tree. + void DeleteSearchTree() const; ///< \ru Удалить дерево поиска. \en Delete search tree. + +private: + // \ru Управление распределением памяти в массиве segments \en Control of memory allocation in the array "segments" + // \ru Не используется \en Not used \~ void CurvesReserve( size_t additionalSpace ) { curves.Reserve( additionalSpace ); } // Зарезервировать место под столько элементов. \en Reserve memory for so many elements. + // \ru Не используется \en Not used \~ void CurvesAdjust () { curves.Adjust(); } // Удалить лишнюю память. \en Remove unnecessary memory. + + void operator = ( const MbCurveBoundedSurface & ); // \ru Не реализовано !!! \en Not implemented!!! + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveBoundedSurface ) +}; + +IMPL_PERSISTENT_OPS( MbCurveBoundedSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить, входят ли параметры в параметрические границы поверхности. \en Check, whether the parameters are in parametric bounds of surface. +// --- +inline void MbCurveBoundedSurface::CheckParam ( double & u, double & v ) const +{ + if (u < umin) + u = umin; + else if ( u > umax ) + u = umax; + + if ( v < vmin) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +#endif // __SURF_CURVE_BOUNDED_SURFACE_H diff --git a/C3d/Include/surf_cylinder_surface.h b/C3d/Include/surf_cylinder_surface.h new file mode 100644 index 0000000..a1b6c92 --- /dev/null +++ b/C3d/Include/surf_cylinder_surface.h @@ -0,0 +1,380 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Цилиндрическая поверхность. + \en The cylindrical surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_CYLINDER_SURFACE_H +#define __SURF_CYLINDER_SURFACE_H + + +#include + + +class MATH_CLASS MbLineSegment3D; +class MATH_CLASS MbPlane; + + +//------------------------------------------------------------------------------ +/** \brief \ru Цилиндрическая поверхность. + \en The cylindrical surface. \~ + \details \ru Цилиндрическая поверхность описывается радиусом radius и высотой height, заданными в локальной системе координат position. \n + Первый параметр поверхности отсчитывается по дуге от оси position.axisX в направлении оси position.axisY. + Первый параметр поверхности u принимает значения на отрезке: umin<=u<=umax. + Значения u=0 и u=2pi соответствуют точке на плоскости XZ локальной системы координат. + Поверхность может быть замкнутой по первому параметру. + У замкнутой поверхности umax-umin=2pi, у не замкнутой поверхности umax-umin<2pi. \n + Второй параметр поверхности отсчитывается по прямой вдоль оси position.axisZ. + Второй параметр поверхности v принимает значения на отрезке: vmin<=v<=vmax. + Значение v=0 соответствует точке плоскости XY локальной системы координат, + а значение v=1 соответствует точке на расстоянии height от плоскости XY локальной системы координат поверхности. \n + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + (radius cos(u) position.axisX) + (radius sin(u) position.axisY) + (height v position.axisZ). \n + Локальная система координат position может быть как правой, так и левой. + Если локальная система координат правая, то нормаль направлена в сторону выпуклости поверхности (от оси position.axisZ), + если локальная система координат левая, то нормаль направлена в сторону вогнутости поверхности (в сторону оси position.axisZ). \n + \en Cylindrical surface is described by 'radius' radius and 'height' height given in 'position' local coordinate system. \n + The first parameter of surface is measured along arc from position.axisX axis in the direction of position.axisY axis. + The first parameter u of surface possesses the values in the range: umin<=u<=umax. + Values u=0 and u=2pi correspond to point on XZ plane of local coordinate system. + Surface can be closed by first parameter. + In case of closed surface: umax-umin=2pi; in case of open surface: umax-umin<2pi. \n + Second parameter of surface is measured by line along position.axisZ axis. + Second parameter v of surface possesses the values in the range: vmin<=v<=vmax. + Value v=0 corresponds to point on XY plane of local coordinate system, + but value v=1 corresponds to point at 'height' distance from XY plane of local coordinate system of surface. \n + Radius-vector of surface is described by the vector function \n + r(u,v) = position.origin + (radius cos(u) position.axisX) + (radius sin(u) position.axisY) + (height v position.axisZ). \n + Local coordinate system 'position' can be both right and left. + If local coordinate system is right then normal is directed to the side of convexity of surface (from position.axisZ axis), + If local coordinate system is left then normal is directed to the side of concavity of surface (to position.axisZ axis). \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbCylinderSurface : public MbElementarySurface { +private: + double radius; ///< \ru Радиус цилиндра. \en Radius of cylinder. + double height; ///< \ru Высота цилиндра. \en Height of cylinder. + bool uclosed; ///< \ru Признак замкнутости по первому параметру. \en Attribute of closedness by first parameter. + +public: + /// \ru Конструктор по системе координат, радиусу и высоте. \en Constructor by a local coordinate system, radius and height. + MbCylinderSurface( const MbPlacement3D & place, double r, double h ); + + /** \brief \ru Конструктор по радиусу, высоте и системе координат. + \en Constructor by radius, height and coordinate system. \~ + \details \ru Конструктор по радиусу, высоте и системе координат. + \en Constructor by radius, height and coordinate system. \~ + \warning \ru Только для использования в конвертерах. + \en Used only in converters. \~ + */ + MbCylinderSurface( double r, double h, const MbPlacement3D & place ); + + /** \brief \ru Конструктор по центру системы координат, оси Z и радиусу. + \en Constructor by an origin of local coordinate system, Z-axis and radius. \~ + \details \ru Конструктор по центру системы координат, оси Z и радиусу. \n + \en Constructor by an origin of local coordinate system, Z-axis and radius. \n \~ + \param[in] org - \ru центр локальной системы координат + \en Origin of the local coordinate system \~ + \param[in] axisZ - \ru Ось Z локальной системы координат + \en Z-axis of the local coordinate system \~ + \param[in] r - \ru Радиус цилиндра и высота цилиндра, при r < Math::lengthRegion высота цилиндра = 1.0 + \en Radius of cylinder and height of cylinder, height of cylinder is equal to 1.0 if r < Math::lengthRegion \~ + \param[in] left - \ru Если true, то система координат цилиндра левая + \en If true, then cylinder coordinate system is left \~ + */ + MbCylinderSurface( const MbCartPoint3D & org, const MbVector3D & axisZ, double r, bool left = false ); + + /** \brief \ru Конструктор по трем точкам. + \en Constructor by three points. \~ + \details \ru Конструктор по трем точкам. + \en Constructor by three points. \~ + \param[in] c0 - \ru центр локальной системы координат цилиндра + \en Origin of the local coordinate system of cylinder \~ + \param[in] c1 - \ru Вектор из точки c0 в точку c1 определяет ось Z + \en Vector from c0 point to c1 point determines Z-axis \~ + \param[in] c2 - \ru Вектор из точки c0 в точку c2 определяет ось X, радиус цилиндра равен расстоянию от оси Z до точки c2 + \en Vector from c0 point to c2 point determines X-axis, radius of cylinder is equal to distance from Z-axis to c2 point \~ + */ + MbCylinderSurface( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2 ); // \ru По трём точкам \en By three points + +protected: + MbCylinderSurface( const MbCylinderSurface & ); +public: + virtual ~MbCylinderSurface (); + +public: + VISITING_CLASS( MbCylinderSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /// \ru Инициализация по цилиндрической поверхности. \en Initialization by cylindrical surface. + void Init( const MbCylinderSurface & init ); + /// \ru Инициализация по локальной системе координат, радиусу и высоте. \en Initialization by a local coordinate system, radius and height. + void Init( const MbPlacement3D & place, double r, double h ); + + /** \brief \ru Инициализация по отрезку и точке. + \en Initialization by segment and point. \~ + \details \ru Инициализация по отрезку и точке. \n + Высота цилиндра определяется длиной отрезка seg. \n + Ось определяется отрезком seg. \n + Радиус цилиндра равен расстоянию от точки point до оси. + \en Initialization by segment and point. \n + Height of cylinder is determined by length of 'seg' segment. \n + Axis is determined by 'seg' segment. \n + Radius of cylinder is equal to distance from 'point' point to axis. \~ + */ + void Init( const MbLineSegment3D & seg, const MbCartPoint3D & point ); + + /** \brief \ru Построение цилиндра радиуса r как сопряжение двух плоскостей в указанном месте. + \en Construction of cylinder of radius 'r' as conjugation of two planes at specified place. \~ + \details \ru Построение цилиндра радиуса r, касающегося двух плоскостей plane1 и plane2 + \en Construction of cylinder of radius 'r' tangent to two planes 'plane1' and 'plane2' \~ + \param[in] plane1 - \ru Первая плоскость + \en First plane \~ + \param[in] plane2 - \ru Вторая плоскость + \en Second plane \~ + \param[in] side1 - \ru Если > 0, то цилиндр над первой плоскостью, если < 0, то цилиндр под первой плоскстью + \en If it is greater than 0, then cylinder is above first plane, if it is less than 0, then cylinder is under first plane \~ + \param[in] side2 - \ru Если > 0, то цилиндр над второй плоскостью, если < 0, то цилиндр под второй плоскстью + \en If it is greater than 0, then cylinder is above second plane, if it is less than 0, then cylinder is under second plane \~ + \param[in] r - \ru Радиус цилиндра + \en Radius of cylinder \~ + */ + bool Init( const MbPlane & plane1, const MbPlane & plane2, int side1, int side2, double r ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; + virtual bool IsVClosed() const; + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for closed function. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for closed function. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке \en Values of derivatives at point + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна вдоль u. \en Curvature along u. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature along v. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность. \en Create a shifted surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + virtual MbCurve3D * CurveUV( const MbLineSegment &, bool bApprox = true ) const; // \ru Пространственная копия линии по параметрической линии. \en Spatial copy of line by parametric line. + + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Пересечение с кривой. \en Intersection with curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + // \ru Определение точки касания поверхностей с одним неподвижным параметром. \en Determination of tangency point of surfaces with one fixed parameter. + virtual MbeNewtonResult SurfaceTangentNewton( const MbSurface & surf1, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + + // \ru Определение точки пересечения цилиндрической поверхности и кривой. \en Determination of intersection point of cylindrical surface and curve. + virtual MbeNewtonResult CurveIntersectNewton( const MbCurve3D & curve, double funcEpsilon, size_t iterLimit, + double & u, double & v, double & t, bool ext0, bool ext1 ) const; + // \ru Определение точки касания цилиндрической поверхности и кривой. \en Determination of tangency point of cylindrical surface and curve. + virtual MbeNewtonResult CurveTangentNewton( const MbCurve3D & curv, double funcEpsilon, size_t iterLimit, + double & u, double & v, double & t, bool ext0, bool ext1 ) const; + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D & axis ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether the surface is convex. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual void CalculateGabarit( MbCube & ) const; // \ru Рассчитать габарит поверхности. \en Calculate bounding box of surface. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + // \ru Является ли объект смещением. \en Is the object is a shift? + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + virtual void IncludePoint( double u, double v ); // \ru Включить точку в область определения \en Include point into domain + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the count of polygons by u + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю \en If true, then all the derivatives by V higher the first one are equal to zero + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces + \{ */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /** \} */ + /** \ru \name Функции цилиндрической поверхности + \en \name Functions of the cylindrical surface + \{ */ + /// \ru Получить внутренний радиус. \en Get internal radius. + double GetR() const { return radius; } + /// \ru Установить внутренний радиус. \en Set an internal radius. + void SetR( double r ) { radius = r; SetDirtyGabarit(); } + + /// \ru Изменение внутренней высоты. \en Change internal height. + void SetHeight( double h ) { height = h; SetDirtyGabarit(); } + /** \brief \ru Внутренняя высота. + \en Internal height. \~ + \details \ru Внутренняя высота. \n + Чтобы получить физическую высоту нужно внутреннюю высоту умножить + на параметрическую длину по V и + длину оси Z ЛСК поверхности. \n + \en Internal height. \n + To obtain the physical height you need to multiply the internal height + by the parametric length along V and + the length of the Z axis of the local coordinate system of the surface. \~ + */ + double GetHeight() const { return height; } + /// \ru Выдать физическую высоту. \en Get physical height. \~ + double GetRealHeight() const { return ( height * (vmax - vmin) * position.GetAxisZ().Length() ); } + + /// \ru Дать точку на оси цилиндра. \en Get point on axis of cylinder. + void GetAxisPoint( double v, MbCartPoint3D & pnt ) const; + /** \} */ +private: + inline void CheckParam( double & u, double & v ) const; // \ru Проверить параметры. \en Check parameters. + // \ru Пересечение с прямолинейной кривой. \en Intersection with rectilinear curve. + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, bool ext0, bool ext ) const; + void operator = ( const MbCylinderSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCylinderSurface ) +}; + +IMPL_PERSISTENT_OPS( MbCylinderSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbCylinderSurface::CheckParam( double & u, double & v ) const +{ + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) + u -= ::floor( (u - umin) * Math::invPI2 ) * M_PI2; + else if ( u < umin ) + u = umin; + else + u = umax; + } + if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +#endif // __SURF_CYLINDER_SURFACE_H diff --git a/C3d/Include/surf_elementary_surface.h b/C3d/Include/surf_elementary_surface.h new file mode 100644 index 0000000..9cf446f --- /dev/null +++ b/C3d/Include/surf_elementary_surface.h @@ -0,0 +1,223 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Элементарная поверхность. + \en An elementary surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_ELEMENTARY_SURFACE_H +#define __SURF_ELEMENTARY_SURFACE_H + + +#include +#include + + +#define CIRC_COUNT 32 +#define HIDE_COUNT 16 +#define LINE_COUNT 10 + + +//------------------------------------------------------------------------------ +/** \brief \ru Элементарная поверхность. + \en An elementary surface. \~ + \details \ru Родительский класс поверхностей: MbConeSurface, MbCylinderSurface, MbPlane, MbSphereSurface, MbTorusSurface. + Элементарная поверхность описывается аналитическим выражением в локальной системе координат. + В локальной системе координат аналитическое выражение радиуса-вектора поверхности имеет канонический вид. \n + Локальная система координат position может быть как правой, так и левой.\n + \en Parent class for surfaces: MbConeSurface, MbCylinderSurface, MbPlane, MbSphereSurface, MbTorusSurface. + Elementary surface is described by analytical expression in local coordinate system. + Analytical expression of radius-vector of surface has canonical form in local coordinate system. \n + Local coordinate system 'position' can be both right and left.\n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbElementarySurface : public MbSurface { +protected: + MbPlacement3D position; ///< \ru Локальная система координат. \en Local coordinate system. + double umin; ///< \ru Минимальное значение первого параметра. \en Minimal value of first parameter. + double vmin; ///< \ru Минимальное значение второго параметра. \en Minimal value of second parameter. + double umax; ///< \ru Максимальное значение первого параметра. \en Maximal value of first parameter. + double vmax; ///< \ru Максимальное значение второго параметра. \en Maximal value of second parameter. + +protected: + MbElementarySurface(); + MbElementarySurface( const MbPlacement3D & ); + MbElementarySurface( const MbCartPoint3D & origin, const MbVector3D & axisZ, const MbVector3D & axisX ); + MbElementarySurface( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2 ); + MbElementarySurface( const MbElementarySurface &other ); +public: + virtual ~MbElementarySurface(); + +public: + VISITING_CLASS( MbElementarySurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA () const = 0; // \ru Тип элемента. \en A type of element. + virtual MbeSpaceType Type() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D & to, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & to ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + + virtual void GetProperties( MbProperties & properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & s ); ///< \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const = 0; // \ru Вернуть минимальное значение параметра u. \en Return the minimum value of parameter u. + virtual double GetVMin() const = 0; // \ru Вернуть минимальное значение параметра v. \en Return the minimum value of parameter v. + virtual double GetUMax() const = 0; // \ru Вернуть максимальное значение параметра u. \en Return the maximum value of parameter u. + virtual double GetVMax() const = 0; // \ru Вернуть максимальное значение параметра v. \en Return the maximum value of parameter v. + virtual bool IsUClosed() const = 0; // \ru Проверка замкнутости по параметру u. \en Check of closedness by parameter u. + virtual bool IsVClosed() const = 0; // \ru Проверка замкнутости по параметру v. \en Check of closedness by parameter v. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + Исключения составляют:\n + 1. MbPlane (плоскость)\n + Функции PointOn, Derive... плоскости не корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + 2. MbSmoothSurface и её наследники (поверхности скругления или фаски)\n + Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр при его выходе за пределы определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + Except:\n + 1. MbPlane (plane)\n + Functions PointOn, Derive... of plane don't correct parameters + when they are out of bounds of rectangular domain of parameters.\n + 2. MbSmoothSurface and its inheritors (fillet or chamfer surfaces)\n + Functions PointOn, Derive... of smooth surfaces don't correct + first parameter when it is out of domain bounds + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const = 0; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const = 0; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const = 0; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const = 0; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double StepU ( double u, double v, double sag ) const = 0; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const = 0; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const = 0; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const = 0; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const = 0; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const = 0; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + // \ru Ближайшая проекция точки на поверхность \en Nearest point projection onto the surface + virtual MbeNewtonResult PointProjectionNewton( const MbCartPoint3D & p, size_t iterLimit, + double & u, double & v, bool ext ) const; // \ru Функция для нахождения проекции точки на поверхность. \en Function for searching the point projection onto the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + + virtual bool IsRectangular() const; // \ru Если true производные по u и v ортогональны. \en If true, then derivatives by u and v are orthogonal. + virtual void SetLimit( double u1, double v1, double u2, double v2 ) = 0; + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces + \{ */ + + /** \brief \ru Ближайшая проекция точки на поверхность. + \en The nearest point projection onto the surface. \~ + \details \ru Ближайшая проекция точки на поверхность. + \en The nearest point projection onto the surface. \~ + \param[in] p - \ru Проецируемая точка + \en Projecting point \~ + \param[in] init - \ru Если true, то входные параметры u, v считаются начальными приближениями + \en If true, then input parameters u and v are considered to be initial approximations \~ + \param[in,out] u - \ru Параметр проекции на поверхности + \en Parameter of projection onto the surface \~ + \param[in,out] v - \ru Параметр проекции на поверхности + \en Parameter of projection onto the surface \~ + \param[in] ext - \ru Признак поиска на продолжении поверхности + \en Attribute of search at the extension of a surface \~ + \param[in] uvRange - \ru Область поиска проекции + \en Region of search the projection \~ + \return \ru true в случае успеха операции + \en True if the operation succeeded \~ + */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const = 0; + + // Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; + + /** \brief \ru Добавить параметры в массив с заданным шагом. + \en Add parameters to the array with given step. \~ + \details \ru Добавить параметры от w1 до w2 в массив с заданным шагом. + \en Add parameters from w1 to w2 to the array with given step. \~ + \param[in] step - \ru Шаг + \en Step \~ + \param[in] maxCount - \ru Максимальное количество ячеек. \en Maximum count of cell. \~ + \param[out] ww - \ru Контейнер с параметрами + \en Container with parameters \~ + */ + void AddTesselation( double step, size_t maxCount, double w1, double w2, SArray & ww ) const; + + /// \ru Локальная система координат. \en A local coordinate system. + const MbPlacement3D & GetPlacement() const { return position; } + /// \ru Установить локальную систему координат. \en Set the local coordinate system. + void InitPlacement( MbPlacement3D & p ) { position.Init( p ); } + /// \ru Является ли система координат ортонормированной. \en Whether the coordinate system is orthonormalized. + bool IsPositionNormal() const { return ( !position.IsAffine() ); } + /// \ru Является ли система координат ортогональной и изотропной по осям. \en Whether the coordinate system is orthogonal and isotropic by the axes. + bool IsPositionIsotropic() const { return ( position.IsIsotropic() ); } + /// \ru Является ли система координат ортогональной с равными по длине осями X,Y. \en Whether the coordinate system is orthogonal with X and Y axes equal by length. + bool IsPositionCircular() const { return ( position.IsCircular() ); } + /** \} */ +protected: + void Init_( const MbElementarySurface & ); // \ru Габарит и position \en Bounding box and 'position' + +private: + void operator = ( const MbElementarySurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS( MbElementarySurface ) +}; + +IMPL_PERSISTENT_OPS( MbElementarySurface ) + +//------------------------------------------------------------------------------- +// \ru Проверить и итерационно уточнить проекцию точки на поверхность по направлению \en Check and refine point projection onto the surface by direction iteratively +// \ru (вспомогательная функция StraightIntersection у конуса и сферы) \en (an auxiliary function StraightIntersection of cone and sphere) +// --- +bool AddStraightIntersect( const MbCartPoint3D & pnt, // \ru Точка проекции, полученная решением квадратного уравнения \en Point of projection obtained by solving square equation + bool specifySolution, // \ru Необходимость уточнения решения \en Necessity of solution refinement + const MbSurface & surf, bool surfExt, + const MbCurve3D & curv, bool curvExt, + double mEps, + SArray & uvArr, + SArray & ttArr ); + + +#endif // __SURF_ELEMENTARY_SURFACE_H diff --git a/C3d/Include/surf_elevation_surface.h b/C3d/Include/surf_elevation_surface.h new file mode 100644 index 0000000..0f40d94 --- /dev/null +++ b/C3d/Include/surf_elevation_surface.h @@ -0,0 +1,355 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность, проходящая через заданное семейство кривых, с направляющей. + \en Lofted surface with guide curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_ELEVATION_SURFACE_H +#define __SURF_ELEVATION_SURFACE_H + +#include +#include + + +class MATH_CLASS MbContourOnPlane; + +const VERSION ELEVATION_SURFACE_VERSION = 0x0B000000L; ///< \ru Версия активации поверхности по сечениям с направляющей. \en Start using version. +const VERSION ELEVATION_SURFACE_VERSION1 = 0x0F001003L; ///< \ru Расчёт точки на поверхности аналогично Lofted-поверхности. \en Calculation of points on the surface is similar to Lofted surface. + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность, проходящая через заданное семейство кривых, с направляющей. + \en Lofted surface with guide curve. \~ + \details \ru Поверхность, построенная на совокупности сечений и направляющей кривой. + Поверхность является аналогом поверхности MbLoftedSurface, построенной по набору сечений, + но отличающаяся от нее наличием направляющей кривой, задающей форму перехода от одного сечения к другому. + Первый параметр поверхности изменяется вдоль сечений. + Второй параметр поверхности изменяется вдоль направляющей кривой. + \en Surface constructed by set of sections and guide curve. + The surface is analog of MbLoftedSurface surface constructed on a set of sections, + but differs from it by existence of the guide curve which is determining a form of transition from one section to another. + The first parameter of the surface is changed along sections. + The second parameter of the surface is changed along guide curve. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbElevationSurface : public MbLoftedSurface { +private: + MbCurve3D * spine; ///< \ru Направляющая кривая (не NULL). \en Guide curve (not NULL). + RPArray mSpines; ///< \ru Множество указателей на направляющие кривые (на основе spine). \en Set of pointers to guide curves (based on 'spine'). + bool isSimToEvol; ///< \ru Способ расчёта точек на поверхности. \en Way of calculating of points on the surface. + +public: + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по набору задающих кривых и направляющей кривой. + \en Constructor of lofted with guide curve surface by the set of driving curves and guide curve. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] sameCurves - \ru Определяет, надо ли копировать задающие кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy driving curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] initSpine - \ru Направляющая кривая. + \en The spine (guide) curve. \~ + \param[in] sameSpine - \ru Определяет, надо ли копировать направляющую кривую: true - использовать полученную кривую без копирования, false - использовать копию. + \en Determines whether to copy guide curve: true - use obtained curve without copying, false - use copy. \~ + \param[in] simToEvol - \ru Определяет способ расчёта точек на поверхности: true - аналогично кинематической поверхности, false - поверхности по сечениям. + \en Determines how to calculate points on the surface: true - similarly to evolution surface, false - lofted surface. \~ + \param[in] version - \ru Версия модели. По умолчанию текущая версия математики. + \en Version of model. Current version of mathematics by default. \~ + */ + MbElevationSurface( const RPArray & initCurves, bool sameCurves, + const MbCurve3D & initSpine, bool sameSpine, + bool simToEvol = true, + VERSION version = Math::DefaultMathVersion() ); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по набору задающих кривых, массиву параметров для них и направляющей кривой. + \en Constructor of lofted with guide curve surface by the set of driving curves, array of parameters for driving curves and guide curve. \~ + \param[in] initVParams - \ru Множество параметров для задающих кривых. + \en Set of parameters for driving curves. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] sameCurves - \ru Определяет, надо ли копировать задающие кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy driving curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] initSpine - \ru Направляющая кривая. + \en The spine (guide) curve. \~ + \param[in] sameSpine - \ru Определяет, надо ли копировать направляющую кривую: true - использовать полученную кривую без копирования, false - использовать копию. + \en Determines whether to copy guide curve: true - use obtained curve without copying, false - use copy. \~ + \param[in] simToEvol - \ru Определяет способ расчёта точек на поверхности: true - аналогично кинематической поверхности, false - поверхности по сечениям. + \en Determines how to calculate points on the surface: true - similarly to evolution surface, false - lofted surface. \~ + \param[in] version - \ru Версия модели. По умолчанию текущая версия математики. + \en Version of model. Current version of mathematics by default. \~ + */ + MbElevationSurface( const SArray & initVParams, + const RPArray & initCurves, bool sameCurves, + const MbCurve3D & initSpine, bool sameSpine, + bool simToEvol = true, + VERSION version = Math::DefaultMathVersion() ); // \ru Конструктор с заданными параметрами для сечений \en Constructor with specified parameters for sections +protected: + MbElevationSurface( const MbElevationSurface &, MbRegDuplicate * reg ); ///< \ru Конструктор копирования. \en Copy-constructor. +private: + MbElevationSurface( const MbElevationSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbElevationSurface(); + +public: + VISITING_CLASS( MbElevationSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты \en Whether the objects are equal + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void Refresh (); + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & s ); ///< \ru Дать базовые объекты. \en Get the base objects. + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual size_t GetVCount() const; + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по u \en Third derivative with respect to u + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по v \en Third derivative with respect to v + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на поверхности \en Point on the surface + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная по u \en Third derivative with respect to u + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная по v \en Third derivative with respect to v + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double DeviationStepV( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей \en Calculation of step by u while intersecting surfaces + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности \en NURBS copy of a surface + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность \en Create a shifted surface + + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const \en Spatial copy of 'u = const'-line + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей \en Construct tangent and normal placements of constructive planes + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + /// \ru Вернуть направляющую кривую. \en Return spine (guide) curve. + const MbCurve3D & GetSpineCurve() const { C3D_ASSERT( spine != NULL ); return *spine; } + + /// \ru Вернуть направляющую кривую. \en Return spine (guide) curve. + bool IsSimilarToEvolution() const { return isSimToEvol; } + +private: + void Init( VERSION version ); // \ru Инициализация данных \en Data initialization + void SpineInit(); + void ProfilePoint( ptrdiff_t i, double v, bool pole, // \ru Полюс. \en Pole. + const MbCartPoint3D & sPoint, + const MbVector3D & point, + MbVector3D & derives0 ) const; + void ProfileExplore( ptrdiff_t i, double v, bool pole, // \ru Полюс. \en Pole. + const MbCartPoint3D & sPoint, + const MbVector3D & sFirst, + const MbVector3D * sSecond, + const MbVector3D * points, + MbVector3D * derives0, + MbVector3D * derives1, + MbVector3D * derives2 ) const; + void ProfileSurface( ptrdiff_t i, double v, bool pole, // \ru Полюс. \en Pole. + uint uDeg, uint vDeg, + const MbCartPoint3D & spinePoint, + const MbVector3D & spineFirst, + const MbVector3D & spineSecond, + const MbVector3D & spineThird, + const MbVector3D * points, + MbVector3D * derives0, + MbVector3D * derives1, + MbVector3D * derives2, + MbVector3D * derives3 ) const; // \ru Определение массива производных для i-го сечения \en Determination of array of derivatives for i-th section + void CalculatePoint( double & u, double & v, bool ext, MbCartPoint3D & point ) const; + void CalculateExplore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer ) const; + void CalculateSurface( double & u, double & v, bool ext, uint uDeg, uint vDeg, + MbVector3D & der ) const; + void CalculateLikeLofted( double & u, double & v, bool ext, + size_t uDer, size_t vDer, MbCartPoint3D & point ) const; + void ExploreLikeLofted( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer ) const; + inline void CheckParam( double & u, double & v, bool ext ) const; + void CheckParam( double & u, bool ext ) const; + + void operator = ( const MbElevationSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbElevationSurface ) +}; + +IMPL_PERSISTENT_OPS( MbElevationSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры. \en Check parameters. +// --- +inline void MbElevationSurface::CheckParam( double & u, double & v, bool ext ) const +{ + if ( !ext ) { // \ru Внутри параметрического прямоугольника. \en Inside of the region of parameters. + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) { + double uRgn = umax - umin; + u -= ::floor((u - umin) / uRgn) * uRgn; + } + else { + if ( u < umin ) + u = umin; + else + u = umax; + } + } + + if ( (v < vmin) || (v > vmax) ) { + if ( vclosed ) { + double vRgn = vmax - vmin; + v -= ( ::floor((v - vmin) / vRgn) * vRgn ); + } + else { + if ( v < vmin ) + v = vmin; + else + v = vmax; + } + } + } + else { // \ru Вне параметрического прямоугольника. \en Outside of the region of parameters. + if ( u < umin && GetPoleUMin() ) { + u = umin; + } + else if ( u > umax && GetPoleUMax() ) { + u = umax; + } + if ( v < vmin && GetPoleVMin() ) { + v = vmin; + } + else if ( v > vmax && GetPoleVMax() ) { + v = vmax; + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Cоздать параметр для заданной кривой + \en Create parameter for specified curve \~ + \details \ru Кривая-профиль должна быть плоской. Если направляющая пересекается с плоскостью профиля, + в качестве параметра принимается координата вдоль направляющей точки пересечения ее с плоскостью профиля, + ближайшей к центру масс профильной кривой. \n + Если направляющая не пересекается с плоскостью профиля, в качестве параметра используется координата на направляющей + проекции центра масс профильной кривой на направляющую. + \en Profile curve should be planar. If guide curve intersects with plane of profile, + then as parameter is used the coordinate along guide curve of intersection point of it with plane of profile + which is nearest to center of mass of profile curve. \n + If guide curve not intersects with plane of profile, then as parameter is used the coordinate on guide curve + of projection of center of mass of profile curve onto guide curve. \~ + \param[in] crvThis - \ru Профильная кривая. + \en The profile curve. \~ + \param[in] spine - \ru Направляющая. + \en The spine (guide) curve. \~ + \param[in,out] wcThis - \ru Центр масс профильной кривой. + \en Center of mass of profile curve. \~ + \param[in,out] ct - \ru Искомый параметр. + \en Required parameter. \~ + \param[in,out] tau - \ru Производная направляющей в точке с координатой ct. Если в функцию передать NULL, производная не вычисляется. + \en Derivative of guide curve at point with 'ct' coordinate. If giving NULL to function, then derivative isn't calculated. \~ + \return \ru true - если направляющая пересекается с плоскостью профиля, false - если не пересекается. + \en True - if guide curve intersects with plane of profile, false - if not intersects. \~ + \ingroup Algorithms_3D +*/ +// --- +bool CreateElevationParam( const MbCurve3D & crvThis, const MbCurve3D & spine, + MbCartPoint3D & wcThis, double & ct, MbVector3D * tau ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Наполнить массив v-параметров и весовых центров заданных кривых. + \en Fill array of v-parameters and weight centers of given curves. \~ + \details \ru Если все профильные кривые плоские, параметры вычисляются функцией CreateElevationParam. + Иначе параметр для каждой кривой вычисляется как координата вдоль направляющей проекции центра масс кривой на направляющую. + \en If all the profile curves are planar, then parameters are calculated by CreateElevationParam function. + Otherwise parameter for each curve is calculated as coordinate along guide projection of center of mass of curve to guide. \~ + \param[in] uCurves - \ru Множество профильных кривых. + \en Set of profile curves. \~ + \param[in] vcls - \ru Замкнута ли поверхность по параметру v. + \en Whether the surface is closed by parameter v. \~ + \param[in] spine - \ru Направляющая. + \en The spine (guide) curve. \~ + \param[in,out] vParams - \ru Множество параметров. + \en Set of parameters. \~ + \param[in,out] tiePnts - \ru Множество центров масс профильных кривых. Не заполняется, если в функцию передать NULL. + \en Set of centers of mass of profile curves. If giving NULL to function, then it isn't filled. \~ + \return \ru true - если массив параметров успешно создан. + \en True - if the array of parameters successfully created. \~ + \ingroup Algorithms_3D +*/ +// --- +bool CreateElevationParams( RPArray & uCurves, bool vcls, const MbCurve3D & spine, + SArray & vParams, SArray * tiePnts ); + + +#endif // __SURF_ELEVATION_SURFACE_H diff --git a/C3d/Include/surf_evolution_surface.h b/C3d/Include/surf_evolution_surface.h new file mode 100644 index 0000000..fdf1022 --- /dev/null +++ b/C3d/Include/surf_evolution_surface.h @@ -0,0 +1,364 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность заметания. + \en The swept surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_EVOLUTION_SURFACE_H +#define __SURF_EVOLUTION_SURFACE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceWorkingData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность заметания. + \en The swept surface. \~ + \details \ru Кинематическая поверхность образуется путем движения образующей кривой curve по направляющей кривой spine->curve. + В процессе движения вдоль направляющей кривой образующая кривая сохраняет своё положение в движущейся локальной системе координат, + начало которой совпадает с текущей точкой базовой кривой. + Одна из осей движущейся локальной системы координат всегда совпадает с касательной направляющей кривой, + а две другие оси ортогональны ей. + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с параметром направляющей кривой. + \en Sweep with guide curve surface is formed by moving the 'curve' generating curve along spine->curve guide curve. + While moving along a guide curve the generating curve keeps its position in the moving local coordinate system, + which origin coincides with the current point of the base curve. + One of the axes of the moving local coordinate system is always coincident to the tangent of the guide curve, + and the other two axes are orthogonal to it. + First parameter of surface coincides with parameter of generating curve. + Second parameter of surface coincides with parameter of guide curve. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbEvolutionSurface : public MbSweptSurface { +protected: + MbSpine * spine; ///< \ru Направляющая кривая. \en Spine (guide) curve. + MbCartPoint3D origin; ///< \ru Начало направляющей кривой. \en Beginning of generating curve. + + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbEvolutionSurfaceAuxiliaryData : public AuxiliaryData { + public: + DPtr wData; ///< \ru Рабочие данные для расчета поверхности. \en Working data for the calculation of a surface. + MbCartPoint3D wPnt; ///< \ru Рабочая точка. \en Working point. + MbVector3D wVect; ///< \ru Рабочий вектор. \en Working vector. + MbMatrix3D wMatr; ///< \ru Рабочая матрица. \en Working matrix. + + MbEvolutionSurfaceAuxiliaryData(); + MbEvolutionSurfaceAuxiliaryData( const MbEvolutionSurfaceAuxiliaryData & ); + virtual ~MbEvolutionSurfaceAuxiliaryData(); + + void Init(); + void Init( const MbEvolutionSurfaceAuxiliaryData & ); + void Move( const MbVector3D & ); + }; + + mutable CacheManager cache; + +public: + + /** \brief \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \details \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \param[in] c - \ru Образующая + \en Generating curve \~ + \param[in] s - \ru Направляющая + \en Guide curve \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sameSpine - \ru Признак использования оригинала направляющей, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + */ + MbEvolutionSurface( const MbCurve3D & c, const MbSpine & s, bool sameCurve, bool sameSpine = false ); + + /** \brief \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \details \ru Конструктор по образующей, направляющей и её кривой векторa ориентации матрицы преобразования. + \en Constructor by generating curve, guide curve and its curve of transformation matrix orientation vector. \~ + \param[in] c - \ru Образующая + \en Generating curve \~ + \param[in] s - \ru Направляющая + \en Guide curve \~ + \param[in] d - \ru Кривая векторa ориентации матрицы преобразования направляющей + \en Curve of orientation vector of transformation matrix of guide curve \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sameSpine - \ru Признак использования оригинала направляющей, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + \param[in] sameD - \ru Признак использования оригинала кривой d, а не копии + \en Attribute of usage of original of 'd' curve, not a copy \~ + */ + MbEvolutionSurface( const MbCurve3D & c, const MbCurve3D & s, const MbCurve3D & d, + bool sameCurve, bool sameSpine, bool sameD ); + + /** \brief \ru Конструктор по радиусу, направляющей и её кривой векторa ориентации матрицы преобразования. + \en Constructor by radius, guide curve and its curve of transformation matrix orientation vector. \~ + \details \ru Конструктор кинематической поверхности с образующей кривой - дугой окружности. + Используется только в конвертерах. + \en Constructor of evolution surface with circular arc as generating curve. + Used only in converters. \~ + \param[in] r - \ru Радиус образующей + \en Radius of generating curve \~ + \param[in] s - \ru Направляющая + \en Guide curve \~ + \param[in] d - \ru Кривая векторa ориентации матрицы преобразования направляющей + \en Curve of orientation vector of transformation matrix of guide curve \~ + \param[in] pURgn - \ru Область параметра U + \en Region of U parameter \~ + \param[in] pVRgn - \ru Область параметра V + \en Region of V parameter \~ + */ + MbEvolutionSurface( double r, const MbCurve3D & s, const MbCurve3D & d, MbRect1D * pURgn, MbRect1D * pVRgn, VERSION version = Math::DefaultMathVersion() ); + +protected: + MbEvolutionSurface( const MbEvolutionSurface &, MbRegDuplicate * ); +private: + MbEvolutionSurface( const MbEvolutionSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbEvolutionSurface(); + +public: + VISITING_CLASS( MbEvolutionSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar ( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии по u. \en Curvature of line by u. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + + virtual void CalculateGabarit( MbCube & ) const; // \ru Выдать габарит. \en Get the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + virtual MbCurve3D * CurveU( double v, MbRect1D *pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D *pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + virtual bool IsSpinePeriodic() const; // \ru Периодичность направляющей. \en Periodicity of a guide curve. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + // \ru Включить точку в область определения. \en Include a point into domain. + virtual void IncludePoint( double u, double v ); + /** \} */ + /** \ru \name Функции кинематической поверхности + \en \name Functions of the evolution surface + \{ */ + + /** \brief \ru Определение матрицы переноса для образующей. + \en Determination of translation matrix for generating curve. \~ + \details \ru Определение матрицы переноса для образующей по параметру направляющей. + \en Determination of translation matrix for generating curve by parameter of guide curve. \~ + \param[in] v - \ru Параметр на направляющей + \en Parameter on the guide curve \~ + \param[in] matr - \ru Матрица-результат + \en Matrix-result \~ + */ + void TransformMatrix( double v, MbMatrix3D & matr ) const; + + /// \ru Направляющая. \en Guide curve. + const MbSpine & GetSpine() const { return *spine; } + + /// \ru Направляющая кривая. \en The spine (guide) curve. + const MbCurve3D & GetSpineCurve() const { return spine->GetCurve(); } + /// \ru Центр тяжести образующей. \en Center of gravity of generating curve. + const MbCartPoint3D & GetOrigin() const { return origin; } + + /// \ru Дать направляющую кривую для изменения. \en Get guide curve for editing. + MbCurve3D & SetSpineCurve() { return spine->SetCurve(); } + /// \ru Задать центр тяжести образующей. \en Set center of gravity of generating curve. + void SetOrigin( const MbCartPoint3D & p ) { origin = p; SetDirtyGabarit(); } + /** \} */ + +protected : + void Init(); +private: + void operator = ( const MbEvolutionSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbEvolutionSurface ) +}; + +IMPL_PERSISTENT_OPS( MbEvolutionSurface ) + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \details \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \param[in] curve - \ru Образующая кривая + \en Generating curve \~ + \param[in] spine - \ru Направляющая кривая + \en Guide curve \~ + \param[in] samec - \ru Признак использования оригинала образующей кривой, а не копии. + \en Attribute of usage of original of generating curve, not a copy. \~ + \param[in] sames - \ru Признак использования оригинала направляющей кривой spine, а не копии. + \en Attribute of usage of original of guide curve (spine), not a copy. \~ + \return \ru Возвращает созданную поверхность. + \en Return the created surface. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbSurface &) CreateEvolutionSurface( const MbCurve3D & curve, const MbSpine & spine, bool samec, bool sames = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \details \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \param[in] curve - \ru Образующая кривая + \en Generating curve \~ + \param[in] spine - \ru Направляющая кривая + \en Guide curve \~ + \param[in] samec - \ru Признак использования оригинала образующей кривой, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sames - \ru Признак использования оригинала направляющей кривой, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + \return \ru Возвращает созданную поверхность. + \en Return the created surface. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbSurface &) CreateEvolutionSurface( const MbCurve3D & curve, const MbCurve3D & spine, + bool samec, bool sames ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \details \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \param[in] curve - \ru Образующая кривая + \en Generating curve \~ + \param[in] spine - \ru Направляющая кривая + \en Guide curve \~ + \param[in] spineDirection - \ru Направляющая кривая для направляющей кривой + \en Guide curve for guide curve \~ + \param[in] samec - \ru Признак использования оригинала образующей кривой, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sames - \ru Признак использования оригинала направляющей кривой, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + \param[in] samed - \ru Признак использования оригинала кривой spineDirection, а не копии + \en Attribute of usage of original of spineDirection curve, not a copy \~ + \return \ru Возвращает созданную поверхность. + \en Return the created surface. \~ + \ingroup Surface_Modeling +*/ +// --- +MATH_FUNC (MbSurface &) CreatePipeSurface( const MbCurve3D & curve, const MbCurve3D & spine, + const MbCurve3D & spineDirection, + bool samec, bool sames, bool samed ); + + +#endif // __SURF_EVOLUTION_SURFACE_H diff --git a/C3d/Include/surf_exaction_surface.h b/C3d/Include/surf_exaction_surface.h new file mode 100644 index 0000000..484349c --- /dev/null +++ b/C3d/Include/surf_exaction_surface.h @@ -0,0 +1,231 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Кинематическая поверхность с адаптацией. + \en Sweep with guide curve surface with rotating ends. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_EXACTION_SURFACE_H +#define __SURF_EXACTION_SURFACE_H + + +#include +#include + + +class MATH_CLASS MbContourOnPlane; +class MATH_CLASS MbContourOnSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Кинематическая поверхность с адаптацией. + \en Sweep with guide curve surface with rotating ends. \~ + \details \ru Кинематическая поверхность образуется путем движения образующей кривой curve по направляющей кривой spine->curve. + Поверхность является аналогом поверхности MbEvolutionSurface, но отличающаяся от нее плоскопараллельным доворотом точек поверхности. + В каждом сечении поверхности v=const точки сдвигаются по линейному закону вдоль образующей так, + чтобы на концах направляющей v=vmin и v=vmax края поверхности повернулись бы за заданные углы angle0 и angle1. + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с параметром направляющей кривой. + Поверхность используется при построении кинематической оболочки с направляющей кривой в виде контура, имеющего негладкую стыковку сегментов. + \en Sweep with guide curve surface is formed by moving the 'curve' generating curve along spine->curve guide curve. + Surface is analog of MbEvolutionSurface, but differs from it by plane-parallel additional turn of surface points. + Points of each 'v=const' surface section are moved by linear law along generating curve so + that on v=vmin and v=vmax ends of guide curve the surface boundaries would rotate by specified angle0 and angle1 angles. + First parameter of surface coincides with parameter of generating curve. + Second parameter of surface coincides with parameter of guide curve. + Surface is used in construction of sweep with guide curve shell as contour with non-smooth connection of segments. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbExactionSurface : public MbEvolutionSurface { +private: + MbVector3D normal0; ///< \ru Вектор нормали к плоскости стыковки в начальной точке. \en A vector of normal to the plane of connection at the start point. + MbVector3D normal1; ///< \ru Вектор нормали к плоскости стыковки в конечной точке. \en A vector of normal to the plane of connection at the end point. + double angle0; ///< \ru Угол излома в начальной точке направляющей. \en Angle of break at start point of guide curve. + double angle1; ///< \ru Угол излома в конечной точке направляющей. \en Angle of break at end point of guide curve. + MbVector3D move0; ///< \ru Касательный вектор сдвига начальных точек. \en Tangent vector of translation of start points. + MbVector3D move1; ///< \ru Касательный вектор сдвига конечных точек. \en Tangent vector of translation of end points. + bool mode0; ///< \ru true, если вектор move0 не равен нулю. \en True if 'move0' vector isn't equal to zero. + bool mode1; ///< \ru true, если вектор move1 не равен нулю. \en True if 'move1' vector isn't equal to zero. + MbVector3D factorX; ///< \ru Сомножитель векторного произведения для касательной к образующей curve (нормаль плоскости эскиза). \en The multiplier of the vector product for the tangent of the generating 'curve' (the scetch normal). + double rangeX; ///< \ru Эквидистантное смещение точек образующей кривой в конце траектории. \en The offset range of generating curve on the end of spine curve. + bool modeX; ///< \ru true, если вектор 'factorX' не равен нулю. \en True if 'factorX' vector isn't equal to zero. + +public: + + /** \brief \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \details \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \param[in] cr - \ru Образующая. + \en Generating curve. \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии. + \en Attribute of usage of original of generating curve, not a copy. \~ + \param[in] sp - \ru Направляющая. + \en Guide curve. \~ + \param[in] n0 - \ru Вектор нормали к плоскости стыковки в начальной точке. + \en Vector of normal to the plane of connection at the start point. \~ + \param[in] ang0 - \ru Угол излома в начальной точке направляющей. + \en Angle of break at start point of guide curve. \~ + \param[in] n1 - \ru Вектор нормали к плоскости стыковки в конечной точке. + \en Vector of normal to the plane of connection at the end point. \~ + \param[in] ang1 - \ru Угол излома в конечной точке направляющей. + \en Angle of break at end point of guide curve. \~ + \param[in] range - \ru Эквидистантное смещение точек образующей кривой в конце траектории. + \en The offset range of generating curve on the end of spine curve. \~ + */ + MbExactionSurface( const MbCurve3D & cr, bool sameCurve, + const MbSpine & sp, + const MbVector3D & n0, double ang0, + const MbVector3D & n1, double ang1, + double range ); + +protected: + MbExactionSurface( const MbExactionSurface &, MbRegDuplicate * ); +private: + MbExactionSurface( const MbExactionSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbExactionSurface(); + +public: + VISITING_CLASS( MbExactionSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равными. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + /** \} */ + /** \ru \name Функции кинематической поверхности с адаптацией + \en \name Functions of sweep with guide curve surface with rotating ends. + \{ */ + /// \ru Признак наличия ненулевого касательного вектора сдвига начальных точек. \en Attribute of existence of non-zero tangent vector of translation of start points. + bool GetMode0() const { return mode0; } + /// \ru Признак наличия ненулевого касательного вектора сдвига конечных точек. \en Attribute of existence of non-zero tangent vector of translation of end points. + bool GetMode1() const { return mode1; } + /// \ru Угол излома в начальной точке направляющей. \en Angle of break at start point of guide curve. + double GetBegAngle() const { return angle0; } + /// \ru Угол излома в конечной точке направляющей. \en Angle of break at end point of guide curve. + double GetEndAngle() const { return angle1; } + /** \} */ + +private: + void Init(); + void InitEnd(); + void PrepareTangent(); + void AddTangent0( double & v, MbVector3D & ) const; + void AddTangentV( MbVector3D & ) const; + void AddOffsetX0( double & v, const MbVector3D & first, MbVector3D & r ) const; + void AddOffsetXU( double & v, MbVector3D & first, const MbVector3D & second ) const; + void AddOffsetXUU( double & v, const MbVector3D & first, MbVector3D & second, const MbVector3D & third ) const; + void AddOffsetXV( const MbVector3D & derive, MbVector3D & r ) const; + void AddOffsetXUV( const MbVector3D & first, const MbVector3D & second, MbVector3D & r ) const; + + void operator = ( const MbExactionSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbExactionSurface ) +}; + +IMPL_PERSISTENT_OPS( MbExactionSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверка на самопересечение кинематической поверхности \en Check for self-intersection of sweep with guide curve surface +// \ru Если изменится расчет точек кинематической поверхности, то надо переделывать \en If calculation of points of a sweep with guide curve surface changes, then it is necessary to remake +// --- +bool FindSelfIntersections( const MbCurve3D & curve3d, + const MbSpine & baseSpine, + const SArray & childSpines );//, + //bool natur ); + + +//------------------------------------------------------------------------------ +// \ru Проверить корректность кинематики по движении по замкнутому контуру \en Check correctness of kinematics while moving along closed contour +// \ru (путем трансформации копии образующего контура по направляющем сегментам \en (by transformation of copy of generating contour along guide segments +// \ru И сравнения его с исходным образующим контуром) \en And comparing it with source generating contour) +// --- +bool CheckClosingContour( const MbContourOnSurface & contourOnSurface, // \ru Образующий контур \en Generating contour + const MbSpine & baseSpine, // \ru Направляющий контур \en Guide contour + const SArray & childSpines, // \ru Сегменты направляющей \en Segments of guide curve + //bool natur, // \ru Тип привязки тела \en Type of binding of solid + bool closedShell ); // \ru Замкнутость результирующей оболочки \en Closedness of resultant shell + + +//------------------------------------------------------------------------------ +// \ru РЕАЛИЗОВАНА НЕ ПОЛНОСТЬЮ \en NOT FULLY IMPLEMENTED +// \ru Проверка на самопересечение кинематической поверхности \en Check for self-intersection of sweep with guide curve surface. +// --- +bool IsSelfIntersect( const MbEvolutionSurface & ); + + +#endif // __SURF_EXACTION_SURFACE_H diff --git a/C3d/Include/surf_expansion_surface.h b/C3d/Include/surf_expansion_surface.h new file mode 100644 index 0000000..11b8643 --- /dev/null +++ b/C3d/Include/surf_expansion_surface.h @@ -0,0 +1,270 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность плоскопараллельного движения. + \en Motion surface (plane-parallel swept surface). \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_EXPANSION_SURFACE_H +#define __SURF_EXPANSION_SURFACE_H + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность плоскопараллельного движения. + \en Motion surface (plane-parallel swept surface). \~ + \details \ru Поверхность плоскопараллельного движения получается путем движения образующей кривой curve + по направляющей кривой spine->curve параллельно самой себе: + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = curve(u) + spine(v) - origin. \n + Направляющая плоскопараллельной поверхности должна быть незамкнутой монотонной кривой. + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с параметром направляющей кривой. + \en Expansion surface is obtained by moving 'curve' generating curve + along 'spine->curve" guide curve parallel to itself: + Radius-vector of surface is described by the vector function \n + r(u,v) = curve(u) + spine(v) - origin. \n + Guide curve of plane-parallel surface should be open monotonous curve. + First parameter of surface coincides with parameter of generating curve. + Second parameter of surface coincides with parameter of guide curve. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbExpansionSurface : public MbSweptSurface { +private: + MbCurve3D * spine; ///< \ru Направляющая кривая. \en Spine (guide) curve. + MbCurve3D * brink; ///< \ru Вторая образующая кривая (первой является curve, может быть NULL). \en The second generating curve ('curve' is first one, may be NULL). + double tmin; ///< \ru Начальный параметр brink. \en Start parameter of 'brink'. + double dt; ///< \ru Производная параметра кривой brink по параметру u (dt * (u - umin) = t_brink - tmin_brink). \en Derivative of parameter of 'brink' curve by u parameter (dt * (u - umin) = t_brink - tmin_brink). + MbCartPoint3D origin; ///< \ru Начало образующей. \en Begin of gravity of generating curve. + MbCartPoint3D ending; ///< \ru Конец образующей. \en End of gravity of generating curve. + +public: + + /** \brief \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \details \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \param[in] cr - \ru Образующая кривая. + \en Generating curve \~ + \param[in] sp - \ru Направляющая кривая. + \en Guide curve \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии. + \en Attribute of usage of original of generating curve, not a copy. \~ + \param[in] sameSpine - \ru Признак использования оригинала направляющей, а не копии + \en Attribute of usage of original of guide curve, not a copy. \~ + \param[in] sl - \ru Вторая образующая кривая. + \en Second generating curve \~ + */ + MbExpansionSurface( const MbCurve3D & cr, const MbCurve3D & sp, bool sameCurve, bool sameSpine, + MbCurve3D * sl = NULL ); + + /** \brief \ru Конструктор по точке, образующей и направляющей. + \en Constructor by point, generating curve and guide curve. \~ + \details \ru Конструктор по точке, образующей и направляющей.\n + Создается поверхность, привязанная к образующей. + \en Constructor by point, generating curve and guide curve.\n + Created a surface is binded to generating curve. \~ + \param[in] point - \ru Точка, определяющая вектор сдвига центра тяжести образующей от направляющей, + он направлен из точки point в точку origin. + \en Point determining translation vector of center of gravity of generating curve from guide curve + which is directed from 'point' point to 'origin' point. \~ + \param[in] curve - \ru Образующая + \en Generating curve \~ + \param[in] spine - \ru Направляющая + \en Guide curve \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sameSpine - \ru Признак использования оригинала направляющей, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + */ + MbExpansionSurface( const MbCartPoint3D & point, const MbCurve3D & curve, const MbCurve3D & spine, + bool sameCurve, bool sameSpine ); +public: + virtual ~MbExpansionSurface(); + +protected: + MbExpansionSurface( const MbExpansionSurface &, MbRegDuplicate * ); + +private: + MbExpansionSurface( const MbExpansionSurface & ); // \ru Не реализовано. \en Not implemented. + +public: + VISITING_CLASS( MbExpansionSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей. \en Calculation of step by u while intersecting surfaces. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v при пересечении поверхностей. \en Calculation of step by v while intersecting surfaces. + virtual double DeviationStepU( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей. \en Calculation of step by u while intersecting surfaces. + virtual double DeviationStepV( double u, double v, double sag ) const; // \ru Вычисление шага по v при пересечении поверхностей. \en Calculation of step by v while intersecting surfaces. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии по u. \en Curvature of line by u. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии по v. \en Curvature of line by v. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + + // \ru Подобные ли поверхности для объединения (слива) (геометрическое совпадение). \en Whether the surfaces to union (joining) are similar (geometric coincidence). + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + /** \} */ + /** \ru \name Функции плоскопараллельной поверхности + \en \name Functions of plane-parallel surface + \{ */ + + /** \brief \ru Определение вектора переноса образующей. + \en Determination of translation vector for generating curve. \~ + \details \ru Определение вектора переноса образующей по параметру на направляющей. + \en Determination of translation vector for generating curve by parameter of guide curve. \~ + \param[in] v - \ru Параметр на направляющей + \en Parameter on the guide curve \~ + \param[in] vect - \ru Вектор-результат + \en Vector-result \~ + */ + void TransformVector( double & v, MbVector3D & vect ) const; + + /// \ru Направляющая кривая. \en The spine (guide) curve. + const MbCurve3D & GetSpineCurve() const { return *spine; } + /// \ru Центр тяжести образующей. \en Center of gravity of generating curve. + const MbCartPoint3D & GetOrigin() const { return origin; } + /// \ru Вторая образующая кривая. \en The second generating curve. + const MbCurve3D * GetBrink() const { return brink; } + + inline double BrinkParameterFrom( const double & u ) const; + inline double BrinkParameterInto( const double & t ) const; + + /// \ru Дать направляющую кривую для изменения. \en Get guide curve for editing. + MbCurve3D & SetSpineCurve() { return *spine; } + /// \ru Изменение центра тяжести образующей. \en Change center of gravity of generating curve. + void SetOrigin( const MbCartPoint3D & p ) { origin = p; SetDirtyGabarit(); } + /** \} */ +private: + void Init(); + void operator = ( const MbExpansionSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbExpansionSurface ) +}; + +IMPL_PERSISTENT_OPS( MbExpansionSurface ) + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра curve в параметр brink \en Convert 'curve' parameter to 'brink' parameter +// --- +inline double MbExpansionSurface::BrinkParameterFrom( const double & u ) const { + double t = u; + if ( brink != NULL ) + t = tmin + (u - umin) * dt; + return t; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра brink в параметр curve \en Convert 'brink' parameter to 'curve' parameter +// --- +inline double MbExpansionSurface::BrinkParameterInto( const double & t ) const { + double u = t; + if ( brink != NULL ) { + double du = (::fabs(dt) > EXTENT_EQUAL) ? 1.0 / dt : 1.0; + u = umin + (t - tmin) * du; + } + return u; +} + + +#endif // __SURF_EXPANSION_SURFACE_H diff --git a/C3d/Include/surf_exploration_surface.h b/C3d/Include/surf_exploration_surface.h new file mode 100644 index 0000000..07f018d --- /dev/null +++ b/C3d/Include/surf_exploration_surface.h @@ -0,0 +1,194 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность заметания с масштабированием и поворотом образующей кривой. + \en The swept surface with scaling and winding of generation curve. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_EXTENSION_SURFACE_H +#define __SURF_EXTENSION_SURFACE_H + + +#include +#include + + +class MATH_CLASS MbFunction; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность заметания с масштабированием и поворотом образующей кривой. + \en The swept surface with scaling and winding of generation curve. \~ + \details \ru Кинематическая поверхность образуется путем движения образующей кривой curve по направляющей кривой spine->curve. + В процессе движения вдоль направляющей кривой образующая кривая сохраняет своё положение в движущейся локальной системе координат, + начало которой совпадает с текущей точкой базовой кривой. + Одна из осей движущейся локальной системы координат всегда совпадает с касательной направляющей кривой, + а две другие оси ортогональны ей. + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с параметром направляющей кривой. + \en Sweep with guide curve surface is formed by moving the 'curve' generating curve along spine->curve guide curve. + While moving along a guide curve the generating curve keeps its position in the moving local coordinate system, + which origin coincides with the current point of the base curve. + One of the axes of the moving local coordinate system is always coincident to the tangent of the guide curve, + and the other two axes are orthogonal to it. + First parameter of surface coincides with parameter of generating curve. + Second parameter of surface coincides with parameter of guide curve. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbExplorationSurface : public MbEvolutionSurface { +protected: + MbFunction * scaling; ///< \ru Функция второго параметра (v) масштабирования образующей кривой. \en The function of curve scale by second parameter (v). + MbFunction * winding; ///< \ru Функция второго параметра (v) вращения образующей кривой. \en The function of curve rotation by second parameter (v). + MbAxis3D axis; ///< \ru Не пишется. \en The axis are not writing. + +protected: + /** \brief \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \details \ru Конструктор по образующей и направляющей. + \en Constructor by generating curve and guide curve. \~ + \param[in] c - \ru Образующая + \en Generating curve \~ + \param[in] s - \ru Направляющая + \en Guide curve \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sameSpine - \ru Признак использования оригинала направляющей, а не копии + \en Attribute of usage of original of guide curve, not a copy \~ + */ + MbExplorationSurface( const MbCurve3D & c, const MbSpine & s, bool sameCurve, bool sameSpine, + MbFunction & _scaling, MbFunction & _winding ); + +protected: + MbExplorationSurface( const MbExplorationSurface &, MbRegDuplicate * ); +private: + MbExplorationSurface( const MbExplorationSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbExplorationSurface(); + +public: + VISITING_CLASS( MbExplorationSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar ( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D *pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D *pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual size_t GetUCount() const; // \ru Количество разбиений по параметру u для проверки событий. \en The number of splittings by u-parameter for a check of events. + virtual size_t GetVCount() const; // \ru Количество разбиений по параметру v для проверки событий. \en The number of splittings by v-parameter for a check of events. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + //------------------------------------------------------------------------------ + /** \brief \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \details \ru Создать кинематическую поверхность. + \en Create an evolution surface. \~ + \param[in] curve - \ru Образующая кривая + \en Generating curve \~ + \param[in] spine - \ru Направляющая кривая + \en Guide curve \~ + \param[in] samec - \ru Признак использования оригинала образующей кривой, а не копии + \en Attribute of usage of original of generating curve, not a copy \~ + \param[in] sFunc - \ru Функция масштабирования образующей кривой. + \en The function of curve scaling. \~ + \param[in] rFunc - \ru Функция вращения образующей кривой. + \en The function of curve rotation. \~ + \return \ru Возвращает созданную поверхность. + \en Return the created surface. \~ + \ingroup Surface_Modeling + */ + // --- + static MbSurface * Create( const MbCurve3D & curve, const MbSpine & spine, bool samec, bool sames, + MbFunction & _scaling, MbFunction & _winding ); + +protected : + void Init(); + +private: + void operator = ( const MbExplorationSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbExplorationSurface ) +}; + + +#endif // __SURF_EXTENSION_SURFACE_H diff --git a/C3d/Include/surf_extrusion_surface.h b/C3d/Include/surf_extrusion_surface.h new file mode 100644 index 0000000..2cc76c0 --- /dev/null +++ b/C3d/Include/surf_extrusion_surface.h @@ -0,0 +1,274 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность выдавливания. + \en Extrusion surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_EXTRUSION_SURFACE_H +#define __SURF_EXTRUSION_SURFACE_H + + +#include + + +class MATH_CLASS MbLine3D; +class MATH_CLASS MbOffsetSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность выдавливания. + \en Extrusion surface. \~ + \details \ru Поверхность выдавливания является кинематической поверхностью с прямолинейной образующей. + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = curve(u) + (direction distance v). \n + Первый параметр поверхности совпадает с параметром образующей кривой. + \en Extrusion surface is swept surface with rectilinear generating curve. + Radius-vector of surface is described by the vector function \n + r(u,v) = curve(u) + (direction distance v). \n + First parameter of surface coincides with parameter of generating curve. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbExtrusionSurface : public MbSweptSurface { +protected: + MbVector3D direction; ///< \ru Направление выдавливания, единичный вектор. \en Direction of extrusion, vector of unit length. + double distance; ///< \ru Длина выдавливания. \en Length of extrusion. + +public: + /** \brief \ru Конструктор по образующей и направлению выдавливания. + \en Constructor by generating curve and direction of extrusion. \~ + \details \ru Конструктор по образующей и направлению выдавливания. + \en Constructor by generating curve and direction of extrusion. \~ + \param[in] curve - \ru Образующая поверхности выдавливания + \en Generating curve of extrusion surface \~ + \param[in] vector - \ru Направление выдавливания + \en Direction of extrusion \~ + \param[in] same - \ru Использование оригинала кривой, а не ее копии + \en Usage of original of curve, not a copy \~ + */ + MbExtrusionSurface ( const MbCurve3D & curve, const MbVector3D & vector, bool same ); + + /** \brief \ru Конструктор по прямой, точке и образующей. + \en Constructor by line, point and generating curve. \~ + \details \ru Конструктор по прямой, точке и образующей.\n + Используется только в конвертерах. + \en Constructor by line, point and generating curve.\n + Used only in converters. \~ + */ + MbExtrusionSurface( const MbLine3D &, const MbCartPoint3D &, MbCurve3D &, bool same ); + +public: + virtual ~MbExtrusionSurface(); + +protected: + MbExtrusionSurface( const MbExtrusionSurface &, MbRegDuplicate * ); + +private: + MbExtrusionSurface( const MbExtrusionSurface & ); // \ru Не реализовано. \en Not implemented. + +public: + VISITING_CLASS( MbExtrusionSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии по u. \en Curvature of line by u. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v-line. + + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether a surface is convex. + + // \ru Проекция точки на поверхность. \en The point projection onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + // \ru Пересечение с кривой. \en Intersection with curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + virtual void CalculateGabarit( MbCube & ) const; // \ru Выдать габарит. \en Get the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D & axis ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If true, then all the derivatives by U higher the first one are equal to zero. + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives by V higher the first one are equal to zero. + /** \} */ + /** \ru \name Функции поверхности выдавливания. + \en \name Functions of extrusion surface. + \{ */ + /// \ru Направление выдавливания. \en A direction of extrusion. + const MbVector3D & GetDirection() const { return direction; } + /// \ru Длина выдаливания. \en A length of extrusion. + double GetDistance () const { return distance; } + /// \ru Изменить направление выдавливания на противоположное. \en Change direction of extrusion to opposite. + void InvertDirection() { direction.Invert(); SetDirtyGabarit(); } + + /** \brief \ru Создание эквидистантной поверхности. + \en Create an offset surface. \~ + \details \ru Создание поверхности типа st_OffsetSurface, совпадающей с данной поверхностью.\n + Если образующая кривая является эквидистантной кривой на плоскости, + то, используя ее базовую кривую в качестве образующей, создается поверхность + выдавливания и по ней эквидистантная поверхность.\n + Поверхность строится в случае, если направление выдавливания + перпендикулярно плоскости образующей кривой.\n + Используется только в конвертерах. + \en Create surface of st_OffsetSurface type coinciding with current surface.\n + If generating curve is offset curve on plane, + then using its base curve as generating curve the extrusion surface + and offset surface by it are created.\n + Surface is created if direction of extrusion + is perpendicular to plane of generating curve.\n + Used only in converters. \~ + */ + MbOffsetSurface * GetSurfaceFromPlaneCurveOffset() const; + /** \} */ + +private: + // \ru Пересечение с прямолинейной кривой. \en Intersection with rectilinear curve. + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, bool ext0, bool ext ) const; + void operator = ( const MbExtrusionSurface & ); // \ru Не реализовано. \en Not implemented. +protected: + inline void CheckParam( double &u, double &v ) const; // \ru Проверить параметры. \en Check parameters. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbExtrusionSurface ) +}; + +IMPL_PERSISTENT_OPS( MbExtrusionSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры. \en Check parameters. +// --- +inline void MbExtrusionSurface::CheckParam( double & u, double & v ) const +{ + if ( u < umin ) { + if ( uclosed ) { + double uRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / uRgn) * uRgn ); + } + else + u = umin; + } + + if ( u > umax ) { + if ( uclosed ) { + double uRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / uRgn) * uRgn ); + } + else + u = umax; + } + + if ( v < vmin ) + v = vmin; + if ( v > vmax ) + v = vmax; +} + + +#endif // __SURF_EXTRUSION_SURFACE_H diff --git a/C3d/Include/surf_fillet_surface.h b/C3d/Include/surf_fillet_surface.h new file mode 100644 index 0000000..3faa846 --- /dev/null +++ b/C3d/Include/surf_fillet_surface.h @@ -0,0 +1,712 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность скругления с постоянными радиусами обычная или с сохранением кромки. + \en Fillet surface of constant radii, ordinary or with preservation of fillet. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_FILLET_SURFACE_H +#define __SURF_FILLET_SURFACE_H + + +#include + + +class MATH_CLASS MbFunction; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность скругления с постоянными радиусами обычная или с сохранением кромки. + \en Fillet surface of constant radii, ordinary or with preservation of fillet. \~ + \details \ru Поверхность скругления является NURBS-поверхностью, + построенной по трём кривым: curve1, curve0, curve2. + Первый параметр поверхности совпадает с параметром кривых curve1, curve0, curve2. + Второй параметр изменяется от нуля (точки совпадают с curve1) до единицы (точки совпадают с curve2). + В отличие от других поверхностей Функции PointOn и Derive... поверхность скругления не корректирует + первый параметр при выходе его за пределы области определения. + Если коэффициент формы conic = _ARC_ ( 0 ), то вес каждой точки кривой curve0 задаётся функцией weights0 и + вычислен так, что сечение поверхности вдоль её второго параметра будет дугой окружности, + то есть при любом параметре u три точки curve1(u), curve0(u), curve2(u) определяют NURBS-кривую в форме дуги окружности. + Если коэффициент формы conic != _ARC_, то вес каждой точки кривой curve0 равен conic / ( 1.0 - conic ). + При conic = 0.5 сечение поверхности вдоль её второго параметра будет параболой. \n + \en Fillet surface is NURBS-surface + constructed by three curves: curve1, curve0, curve2. + First parameter of surface coincides with parameter of curve1, curve0, curve2 curves. + Second parameter is changed between 0 (points are coincident to curve1) and 1 (points are coincident to curve2). + For fillet surface in contrast to other surfaces PointOn and Derive... functions don't correct + first parameter when it is out of domain bounds. + If coefficient of shape conic = _ARC_ ( 0 ), then weight of each point of curve0 curve is given by weights0 function and + is calculated as that the section of surface along its second parameter will be a circular arc, + that is three points curve1(u), curve0(u), curve2(u) determine NURBS-curve with shape of circular arc at any u parameter. + If coefficient of shape conic != _ARC_, then weight of each point of curve0 curve is equal to conic / ( 1.0 - conic ). + If conic = 0.5, then section of surface along its second parameter will be a parabola. \n \~ + \ingroup Surfaces +*/// --- +class MATH_CLASS MbFilletSurface : public MbSmoothSurface { +protected: + MbCurve3D * curve0; ///< \ru Кривая пересечения касательных к поверхностям - всегда не NULL. \en Intersection curve of tangents to surfaces - always not NULL. + MbFunction * weights0; ///< \ru Функция веса точек средней кривой curve0. \en Function of weight of points of curve0 mid-curve. + double conic; ///< \ru Коэффициент формы, изменяется от 0.05 до 0.95, определяет вес точек кривой curve0. \en Coefficient of shape is changed between 0.05 and 0.95 and determines weight of points of curve0 curve. + bool even; ///< \ru Равномерная параметризация по дуге или нет. \en Whether arc length parameterization is uniform or not. + bool equable; ///< \ru true - обычная поверхность, false - curve1 или curve2 является кромкой. \en True - ordinary surface, false - curve1 or curve2 is fillet. + bool byCurve1; ///< \ru true - curve2 является кромкой, false - curve1 является кромкой. \en True - curve2 is fillet, false - curve1 is fillet. + MbCurve3D * spine; ///< \ru Кривая центров дуг окружности для случая равномерной параметризации. \en Curve of centers of circular arcs in case of uniform parameterization. + MbVector3D * spineDerUMin; // \ru Производные spine в точках uMin и uMax ( для случая равномерной параметризации ). \en Derivatives of spine at uMin and uMax points (in case of uniform parameterization). + MbVector3D * spineDerUMax; // \ru Производные spine в точках uMin и uMax ( для случая равномерной параметризации ). \en Derivatives of spine at uMin and uMax points (in case of uniform parameterization). + +public: + + /** \brief \ru Конструктор поверхности скругления. + \en Constructor of fillet surface. \~ + \details \ru Конструктор поверхности скругления. + \en Constructor of fillet surface. \~ + \param[in] curv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface \~ + \param[in] curv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой curve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой curve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой + st_Fillet - скругление с заданными радиусами + \en Conjugation type: \n + st_Span - fillet with a given chord + st_Fillet - fillet with given radii \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0 - дуга окружности) + \en Coefficient of shape is changed between 0.05 and 0.95 (if 0 - circular arc) \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Whether arc length parameterization is uniform or not \~ + */ + MbFilletSurface( MbSurfaceCurve & curv1, MbSurfaceCurve & curv2, + double d1, double d2, MbeSmoothForm fm, double cn, bool ev ); + + /** \brief \ru Конструктор поверхности с сохранением кромки. + \en Constructor of surface with preservation of fillet. \~ + \details \ru Конструктор поверхности с сохранением кромки. + \en Constructor of surface with preservation of fillet. \~ + \param[in] curv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface \~ + \param[in] curv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой crve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой crve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой \n + st_Fillet - скругление с заданными радиусами + \en Conjugation type: \n + st_Span - fillet with a given chord\n + st_Fillet - fillet with given radii \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0 - дуга окружности) + \en Coefficient of shape is changed between 0.05 and 0.95 (if 0 - circular arc) \~ + \param[in] byFirst - \ru true - кривая curve2 является кромкой, false - кривая curve1 является кромкой + \en True - curve2 curve is fillet, false - curve1 curve is fillet. \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Whether arc length parameterization is uniform or not \~ + */ + MbFilletSurface( MbSurfaceCurve & curv1, MbSurfaceCurve & curv2, + double d1, double d2, MbeSmoothForm fm, double cn, bool byFirst, bool ev ); + + /** \brief \ru Конструктор поверхности скругления. + \en Constructor of fillet surface. \~ + \details \ru Конструктор поверхности скругления c кривой пересечения касательных к поверхностям. + \en Constructor of fillet surface with intersection curve of tangents to surfaces. \~ + \param[in] surf1 - \ru Первая поверхность + \en First surface \~ + \param[in] curv1 - \ru Опорная кривая в параметрах первой поверхности + \en Support curve at parameters of the first surface \~ + \param[in] surf2 - \ru Вторая поверхность + \en Second surface \~ + \param[in] curv2 - \ru Опорная кривая в параметрах второй поверхности + \en Support curve at parameters of the second surface \~ + \param[in] curv0 - \ru Кривая пересечения касательных к поверхностям + \en Intersection curve of tangents to surfaces \~ + \param[in] d1 - \ru Радиус скругления со знаком для поверхности кривой curv1 + \en Fillet radius with sign for surface of curv1 curve \~ + \param[in] d2 - \ru Радиус скругления со знаком для поверхности кривой curv2 + \en Fillet radius with sign for surface of curv2 curve \~ + \param[in] fm - \ru Тип сопряжения: \n + st_Span - скругление с заданной хордой \n + st_Fillet - скругление с заданными радиусами + \en Conjugation type: \n + st_Span - fillet with a given chord\n + st_Fillet - fillet with given radii \~ + \param[in] cn - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0 - дуга окружности) + \en Coefficient of shape is changed between 0.05 and 0.95 (if 0 - circular arc) \~ + \param[in] ev - \ru Равномерная параметризация по дуге или нет + \en Whether arc length parameterization is uniform or not \~ + */ + MbFilletSurface( MbSurface & surf1, MbCurve & curv1, + MbSurface & surf2, MbCurve & curv2, + MbCurve3D & curv0, double d1, double d2, MbeSmoothForm fm, double cn, bool ev ); + +protected: + /// \ru Конструктор для наследников обычной поверхности скругления. \en Constructor for inheritors of ordinary fillet surface. + MbFilletSurface( MbSurfaceCurve & curv1, double d1, + MbSurfaceCurve & curv2, double d2, MbeSmoothForm fm, double cn, bool ev ); + /// \ru Конструктор для наследников поверхности с сохранением кромки. \en Constructor for inheritors of surface with preservation of fillet. + MbFilletSurface( MbSurfaceCurve & curv1, double d1, + MbSurfaceCurve & curv2, double d2, MbeSmoothForm fm, double cn, bool byFirst, bool ev ); + /// \ru Конструктор поверхности скругления c кривой пересечения касательных к поверхностям. \en Constructor of fillet surface with intersection curve of tangents to surfaces. \~ + MbFilletSurface( MbSurface & surf1, MbCurve & curv1, double d1, + MbSurface & surf2, MbCurve & curv2, double d2, + MbCurve3D & curv0, MbFunction & weig0, + MbeSmoothForm fm, double cn, bool ev ); + + /// \ru Конструктор копирования. \en Copy-constructor. + MbFilletSurface( const MbFilletSurface &, MbRegDuplicate * ); + /// \ru Конструктор копирования с теми же опорными поверхностями. \en Copy-constructor with the same support surfaces. + MbFilletSurface( const MbFilletSurface * ); + // \ru Для CurvesDuplicate() \en For CurvesDuplicate() +private: + MbFilletSurface( const MbFilletSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbFilletSurface (); + +public: + VISITING_CLASS( MbFilletSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + // \ru Коррекция средней линии поверхности скругления. \en Correction of mid-line of fillet surface. + virtual void Init0( double wmin, double wmax, bool insertPoints = true ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems( RPArray &s ); // \ru Дать базовые поверхности. \en Get base surfaces. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetVPeriod() const; // \ru Период для замкнутой поверхности или 0. \en Period for closed surface or 0. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр при его выходе за пределы определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... of smooth surfaces don't correct + first parameter when it is out of domain bounds. + \{ */ + virtual void PointOn ( double &u, double &v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double &u, double &v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double &u, double &v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double &u, double &v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double &u, double &v, MbVector3D & ) const; + virtual void DeriveUUV( double &u, double &v, MbVector3D & ) const; + virtual void DeriveUVV( double &u, double &v, MbVector3D & ) const; + virtual void DeriveVVV( double &u, double &v, MbVector3D & ) const; + virtual void Normal ( double &u, double &v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double &u, double &v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void NormalV ( double &u, double &v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + // \ru Вычислить значения всех производных в точке. \en Calculate all derivatives at point. \~ + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D & norm, MbVector3D & uNorm, MbVector3D & vNorm, + MbVector3D & uuDer, MbVector3D & vvDer, MbVector3D & uvDer ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature along v. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru Построить NURBS копию поверхности. \en Construct a NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru Построить NURBS-копию поверхности. \en Construct a NURBS-copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Create an offset surface. + + virtual MbCurve3D * CurveV( double u, MbRect1D *pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + virtual bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); // \ru Изменение носимых элементов. \en Change a carrier elements. + // \ru Нахождениe точки касания поверхностей \en Searching of surfaces tangency point + virtual MbeNewtonResult SurfaceTangentNewton( const MbSurface &, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double &u0, double &v0, double &u1, double &v1, + bool ext0, bool ext1 ) const; + + // \ru Проекции точки на поверхность. \en The point projections onto the surface. + virtual MbeNewtonResult PointProjectionNewton( const MbCartPoint3D & p, size_t iterLimit, + double & u, double & v, bool ext ) const; // \ru Функция для нахождения проекции точки на поверхность. \en Function for searching the point projection onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D &axis ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether the surface is convex. + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + /** \} */ + /** \ru \name Функции поверхности сопряжения + \en \name Functions of smooth surface + \{ */ + virtual MbSmoothSurface & CurvesDuplicate() const; // \ru Копия с теми же опорными поверхностями. \en Copy with the same support surfaces. + virtual double GetSmoothRadius() const; // \ru Дать радиус. \en Get radius. + virtual void GetDistances( double u, double &d1, double &d2 ) const; // \ru Дать радиусы со знаком. \en Get radii with a sign. + virtual double GetDistance( bool s ) const; // \ru Дать радиус со знаком. \en Get radius with a sign. + // \ru Объединить поверхности путём включения поверхности init в данную поверхность. \en Unite surfaces by inclusion of 'init' surface into current surface. + virtual bool SurfacesCombine( const MbSurfaceIntersectionCurve & edge, + const MbSurface & init, bool add, MbMatrix & matr, + const MbSurfaceIntersectionCurve * seam ); + /// \ru Дать коэффициент для радиуса. \en Get coefficient for radius. + virtual double DistanceRatio( bool firstCurve, MbCartPoint3D & p, double distance ) const; + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + /** \} */ + /** \ru \name Функции поверхности скругления + \en \name Functions of fillet surface + \{ */ + + /** \brief \ru Веса точек средней кривой. + \en Weights of points of mid-curve. \~ + \details \ru Веса точек средней кривой. + \en Weights of points of mid-curve. \~ + \param[in] u - \ru Параметр на средней кривой (по направлению U) + \en Parameter on mid-curve (by U direction) \~ + */ + double GetWeight( double u ) const; + + /** \brief \ru Угол раствора дуги. + \en Arc opening angle. \~ + \details \ru Угол раствора дуги. + \en Arc opening angle. \~ + \param[in] u - \ru Параметр по направлению U + \en Parameter by U direction \~ + \return \ru Угол раствора + \en Angle of opening \~ + */ + double GetAngle( double u ) const; // \ru Дать угол раствора дуги v \en Get v arc opening angle + + /** \brief \ru Ось поверхности в данной точке. + \en Axis of surface at given point. \~ + \details \ru Ось поверхности в данной точке. + \en Axis of surface at given point. \~ + \param[in] u - \ru Параметр по направлению U + \en Parameter by U direction \~ + \param[out] axis - \ru Результат - ось вращения + \en Result - rotation axis \~ + */ + double GetLocalAxis ( double u, MbAxis3D & axis ) const; // \ru Дать ось поверхности в данной точке \en Get axis of surface at given point + + /** \brief \ru Дать точку на оси. + \en Get point on axis. \~ + \details \ru Дать точку на оси. + \en Get point on axis. \~ + \param[in] u - \ru Параметр по направлению U + \en Parameter by U direction \~ + \param[out] p1 - \ru Точка на первой опорной кривой по параметру U + \en Point on first support curve by U parameter \~ + \param[out] p2 - \ru Точка на второй опорной кривой по параметру U + \en Point on second support curve by U parameter \~ + \param[out] p0 - \ru Точка на кривой пересечения касательных к поверхностям по параметру u (точка на оси) + \en Point on intersection curve of tangents to surfaces by u parameter (point on axis) \~ + */ + void GetCentrePoint( double u, MbCartPoint3D &p1, MbCartPoint3D &p2, MbCartPoint3D &p0 ) const; + + /** \brief \ru Дать среднюю точку. + \en Get the mid-point. \~ + \details \ru Дать среднюю точку. + \en Get the mid-point. \~ + \param[in] u - \ru Параметр по направлению U + \en Parameter by U direction \~ + \param[out] p1 - \ru Точка на первой опорной кривой по параметру U + \en Point on first support curve by U parameter \~ + \param[out] p2 - \ru Точка на второй опорной кривой по параметру U + \en Point on second support curve by U parameter \~ + \param[out] p0 - \ru Средняя точка + \en Mid-point \~ + \param[out] w - \ru Вес полученной средней точки + \en Weight of obtained mid-point \~ + */ + bool GetMiddlePoint( double u, MbCartPoint3D &p1, MbCartPoint3D &p2, MbCartPoint3D &p0, double &w ) const; + + // \ru Если параметризация равномерная, то на продолжении по V замыкается и период зависит от U \en If parameterization is uniform, then it is closed on extension by V and period depends on U + /** \brief \ru Период по направлению V. + \en Period by direction V. \~ + \details \ru Период по направлению V.\n + Если параметризация поверхности равномерная, то период по направлению V зависит от параметра U. + \en Period by direction V.\n + If parameterization of surface is uniform, then period by direction V depends on U parameter. \~ + \param[in] u - \ru Параметр по направлению U + \en Parameter by U direction \~ + \return \ru Период для заданного параметра + \en Period for given parameter \~ + */ + double GetVPeriod( double u ) const; + + /// \ru Кривая пересечения касательных к поверхностям. \en Intersection curve of tangents to surfaces. + const MbCurve3D & GetCurve0() const { return *curve0; } + + /** \brief \ru Скругление не круговое. + \en Fillet isn't circular. \~ + \details \ru Скругление не круговое. + \en Fillet isn't circular. \~ + \return \ru true, если радиусы скруглений для поверхностей не равны + \en True if surfaces fillet radii aren't equal \~ + */ + bool IsEllipse() const { return (fabs(fabs(distance1) - fabs(distance2))>=LENGTH_EPSILON); } // \ru Не равные радиусы \en Not equal radii + + /// \ru Параметризация по дуге равномерная. \en Uniform arc length parameterization. + bool IsEven() const { return even; } + + /** \brief \ru Однородная ли поверхность скругления. + \en Whether the fillet surface is homogeneous. \~ + \details \ru Однородная ли поверхность скругления. Поверхность скругления без сохранения кромки. + \en Whether the fillet surface is homogeneous. Fillet surface without preservation of fillet. \~ + \return \ru false, если одна из кривых curve1 или curve2 является кромкой + \en False if one of curve1 or curve2 curves is fillet \~ + */ + bool IsFilletSurface() const { return equable; } + + /** \brief \ru Коническое сечение общего вида. + \en General conic section. \~ + \details \ru Коническое сечение общего вида. + \en General conic section. \~ + \return \ru false, если сечение поверхности скругления является дугой окружности + \en False if section of fillet surface is circular arc \~ + */ + bool IsConic() const { return ( ::fabs(conic - c3d::_ARC_) >= EPSILON ); } // \ru Коническое сечение общего вида \en General conic section + + /** \brief \ru Коэффициент формы. + \en Coefficient of shape. \~ + \details \ru Коэффициент формы сечения поверхности скругления.\n + Изменяется от 0.05 до 0.95, при 0 сечение является дугой окружности. + \en Coefficient of shape of section of fillet surface.\n + Is changed between 0.05 and 0.95, if 0, then section is circular arc. \~ + \return \ru Коэффициент + \en Coefficient \~ + */ + double Conic() const { return conic; } + + /** \brief \ru Поверхность скругления с сохранением кромки. + \en Fillet surface with preservation of fillet. \~ + \details \ru Поверхность скругления с сохранением кромки. + \en Fillet surface with preservation of fillet. \~ + \return \ru true, если одна из кривых curve1 или curve2 является кромкой + \en True if one of curve1 or curve2 curves is fillet \~ + */ + bool IsKerbSurface() const { return !equable; } + + /** \brief \ru Является ли первая кривая кромкой. + \en Whether the first curve is fillet. \~ + \details \ru Является ли первая кривая кромкой. + \en Whether the first curve is fillet. \~ + \return \ru true, если первая кривая является кромкой + \en True if the first curve is fillet. \~ + */ + bool ByFirstCurve() const { return byCurve1; } + + /** \brief \ru Установить поверхность скругления типа с сохранением кромки. + \en Set fillet surface with preservation of fillet. + Need to call this->Init0() after this method \~ + \details \ru Установить поверхность скругления с сохранением кромки и указать определяющую кривую на поверхности. + Далее нужно вызвать метод this->Init0(). + \en Set fillet surface with preservation of fillet. \~ + \param[in] bc1 - \ru Определяющая кривая на поверхности: curve1 (bc1 = true), curve2 (bc1 = false). + \en General curve on surface: curve1 (bc1 = true), curve2 (bc1 = false). \~ + */ + void SetKerbSurface( bool bc1 ) { if ( equable ) { equable = false; byCurve1 = bc1; } } + + // \ru Выдать функцию весов точек средней кривой curve0. \en Get weight function for points of mid-curve (curve0). + const MbFunction * GetWeights() const; + // \ru Установить функцию весов точек средней кривой curve0. \en Set weight function for points of mid-curve (curve0). + bool SetWeights( MbFunction & func ); + + MbCurve3D * GetSpine() const; + void SetSpine( MbCurve3D * ); + + /** \} */ +protected: + void WeightKoefficient( double & w ) const; // \ru Вычисление веса при заданном коэффициенте \en Calculation of weight at given coefficient + void InitFilletSurface ( const MbFilletSurface & init ); + void CalculateCurve( double wmin, double wmax, bool insertPoints ); + double CalculateVParam( const MbCartPoint3D & p, double u ) const; // \ru Нахождение параметра v проекции точки на вырожденную поверхность \en Searching of v parameter of point projection onto degenerate surface + +protected: + // \ru Вычисление точки \en Calculation of a point +// void CalculateSurface( double u ) const; + // \ru Дать коэффициент для радиуса \en Get coefficient for radius + virtual double FunctionValue( double u ) const; + void CalculateData ( double & u, double & v, + MbCartPoint3D & uPoint0, MbCartPoint3D & uPoint1, MbCartPoint3D & uPoint2, // \ru Точки на кривых curve0, curve1, curve2. \en Points on curve0, curve1, curve2. + MbVector3D * uFirst0, MbVector3D * uFirst1, MbVector3D * uFirst2, // \ru Производные кривых curve0, curve1, curve2. \en Derivatives of curve0, curve1, curve2. + MbVector3D * uSecond0, MbVector3D * uSecond1, MbVector3D * uSecond2, // \ru Производные кривых curve0, curve1, curve2. \en Derivatives of curve0, curve1, curve2. + double & uWeight, double * wFirst, double * wSecond, // \ru Вес и его производные средней точки uPoint0. \en The weight and it derivatives of the mid-point uPoint0. + double & uP0, double & uP1, double & uP2, double & uPw, // \ru Коэффициенты точек uPoint0, uPoint1, uPoint2. \en Coefficients of points uPoint0, uPoint1, uPoint2. + double & uF0, double & uF1, double & uF2, double & uFw ) const; // \ru Коэффициенты производных uFirst0, uFirst1, uFirst2. \en Coefficients of derivatives uFirst0, uFirst1, uFirst2. + void InitSpineDerives(); + void CalculatePointOn ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const double & uWeight, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + void CalculateDeriveU ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const double & uWeight, const double & wFirst, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + void CalculateDeriveV ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const double & uWeight, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + void CalculateDeriveUU ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const MbVector3D & uSecond0, const MbVector3D & uSecond1, MbVector3D &uSecond2, + const double & uWeight, const double & wFirst, const double & wSecond, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + void CalculateDeriveVV ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const double & uWeight, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + void CalculateDeriveUV ( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const double & uWeight, const double & wFirst, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + void CalculateDeriveUUU( double & u, double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const MbVector3D & uSecond0, const MbVector3D & uSecond1, MbVector3D &uSecond2, + const double & uWeight, const double & wFirst, const double & wSecond, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + MbVector3D & ) const; + void CalculateDeriveUUV( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const MbVector3D & uSecond0, const MbVector3D & uSecond1, MbVector3D &uSecond2, + const double & uWeight, const double & wFirst, const double & wSecond, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; + void CalculateDeriveUVV( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const double & uWeight, const double & wFirst, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; + void CalculateDeriveVVV( double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const double & uWeight, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; + void CalculateNormal ( double & u, double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const double & uWeight, const double & wFirst, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Нормаль. \en Normal. + void CalculateNormalU ( double & u, double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const MbVector3D & uSecond0, const MbVector3D & uSecond1, MbVector3D &uSecond2, + const double & uWeight, const double & wFirst, const double & wSecond, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + void CalculateNormalV ( double & u, double & v, + const MbCartPoint3D & uPoint0, const MbCartPoint3D & uPoint1, const MbCartPoint3D & uPoint2, + const MbVector3D & uFirst0, const MbVector3D & uFirst1, const MbVector3D & uFirst2, + const double & uWeight, const double & wFirst, + const double & uP0, const double & uP1, const double & uP2, const double & uPw, + const double & uF0, const double & uF1, const double & uF2, const double & uFw, + MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + + // \ru Проверка параметров. \en Check parameters. + void CheckUParam( double & u ) const; + void CheckVParam( double & v ) const; + + void operator = ( const MbFilletSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFilletSurface ) +}; // MbFilletSurface + + +IMPL_PERSISTENT_OPS( MbFilletSurface ) + + +//------------------------------------------------------------------------------ +// \ru Проверка параметра u по отношению к полюсам и замкнутости \en Check u parameter against poles and closedness +// --- +inline void MbFilletSurface::CheckUParam( double & u ) const { + if ( uclosed ) { + if ( (u < umin) || (u > umax ) ) { + double tmp = umax - umin; + u -= ::floor((u - umin) / tmp) * tmp; + } + } + else { + if ( poleMin && uumax ) + u = umax; + } +} + + +//------------------------------------------------------------------------------ +// \ru Проверка параметра v \en Check v parameter +// --- +inline void MbFilletSurface::CheckVParam( double & v ) const { + if ( v < vmin ) + v = vmin; + else + if ( v > vmax ) + v = vmax; +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить вес для эллиптической точки \en Calculate weight for elliptic point +// --- +inline bool FilletWeight( double cos_a, double d1, double d2, double & uW ) +{ + bool result = false; + // \ru cos_a - косинус угла между нормалями \en Cos_a - cosine of angle between normals + if ( ::fabs( cos_a ) > PARAM_PRECISION ) { // \ru Не прямой угол \en Angle not right + if ( (d1 * d2) < 0 ) + cos_a = -cos_a; + double cos2_a = cos_a * cos_a; + double sin2_a = ::fabs( 1.0 - cos2_a ); + double sin_a = ::sqrt( sin2_a ); // \ru Синус угла между нормалями \en Sine of angle between normals + bool first = ( ::fabs(d1) > ::fabs(d2) ); + double a = first ? ::fabs( d1 ) : ::fabs( d2 ); // \ru Большая полуось эллипса \en Major semi axis of ellipse + double b = first ? ::fabs( d2 ) : ::fabs( d1 ); // \ru Малая полуось эллипса \en Minor semi axis of ellipse + // \ru Эллипс наиболее удалённой от центра точкой касался одной из поверхностей \en Ellipse concerns one of the surfaces by the point most remote from the center + if ( sin_a > PARAM_PRECISION ) { // \ru Не малый угол \en Angle not small + double aa = a * a; + double bb = b * b; + double p = ::sqrt( (aa*cos2_a) + (bb*sin2_a) ); // \ru Знаменатель (расстояние от центра эллипса до касательной) \en Denominator (distance from center of ellipse to tangent) + if ( p > NULL_EPSILON ) { // \ru Всегда должно выполняться, если a!=0 и b!=0 \en Always hold, if a! =0 and b! =0 + double d = 1.0 / p; + double cos_t = a * cos_a * d; // \ru Косинус параметрического угла эллипса \en Cosine of metric angle of ellipse + uW = ::sqrt( (1.0 + cos_t) * 0.5 ); // \ru Половина косинуса параметрического угла эллипса \en Half of cosine of metric angle of ellipse + result = true; + } + } + } + return result; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать поверхность сопряжения. + \en Create the fillet surface. \~ + \details \ru Создать поверхность сопряжения с сохранением кромки грани. + \en Create the fillet surface with the edge. \~ + \param[in] surface1 - \ru Сопрягаемая поверхность. + \en The conjugate surface. \~ + \param[in] points1 - \ru Точки для опорной кривой на сопрягаемой поверхности. + \en Points for curve on the conjugated surface. \~ + \param[in] surface2 - \ru Сопрягаемая поверхность. + \en The conjugate surface. \~ + \param[in] points2 - \ru Точки для опорной кривой на сопрягаемой поверхности. + \en Points for curve on the conjugated surface. \~ + \param[in] form - \ru Тип повержности сопряжения. + \en The surface type \~ + \param[in] distance1 - \ru Радиус скругления со знаком для поверхности кривой crve1 + \en Fillet radius with sign for surface of crve1 curve \~ + \param[in] distance2 - \ru Радиус скругления со знаком для поверхности кривой crve2 + \en Fillet radius with sign for surface of crve2 curve \~ + \param[in] conic - \ru Коэффициент формы, изменяется от 0.05 до 0.95 (при 0.5 - дуга окружности) + \en Coefficient of shape is changed from 0.05 to 0.95 (if 0.5 - circular arc) \~ + \param[in] curve - \ru Кривая опорной кромки. + \en The edge curve \~ + \param[in] params - \ru Параметры поверхности вдоль первого напрвыления (u). + \en The parameters of new the surface by first direction (u) \~ + \param[in] byFirstSurface - \ru Пурвая или вторая поверхность сопрягается гладко с новой поверхностью. + \en Is the first or second conjugate surface smooth with the new surface. \~ + \param[in] even - \ru Равномерная параметризация по дуге (v) или нет + \en Uniform parametrization by arc (v) or not \~ + \return \ru Возвращает созданную поверхность. + \en Return the created surface. \~ + \ingroup Surface_Modeling +*/ +MbSmoothSurface * CreateKerbSurface( const MbSurface &surface1, SArray & points1, + const MbSurface &surface2, SArray & points2, + MbeSmoothForm form, double distance1, double distance2, double conic, + const MbSurfaceIntersectionCurve & curve, SArray & params, + bool byFirstSurface, bool even, VERSION version ); + + +#endif // __SURF_FILLET_SURFACE_H diff --git a/C3d/Include/surf_gregory_surface.h b/C3d/Include/surf_gregory_surface.h new file mode 100644 index 0000000..c96e3d8 --- /dev/null +++ b/C3d/Include/surf_gregory_surface.h @@ -0,0 +1,240 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность на ограничивающем контуре. + \en The surface on the bounding contour. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_GREGORY_SURFACE_H +#define __SURF_GREGORY_SURFACE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbContour3D; +class MbTriWorkingData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность на ограничивающем контуре. + \en The surface on the bounding contour. \~ + \details \ru Поверхность, построенная на замкнутом контуре. + Поверхность определяется замкнутым контуром из n, n>1, пространственных кривых и состоит из n патчей, + G1-гладко стыкующихся между собой. Каждый патч является модификацией четырехугольной поверхности Грегори. + В вершинах патча нарушается равенство смешанных производных. + \en The surface defined by closed contour. + The surface is defined by closed contour of n, n>1, spacial curves and consists of n patches connected in such + a way to satisfy G1-continuity. Every patch is the modification of quadrilateral Gregory surface. + At the vertex of patch the equality of mixed derivatives is not fulfilled. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbGregorySurface : public MbSurface { + class MbGregoryWorkingData; +private: + size_t sn; ///< \ru Количество сторон многоугольника. \en The sides count of polygon. + RPArray contour; ///< \ru Границы многоугольника. \en The polygon boundaries. + SArray conjug; ///< \ru Тип сопряжения вдоль границы. \en Conjugation type along the curve. + RPArray radial; ///< \ru Кривые от заданной точки до сторон многоугольника. \en Curves from given point to polygon sides. + DPtr gd; ///< \ru Расчетные данные поверхности. \en Surface computational data. + +public: + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности на ограничивающем контуре. + \en Constructor of surface on the bounding contour. \~ + \param[in] initContour - \ru Контур. + \en The contour. \~ + */ + MbGregorySurface( const MbContour3D & initContour, const SArray * conj = NULL ); +protected: + /// \ru Конструктор-копия. \en Copy constructor. + MbGregorySurface( const MbGregorySurface &, MbRegDuplicate * ); +public: + virtual ~MbGregorySurface(); + +public: + VISITING_CLASS( MbGregorySurface ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of a geometric object. + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Make a copy of element. + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными. \en Whether the objects are similar. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг. \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis + virtual void Refresh(); // \ru Сбросить все временные данные. \en Flush all the temporary data. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности. + \en \name Functions for surface domain description. + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + + virtual bool IsUClosed() const; // \ru Замкнута ли гладко поверхность по параметру u без учета граничного контура. \en Whether the surface is smoothly closed by parameter u without regard to the boundary contour. + virtual bool IsVClosed() const; // \ru Замкнута ли гладко поверхность по параметру v без учета граничного контура. \en Whether the surface is smoothly closed by parameter v without regard to the boundary contour. + virtual bool IsUTouch() const; // \ru Замкнута ли фактически поверхность по параметру u независимо от гладкости. \en Whether the surface is actually closed by parameter u regardless of the smoothness. + virtual bool IsVTouch() const; // \ru Замкнута ли фактически поверхность по параметру v независимо от гладкости. \en Whether the surface is actually closed by parameter v regardless of the smoothness. + virtual bool IsUPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру u. \en Whether the surface is smoothly closed by parameter u. + virtual bool IsVPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру v. \en Whether the surface is smoothly closed by parameter v. + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой поверхности или 0. \en Return period for closed surface or 0. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой поверхности или 0. \en Return period for closed surface or 0. + + virtual size_t GetUCount() const; + // \ru Существует ли полюс на границе параметрической области. \en Whether there is pole on boundary of parametric region. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void Normal ( double & u, double & v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void _DeriveU ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _Normal ( double u, double v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности. + \en \name Functions of moving along the surface. + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага параметра u по по величине прогиба. \en Calculation of parameter u step by the value of sag. + //virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага параметра v по по величине прогиба. \en Calculation of parameter v step by the value of sag. + virtual double DeviationStepU( double u, double v, double ang ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + //virtual double DeviationStepV( double u, double v, double ang ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + /** \} */ + + /** \ru \name Общие функции поверхности. + \en \name Common functions of surface. + \{ */ + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + /** \} */ + +private: + // \ru Проверить параметры и в случае выхода за пределы загнать в область определения. + // \en Check parameters and if it is out of limits, then move it to domain. + void CheckParams( double & u, double & v ) const; + // \ru Проверить параметры и в случае захода за полюс или выходе за период загнать в область определения. + // \en Check parameters and if it is out of pole or it is out of period, then drive it to the domain region. + void CheckParamsEx( double & u, double & v ) const; + + // \ru Определить местные координаты области поверхности. \en Determine local coordinates of surface region. + void LocalCoordinate( double u, double v, double & ul, double & vl, size_t & i, MbTriWorkingData * pd ) const; + // \ru Вычислить вспомогательные векторы производных в узлах кривых. \en Calculate auxiliary vectors of derivatives at nodes of curves. + void CalculateVertex( const size_t & i, MbTriWorkingData * pd ) const; + // \ru Вычислить вспомогательные вектора производных вдоль кривых патча. \en Calculate auxiliary vectors of derivatives along curves of patch. + void CalculateAlong0( const double & ul, const double & vl, const size_t & patch, MbTriWorkingData * pd ) const; + void CalculateAlong1( const double & ul, const size_t & patch, MbTriWorkingData * pd ) const; + void CalculateAlong2( const double & vl, const size_t & patch, MbTriWorkingData * pd ) const; + // \ru Производные в локальных координатах. \en Derivatives in the local coordinates. + void DerU ( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Первая производная по u. \en First derivative with respect to u. + void DerV ( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Первая производная по v. \en First derivative with respect to v. + void DerUU ( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + void DerVV ( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + void DerUV ( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Вторая производная по uv. \en Second derivative with respect to uv. + void DerUUU( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Третья производная. \en Third derivative. + void DerUUV( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Третья производная. \en Third derivative. + void DerUVV( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Третья производная. \en Third derivative. + void DerVVV( const double & ul, const double & vl, MbTriWorkingData * pd, MbVector3D & vect ) const; // \ru Третья производная. \en Third derivative. + // \ru Вычислить нормаль. \en Normal calculation. + void ExactNormal( double u, double v, const MbVector3D & derU, const MbVector3D & derV, MbVector3D & norm ) const; + + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbGregorySurface ) +OBVIOUS_PRIVATE_COPY( MbGregorySurface ) +}; // MbGregorySurface + +IMPL_PERSISTENT_OPS( MbGregorySurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры и в случае выхода за пределы загнать в область определения. \en Check parameters and if it is out of limits, then move it to domain. +// --- +inline void MbGregorySurface::CheckParams( double & u, double & v ) const +{ + if ( (u > -EXTENT_EPSILON && u < 0.0) || (u >= static_cast(sn) && u < static_cast(sn) + EXTENT_EPSILON) ) + u = 0.0; + else if ( (u < 0.0) || (u >= static_cast(sn)) ) + u -= ::floor( u / static_cast(sn) ) * static_cast(sn); + if ( v < 0.0 ) + v = 0.0; + else if ( v > 1.0 ) + v = 1.0; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить параметры и в случае захода за полюс или выходе за период загнать в область определения. \en Check parameters and if it is out of pole or it is out of period, then drive it to the domain region. +// --- +inline void MbGregorySurface::CheckParamsEx( double & u, double & v ) const +{ + if ( (u > -EXTENT_EPSILON && u < 0.0) || (u >= static_cast(sn) && u < static_cast(sn) + EXTENT_EPSILON) ) + u = 0.0; + else if ( (u < 0.0) || (u >= static_cast(sn)) ) + u -= ::floor( u / static_cast(sn) ) * static_cast(sn); + if ( v < 0.0 ) + v = 0.0; +} + +#endif // __SURF_GREGORY_SURFACE_H diff --git a/C3d/Include/surf_grid_surface.h b/C3d/Include/surf_grid_surface.h new file mode 100644 index 0000000..a64075e --- /dev/null +++ b/C3d/Include/surf_grid_surface.h @@ -0,0 +1,413 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность на базе триангуляции. + \en Surface based on triangulation. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_GRID_SURFACE_H +#define __SURF_GRID_SURFACE_H + + +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbMesh; +class MATH_CLASS MbGrid; + + +#define _C3D_3_ 3 +#define _C3D_4_ 4 + + +//------------------------------------------------------------------------------ +/// \ru Tреугольная пластина поверхности на сетке точек. \en Triangular plate. +// --- +class MbTrigon { +protected : + size_t index[_C3D_3_]; ///< \ru Номера вершин треугольника в массиве точек. \en The numbers of vertices in points array. + size_t neighbour[_C3D_3_]; ///< \ru Номера соседних треугольников. \en The numbers of neighbour triangles. SYS_MAX_T if it is absent. + +// points[index[2]] +// + +// / \ +// neighbour[2] / \ neighbour[1] +// / \ +// points[index[0]] +---------------+ points[index[1]] +// neighbour[0] + +public : + MbTrigon() { index[0] = SYS_MAX_T; index[1] = SYS_MAX_T; index[2] = SYS_MAX_T; + neighbour[0] = SYS_MAX_T; neighbour[1] = SYS_MAX_T; neighbour[2] = SYS_MAX_T; } + MbTrigon( size_t i0, size_t i1, size_t i2 ) { index[0] = i0; index[1] = i1; index[2] = i2; + neighbour[0] = SYS_MAX_T; neighbour[1] = SYS_MAX_T; neighbour[2] = SYS_MAX_T; } + MbTrigon( const MbTrigon & init ) { index[0] = init.index[0]; index[1] = init.index[1]; index[2] = init.index[2]; + neighbour[0] = init.neighbour[0]; neighbour[1] = init.neighbour[1]; neighbour[2] = init.neighbour[2]; } + MbTrigon( const MbTriangle & init ) { + uint i0, i1, i2; + init.GetTriangle( i0, i1, i2 ); + index[0] = i0; index[1] = i1; index[2] = i2; + neighbour[0] = SYS_MAX_T; neighbour[1] = SYS_MAX_T; neighbour[2] = SYS_MAX_T; } +public : + void Init( size_t i0, size_t i1, size_t i2, bool orientation ) { + if ( orientation ) { index[0] = i0; index[1] = i1; index[2] = i2; } + else { index[0] = i0; index[1] = i2; index[2] = i1; } + neighbour[0] = SYS_MAX_T; neighbour[1] = SYS_MAX_T; neighbour[2] = SYS_MAX_T; + } + void Init( size_t i0, size_t i1, size_t i2, size_t n0, size_t n1, size_t n2 ) { + index[0] = i0; index[1] = i1; index[2] = i2; + neighbour[0] = n0; neighbour[1] = n1; neighbour[2] = n2; + } + void GetTriangle( size_t & i0, size_t & i1, size_t & i2 ) const { i0 = index[0]; i1 = index[1]; i2 = index[2]; } + void GetTriangle( size_t & i0, size_t & i1, size_t & i2, size_t & n0, size_t & n1, size_t & n2 ) const { + i0 = index[0]; i1 = index[1]; i2 = index[2]; + n0 = neighbour[0]; n1 = neighbour[1]; n2 = neighbour[2]; + } + size_t GetNunber( size_t & i ) const { return index[i % _C3D_3_]; } + size_t GetNeihbour( size_t & i ) const { return neighbour[i % _C3D_3_]; } + // \ru Инициализация соседа. \en The neighbour initiation. + void SetNeihbour( size_t i, size_t n ) { neighbour[i % _C3D_3_] = n; } + MbTrigon & operator = ( const MbTrigon & init ) { init.GetTriangle( index[0], index[1], index[2] ); + neighbour[0] = init.neighbour[0]; neighbour[1] = init.neighbour[1]; neighbour[2] = init.neighbour[2]; + return *this; } + MbTrigon & operator = ( const MbTriangle & init ) { + uint i0, i1, i2; + init.GetTriangle( i0, i1, i2 ); + index[0] = i0; index[1] = i1; index[2] = i2; + neighbour[0] = SYS_MAX_T; neighbour[1] = SYS_MAX_T; neighbour[2] = SYS_MAX_T; + return *this; } +}; // MbTrigon + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность на базе триангуляции. + \en Surface based on triangulation. \~ + \details \ru Поверхность на базе триангуляции образована криволинейными треугольниками, + гладко стыкующимися между собой по общим сторонам. + В общих вершинах стыкующиеся треугольники имеют общую нормаль. + Сторону треугольников изменяются по кубическому закону. \n + \en Surface based on triangulation is formed by curvilinear triangles + which are smoothly connected together through common edges. + Connected triangles have common normal at common vertices. + Edges of triangles are changed by cubic law. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbGridSurface : public MbSurface { + +private: + // \ru Согласованные между собой множества данных в вершинах. \en Sets of data at vertices matched each other. + std::vector params; ///< \ru Множество точек на параметрической области поверхности. \en Set of points in parametric space of surface. + std::vector points; ///< \ru Множество точек поверхности. \en Set of points of surface. + std::vector normals; ///< \ru Множество нормалей поверхности. \en Set of normals of surface. + std::vector triangles; ///< \ru Множество треугольников. \en Set of triangles. + // \ru Описание области параметров поверхности. \en Description of surface parameters region. + size_t uCount; ///< \ru Количество разбиений области по u. \en Count of splittings of region by u. + size_t vCount; ///< \ru Количество разбиений области по v. \en Count of splittings of region by v. + PArray< std::vector > cell; ///< \ru Сетка области параметров поверхности. \en Grid of surface parameters region. + std::vector boundary; ///< \ru Граничные кривые области параметров поверхности. \en Boundary curves of surface parameters region. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + bool uclosed; ///< \ru Признак замкнутости по параметру u. \en Attribute of closedness by parameter u. + bool vclosed; ///< \ru Признак замкнутости по параметру v. \en Attribute of closedness by parameter v. + +private: + /// \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en Declaration without implementation of the copy-constructor to prevent copying by default. + MbGridSurface( const MbGridSurface & init ); + MbGridSurface( const MbGridSurface & init, MbRegDuplicate * iReg ); +protected: + /// \ru Конструктор поверхности. \en Constructor of surface. + template + MbGridSurface ( const Params & _params + , const Points & _points + , const Normals & _normals + , const Triangles & _triangles + , const Bounds & _bounds) + : MbSurface () + , params () + , points () + , normals () + , triangles () + , uCount( 1 ) + , vCount( 1 ) + , cell( 0, 1, true) + , boundary () + , umin ( 0.0 ) + , vmin ( 0.0 ) + , umax ( 0.0 ) + , vmax ( 0.0 ) + , uclosed ( false ) + , vclosed ( false ) + { + size_t k, cnt; + + cnt = _params.size(); + params.reserve( cnt ); + for ( k = 0; k < cnt; k++ ) + params.push_back( _params[k] ); + cnt = _points.size(); + points.reserve( cnt ); + for ( k = 0; k < cnt; k++ ) + points.push_back( _points[k] ); + + if ( _normals.size() > 0 ) { + size_t normalsLast = _normals.size() - 1; + normals.reserve( cnt ); + for ( k = 0; k < cnt; k++ ) { + size_t ind = std_min( k, normalsLast ); + normals.push_back( _normals[ind] ); + } + } + cnt = _triangles.size(); + triangles.reserve( cnt ); + for ( k = 0; k < cnt; k++ ) + triangles.push_back( _triangles[k] ); + + cnt = _bounds.size(); + boundary.reserve(cnt); + for (k = 0; k < cnt; k++) { + _bounds[k]->AddRef(); + boundary.push_back(_bounds[k]); + } + + Init( boundary.size() == 0 ); + } + +public: + virtual ~MbGridSurface(); + +public: + VISITING_CLASS( MbGridSurface ); + + /** \name Общие функции геометрического объекта + \{ */ + // \ru Общие функции геометрического объекта \en Common functions of a geometric object + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента \en Make a copy of element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; + virtual bool SetEqual( const MbSpaceItem &init ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem &init ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + /** \} */ + + /** \name Функции описания области определения поверхности + \{ */ + // \ru Функции описания области определения поверхности. \en Functions for surface domain description. + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + /** \} */ + + /** \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \{ */ + // \ru Функции для работы в области определения поверхности. \en Functions for working at surface domain. + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & der ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & der ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & der ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & der ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & der ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + /** \} */ + + /** \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + За пределами параметрической области поверхность продолжается по касательной. + \{ */ + // \ru Функции для работы внутри и вне области определения поверхности. \en Functions for working inside and outside the surface's domain. + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная. \en The second derivative. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + // \ru Функции движения по поверхности \en Functions of moving along the surface + virtual double StepU( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по U \en Calculation of the approximation step with consideration of the curvature radius by U + virtual double StepV( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по V \en Calculation of the approximation step with consideration of the curvature radius by V + virtual double DeviationStepU( double u, double v, double ang ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double ang ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + + // \ru Выдать граничную точку \en Get the boundary point + virtual void GetLimitPoint( ptrdiff_t num, MbCartPoint3D & ) const; // \ru Выдать граничную трехмерную точку. \en Get the three-dimensional boundary point. + virtual void GetLimitPoint( ptrdiff_t num, MbCartPoint & ) const; // \ru Выдать граничную двумерную точку (граничные параметры). \en Get the two-dimensional boundary point (boundary parameters). + + virtual MbeItemLocation PointClassification( const MbCartPoint &, bool ignoreClosed = false ) const; // \ru Находится ли точка в области, принадлежащей поверхности. \en Whether the point is in region belonging to the surface. + virtual double DistanceToBorder ( const MbCartPoint &, double & eps ) const; // \ru Параметрическое расстояние до ближайшей границы. \en Parametric distance to the nearest boundary. + // \ru Определение точек пересечения кривой с контурами поверхности. \en Determine intersection points of a curve with the contours on the surface. + virtual size_t CurveClassification( const MbCurve & curve, SArray & tcurv, SArray & dir ) const; + + // \ru Найти ближайшую проекцию точки на поверхность. \en Find the nearest projection of a point onto the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Вce точки пересечения поверхности и кривой. \en All the points of intersection of a surface and a curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + // \ru Расчёт площади области определения параметров. \en Calculate area of parameter domain. + virtual double ParamArea() const; + virtual size_t GetUPairs( double v, SArray & u ) const; // \ru Вычислить U-пары от V. \en Calculate U-pairs by V. + virtual size_t GetVPairs( double u, SArray & v ) const; // \ru Вычислить V-пары от U. \en Calculate V-pairs by U. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + virtual void CalculateSurfaceWire( const MbStepData & stepData, size_t beg, MbMesh & mesh, + size_t uMeshCount = c3d::WIRE_MAX, size_t vMeshCount = c3d::WIRE_MAX ) const; // \ru Рассчитать сетку. \en Calculate mesh. + // \ru Аппроксимация поверхности треугольными пластинами. \en Approximation of a surface by triangular plates. + virtual void CalculateSurfaceGrid( const MbStepData & stepData, bool sense, MbGrid & grid ) const; + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + // \ru Пересчитать нормали в вершинах. \en Normals Calculation on vertex. + virtual void Normalize(); + + size_t GetBoundariesCount() const { return boundary.size(); } // \ru Выдать количество граничных двумерных кривых. \en Get the two-dimensional boundary curves count. + virtual MbContour & MakeContour( bool sense ) const; // \ru Выдать граничных двумерный контур. \en Get the two-dimensional boundary contour. + virtual MbCurve & MakeSegment( size_t i, bool sense ) const; // \ru Дать граничную двумерную кривую. \en Get the two-dimensional boundary curve. + + /// \ru Инициализация объекта по другому такому же. \en Initialization of a object by same other object. + void Init( const MbGridSurface & init ); + + /// \ru Выдать количество точек. \en Get the number of points. + size_t PointsCount() const { return points.size(); } + /// \ru Выдать количество нормалей. \en Get the number of normals. + size_t NormalsCount() const { return normals.size(); } + /// \ru Выдать количество параметров. \en Get the number of parameters. + size_t ParamsCount() const { return params.size(); } + // \ru Выдать количество треугольников. \en Get the number of triangles. + size_t TrianglesCount() const { return triangles.size(); } + // \ru Выдать количество граничных кривых. \en Get the number of boundary curves. + size_t BoundariesCount() const { return boundary.size(); } + + // \ru Добавить в контейнер параметры в опорных точках поверхности. \en Get the parameters to container. + void GetParams( std::vector & paramsVector ) const; + // \ru Добавить в контейнер опорные точки. \en Get the points to container. + void GetPoints( std::vector & pointsVector ) const; + // \ru Добавить в контейнер нормали в опорных точках. \en Add the normals to container. + void GetNormals( std::vector & normalsVector ) const; + // \ru Добавить в контейнер треугольники. \en Add the triangles to container. + void GetTriangles( std::vector & tVector ) const; + // \ru Добавить в контейнер треугольники. \en Add the triangles to container. + void GetTriangles( std::vector & tVector ) const; + // \ru Добавить в контейнер граничные кривые. \en Add the boundary curves of surface parameters region. + void GetBoundaries( std::vector & bVector ) const; + + /// \ru Создание поверхности. \en Creatying of surface. + template + + static MbGridSurface * Create( const Params & _params + , const Points & _points + , const Normals & _normals + , const Triangles & _triangles + , const Bounds & _bounds ) + { + MbGridSurface * surface = NULL; + + const size_t itemsCnt = _params.size(); + + if ( (itemsCnt > 2) && (itemsCnt == _points.size()) && (_triangles.size() > 0) ) { + if ( (itemsCnt == _normals.size()) || (_normals.size() == 1) ) + surface = new MbGridSurface( _params, _points, _normals, _triangles, _bounds ); + } + return surface; + } + +private: + /// \ru Инициализация. \en Initialization. + void Init( bool bound = true ); + // \ru Инициализация граничных кривых. \en Initialization of boundary curves. + void MakeBoundary(); + // \ru Выдать треугольник. \en Get triangle. + MbTrigon & GetTriangle( size_t i ) { return triangles[i]; } + void PointOn ( double & u, double & v, bool ext, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + void DeriveU ( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Первая производная по u \en First derivative with respect to u + void DeriveV ( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Первая производная по v \en First derivative with respect to v + void DeriveUU ( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Вторая производная по u \en Second derivative with respect to u + void DeriveVV ( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Вторая производная по v \en Second derivative with respect to v + void DeriveUV ( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + void DeriveUUU( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + void DeriveUUV( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + void DeriveUVV( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + void DeriveVVV( double & u, double & v, bool ext, MbVector3D & der ) const; // \ru Третья производная \en Third derivative + // \ru Выставить взаимные связи триангуляции. \en Set mutual connections of triangulation. + bool SetTrigonNeihbours(); + // \ru Поиск ближайшего треугольника для инициализации данных ячейки. \en Search nearest triangle for initialization of data of cell. + void FindNearest( size_t i, size_t j, std::vector & indecies, + double uDelta, double vDelta, double u, double v ); + // \ru Добавить ближайший треугольник в ячейку. \en Add nearest triangle to cell. + bool AddNearest( size_t i, size_t j, size_t ind ); + // \ru Вычислить индккс ближайшего треугольника и барицентрические координаты точки для него. \en Calculate barycentric coordinates of the nearest trianle. + size_t FindIndex( const double & u, const double & v, double & a, double & b, double & c, double & d ) const; + // \ru Расстояние до треугольника. \en The distance to a triangle. + double RangeToTriangle( size_t ind, const double & u, const double & v, double eps, + double & a, double & b, double & c, double & d ) const; + // \ru Расстояние до треугольника. \en The distance to a triangle. + double DistanceToTriangle( size_t ind, const double & u, const double & v, double eps, + MbCartPoint & p ) const; + // \ru Проверка параметров. \en Check parameters. + void CheckParam( double & u, double & v ) const; + // \ru Выдать данные триангуляции. \en Get triangulation data. + void GetTriangleData( size_t tIndex, + size_t & index1, size_t & index2, size_t & index3, + size_t & neigh1, size_t & neigh2, size_t & neigh3, + MbCartPoint & param1, MbCartPoint & param2, MbCartPoint & param3, + MbCartPoint3D & point1, MbCartPoint3D & point2, MbCartPoint3D & point3, + MbVector3D & normal1, MbVector3D & normal2, MbVector3D & normal3 ) const; + // \ru Выдать данные триангуляции соседнего треугольника. \en Get neighbour triangulation data. + bool GetNeighbourData( double u, double v, + size_t neigh1, size_t neigh2, size_t neigh3, + double & aCalc, double & bCalc, double & cCalc, double & deter, double & portion, + MbCartPoint & param1, MbCartPoint & param2, MbCartPoint & param3, + MbCartPoint3D & point1, MbCartPoint3D & point2, MbCartPoint3D & point3, + MbVector3D & normal1, MbVector3D & normal2, MbVector3D & normal3 ) const; + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbGridSurface & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbGridSurface ) +}; // MbGridSurface + +IMPL_PERSISTENT_OPS( MbGridSurface ) + + +#endif // __SURF_GRID_SURFACE_H diff --git a/C3d/Include/surf_join_surface.h b/C3d/Include/surf_join_surface.h new file mode 100644 index 0000000..f49b465 --- /dev/null +++ b/C3d/Include/surf_join_surface.h @@ -0,0 +1,421 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность соединения. + \en The surface of the joint. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_JOIN_SURFACE_H +#define __SURF_JOIN_SURFACE_H + + +#include +#include +#include + + +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbProperties; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность соединения. + \en The surface of the joint. \~ + \details \ru Поверхность представляет собой сплайновую поверхность, + натянутую на набор заданных однонаправленных кривых. + Кривые не должны пересекаться или касаться друг друга. + Касание или пересечение кривых допустимо только в конечных точках. + Координата u изменяется вдоль заданных кривых в соответствии с параметризацией каждой кривой. + Значение координаты v вдоль каждой кривой постоянно. + В направлении координаты v поверхность строится аналогично NURBS кривой с заданной степенью, узловым вектором и + использующей в качестве узлов точки заданных кривых, вычисленных с одинаковыми параметрами u. + Поверхность используется для гладкого соединения краёв двух поверхностей. + \en The surface is spline surface + tensed on a set of the given unidirectional curves. + Curves shouldn't be intersected or concerned each other. + Tangency or intersection of curves is acceptable only at the end points. + Coordinate u is changed along given curves according to parameterization of each curve. + Value of coordinate v along each curve is constant. + In the direction of v coordinate the surface is constructed similar to NURBS curve with the given degree, a nodal vector and + points of the given curves calculated with identical parameters u are used as knots. + Surface is used for smooth connection of boundaries of two surfaces. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbJoinSurface : public MbSurface { +protected: + RPArray curves; ///< \ru Набор кривых для построения поверхности. \en Set of curves to construct surface. + SArray knots; ///< \ru Значения узлов для сплайна по v. \en Knot values for spline by v. + ptrdiff_t degree; ///< \ru Степень сплайна по v. \en Order of spline by v. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + bool closedU; ///< \ru Замкнутость по u. \en Closedness by u. + bool closedV; ///< \ru Замкнутость по V. \en Closedness by V. + bool isPoleUmin; ///< \ru Полюс при u == umin. \en Pole at u == umin. + bool isPoleUmax; ///< \ru Полюс при u == umax. \en Pole at u == umax. + bool isPoleVmin; ///< \ru Полюс при u == vmin. \en Pole at u == vmin. + bool isPoleVmax; ///< \ru Полюс при u == vmax. \en Pole at u == vmax. + +private: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbJoinSurfaceAuxiliaryData : public AuxiliaryData { + public: + double calcU; ///< \ru Последнее обработанное значение u. \en Last processed value of u. + double calcV; ///< \ru Последнее обработанное значение v. \en Last processed value of v. + ptrdiff_t lastIndex; ///< \ru Левый индекс узлового вектора из последних вычислений. \en Left index of knot vector from last calculations. + double ** points; ///< \ru 2-х мерный массив для хранения данных по точкам для текущих вычислений. \en Two-dimensional array to store points data for current calculations. + double ** nMatrix; ///< \ru Матрица коэффициентов для NURBS. \en Matrix of coefficients for NURBS. + SArray tempPoints; ///< \ru Множество рабочих точек. \en Set of working points. + SArray tempVectors; ///< \ru Множество рабочих векторов. \en Set of working vectors. + SArray readyData; ///< \ru Множество для хранения вычисленных значений точки и производных. \en Set to store calculated values of point and derivatives. + + // \ru Рабочие указатели для создания базисных сплайнов \en Working pointers for creation of basis splines + double * m_left; ///< \ru Рабочие указатели для создания базисных сплайнов. \en Working pointers for creation of basis splines. + double * m_right; ///< \ru Рабочие указатели для создания базисных сплайнов. \en Working pointers for creation of basis splines. + ptrdiff_t *degree; ///< \ru Степень сплайна по v. \en Order of spline by v. + MbJoinSurfaceAuxiliaryData(); + MbJoinSurfaceAuxiliaryData( const MbJoinSurfaceAuxiliaryData & init ); + virtual ~MbJoinSurfaceAuxiliaryData(); + void CreateVars(); + void InitVars (); + void FreeVars (); + private: + void operator = ( const MbJoinSurfaceAuxiliaryData & ); + }; + mutable CacheManager cache; + +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbJoinSurface( const MbJoinSurface &, MbRegDuplicate * ); +private: + MbJoinSurface( const MbJoinSurface & ); // \ru Не реализовано. \en Not implemented. +public: + /** \brief \ru Конструктор поверхности соединения. + \en Constructor of surface of the joint. \~ + \details \ru Конструктор поверхности соединения по набору кривых. Кривые должны быть непересекающиеся.\n + В конструкторе этот факт не проверяется.\n + \en Constructor of surface of the joint by set of curves. Curves shouldn't be intersected.\n + In constructor this fact doesn't checked.\n \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + MbJoinSurface( const RPArray & initCurves, bool sameCurves ); + /** \brief \ru Конструктор поверхности соединения. + \en Constructor of surface of the joint. \~ + \details \ru Конструктор поверхности соединения по набору кривых и порядку поверхности. Кривые должны быть непересекающиеся.\n + В конструкторе этот факт не проверяется. + \en Constructor of surface of the joint by set of curves and order of surface. Curves shouldn't be intersected.\n + In constructor this fact doesn't checked. \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] initDegree - \ru Порядок поверхности по v. + \en Surface order by v. \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + MbJoinSurface( const RPArray & initCurves, ptrdiff_t initDegree, bool sameCurves ); + /** \brief \ru Конструктор поверхности соединения. + \en Constructor of surface of the joint. \~ + \details \ru Конструктор поверхности соединения по набору кривых, порядку поверхности и узловому вектору.\n + Кривые должны быть непересекающиеся. В конструкторе этот факт не проверяется. + \en Constructor of surface of the joint by set of curves, order of surface and knot vector.\n + Curves shouldn't be intersected. In constructor this fact doesn't checked. \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] initDegree - \ru Порядок поверхности по v. + \en Surface order by v. \~ + \param[in] initKnots - \ru Узловой вектор по v. + \en A knot vector by v. \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + MbJoinSurface( const RPArray & initCurves, ptrdiff_t initDegree, const SArray & initKnots, bool sameCurves ); + +public: + virtual ~MbJoinSurface(); + +public: + VISITING_CLASS( MbJoinSurface ); + +public: + /** \brief \ru Инициализация поверхности соединения. + \en Initialization of surface of the joint. \~ + \details \ru Инициализация поверхности соединения по набору кривых. Кривые должны быть непересекающиеся.\n + Этот факт в функции не проверяется. Порядок поверхности не изменяется. + \en Initialization of surface of the joint by set of curves. Curves shouldn't be intersected.\n + This fact isn't checked in the function. Surface order doesn't changed. \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + void Init( const RPArray & initCurves, bool sameCurves ); + /** \brief \ru Инициализация поверхности соединения. + \en Initialization of surface of the joint. \~ + \details \ru Инициализация поверхности соединения по набору кривых и порядку поверхности. Кривые должны быть непересекающиеся.\n + Этот факт в функции не проверяется. Порядок поверхности не изменяется. + \en Initialization of surface of the joint by set of curves and order of surface. Curves shouldn't be intersected.\n + This fact isn't checked in the function. Surface order doesn't changed. \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] initDegree - \ru Порядок поверхности по v.\n + \en Surface order by v.\n \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + bool Init( const RPArray & initCurves, ptrdiff_t initDegree, bool sameCurves ); + /** \brief \ru Инициализация поверхности соединения. + \en Initialization of surface of the joint. \~ + \details \ru Инициализация поверхности соединения по набору кривых, порядку поверхности и узловому вектору.\n + Кривые должны быть непересекающиеся. Этот факт в функции не проверяется. Порядок поверхности не изменяется. + \en Initialization of surface of the joint by set of curves, order of surface and knot vector.\n + Curves shouldn't be intersected. This fact isn't checked in the function. Surface order doesn't changed. \~ + \param[in] initCurves - \ru Список кривых, на которых натягивается поверхность. + \en List of of curves which the surface is tensed on. \~ + \param[in] initDegree - \ru Порядок поверхности по v. + \en Surface order by v. \~ + \param[in] initKnots - \ru Узловой вектор по v. + \en A knot vector by v. \~ + \param[in] sameCurves - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + */ + bool Init( const RPArray & initCurves, ptrdiff_t initDegree, const SArray & initKnots, bool sameCurves ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; // \ru Минимальное значение параметра u \en Minimal value of parameter u + virtual double GetVMin() const; // \ru Минимальное значение параметра v \en Minimal value of parameter v + virtual double GetUMax() const; // \ru Максимальное значение параметра u \en Maximal value of parameter u + virtual double GetVMax() const; // \ru Максимальное значение параметра v \en Maximal value of parameter v + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная \en The second derivative + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная \en Third derivative + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void _DeriveU ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага параметра u по по величине прогиба \en Calculation of parameter u step by the value of sag + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага параметра v по по величине прогиба \en Calculation of parameter v step by the value of sag + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага параметра u по заданной метрической длине \en Calculation of parameter u step by the given metric length + virtual size_t GetUCount() const; // \ru Количество разбиений по параметру u для проверки событий \en Count of splittings by parameter u to check for events + virtual size_t GetVCount() const; // \ru Количество разбиений по параметру v для проверки событий \en Count of splittings by parameter v to check for events + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual void Refresh (); ///< \ru Cбросить все временные данные. \en Reset all temporary data. + + virtual MbSplineSurface * NurbsSurface( double u1, double u2, double v1, double v2, bool bmatch = false ) const; + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность \en Create a shifted surface + + /// \ru Изменение степени NURBS кривой по v. \en Change degree of NURBS curve by v. + void ChangeDegree ( ptrdiff_t newDegree ); + /// \ru Получить количество базовых кривых. \en Get count of base curves. + size_t GetCurvesCount () const; + /// \ru Получить кривую с индeксом num. \en Get curve with 'num' index. + const MbCurve3D * GetCurve( size_t k ) const; + const SArray & GetKnots() const { return knots; } ///< \ru Получить значения узлов для сплайна по v. \en Get knot values for spline by v. + + /** \brief \ru Получить список начальных или конечных базовых точек кривых. + \en Get list of start or end base points of curves. \~ + \details \ru Получить список начальных или конечных базовых точек кривых.\n + \en Get list of start or end base points of curves.\n \~ + \param[in] isFirstPoints - \ru Определяет конечные или начальные точки запрошены: true - начальные, false - конечные.\n + \en Determines start or end points were requested: true - start, false - end.\n \~ + \param[in] points - \ru Список, в который помещаются найденные точки. \n + Порядок точек соответствует порядку кривых в списке curves. + \en List to store found points. \n + Order of points corresponds to order of curves in 'curves' list. \~ + \return \ru false и список points остается пустым,\n + если хотя бы одна кривая не имеет базовых точек (не отрезок и не кривая, заданная точками). + \en False then 'points' list remains empty,\n + if at least one curve has no base points (not segment and not curve given by points). \~ + */ + bool GetCurvesBasePoints( bool isFirstPoints, SArray & points ) const; + /** \brief \ru Изменить крайние базовые точки кривых. + \en Change end base points of curves. \~ + \details \ru Базовые точки можно изменить в том случае, если все кривые, на которые натянута поверхность,\n + являются отрезками или кривыми, заданными точками. + \en Base points can be changed in case of all curves which the surface is tensed on\n + are segments or curves given by points. \~ + \param[in] isFirstPoints - \ru Определяет конечные или начальные точки запрошены: true - начальные, false - конечные.\n + \en Determines start or end points were requested: true - start, false - end.\n \~ + \param[in] points - \ru Список, в который помещаются новые значения базовых точек.\n + Порядок точек соответствует порядку кривых в списке curves. + \en List to store new values of base points.\n + Order of points corresponds to order of curves in 'curves' list. \~ + \return \ru false и список points остается пустым,\n + если хотя бы одна кривая не имеет базовых точек (не отрезок и не кривая, заданная точками). + \en False then 'points' list remains empty,\n + if at least one curve has no base points (not segment and not curve given by points). \~ + */ + bool SetCurvesBasePoints( bool isFirstPoints, SArray & points ); + /** \} */ + + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbJoinSurface ) + +private: + void operator = ( const MbJoinSurface & ); // \ru Не реализовано. \en Not implemented. + + void ResetTCalc(); + bool CheckData ( const SArray & newKnots, ptrdiff_t newDegree ); // \ru Проверить корректность данных для NURBS \en Check correctness of data for NURBS + void ChangeKnots ( const ptrdiff_t newDegree, const bool closed, SArray & newKnots ); // \ru Изменить массив узлов, если изменилась степень сплайна \en Change array of knots if degree of spline was changed + void CreateTempVars( MbJoinSurfaceAuxiliaryData * ucache ) const; + void InitTempVars ( MbJoinSurfaceAuxiliaryData * ucache ) const; + void FreeTempVars ( MbJoinSurfaceAuxiliaryData * ucache ) const; + void PreparePointsData( ptrdiff_t lIndex, ptrdiff_t derNum, MbJoinSurfaceAuxiliaryData * ucache ) const; + void PreparePointList ( const double u, ptrdiff_t derNumberU, MbJoinSurfaceAuxiliaryData * ucache ) const; + void CheckPointData ( const MbeSurfaceDerivativeType derUVNumber, double & u, double & v, MbVector3D & vect, MbJoinSurfaceAuxiliaryData * ucache ) const; + ptrdiff_t GetUDerNumber( const MbeSurfaceDerivativeType derUVNumber ) const; + ptrdiff_t GetVDerNumber( const MbeSurfaceDerivativeType derUVNumber ) const; + void CheckPole(); + void CheckParams ( double & u, double & v ) const; + void PoleDerive ( double u, double v, MbVector3D & vDerU, MbVector3D & vDerV ) const; + double DeviationStep( double u, double v, double angle ) const; + double StepD ( double u, double v, double sag, bool checkAngle, double angle ) const; + // \ru Вычисление точки и производных поверхности. \en Calculation of the point and derivatives of the surface. \~ + void ExploreVector( SArray & points, SArray & vectors, + ptrdiff_t lIndex, ptrdiff_t derNum, MbVector3D & vect, MbJoinSurfaceAuxiliaryData * ucache ) const; + +}; + +IMPL_PERSISTENT_OPS( MbJoinSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры и в случае захода за полюс загнать в полюсную область \en Check parameters and if it is out of pole, then drive it to pole region +// --- +inline void MbJoinSurface::CheckParams( double & u, double & v ) const +{ + if ( isPoleUmin ) { + if ( u < umin ) + u = umin; + } + if ( isPoleUmax ) { + if ( u > umax ) + u = umax; + } + if ( isPoleVmin ) { + const double & vmin = knots[degree - 1]; + if ( v < vmin ) + v = vmin; + } + if ( isPoleVmax ) { + const double & vmax = knots[knots.MaxIndex() - degree + 1]; + if ( v > vmax ) + v = vmax; + } +} + + +#endif // __SURF_JOIN_SURFACE_H diff --git a/C3d/Include/surf_lofted_surface.h b/C3d/Include/surf_lofted_surface.h new file mode 100644 index 0000000..6060c09 --- /dev/null +++ b/C3d/Include/surf_lofted_surface.h @@ -0,0 +1,664 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность, проходящая через заданное семейство кривых. + \en Lofted surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_LOFTED_SURFACE_H +#define __SURF_LOFTED_SURFACE_H + +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceContiguousData; + +#define LOFT_NUMB 4 ///< \ru Вспомогательный параметр для поверхности MbLoftedSurface. Используется для определения количества элементов в массивах, где хранится точка и первые три производные в этой точке. \en Auxiliary parameter for MbLoftedSurface surface. Used for determination of count of elements in arrays of points and first three derivatives at this point. +const VERSION LOFTED_SURFACE_VERSION1 = 0x0F000013L; ///< \ru Корректировка коэффициентов уравнения поверхности. \en Correction of surface equation coefficients. +const VERSION LOFTED_SURFACE_VERSION2 = 0x13000015L; ///< \ru Возможность устанавливать нормали на торцевых сечениях в виде точки. \en Ability to set normals on end sections as a point. + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность, проходящая через заданное семейство кривых. + \en Lofted surface passing through given family of curves. \~ + \details \ru Поверхность, проходящая через заданное семейство кривых, построена аналогично сплайну Эрмита MbHermit3D, + проходящего через заданное семейство точек. + Первый параметр поверхности пропорционален параметрам кривых семейства. + Вдоль второго параметра поверхность изменяется по закону сплайна Эрмита MbHermit3D, точками которого служат точки кривых семейства. + Производные по второму параметру в точках кривых вычисляются как производные параболы, + построенной по трём точкам и значениям параметров в них. + На каждом участке между двумя соседними кривыми семейства поверхность описывается кубическим полиномом + с заданными точками и производными на краях. + Поверхность проходит через кривые семейства при значениях параметра из множества vParams. + \en The surface passing through given family of curves is constructed similar to MbHermit3D Hermite spline + passing through given family of points. + First parameter of surface is proportional to parameters of curves of family. + Along the second parameter the surface changes under the law of MbHermit3D Hermite spline, which points are points of curves of family. + Derivatives by second parameter at points of curves are calculated as derivatives of parabola + constructed by three points and values of parameters at this points. + On each region between two neighboring curves of family the surface is described by the cubic polynomial + with given points and derivatives at the edges. + Surface passes through curves of family for parameter values from vParams set. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbLoftedSurface : public MbSurface { +protected: + RPArray uCurves; ///< \ru Множество кривых семейства. \en Set of curves of family. + SArray vParams; ///< \ru Множество параметров v для кривых. \en Set of parameters v for curves. + SArray vLabels; ///< \ru Множество признаков одинаковых кривых. \en Set of attributes of similar curves. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + bool uclosed; ///< \ru Признак замкнутости по параметру u. \en Attribute of closedness by parameter u. + bool vclosed; ///< \ru Признак замкнутости по параметру v. \en Attribute of closedness by parameter v. + MbVector3D derive1; ///< \ru Направление производной в начале незамкнутой поверхности. Если не задано, то нулевой длины. \en The direction of derivative at the beginning of the open surface. If it isn't set, then its length is zero. + MbVector3D derive2; ///< \ru Направление производной в конце незамкнутой поверхности. Если не задано, то нулевой длины. \en The direction of derivative at the end of the open surface. If it isn't set, then its length is zero. + bool setNormal1; ///< \ru Установлена нормаль в начальном сечении. \en The normal is set in initial section. + bool setNormal2; ///< \ru Установлена нормаль в конечном сечении. \en The normal is set in end section. + VERSION surfaceVersion; ///< \ru Версия расчета коэффициентов уравнения поверхности. \en Version of coefficient calculation of surface equation. + +protected: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbLoftedSurfaceAuxiliaryData : public AuxiliaryData { + public: + DPtr data; ///< \ru Дополнительные данные о поверхности. \en Additional data about a surface. + MbLoftedSurfaceAuxiliaryData(); + MbLoftedSurfaceAuxiliaryData( const MbLoftedSurfaceAuxiliaryData & init ); + virtual ~MbLoftedSurfaceAuxiliaryData(); + }; + + mutable CacheManager cache; + +public: + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по массиву профильных кривых, направляющим векторам и замкнутости по v. + \en Constructor of surface by array of profile curves, guide vectors and closedness by v. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] vc - \ru Замкнутость поверхности по v. + \en Surface closedness by v. \~ + \param[in] v1 - \ru Направляющий вектор. + \en Guide vector. \~ + \param[in] v2 - \ru Направляющий вектор. + \en Guide vector. \~ + \param[in] same - \ru Определяет, надо ли копировать профильные кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy profile curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + */ + MbLoftedSurface( const RPArray & initCurves, + bool vc, const MbVector3D & v1, const MbVector3D & v2, bool same, + VERSION version = Math::DefaultMathVersion() ); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по массиву профильных кривых, массиву параметров, направляющим векторам и замкнутости по v. + \en Constructor of surface by array of profile curves, array of parameters, guide vectors and closedness by v. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] initParams - \ru Множество параметров, соответствующих задающим кривым. + \en Set of parameters corresponding to driving curves. \~ + \param[in] vc - \ru Замкнутость поверхности по v. + \en Surface closedness by v. \~ + \param[in] v1 - \ru Направляющий вектор. + \en Guide vector. \~ + \param[in] v2 - \ru Направляющий вектор. + \en Guide vector. \~ + \param[in] same - \ru Определяет, надо ли копировать профильные кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy profile curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + */ + MbLoftedSurface( const RPArray & initCurves, const SArray & initParams, + bool vc, const MbVector3D & v1, const MbVector3D & v2, bool setNormal1, bool setNormal2, bool same, + VERSION version = Math::DefaultMathVersion() ); +protected: // \ru Конструкторы для наследников \en Constructors for inheritors + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по набору профильных кривых. + \en Constructor of surface by family of profile curves. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] same - \ru Определяет, надо ли копировать профильные кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy profile curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + */ + MbLoftedSurface( const RPArray & initCurves, bool same, VERSION version = Math::DefaultMathVersion() ); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по массиву профильных кривых и массиву параметров. + \en Constructor of surface by array of profile curves and array of parameters. \~ + \param[in] initParams - \ru Множество параметров, соответствующих задающим кривым. + \en Set of parameters corresponding to driving curves. \~ + \param[in] initCurves - \ru Множество задающих кривых. + \en Set of driving curves. \~ + \param[in] same - \ru Определяет, надо ли копировать профильные кривые: true - использовать полученные кривые без копирования, false - использовать копии. + \en Determines whether to copy profile curves: true - use obtained curves without copying, false - use copies. \~ + \param[in] version - \ru Версия, по умолчанию - последняя. + \en Version, last by default. \~ + */ + MbLoftedSurface( const SArray & initParams, const RPArray & initCurves, bool same, VERSION version = Math::DefaultMathVersion() ); + /// \ru Конструктор-копия. \en Copy constructor. + MbLoftedSurface( const MbLoftedSurface &, MbRegDuplicate * reg ); +private: + MbLoftedSurface( const MbLoftedSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbLoftedSurface(); + +public: + VISITING_CLASS( MbLoftedSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbeSpaceType Type() const; // \ru Тип элемента \en A type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента \en Create a copy of the element + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты \en Whether the objects are equal + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void Refresh(); + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & s ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin () const; // \ru Вернуть минимальное значение параметра u \en Return the minimum value of parameter u + virtual double GetVMin () const; // \ru Вернуть минимальное значение параметра v \en Return the minimum value of parameter v + virtual double GetUMax () const; // \ru Вернуть максимальное значение параметра u \en Return the maximum value of parameter u + virtual double GetVMax () const; // \ru Вернуть максимальное значение параметра v \en Return the maximum value of parameter v + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether the surface is closed by parameter u. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether the surface is closed by parameter v. + virtual double GetUPeriod() const; // \ru Период для замкнутой поверхности или 0. \en Period for closed surface or 0. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + // \ru Существует ли полюс на границе параметрической области \en Whether there is pole on boundary of parametric region + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по u \en Third derivative with respect to u + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по v \en Third derivative with respect to v + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности \en Point on the extended surface + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная по u \en Third derivative with respect to u + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная по v \en Third derivative with respect to v + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uv \en Third derivative with respect to uv + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны \en Calculation of step of approximation with consideration of curvature radius + virtual double DeviationStepU( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей \en Calculation of step by u while intersecting surfaces + virtual double DeviationStepV( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей \en Calculation of step by u while intersecting surfaces + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской \en Whether the surface is planar + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + virtual void CalculateGabarit( MbCube & ) const; // \ru Рассчитать габарит поверхности \en Calculate bounding box of surface + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей \en Construct tangent and normal placements of constructive planes + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D & axis ) const; // \ru Дать ось вращения для поверхности \en Get a rotation axis of a surface + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности \en NURBS copy of a surface + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность \en Create a shifted surface + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const \en Spatial copy of 'v = const'-line + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const \en Spatial copy of 'u = const'-line + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the count of polygons by u + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the count of polygons by v + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями \en Determine splitting of parametric region of surface by vertical and horizontal lines + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + // \ru Найти ближайшую проекцию точки на поверхность или ее продолжение по заданному начальному приближению. \en Find the neares projection of a point onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & pnt, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю \en If true, then all the derivatives by U higher the first one are equal to zero + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю \en If true, then all the derivatives by V higher the first one are equal to zero + + // \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + // Аналог глобальной функции _CheckParams, оптимизированный под использование кэшей. + // \en Check parameters and move them inside domain if parameter is out of pole. + // \en Check parameters. Analogue of the global function _CheckParams, optimized for caches usage. + // \param[in] surface - \ru Поверхность. \en Surface. + // \param[in] u - \ru Первый параметр. \en First parameter. + // \param[in] v - \ru Второй параметр. \en Second parameter. + virtual void CheckSurfParams( double & u, double & v ) const; + + /// \ru Получить количество кривых, на которых построена поверхность \en Get count of curves which the surface is constructed by + ptrdiff_t CurvesCount() const { return (ptrdiff_t)uCurves.Count(); } + + /** \brief \ru Получить кривую по номеру. + \en Get curve by an index. \~ + \details \ru Получить кривую по номеру. \n + \en Get curve by an index. \n \~ + \param[in] ind - \ru Порядковый номер кривой в массиве кривых uCurves. + \en Index of curve in uCurves array of curves. \~ + \return \ru Константная кривая. + \en The constant curve. \~ + */ + const MbCurve3D * GetCurve( ptrdiff_t ind ) const { return (ind >= 0 && ind < (ptrdiff_t)uCurves.Count()) ? uCurves[ind] : NULL; } + /** \brief \ru Получить кривую для редактирования по номеру. + \en Get curve for editing by an index. \~ + \details \ru Получить кривую для редактирования по номеру. \n + \en Get curve for editing by an index. \n \~ + \param[in] ind - \ru Порядковый номер кривой в массиве кривых uCurves. + \en Index of curve in uCurves array of curves. \~ + \return \ru Кривая. + \en A curve. \~ + */ + MbCurve3D * SetCurve( ptrdiff_t ind ) { return (ind >= 0 && ind < (ptrdiff_t)uCurves.Count()) ? uCurves[ind] : NULL; } + /** \brief \ru Получить параметр по номеру. + \en Get parameter by an index. \~ + \details \ru Получить параметр по номеру.\n + \en Get parameter by an index.\n \~ + \param[in] ind - \ru Порядковый номер параметра в массиве параметров vParams. + \en Index of parameter in vParams array of parameters. \~ + \return \ru Значение параметра. + \en A parameter value. \~ + */ + double GetParam( ptrdiff_t ind ) const { return (ind >= 0 && ind < (ptrdiff_t)vParams.Count()) ? vParams[ind] : 0.0; } + /** \brief \ru Заполнить массив параметрами. + \en Fill an array by parameters. \~ + \details \ru Заполнить массив параметрами. \n + \en Fill an array by parameters. \n \~ + \param[in,out] params - \ru Множество для заполнения параметрами. + \en A set to fill by parameters. \~ + */ + void GetParams( SArray & params ) const { params = vParams; } + /** \brief \ru Заполнить массив признаков одинаковых кривых. + \en Fill array of attributes of similar curves. \~ + \details \ru Заполнить массив признаков одинаковых кривых. \n + \en Fill array of attributes of similar curves. \n \~ + \param[in,out] labels - \ru Множество для заполнения. + \en A set to fill. \~ + */ + void GetLabels( SArray & labels ) const { labels = vLabels; } + + /// \ru Направление производной в начале незамкнутой поверхности. Если не задано, то нулевой длины. \en The direction of derivative at the beginning of the open surface. If it isn't set, then its length is zero. + const MbVector3D & GetDerive1() const { return derive1; } + ///< \ru Направление производной в конце незамкнутой поверхности. Если не задано, то нулевой длины. \en The direction of derivative at the end of the open surface. If it isn't set, then its length is zero. + const MbVector3D & GetDerive2() const { return derive2; } + + bool IsEqualLabels() const; ///< \ru Определить, есть ли одинаковые кривые. \en Determine whether there are similar curves. + /** \brief \ru Определить, есть ли кривые, одинаковые с кривой под номером ind. + \en Determine whether there are curves similar to curve with 'ind' index. \~ + \details \ru Определить, есть ли кривые, одинаковые с кривой под номером ind. \n + \en Determine whether there are curves similar to curve with 'ind' index. \n \~ + \param[in] ind - \ru Номер кривой для сравнения. + \en An index of curve for comparison. \~ + \return \ru true - Если в массиве есть кривые, одинаковые с кривой под номером ind. + \en True - If there are curves similar to curve with 'ind' index in array. \~ + */ + bool IsEqualLabels( ptrdiff_t ind ) const; + + + /** \brief \ru Определить, можно ли создать эквидистантную поверхность. + \en Determine whether it is possible to create an offset surface. \~ + \details \ru Определить, можно ли создать эквидистантную поверхность.\n + \en Determine whether it is possible to create an offset surface.\n \~ + \param[in] h - \ru Величина смещения. + \en The offset distance. \~ + \param[in] uLimBeg - \ru Нижняя граница по u области, к которой надо построить эквидистантную поверхность. + \en Lower bound of region by u which offset surface is necessary to construct to. \~ + \param[in] uLimEnd - \ru Верхняя граница по u области, к которой надо построить эквидистантную поверхность. + \en Upper bound of region by u which offset surface is necessary to construct to. \~ + \param[in] vLimBeg - \ru Нижняя граница по v области, к которой надо построить эквидистантную поверхность. + \en Lower bound of region by v which offset surface is necessary to construct to. \~ + \param[in] vLimEnd - \ru Верхняя граница по v области, к которой надо построить эквидистантную поверхность. + \en Upper bound of region by v which offset surface is necessary to construct to. \~ + \return \ru true - Если в можно создать эквидистантную поверхность. + \en True - If it is possible to create an offset surface. \~ + */ + bool IsPossibleCreateThin( double h, + double uLimBeg, double uLimEnd, + double vLimBeg, double vLimEnd ) const; + /** \brief \ru Согласовать массивы признаков одинаковости кривых у смежных поверхностей. + \en Match arrays of attributes of similarity of curves between adjacent surfaces. \~ + \details \ru Согласовать массивы признаков одинаковости кривых у смежных поверхностей. \n + \en Match arrays of attributes of similarity of curves between adjacent surfaces. \n \~ + \param[in] surf - \ru Смежная поверхность. + \en Adjacent surface. \~ + \return \ru true - Если есть изменения в массиве признаков кривых хотя бы одной поверхности. + \en True - If there are changes in array of attributes of curves of at least one surface. \~ + */ + bool AgreeLabels( MbLoftedSurface & surf ); + /** \} */ + +protected: + void CheckParam( double & u, bool ext ) const; // \ru Корректировка параметров. \en Correct parameters. \~ + /** \brief \ru Определение местных координат области поверхности. + \en Determination of local coordinates of a surface region. \~ + \details \ru Определение местных координат области поверхности. \n + \en Determination of local coordinates of a surface region. \n \~ + \param[in] v - \ru Координата v на поверхности. + \en V coordinate on the surface. \~ + \param[in,out] j1 - \ru Номер ближайшей кривой с параметром, меньшим v. + \en Index of nearest curve with parameter less than v. \~ + \param[in,out] j2 - \ru Номер ближайшей кривой с параметром, большим v. + \en Index of nearest curve with parameter greater than v. \~ + \param[in,out] y1 - \ru Параметрическое расстояние от точки с координатой v до кривой j1, при условии, что расстояние между кривыми j1 и j2 равно 1. + \en Parametric distance from point with v coordinate to j1 curve provided that distance between j1 and j2 curves is equal to 1. \~ + \param[in,out] y2 - \ru Параметрическое расстояние от точки с координатой v до кривой j2, при условии, что расстояние между кривыми j1 и j2 равно 1. + \en Parametric distance from point with v coordinate to j2 curve provided that distance between j1 and j2 curves is equal to 1. \~ + \param[in,out] t1 - \ru Значение параметра для кривой j1. + \en Value of parameter for j1 curve. \~ + \param[in,out] t2 - \ru Значение параметра для кривой j2. + \en Value of parameter for j2 curve. \~ + */ + void LocalCoordinate( double & v, ptrdiff_t & j1, ptrdiff_t & j2, double & y1, double & y2, double & t1, double & t2 ) const; + /** \brief \ru Определение массива векторов кривой. + \en Determination of the array of curve vectors. \~ + \details \ru Определение массива векторов кривой. \n + \en Determination of the array of curve vectors. \n \~ + \param[in] i - \ru Номер кривой. + \en Index of curve. \~ + \param[in] u - \ru Координата u на поверхности. + \en U coordinate on the surface. \~ + \param[in] der - \ru Ссылка на массив векторов для хранения вычисленной точки и производных. + \en Reference to array of vectors to store calculated point and derivatives. \~ + \param[in] ext - \ru Можно ли продолжить кривую за границы области определения ее параметра. + \en Whether it is possible to extend curve out of its parametric domain bounds. \~ + */ + void CalculateCurve( ptrdiff_t i, double u, MbVector3D & point, bool ext, size_t numb ) const; + void CalculateCurve( ptrdiff_t i, double u, MbVector3D & pnt, MbVector3D & fir, MbVector3D * sec, bool ext ) const; + /** \brief \ru Определение массива векторов параметрa u для точки на поверхности с координатами (u, v). + \en Determination of array of vectors of u parameter for point on surface with coordinates (u, v). \~ + \details \ru Определение массива векторов параметрa u для точки на поверхности с координатами (u, v). \n + \en Determination of array of vectors of u parameter for point on surface with coordinates (u, v). \n \~ + \param[in] u - \ru Координата u на поверхности. + \en U coordinate on the surface. \~ + \param[in] j1 - \ru Номер ближайшей кривой с параметром, меньшим v. + \en Index of nearest curve with parameter less than v. \~ + \param[in] j2 - \ru Номер ближайшей кривой с параметром, большим v. + \en Index of nearest curve with parameter greater than v. \~ + \param[in] t1 - \ru Значение параметра для кривой j1. + \en Value of parameter for j1 curve. \~ + \param[in] t2 - \ru Значение параметра для кривой j2. + \en Value of parameter for j2 curve. \~ + \param[in] ext - \ru Можно ли продолжить поверхность за границы области определения ее параметров. + \en Whether it is possible to extend surface out of its parametric domain bounds. \~ + */ + void CalculateSurface( double & u, ptrdiff_t j1, ptrdiff_t j2, + double t1, double t2, bool ext, size_t numb, + MbVector3D & point1, MbVector3D & point2, + MbVector3D & vector1, MbVector3D & vector2, bool correctVectors = true ) const; + void CalculateExplore( double & u, ptrdiff_t j1, ptrdiff_t j2, + double t1, double t2, bool ext, bool boolsecond, + MbVector3D * point1, MbVector3D * point2, + MbVector3D * vector1, MbVector3D * vector2, + double * tLoft ) const; + + void ParamPoint ( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamFirst ( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamSecond( double y1, double y2, double t1, double t2, double * tLoft ) const; + void ParamThird ( double t1, double t2, double * tLoft ) const; + + /** \brief \ru Проверка полюсов на кривых. + \en Check poles on curves. \~ + \details \ru Определяет, есть ли полюс на границе области определения по длине кривой, определяющей границу.\n + Результат вычислений можно получить с помощью функций GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax. + \en Determines whether the pole at domain boundary by curve length determining boundary.\n + Result of calculations can be obtained with help of GetPoleUMin, GetPoleUMax, GetPoleVMin, GetPoleVMax functions. \~ + */ + bool CheckPoles( MbLoftedSurfaceAuxiliaryData * ) const; // \ru Проверка полюсов на кривых \en Check poles on curves + +private: + void Init( bool close ); + bool IsSimilarCurves( ptrdiff_t i1, ptrdiff_t i2 ) const; // \ru Определение одинаковых кривых \en Determination of similar curves + bool IsSimilarLabels( ptrdiff_t i1, ptrdiff_t i2 ) const; // \ru Определение одинаковых кривых по меткам. \en Determination of similar curves by labels. + void InitLabels(); // \ru Инициализация признаков одинаковых кривых. \en Initialization of attributes of similar curves. + + MbVector3D DirByGivenNormal( bool isStart, const MbVector3D & point1, const MbVector3D & point2 ) const; // \ru Определить вектор направления с заданной нормалью. \en Determine the direction vector with a given normal. + + void operator = ( const MbLoftedSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLoftedSurface ) +}; + +IMPL_PERSISTENT_OPS( MbLoftedSurface ) + +//------------------------------------------------------------------------------ +// \ru Корректировка параметров. \en Correct parameters. \~ +// --- +inline void MbLoftedSurface::CheckParam( double & u, bool ext ) const +{ + if ( !ext ) { + if ( uclosed ) { // переписана на ::floor(), т.к. подвисала на while + if ( (u < umin) || (u > umax) ) { + double pRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / pRgn) * pRgn ); + } + } + else if ( u < umin ) { + u = umin; + } + else if ( u > umax ) { + u = umax; + } + } + else { + if ( u < umin && GetPoleUMin() ) { + u = umin; + } + else if ( u > umax && GetPoleUMax() ) { + u = umax; + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Определение местных координат области поверхности \en Determination of local coordinates in a surface region +// --- +inline void MbLoftedSurface::LocalCoordinate( double & v, ptrdiff_t & j1, ptrdiff_t & j2, + double & y1, double & y2, + double & t1, double & t2 ) const +{ + if ( v < vmin || v > vmax ) { // \ru Параметр вне границ \en Parameter is out of bounds + if ( vclosed ) { + double tmp = vmax - vmin; + v -= ::floor((v - vmin) / tmp) * tmp; + } + else { + if ( v < vmin ) + v = vmin; + else + v = vmax; + } + } + + j1 = 0; + j2 = vParams.MaxIndex(); + + ptrdiff_t ind, delta = j2; // \ru Диапазон \en A range + + // \ru Поиск половинным делением \en Search by bisection + while ( delta > 1 ) { + ind = j1 + ( delta / (ptrdiff_t)2 ); // \ru Индекс в середине \en The index in the middle + if ( v < vParams[ind] ) // \ru Если v меньше серединного параметра \en If v is less than the middle parameter + j2 = ind; // \ru Изменить правую границу \en Change the right bound + else + j1 = ind; // \ru Изменить левую границу \en Change the left bound + delta = j2 - j1; // \ru Диапазон \en A range + } + + t1 = vParams[j1]; + t2 = vParams[j2]; + double dt = t2 - t1; + double antiDt = 1.0; + if ( dt > NULL_EPSILON ) + antiDt /= dt; + y1 = (t2 - v) * antiDt; + y2 = (v - t1) * antiDt; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa точки \en Determination of array of degrees of point parameter +// --- +inline void MbLoftedSurface::ParamPoint( double y1, double y2, double t1, double t2, double * tLoft ) const +{ + double y1pow2 = y1 * y1; + double y2pow2 = y2 * y2; + double y1pow3 = y1pow2 * y1; + double y2pow3 = y2pow2 * y2; + tLoft[0] = 3.0 * y1pow2 - 2.0 * y1pow3; + tLoft[1] = 3.0 * y2pow2 - 2.0 * y2pow3; + tLoft[2] = (y1pow3 - y1pow2) * (t1-t2); + tLoft[3] = (y2pow3 - y2pow2) * (t2-t1); +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa производной \en Determination of array of degrees of derivative parameter +// --- +inline void MbLoftedSurface::ParamFirst( double y1, double y2, double t1, double t2, double * tLoft ) const +{ + double y1pow2 = y1 * y1; + double y2pow2 = y2 * y2; + double kdt1 = 1.0 / (t1 - t2); + double kdt2 = -kdt1; + tLoft[0] = 6.0 * (y1 - y1pow2) * kdt1; + tLoft[1] = 6.0 * (y2 - y2pow2) * kdt2; + tLoft[2] = (3.0 * y1pow2 - 2.0 * y1); + tLoft[3] = (3.0 * y2pow2 - 2.0 * y2); +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa второй производной \en Determination of array of degrees of second derivative parameter +// --- +inline void MbLoftedSurface::ParamSecond( double y1, double y2, double t1, double t2, double * tLoft ) const { + double d1 = 1 / (t1-t2); + double d2 = -d1; + tLoft[0] = (6 - 12 * y1) * d1 * d1; + tLoft[1] = (6 - 12 * y2) * d2 * d2; + tLoft[2] = (6 * y1 - 2) * d1; + tLoft[3] = (6 * y2 - 2) * d2; +} + + +//------------------------------------------------------------------------------ +// \ru Определение массива степеней параметрa третьей производной \en Determination of array of degrees of third derivative parameter +// --- +inline void MbLoftedSurface::ParamThird( double t1, double t2, double * tLoft ) const { + double d1 = 1 / (t1-t2); + double d2 = -d1; + double d1pow2 = d1 * d1; + double d2pow2 = d2 * d2; + tLoft[0] = -12 * d1pow2 * d1; + tLoft[1] = -12 * d2pow2 * d2; + tLoft[2] = 6 * d1pow2; + tLoft[3] = 6 * d2pow2; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Наполнить массив v-параметров и весовых центров заданных кривых. + \en Fill array of v-parameters and weight centers of given curves. \~ + \details \ru Если все профильные кривые плоские, параметры вычисляются функцией CreateElevationParam. + Иначе параметр для каждой кривой вычисляется как координата вдоль направляющей проекции центра масс кривой на направляющую. + \en If all the profile curves are planar, then parameters are calculated by CreateElevationParam function. + Otherwise parameter for each curve is calculated as coordinate along guide projection of center of mass of curve to guide. \~ + \param[in] uCurves - \ru Множество профильных кривых. + \en Set of profile curves. \~ + \param[in] vcls - \ru Замкнута ли поверхность по параметру v. + \en Whether the surface is closed by parameter v. \~ + \param[in,out] vParams - \ru Множество параметров. + \en Set of parameters. \~ + \param[in,out] tiePnts - \ru Множество центров масс профильных кривых. Не заполняется, если в функцию передать NULL. + \en Set of centers of mass of profile curves. If giving NULL to function, then it isn't filled. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \return \ru true - если массив параметров успешно создан. + \en True - if the array of parameters successfully created. \~ + \ingroup Algorithms_3D +*/ +// --- +bool CreateLoftedParams( const RPArray & uCurves, + bool vcls, + SArray & vParams, + SArray * tiePnts, + VERSION version ); + + +#endif // __SURF_LOFTED_SURFACE_H diff --git a/C3d/Include/surf_mesh_surface.h b/C3d/Include/surf_mesh_surface.h new file mode 100644 index 0000000..ff22843 --- /dev/null +++ b/C3d/Include/surf_mesh_surface.h @@ -0,0 +1,705 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность на двух семействах кривых (на сетке кривых). + \en The surface passing through two families of curves. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_MESH_SURFACE_H +#define __SURF_MESH_SURFACE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbFunction; +class MATH_CLASS MbSurfaceContiguousData; +class MbPatchWorkingData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Версия реализации поверхности на сетке кривых. + \en Version of implementation of surface constructed by the grid curves. \~ + \details \ru Версия реализации поверхности на сетке кривых. \n + \en Version of implementation of surface constructed by the grid curves. \n \~ + \ingroup Surfaces +*/ +// --- +enum MbeMeshSurfaceVersion { + msv_Ver0 = 0, ///< \ru Первая версия. \en The first version. + msv_Ver1, ///< \ru Вторая версия. \en The second version. + msv_Ver2, ///< \ru Третья версия. \en The third version. + msv_Ver3, ///< \ru Четвертая версия. \en The fourth version. + msv_Count ///< \ru Количество версий. \en Count of versions. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность на сетке кривых. + \en The surface constructed by the grid curves. \~ + \details \ru Поверхность, проходящая через два семейства кривых. + Первое семейство определяет форму поверхности при изменении первого параметра и неподвижном втором параметре, + Второе семейство определяет форму поверхности при изменении второго параметра и неподвижном первом параметре. + Каждая кривая первого семейства должна пересекаться или иметь точки скрещивания с каждой кривой второго семейства. + \en The surface passing through two families of curves. + The first family determines a surface form at change of the first parameter and fixed second parameter. + The second family determines a surface form at change of the second parameter and fixed first parameter. + Each curve of first family has to be intersected or has intersection points with each curve of the second family. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbMeshSurface : public MbSurface { + +// t2min curve2 t2max +// P3______________________P2 +// t3max | | t1max +// | | +// | | +// curve3 | R | curve1 +// | | +// | | +// t3min |______________________|t1min +// P0 P1 +// t0min curve0 t0max +// \ru Состыкованные между собой поверхности Кунса \en Coons surfaces joined among themselves +// \ru В пределах одного патча выражается как булева сумма двух Loft -ов \en Within one patch it is expressed as the Boolean sum of two Lofts +// R(u,v) = P(u,v) + P(v,u) - P(u,v)P(v,u) +// \ru где \en Where +// H1(w) = 2*w*w*w - 3*w*w + 1 +// H2(w) = w*w*w - 2*w*w + w +// H3(w) = -2*w*w*w + 3*w*w +// H4(w) = w*w*w - w*w +// \ru P(u,v) = curve0(t0) * (H1(v)) + - Эрмитова кубическая интерполяция \en P(u,v) = curve0(t0) * (H1(v)) + - cubic Hermite interpolation +// \ru d(curve0(t0))/dv * (H2(v)) + - аппроксимация выводящей производной с кривой \en D(curve0(t0))/dv * (H2(v)) + - approximation of leading out derivative from curve +// curve2(t2) * (H3(v)) + +// d(curve2(t2))/dv * (H4(v)) +// P(v,u) = curve3(t3) * (H1(u)) + +// d(curve3(t3))/du * (H2(u)) + +// curve1(t1) * (H3(u)) + +// d(curve1(t1))/du * (H3(u)) +// P(u,v)P(v,u) = +// |R(0,0) d(R(0,0))/(dv) R(0,1) d(R(0,1))/(dv) | |H1(v)| +// [H1(u) H2(u) H3(u) H4(u)] x |d(R(0,0))/(du) d2(R(0,0))/(dudv) d(R(0,1))/(du) d2(R(0,1))/(dudv)| |H2(v)| +// |R(1,0) d(R(1,0))/(dv) R(1,1) d(R(1,1))/(dv) | x |H3(v)| +// |d(R(1,0))/(du) d2(R(1,0))/(dudv) d(R(1,1))/(du) d2(R(1,1))/(dudv)| |H4(v)| +// R(I,J) === curveI(tI(J)) +private: + size_t nu; ///< \ru Количество кривых вдоль первого параметра u. \en Count of curves along first parameter u. + size_t nv; ///< \ru Количество кривых вдоль второго параметра v. \en Count of curves along second parameter v. + RPArray uCurves; ///< \ru Множество кривых первого семейства, которые направлены вдоль параметра u. \en Set of curves of first family which are directed along parameter u. + RPArray vCurves; ///< \ru Множество кривых второго семейства, которые направлены вдоль параметра v. \en Set of curves of second family which are directed along parameter v. + RPArray tuParams; ///< \ru Множество функций перехода к параметрам первого семейства. \en Set of transformations to parameters of first set. + RPArray tvParams; ///< \ru Множество функций перехода к параметрам второго семейства. \en Set of transformations to parameters of second set. + SArray uParams; ///< \ru Множество параметров u для задающих кривых. \en Set of parameters u for driving curves. + SArray vParams; ///< \ru Множество параметров v для задающих кривых. \en Set of parameters v for driving curves. + + SArray tuCurve; ///< \ru Множество параметров uCurves[i] точек пересечения кривых. \en Set of parameters of uCurves[i] intersection points of curves. + SArray tvCurve; ///< \ru Множество параметров vCurves[j] точек пересечения кривых. \en Set of parameters of vCurves[j] intersection points of curves. + + SArray points; ///< \ru Множество узловых точек поверхности. \en The surface nodes set. + SArray uFirstDers; ///< \ru Множество первых производных поверхности в направлении u в узлах. \en Set of first derivatives by u at the surface nodes. + // \ru Множество первых производных uCurves[i] точек пересечения кривых для версий ранее msv_Ver2. \en Set of first derivatives of uCurves[i] intersection points of curves for versions less than msv_Ver2. + SArray vFirstDers; ///< \ru Множество первых производных поверхности в направлении v в узлах. \en Set of first derivatives by v at the surface nodes. + // \ru Множество первых производных vCurves[j] точек пересечения кривых для версий ранее msv_Ver2. \en Set of first derivatives of vCurves[j] intersection points of curves for versions less than msv_Ver2. + SArray uSecondDers; ///< \ru Множество вторых производных поверхности в направлении u в узлах. \en Set of second derivatives by u at the surface nodes. + // \ru Множество вторых производных uCurves[i] точек пересечения кривых для версий ранее msv_Ver2. \en Set of second derivatives of uCurves[i] intersection points of curves for versions less than msv_Ver2. + SArray vSecondDers; ///< \ru Множество вторых производных поверхности в направлении v в узлах. \en Set of second derivatives by v at the surface nodes. + // \ru Множество вторых производных vCurves[j] точек пересечения кривых для версий ранее msv_Ver2. \en Set of second derivatives of vCurves[j] intersection points of curves for versions less than msv_Ver2. + + SArray twists; ///< \ru Множество смешанных производных (сначала по v, потом по u) в узлах сетки. \en Set of mixed derivatives (at first by u, then by v) at grid nodes. + // \ru Последовательность точек пересечения кривых: \en Sequence of intersection points of curves: + // \ru uCurves[0] и vCurves[0], uCurves[0] и vCurves[1], ... \en UCurves[0] and vCurves[0], uCurves[0] and vCurves[1], ... + // \ru uCurves[1] и vCurves[0], uCurves[1] и vCurves[1], ... \en UCurves[1] and vCurves[0], uCurves[1] and vCurves[1], ... + SArray cornerTwists; ///< \ru Множество смешанных производных (сначала по u, потом по v) в угловых узлах сетки. \en Set of mixed derivatives (at first by v, then by u) at corner grid nodes. + SArray cornerRegular;///< \ru Регулярность в углах поверхности. \en Regularity in the surface corners. + // 3 x-------x 2 + // | | + // | | + // 0 x-------x 1 + + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + bool uclosed; ///< \ru Признак замкнутости по параметру u. \en Attribute of closedness by parameter u. + bool vclosed; ///< \ru Признак замкнутости по параметру v. \en Attribute of closedness by parameter v. + // \ru Сопряжение на границе определяет способ вычисления выводящих производных в прилегающих ячейках. \en Conjugation on boundary determines a way of calculation of leading out derivatives at adjacent cells. + uint type0; ///< \ru Вид сопряжения заданный на curvesU[0]. \en Type of conjugation given on curvesU[0]. + uint type1; ///< \ru Вид сопряжения заданный на curvesV[0]. \en Type of conjugation given on curvesV[0]. + uint type2; ///< \ru Вид сопряжения, заданный на curvesU[nu-1]. \en Type of conjugation given on curvesU[nu-1]. + uint type3; ///< \ru Вид сопряжения, заданный на curvesV[nv-1]. \en Type of conjugation given on curvesV[nv-1]. + + MbeMeshSurfaceVersion version; ///< \ru Версия реализации определяет форму поверхности. \en Version of implementation determines a shape of surface. + +private: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbMeshSurfaceAuxiliaryData : public AuxiliaryData { + public: + DPtr data; ///< \ru Дополнительные данные о поверхности. \en Additional data about a surface. + DPtr mp; ///< \ru Дополнительные временные данные для ускорения вычислений. \en Additional temporary data to speed up computations. + MbMeshSurfaceAuxiliaryData(); + MbMeshSurfaceAuxiliaryData( const MbMeshSurfaceAuxiliaryData & init ); + virtual ~MbMeshSurfaceAuxiliaryData(); + }; + mutable CacheManager cache; + +public: + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по двум семействам кривых. Каждая кривая семейства U должна пересекаться или + иметь точки скрещивания с каждой кривой семейства V. + \en Constructor of surface by two families of curves. Each curve of family U has to be intersected or + has intersection points with each curve of family V. \~ + \param[in] initU - \ru Множество кривых в направлении параметра u. + \en Set of curves at direction of parameter u. \~ + \param[in] initV - \ru Множество кривых в направлении параметра v. + \en Set of curves at direction of parameter v. \~ + \param[in] uClosed - \ru Замкнута ли поверхность по параметру u. + \en Whether the surface is closed by parameter u. \~ + \param[in] vClosed - \ru Замкнута ли поверхность по параметру v. + \en Whether the surface is closed by parameter v. \~ + \param[in] same - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + \param[in] types - \ru Ссылка на массив с типами сопряжений на границах. + \en Reference to array with types of conjugations at boundaries. \~ + \param[in] vers - \ru Версия реализации поверхности. + \en Version of surface implementation. \~ + */ + MbMeshSurface( RPArray & initU, RPArray & initV, + bool uClosed, bool vClosed, + bool same, const SArray * types = NULL, + MbeMeshSurfaceVersion vers = msv_Ver1 ); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по двум семействам кривых. Каждая кривая семейства U должна пересекаться или + иметь точки скрещивания с каждой кривой семейства V. + \en Constructor of surface by two families of curves. Each curve of family U has to be intersected or + has intersection points with each curve of family V. \~ + \param[in] initU - \ru Множество кривых в направлении параметра u. + \en Set of curves at direction of parameter u. \~ + \param[in] initV - \ru Множество кривых в направлении параметра v. + \en Set of curves at direction of parameter v. \~ + \param[in] parsU - \ru Множество параметров u для задающих кривых. + \en Set of parameters u for driving curves. \~ + \param[in] parsV - \ru Множество параметров v для задающих кривых. + \en Set of parameters v for driving curves. \~ + \param[in] uClosed - \ru Замкнута ли поверхность по параметру u. + \en Whether the surface is closed by parameter u. \~ + \param[in] vClosed - \ru Замкнута ли поверхность по параметру v. + \en Whether the surface is closed by parameter v. \~ + \param[in] same - \ru Определяет, надо ли делать копии кривых:\n + true - использовать в объекте пришедшие в конструктор кривые не дублируя,\n + false - использовать копии кривых. + \en Determines whether to copy curves:\n + true - use curves given in the constructor in object without copying,\n + false - use copies of curves. \~ + \param[in] types - \ru Ссылка на массив с типами сопряжений на границах. + \en Reference to array with types of conjugations at boundaries. \~ + \param[in] vers - \ru Версия реализации поверхности. + \en Version of surface implementation. \~ + */ + MbMeshSurface( RPArray & initU, RPArray & initV, + SArray & parsU, SArray & parsV, + bool uClosed, bool vClosed, + bool same, const SArray * types = NULL, + MbeMeshSurfaceVersion vers = msv_Ver1 ); +protected: + /// \ru Конструктор-копия. \en Copy constructor. + MbMeshSurface( const MbMeshSurface &, MbRegDuplicate * ); +public: + virtual ~MbMeshSurface(); + +public: + VISITING_CLASS( MbMeshSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента \en A type of element + virtual MbeSpaceType Type() const; // \ru Групповой тип элемента. \en Group element type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента \en Make a copy of element + virtual bool IsSame( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual( const MbSpaceItem & init ); // \ru Сделать равным \en Make equal + virtual bool IsSimilar( const MbSpaceItem & init ) const; // \ru Являются ли объекты подобными \en Whether the objects are similar + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move( const MbVector3D &to, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate( const MbAxis3D &axis, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate around an axis + virtual void Refresh(); // \ru Сбросить все временные данные \en Flush all the temporary data + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты \en Get the base objects + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + + virtual bool IsUClosed() const; // \ru Замкнута ли гладко поверхность по параметру u без учета граничного контура. \en Whether the surface is smoothly closed by parameter u without regard to the boundary contour. + virtual bool IsVClosed() const; // \ru Замкнута ли гладко поверхность по параметру v без учета граничного контура. \en Whether the surface is smoothly closed by parameter v without regard to the boundary contour. + virtual bool IsUTouch() const; // \ru Замкнута ли фактически поверхность по параметру u независимо от гладкости. \en Whether the surface is actually closed by parameter u regardless of the smoothness. + virtual bool IsVTouch() const; // \ru Замкнута ли фактически поверхность по параметру v независимо от гладкости. \en Whether the surface is actually closed by parameter v regardless of the smoothness. + virtual bool IsUPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру u. \en Whether the surface is smoothly closed by parameter u. + virtual bool IsVPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру v. \en Whether the surface is smoothly closed by parameter v. + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой поверхности или 0. \en Return period for closed surface or 0. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой поверхности или 0. \en Return period for closed surface or 0. + + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + // \ru Существует ли полюс на границе параметрической области \en Whether there is pole on boundary of parametric region + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной \en Whether the point is special + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters.\n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void DeriveU ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void DeriveUUU( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUUV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveUVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void DeriveVVV( double & u, double & v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void Normal ( double & u, double & v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; // \ru Точка на поверхности \en Point on the surface + virtual void _DeriveU ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по u \en First derivative with respect to u + virtual void _DeriveV ( double u, double v, MbVector3D & p ) const; // \ru Первая производная по v \en First derivative with respect to v + virtual void _DeriveUU ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void _DeriveVV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void _DeriveUV ( double u, double v, MbVector3D & p ) const; // \ru Вторая производная по uv \en Second derivative with respect to uv + virtual void _DeriveUUU( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUUV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveUVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _DeriveVVV( double u, double v, MbVector3D & p ) const; // \ru Третья производная \en Third derivative + virtual void _Normal ( double u, double v, MbVector3D & p ) const; // \ru Нормаль \en Normal + /** \} */ + + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага параметра u по по величине прогиба \en Calculation of parameter u step by the value of sag + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага параметра v по по величине прогиба \en Calculation of parameter v step by the value of sag + virtual double DeviationStepU( double u, double v, double ang ) const; // \ru Вычисление шага параметра u по углу отклонения нормали \en Calculation of parameter u step by the angle of deviation of normal + virtual double DeviationStepV( double u, double v, double ang ) const; // \ru Вычисление шага параметра v по углу отклонения нормали \en Calculation of parameter v step by the angle of deviation of normal + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю \en If true, then all the derivatives by U higher the first one are equal to zero + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю \en If true, then all the derivatives by V higher the first one are equal to zero + + // \ru Найти ближайшую проекцию точки на поверхность или ее продолжение по заданному начальному приближению. \en Find the neares projection of a point onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & pnt, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + + // \ru Оффсет на поверхность. \en Offset to the surface + virtual MbSurface * Offset( double d, bool same ) const; + + /** \brief \ru Проверить параметры. Аналог глобальной функции _CheckParams, оптимизированный под использование кэшей. + \en Check parameters. Analogue of the global function _CheckParams, optimized for caches usage. \~ + \details \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + \en Check parameters and move them inside domain if parameter is out of pole. \~ + \param[in] surface - \ru Поверхность. \en Surface. \~ + \param[in] u - \ru Первый параметр. \en First parameter. \~ + \param[in] v - \ru Второй параметр. \en Second parameter. \~ + */ + virtual void CheckSurfParams( double & u, double & v ) const; + + /// \ru Вернуть количество кривых в первом семействе. \en Get count of curves of first family. + size_t GetUCurvesCount() const { return uCurves.Count(); } + /// \ru Вернуть количество кривых во втором семействе. \en Get count of curves of second family. + size_t GetVCurvesCount() const { return vCurves.Count(); } + /** \brief \ru Получить кривую с индексом ind из первого семейства. + \en Get curve with 'ind' index from first family. \~ + \details \ru Получить кривую с индексом ind из первого семейства. \n + \en Get curve with 'ind' index from first family. \n \~ + \param[in] ind - \ru Номер запрашиваемой кривой в массиве. + \en Index of required curve in array. \~ + \return \ru Кривая или NULL, если значение ind выходит за диапазон возможных индексов массиве кривых. + \en Curve or NULL if value of 'ind' is out of range of possible indices of array of curves. \~ + */ + const MbCurve3D * GetUCurve( size_t ind ) const { return ( ind < uCurves.Count()) ? uCurves[ind] : NULL; } + /** \brief \ru Получить кривую с индексом ind из второго семейства. + \en Get curve with 'ind' index from second family. \~ + \details \ru Получить кривую с индексом ind из второго семейства. \n + \en Get curve with 'ind' index from second family. \n \~ + \param[in] ind - \ru Номер запрашиваемой кривой в массиве. + \en Index of required curve in array. \~ + \return \ru Кривая или NULL, если значение ind выходит за диапазон возможных индексов массиве кривых. + \en Curve or NULL if value of 'ind' is out of range of possible indices of array of curves. \~ + */ + const MbCurve3D * GetVCurve( size_t ind ) const { return ( ind < vCurves.Count()) ? vCurves[ind] : NULL; } + /** \brief \ru Получить значение параметра, соответствующего кривой с индексом ind из первого семейства. + \en Get value of parameter corresponding to curve with 'ind' index from first family. \~ + \details \ru Получить значение параметра, соответствующего кривой с индексом ind из первого семейства.\n + \en Get value of parameter corresponding to curve with 'ind' index from first family.\n \~ + \param[in] ind - \ru Номер кривой в массиве. + \en Index of curve in array. \~ + \return \ru Значение параметра или 0, если значение ind выходит за диапазон возможных индексов массиве кривых. + \en Value of parameter or 0 if value of 'ind' is out of range of possible indices of array of curves. \~ + */ + double GetUParam( size_t ind ) const { return ( ind < uParams.Count()) ? uParams[ind] : 0; } + /** \brief \ru Получить значение параметра, соответствующего кривой с индексом ind из второго семейства. + \en Get value of parameter corresponding to curve with 'ind' index from second family. \~ + \details \ru Получить значение параметра, соответствующего кривой с индексом ind из второго семейства.\n + \en Get value of parameter corresponding to curve with 'ind' index from second family.\n \~ + \param[in] ind - \ru Номер кривой в массиве. + \en Index of curve in array. \~ + \return \ru Значение параметра или 0, если значение ind выходит за диапазон возможных индексов массиве кривых. + \en Value of parameter or 0 if value of 'ind' is out of range of possible indices of array of curves. \~ + */ + double GetVParam( size_t ind ) const { return ( ind < vParams.Count()) ? vParams[ind] : 0; } + /** \brief \ru Заполнить массив параметров по u. + \en Fill array of parameters by u. \~ + \details \ru Заполнить массив параметров по u.\n + \en Fill array of parameters by u.\n \~ + \param[in,out] params - \ru Множество параметров. + \en Set of parameters. \~ + */ + void GetUParams( SArray & params ) const { params = uParams; } + /** \brief \ru Заполнить массив параметров по v. + \en Fill array of parameters by v. \~ + \details \ru Заполнить массив параметров по v.\n + \en Fill array of parameters by v.\n \~ + \param[in,out] params - \ru Множество параметров. + \en Set of parameters. \~ + */ + void GetVParams( SArray & params ) const { params = vParams; } + + /** \brief \ru Получить версию алгоритма расчета поверхности. + \en Get version of the algorithm for calculating the surface. \~ + \details \ru Получить версию алгоритма расчета поверхности.\n + \en Get version of the algorithm for calculating the surface.\n \~ + \return \ru Версию алгоритма расчета поверхности. + \en The version of the algorithm for calculating the surface. \~ + */ + MbeMeshSurfaceVersion GetSurfaceVersion() const { return version; } + +private: + void AddCurvesRef(); + void ReleaseCurves(); + void Init(); + bool CheckPoles( MbMeshSurfaceAuxiliaryData * ) const; // \ru Инициализировать полюсы на границе параметрической области. \en Initialize poles on the border of parameters area. + // \ru Определить местные координаты области поверхности. \en Determine local coordinates of surface region. + void LocalCoordinate( double u, double v, double & ul, double & vl, size_t & i0,size_t & j0,size_t & i1, size_t & j1, MbMeshSurfaceAuxiliaryData * ucache = NULL ) const; + void LocalCoordinate_v2( double u, double v, double & ul, double & vl, size_t & i0, size_t & j0, size_t ord, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить вспомогательные вектора производных вдоль U кривых патча. \en Calculate auxiliary vectors of derivatives along U curves of patch. + void CalculateAlongU( const double & ul, const size_t & j0, const size_t & j1, MbMeshSurfaceAuxiliaryData * ucache ) const; + void CalculateAlongU_v2( const double & u, const size_t & j0, const size_t & j1, size_t indP, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить вспомогательные вектора производных вдоль V кривых патча. \en Calculate auxiliary vectors of derivatives along V curves of patch. + void CalculateAlongV( const double & vl, const size_t & i0, const size_t & i1, MbMeshSurfaceAuxiliaryData * ucache ) const; + void CalculateAlongV_v2( const double & v, const size_t & i0, const size_t & i1, size_t indP, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить вспомогательные вектора производных в узлах кривых. \en Calculate auxiliary vectors of derivatives at nodes of curves. + void CalculateVertex( const size_t & i0, const size_t & j0, const size_t & i1, const size_t & j1, MbMeshSurfaceAuxiliaryData * ucache ) const; + void CalculateVertex_v2( const size_t & i0, const size_t & j0, const size_t & i1, const size_t & j1, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить дополнительные вспомогательные вектора производных в узлах кривых. Для 1-й версии поверхности. \en Calculate additional auxiliary vectors of derivatives at nodes of curves. For 1-st version of surface. + void AdditionalCalculateVertex( size_t i0, size_t j0, size_t i1, size_t j1, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Создать массив смешанных производных. \en Create an array of mixed derivatives. + void CreateTwists (); + void CreateTwists_v1(); + // \ru Аппроксимировать смешанную производную. \en Approximate mixed derivative. + void ApproxTwistBilinear ( size_t iL, size_t iR, size_t jD, size_t jU, size_t iCent, size_t jCent, MbVector3D & resTwist ); + void ApproxTwistBilinear_v1( size_t iCent, size_t jCent, MbVector3D & resTwist ); + void ApproximateOneCornerTwist_v1( size_t iL, size_t iR, size_t jD, size_t jU, size_t corner, MbVector3D & resTwist ) const; + // \ru Вычислить вспомогательные массивы трансверсальных производных. \en Calculate auxiliary arrays of transversal derivatives. + void CalculateTransDiffs ( double ul, double vl, size_t i0, size_t j0, size_t i1, size_t j1, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить выводящую производную с линии V = const и ее первые производные по U. \en Calculate leading out derivative from 'V = const'-line and its first derivatives by U. + void CalculateVDiffs ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Вычислить выводящую производную с линии U = const и ее первые производные по V. \en Calculate leading out derivative from 'U = const'-line and its first derivatives by V. + void CalculateUDiffs ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Вычислить выводящую производную с линии U (V) = const и ее первые производные по V (U). \en Calculate leading out derivative from 'U (V) = const'-line and its first derivatives by V (U). + void CalcTransvDiffs_v1( bool uDir, double par, size_t ind, bool leftOrDown, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2, + MbVector3D & resDer3, MbMeshSurfaceAuxiliaryData * ucache ) const; + void CalcTransvDiffs_v2( bool uDir, double par, double apar, size_t ind, size_t indt, bool leftOrDown, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2, + MbVector3D & resDer3, size_t ord, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Аппроксимация нормали вдоль U - линии. \en Approximation of normal along U - line. + bool NormalAlongV ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Аппроксимация нормали вдоль V - линии. \en Approximation of normal along V - line. + bool NormalAlongU ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Вычислить выводящую производную с линии V = const и ее первые производные по U. \en Calculate leading out derivative from 'V = const'-line and its first derivatives by U. + void NormalVDiffs ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Вычислить выводящую производную с линии U = const и ее первые производные по V. \en Calculate leading out derivative from 'U = const'-line and its first derivatives by V. + void NormalUDiffs ( double ul, double vl, size_t i0, size_t j0, bool dir, + MbVector3D & res, + MbVector3D & resDer1, + MbVector3D & resDer2 ) const; + // \ru Вычислить выводящие производные с учетом сопряжения к поверхности. \en Calculate leading out derivatives with consideration of conjugation to surface. + void SurfaceDiff ( const MbCurve3D & srfCrv, uint type, double ul, double vl, + size_t i0, size_t j0, size_t i1, size_t j1, + bool leftOrDown, // \ru Где происходит сам стык. \en Where is a joint. + bool uDir, // \ru Вдоль какого направления направлена кривая. \en Which direction the curve is directed along. + MbVector3D & first, + MbVector3D & secnd, + MbVector3D & third, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Вычислить выводящую производную и ей сопутствующие производные вдоль кривой. \en Calculate leading out derivative and its associated derivatives along curve. + void SurfaceTangent ( const MbCurve3D & surfCrv, // \ru Кривая, к поверхности которой вычисляется производная \en Curve which surface the derivative is calculated to + const MbVector3D * coons, // \ru Массив выводящих производных обычного патча Кунса \en Array of leading out derivatives of ordinary Coons patch + size_t border, // \ru Порядковый номер сопрягаемой границы \en Serial number of conjugated boundary + double tCurve, // \ru Параметр на кривой \en Parameter on the curve + double paramLoc, // \ru Параметр патча, соответствующий параметру на кривой \en Patch parameter corresponding to parameter on curve + double dt, // (dt / d(paramLoc)) + MbVector3D & res, // \ru Сам вектор \en Vector + MbVector3D & resDiff, // \ru Его первая производная \en Its first derivative + MbVector3D & resDiff2, MbMeshSurfaceAuxiliaryData * ucache ) const; + void PureSurfTangent( const MbCurve3D & surfCrv, + const MbVector3D * coons, + size_t border, + double tCurve, + double dt, + MbVector3D & res, + MbVector3D & resDiff, + MbVector3D * resDiff2 ) const; + void SurfaceNormal ( const MbCurve3D & srfCrv, + const MbVector3D * coons, // \ru Массив выводящих производных обычного патча Кунса \en Array of leading out derivatives of ordinary Coons patch + size_t border, // \ru Порядковый номер сопрягаемой границы \en Serial number of conjugated boundary + double tCurve, + double paramLoc, + double dt, + MbVector3D & res, // \ru Сам вектор \en Vector + MbVector3D & resDiff, // \ru Производная вектора вдоль кривой ( по paramLoc ) \en Derivative of vector along curve ( by paramLoc ) + MbVector3D & resDiff2, MbMeshSurfaceAuxiliaryData * ucache ) const ; + void PureSurfNormal ( const MbCurve3D & surfCrv, + const MbVector3D * coons, + size_t border, + double tCurve, + double dt, + MbVector3D & res, + MbVector3D & resDiff, + MbVector3D * resDiff2 ) const; + // \ru Нормализовать массивы пересечений \en Normalize arrays of intersections + void NormalizeIntersection(); + + // \ru Определить индексы в массиве точек пересечения для кривых по направлению U \en Determine indices in array of intersection points for curves by U direction + void DefineEndTUIndices( size_t i0, size_t j0, size_t i1, size_t j1, + size_t & k0min, size_t & k0max, + size_t & k2min, size_t & k2max ) const; + // \ru Определить индексы в массиве точек пересечения для кривых по направлению V \en Determine indices in array of intersection points for curves by V direction + void DefineEndTVIndices( size_t i0, size_t j0, size_t i1, size_t j1, + size_t & k1min, size_t & k1max, + size_t & k3min, size_t & k3max ) const; + + // \ru Определить параметры пересечений для U направления \en Determine parameters of intersections for U direction + void DefineEndTUPars( size_t i0, size_t j0, size_t i1, size_t j1, + double & t0min, double & t0max, + double & t2min, double & t2max, bool dir = true ) const; + // \ru Определить параметры пересечений для V направления \en Determine parameters of intersections for V direction + void DefineEndTVPars( size_t i0, size_t j0, size_t i1, size_t j1, + double & t1min, double & t1max, + double & t3min, double & t3max, bool dir = true ) const; + + void ExactNormal( double u, double v, const MbVector3D & uDer, const MbVector3D & vDer, MbVector3D & nor ) const; + + // \ru Проверить параметры и в случае выхода за пределы загнать в область определения. + // \en Check parameters and if it is out of limits, then drive it to domain + void CheckParams( double & u, double & v ) const; + // \ru Проверить параметры и в случае захода за полюс или выходе за период загнать в область определения. + // \en Check parameters and if it is out of pole or it is out of period, then drive it to the domain region. + void CheckParamsEx( double & u, double & v ) const; + + // \ru Нормализовать семейство кривых по параметрической длине \en Normalize family of curves by parametric length + void CreateReparamCurves( const MbCurve3D & curveBeg, + const MbCurve3D & curveEnd, + double tBeg, + double tEnd, + bool closed, + RPArray & curves ) ; + // \ru Попытаться вычислить шаг по U, исходя из шагов по соответствующим операторам Loft-ов \en Try to calculate step by U through steps of corresponding Loft operators + bool SurfDeviationStepU( double & u, double & v, double ang, double & resStep, MbMeshSurfaceAuxiliaryData * ucache ) const; + // \ru Попытаться вычислить шаг по V, исходя из шага по соответствующим операторам Loft-ов \en Try to calculate step by V through steps of corresponding Loft operators + bool SurfDeviationStepV( double & u, double & v, double ang, double & resStepv, MbMeshSurfaceAuxiliaryData * ucache ) const; + /** \} */ + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbMeshSurface ) +OBVIOUS_PRIVATE_COPY( MbMeshSurface ) +}; // MbMeshSurface + +IMPL_PERSISTENT_OPS( MbMeshSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры и в случае выхода за пределы загнать в область определения \en Check parameters and if it is out of limits, then drive it to domain +// --- +inline void MbMeshSurface::CheckParams( double & u, double & v ) const +{ + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) { + double rgn = umax - umin; + u -= ::floor( (u - umin) / rgn ) * rgn; + } + else if ( u < umin ) + u = umin; + else if ( u > umax ) + u = umax; + } + if ( (v < vmin) || (v > vmax) ) { + if ( vclosed ) { + double rgn = vmax - vmin; + v -= ::floor( (v - vmin) / rgn ) * rgn; + } + else if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; + } +} + + +//------------------------------------------------------------------------------ +// \ru Проверить параметры и в случае захода за полюс или выходе за период загнать в область определения. \en Check parameters and if it is out of pole or it is out of period, then drive it to the domain region. +// --- +inline void MbMeshSurface::CheckParamsEx( double & u, double & v ) const +{ + if ( GetPoleUMin() ) { + const double & umin_ = uParams[0]; + if ( u < umin_ ) + u = umin_; + } + if ( GetPoleUMax() ) { + const double & umax_ = uParams[uParams.MaxIndex()]; + if ( u > umax_ ) + u = umax_; + } + if ( GetPoleVMin() ) { + const double & vmin_ = vParams[0]; + if ( v < vmin_ ) + v = vmin_; + } + if ( GetPoleVMax() ) { + const double & vmax_ = vParams[vParams.MaxIndex()]; + if ( v > vmax_ ) + v = vmax_; + } + if ( uclosed && (u > umax || u < umin) ) { + double period = umax - umin; + if ( period < Math::paramAccuracy ) + period = Math::paramAccuracy; + u -= period * ::floor( (u - umin)/period ); + } + if ( vclosed && (v > vmax || v < vmin) ) { + double period = vmax - vmin; + if ( period < Math::paramAccuracy ) + period = Math::paramAccuracy; + v -= period * ::floor( (v - vmin)/period ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Пересечение MbMeshSurface с MbMeshSurface. \en Intersection of MbMeshSurface with MbMeshSurface. +// --- +inline void GetBoundCurves( const MbMeshSurface & mesh, RPArray & meshCurves ) //-V801 +{ // \ru Не менять порядок выдачи кривых \en Not to change an order of output of curves + size_t cnt = mesh.GetUCurvesCount(); + if ( cnt > 0 ) { + meshCurves.Add( mesh.GetUCurve( 0 ) ); + if ( cnt > 1 ) + meshCurves.Add( mesh.GetUCurve( --cnt ) ); + } + cnt = mesh.GetVCurvesCount(); + if ( cnt > 0 ) { + meshCurves.Add( mesh.GetVCurve( 0 ) ); + if ( cnt > 1 ) + meshCurves.Add( mesh.GetVCurve( --cnt ) ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Попытаться сделать параметры монотонно меняющимися и в пределах периода. + \en Try to make parameters monotonously changing and within the period. \~ + \details \ru Параметры местами не меняются. Пытаемся добиться монотонности прибавлением или вычитанием периода из значения параметра. + Получившийся в результате набор параметров должен помещаться в один период. + \en Parameters don't swap. Try to achieve monotony by addition or subtraction of period from value of parameter. + The resulting set of parameters has to be within single period. \~ + \param[in,out] params - \ru Множество параметров. Отсортирован после успешного выполнения. Если попытка не удалась - не изменяется. + \en Set of parameters. Ordered after successful execution. If attempt wasn't successful - doesn't change. \~ + \param[in] period - \ru Период. + \en Period. \~ + \return \ru true в случае успешного выполнения. + \en True in case of successful execution. \~ +*/ +//--- +bool MakeMonotoneParams( SArray & params, double period ); + + +#endif // __SURF_MESH_SURFACE_H diff --git a/C3d/Include/surf_offset_surface.h b/C3d/Include/surf_offset_surface.h new file mode 100644 index 0000000..b9ab675 --- /dev/null +++ b/C3d/Include/surf_offset_surface.h @@ -0,0 +1,438 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Эквидистантная поверхность. + \en Offset surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_OFFSET_SURFACE_H +#define __SURF_OFFSET_SURFACE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceContiguousData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Эквидистантная и расширенная поверхность. + \en Offset surface. \~ + \details \ru Эквидистантная поверхность построена на базовой поверхности basisSurface и располагается на расстоянии от неё, определяемом параметрами offsetUminVmin, offsetUmaxVmin, offsetUminVmax, offsetUmaxVmax. + Параметры offsetUminVmin, offsetUmaxVmin, offsetUminVmax, offsetUmaxVmax могут быть как больше нуля, так и меньше нуля. + Область определения параметров эквидистантной поверхности может отличаться от область определения параметров базовой поверхности basisSurface. + Это отличие задано параметрами deltaUmin, deltaUmax, deltaVmin, deltaVmax. + Радиус-вектор эквидистантной поверхности описывается векторной функцией \n + r(u,v) = basisSurface(u,v) + (Offset0(u,v) * basisSurface->Normal(u,v)). \n + Базовой поверхностью для эквидистантной поверхности не может служить другая эквидистантная поверхность. + В подобной ситуации выполняется переход к первичной базовой поверхности. + \en The offset surface is constructed on 'basisSurface' base surface and placed at distance from it, determined by 'offsetUminVmin, offsetUmaxVmin, offsetUminVmax, offsetUmaxVmax' parameters. + 'offsetUminVmin, offsetUmaxVmin, offsetUminVmax, offsetUmaxVmax' parameters can be both greater than zero and less than zero. + Domain of parameters of the offset surface can differs from domain of parameters of basisSurface base surface. + This difference is given by the parameters deltaUmin, deltaUmax, deltaVmin, deltaVmax. + Radius-vector of offset surface is described by the vector function \n + r(u,v) = basisSurface(u,v) + (Offset0(u,v) * basisSurface->Normal(u,v)). \n + Base surface for offset surface can't be other offset surface. + In this situation it changes to the initial base surface. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbOffsetSurface : public MbSurface { +private: + MbSurface * basisSurface; ///< \ru Базовая поверхность (всегда не NULL). \en Base surface (always not NULL). + double u0min; ///< \ru Минимальный параметр u базовой поверхности. \en Minimal parameter u of the base surface. + double u0max; ///< \ru Максимальный параметр u базовой поверхности. \en Maximal parameter u of the base surface. + double v0min; ///< \ru Минимальный параметр v базовой поверхности. \en Minimal parameter v of the base surface. + double v0max; ///< \ru Максимальный параметр v базовой поверхности. \en Maximal parameter v of the base surface. + bool u0closed; ///< \ru Признак замкнутости по u базовой поверхности. \en Attribute of closedness of base surface by u. + bool v0closed; ///< \ru Признак замкнутости по v базовой поверхности. \en Attribute of closedness of base surface by v. + double offsetUminVmin; ///< \ru Смещение от базовой поверхности по нормали в точке [u0min v0min]. \en The offset from the base surface along normal in a point [u0min v0min]. + double offsetUmaxVmin; ///< \ru Смещение от базовой поверхности по нормали в точке [u0max v0min]. \en The offset from the base surface along normal in a point [u0max v0min]. + double offsetUminVmax; ///< \ru Смещение от базовой поверхности по нормали в точке [u0min v0max]. \en The offset from the base surface along normal in a point [u0min v0max]. + double offsetUmaxVmax; ///< \ru Смещение от базовой поверхности по нормали в точке [u0max v0max]. \en The offset from the base surface along normal in a point [u0max v0max]. + MbeOffsetType type; ///< \ru Тип смещения точек: константный, линейный или кубический. \en The type of points offset: constant, or linear, or cubic. + double deltaUmin; ///< \ru Изменение параметрической области относительно параметра u0min базовой поверхности. \en The change of minimum of the first parameter relative of u0min parameter of the base surface. + double deltaUmax; ///< \ru Изменение параметрической области относительно параметра u0max базовой поверхности. \en The change of maximum of the first parameter relative of u0max parameter of the base surface. + double deltaVmin; ///< \ru Изменение параметрической области относительно параметра v0min базовой поверхности. \en The change of minimum of the second parameter relative of v0min parameter of the base surface. + double deltaVmax; ///< \ru Изменение параметрической области относительно параметра v0max базовой поверхности. \en The change of maximum of the second parameter relative of v0max parameter of the base surface. + +private: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbOffsetSurfaceAuxiliaryData : public AuxiliaryData { + public: + DPtr data; ///< \ru Дополнительные данные о поверхности. \en Additional data about a surface. + MbOffsetSurfaceAuxiliaryData(); + MbOffsetSurfaceAuxiliaryData( const MbOffsetSurfaceAuxiliaryData & init ); + virtual ~MbOffsetSurfaceAuxiliaryData(); + }; + + mutable CacheManager cache; + +public: + + /** \brief \ru Конструктор по базовой поверхности и смещению. + \en Constructor by base surface and offset. \~ + \details \ru Конструктор по базовой поверхности и смещению. + \en Constructor by base surface and offset. \~ + \param[in] s - \ru Базовая поверхность + \en Base surface \~ + \param[in] d - \ru Величина смещения + \en Offset distance \~ + \param[in] same - \ru Признак использования оригинала базовой поверхности, а не ее копии + \en Attribute of usage of original of base surface, not copy \~ + */ + MbOffsetSurface( const MbSurface & s, double d, bool same ); + + /** \brief \ru Конструктор по базовой поверхности и смещению c приращениями параметров. + \en Constructor by base surface and offset with increments of parameters. \~ + \details \ru Конструктор по базовой поверхности и смещению c приращениями параметров.\n + Приращение параметров нужно использовать для изменения области определения поверхности + относительно базовой поверхности. + \en Constructor by base surface and offset with increments of parameters.\n + Increment of parameters needs to be used for change of surface domain + relative to base surface. \~ + \param[in] s - \ru Базовая поверхность + \en Base surface \~ + \param[in] d - \ru Величина смещения + \en Offset distance \~ + \param[in] du0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] du1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + \param[in] dv0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] dv1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + \param[in] same - \ru Признак использования оригинала базовой поверхности, а не ее копии. + \en Attribute of usage of original of base surface, not copy. \~ + */ + MbOffsetSurface( const MbSurface & s, double d, double du0, double du1, double dv0, double dv1, bool same ); + + /** \brief \ru Конструктор по базовой поверхности и смещению c приращениями параметров. + \en Constructor by base surface and offset with increments of parameters. \~ + \details \ru Смещение задано в углах параметрической области базовой поверхности и может изменяться по константному, линейному и кубическому законам.\n + Приращение параметров нужно использовать для изменения области определения поверхности относительно базовой поверхности. + \en The offset displacement is defined in the corners of the parametric region of the base surface and can be changed by constant, linear and cubic laws.\n + Increment of parameters needs to be used for change of surface domain relative to base surface. \~ + \param[in] s - \ru Базовая поверхность + \en Base surface \~ + \param[in] d0 - \ru Величина смещения offsetUminVmin. + \en Offset distance offsetUminVmin. \~ + \param[in] d1 - \ru Величина смещения offsetUmaxVmin. + \en Offset distance offsetUmaxVmin. \~ + \param[in] d2 - \ru Величина смещения offsetUminVmax. + \en Offset distance offsetUminVmax. \~ + \param[in] d3 - \ru Величина смещения offsetUmaxVmax. + \en Offset distance offsetUmaxVmax. \~ + \param[in] t - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[in] u0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] u1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + \param[in] v0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] v1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + \param[in] same - \ru Признак использования оригинала базовой поверхности, а не ее копии. + \en Attribute of usage of original of base surface, not copy. \~ + */ + MbOffsetSurface( const MbSurface & s, double d0, double d1, double d2, double d3, MbeOffsetType t, + double u0, double u1, double v0, double v1, bool same ); + +protected: + MbOffsetSurface( const MbOffsetSurface &, MbRegDuplicate * ); +private: + MbOffsetSurface( const MbOffsetSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbOffsetSurface (); + +public: + VISITING_CLASS( MbOffsetSurface ); + +public: + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /** \brief \ru Инициализация по смещению и приращениям параметров. + \en Initialization by offset and increments of parameters. \~ + \details \ru Инициализация по смещению и приращениям параметров.\n + Приращение параметров нужно использовать для изменения области определения поверхности относительно базовой поверхности. + \en Initialization by offset and increments of parameters.\n + Increment of parameters needs to be used for change of surface domain relative to base surface. \~ + \param[in] d0 - \ru Величина смещения offsetUminVmin. + \en Offset distance offsetUminVmin. \~ + \param[in] d1 - \ru Величина смещения offsetUmaxVmin. + \en Offset distance offsetUmaxVmin. \~ + \param[in] d2 - \ru Величина смещения offsetUminVmax. + \en Offset distance offsetUminVmax. \~ + \param[in] d3 - \ru Величина смещения offsetUmaxVmax. + \en Offset distance offsetUmaxVmax. \~ + \param[in] t - \ru Тип смещения точек: константный, линейный или кубический. + \en The offset type: constant, or linear, or cubic. \~ + \param[in] u0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] u1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + \param[in] v0 - \ru Изменение umin параметра + \en The change of umin parameter \~ + \param[in] v1 - \ru Изменение umax параметра + \en The change of umax parameter \~ + */ + void Init( double d0, double d1, double d2, double d3, MbeOffsetType t, double u0, double u1, double v0, double v1 ); + void Init( double d, double u0, double u1, double v0, double v1 ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект копией. \en Whether the object is a copy. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual void Refresh(); // \ru Сбросить все временные данные \en Flush all the temporary data + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые поверхности. \en Get base surfaces. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin () const; // \ru Вернуть минимальное значение параметра u. \en Return the minimum value of parameter u. + virtual double GetVMin () const; // \ru Вернуть минимальное значение параметра v. \en Return the minimum value of parameter v. + virtual double GetUMax () const; // \ru Вернуть максимальное значение параметра u. \en Return the maximum value of parameter u. + virtual double GetVMax () const; // \ru Вернуть максимальное значение параметра v. \en Return the maximum value of parameter v. + virtual bool IsUClosed () const; // \ru Проверка замкнутости по параметру u. \en Check of closedness by parameter u. + virtual bool IsVClosed () const; // \ru Проверка замкнутости по параметру v. \en Check of closedness by parameter v. + virtual double GetUPeriod() const; // \ru Период по u. \en Period by u. + virtual double GetVPeriod() const; // \ru Период по v. \en Period by v. + virtual size_t GetUCount() const; // \ru Получить разбиение по u. \en Get splitting by u. + virtual size_t GetVCount() const; // \ru Получить разбиение по v. \en Get splitting by v. + + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole ( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is special. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная. \en The third derivative. + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке. \en Values of derivatives at point. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по U. \en Calculation of the approximation step with consideration of the curvature radius by U. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по V. \en Calculation of the approximation step with consideration of the curvature radius by V. + virtual double DeviationStepU( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей. \en Calculation of step by u while intersecting surfaces. + virtual double DeviationStepV( double u, double v, double sag ) const; // \ru Вычисление шага по v при пересечении поверхностей. \en Calculation of step by v while intersecting surfaces. + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии u. \en Curvature of u-line. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v-line. + // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Изменение носителя. \en Changing of carrier. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); + // \ru Изменение носимых элементов. \en Change a carrier elements. + virtual bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); + virtual const MbSurface & GetBasisSurface() const; // \ru Дать базовую поверхность. \en Get the base surface. + virtual MbSurface & SetBasisSurface(); // \ru Дать базовую поверхность. \en Get the base surface. + + virtual bool GetCylinderAxis( MbAxis3D & ) const; // \ru Дать ось вращения для поверхности. \en Get a rotation axis of a surface. + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces to union (joining) are similar + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + // \ru Определение параметрической области поверхности. \en Returns parametric region of surface. + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void IncludePoint ( double u, double v ); // \ru Включить точку в область определения. \en Include point into domain. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность. \en Create a shifted surface. + + virtual bool IsLineU () const; // \ru Если true все производные по U выше первой равны нулю. \en If true, then all the derivatives by U higher the first one are equal to zero. + virtual bool IsLineV () const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives by V higher the first one are equal to zero. + + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + /** \brief \ru Проверить параметры. Аналог глобальной функции _CheckParams, оптимизированный под использование кэшей. + \en Check parameters. Analogue of the global function _CheckParams, optimized for caches usage. \~ + \details \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + \en Check parameters and move them inside domain if parameter is out of pole. \~ + \param[in] surface - \ru Поверхность. + \en Surface. \~ + \param[in] u - \ru Первый параметр. + \en First parameter. \~ + \param[in] v - \ru Второй параметр. + \en Second parameter. \~ + */ + virtual void CheckSurfParams( double & u, double & v ) const; + + /** \} */ + /** \ru \name Функции эквидистантной поверхности + \en \name Functions of the offset surface + \{ */ + + // \ru Тип смещения точек. \en The type of points offset. + MbeOffsetType GetOffsetType() const { return type; } + // \ru Постоянное ли смещение точек? \en Is const the offset type? + bool IsConstOffset() const { return ( (type == off_Empty) || (type == off_Const) ); } + // \ru Величина смещения. \en The offset distance. + double GetDistance( size_t i = 0 ) const { + if ( i == 1 ) return offsetUmaxVmin; + else + if ( i == 2 ) return offsetUminVmax; + else + if ( i == 3 ) return offsetUmaxVmax; + return offsetUminVmin; + } + + /** \brief \ru Установить величины смещения. + \en Set offset distances. \~ + \param[in] d - \ru Новая величина смещения + \en New offset distance \~ + */ + void SetDistance( double d, size_t i = 0 ); + + /** \brief \ru Проверить корректность точки поверхности. + \en Check the correctness of the point of a surface. \~ + \details \ru Проверить корректность точки поверхности по кривизне подложки.\n + Точка считается некорректной, если в ней поверхность самопересекается или имеет излом. + \en Check the correctness of the point of a surface by curvature of substrate.\n + Point is considered incorrect if a surface is self-intersected or has a break in it. \~ + \param[in] uv - \ru Точка для проверки + \en Point to check \~ + \return \ru true, если точка корректная + \en True if point is correct \~ + */ + bool IsCurvatureValid( const MbCartPoint & uv ) const; + /** \} */ +private: + void CheckParam ( double & u, double & v ) const; // \ru Проверка параметров (попадание в пределы). \en Check parameters (being in limits). + void CheckExtParam( double & u, double & v, MbOffsetSurfaceAuxiliaryData * ucache ) const; // \ru Проверка параметров (на наличие полюсов). \en Check parameters (for presence of poles). + void CheckPoles ( MbOffsetSurfaceAuxiliaryData * ) const; // \ru Проверить наличие полюсов на краях поверхности \en Check presence of poles on surface boundaries + void CheckPole ( double param, bool isU, MbeSurfacePoleType & poleType, CommonMutex* lock, MbOffsetSurfaceAuxiliaryData * ) const; + + // \ru Вычисление эквидистанты и её производных. \en The offset calculation and it derivatives calculation. + double Offset0 ( double u, double v ) const; + double OffsetU ( double u, double v ) const; + double OffsetV ( double u, double v ) const; + double OffsetUU ( double u, double v ) const; + double OffsetUV ( double u, double v ) const; + double OffsetVV ( double u, double v ) const; + double OffsetUUU( double u, double v ) const; + double OffsetUUV( double u, double v ) const; + double OffsetUVV( double u, double v ) const; + double OffsetVVV( double u, double v ) const; + + // \ru Точка на расширенной поверхности. \en The point on the extended surface. + void _PointOn( double u, double v, MbCartPoint3D &, MbOffsetSurfaceAuxiliaryData * ) const; + + // \ru Частные случаи поверхностей. \en Special cases of surfaces. + MbSplineSurface * CasePlane ( double, double, double, double, bool ) const; + MbSplineSurface * CaseCylinder ( double, double, double, double, bool ) const; + MbSplineSurface * CaseCone ( double, double, double, double, bool ) const; + MbSplineSurface * CaseSphere ( double, double, double, double, bool ) const; + MbSplineSurface * CaseTorus ( double, double, double, double, bool ) const; + MbSplineSurface * CaseFillets ( double, double, double, double, bool ) const; + MbSplineSurface * CaseLine ( double, double, double, double, bool ) const; + MbSplineSurface * CaseRevolution( double, double, double, double, bool ) const; + MbSplineSurface * CaseExtrusion ( double, double, double, double, bool ) const; + MbSplineSurface * CaseSwept ( double, double, double, double, bool ) const; + MbSplineSurface * CaseLofted ( double, double, double, double, bool ) const; + MbSplineSurface * CaseArbitrary ( double, double, double, double, bool ) const; + + void operator = ( const MbOffsetSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbOffsetSurface ) +}; + +IMPL_PERSISTENT_OPS( MbOffsetSurface ) + + +#endif // __SURF_OFFSET_SURFACE_H diff --git a/C3d/Include/surf_plane.h b/C3d/Include/surf_plane.h new file mode 100644 index 0000000..7565580 --- /dev/null +++ b/C3d/Include/surf_plane.h @@ -0,0 +1,536 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Плоскость. + \en A plane. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_PLANE_H +#define __SURF_PLANE_H + + +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbLine3D; + + +//------------------------------------------------------------------------------ +/** \brief \ru Плоскость. + \en A plane. \~ + \details \ru Плоскость располагается в координатной плоскости XY местной системы координат position. \n + Параметры плоскости отсчитываются от начала координат position.origin. + Первый параметр плоскости отсчитывается по оси position.axisX, второй параметр плоскости отсчитывается по оси position.axisY. \n + Плоскость ведёт себя как бесконечная поверхность, хотя в своих данных имеет граничные значения параметров umin, umax и vmin, vmax. + В отличие от других поверхностей Функции PointOn и Derive... плоскости не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. \n + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + (u position.axisX) + (v position.axisY). \n + \en A plane is located on the XY coordinate plane of the local coordinate system 'position'. \n + Parameters of plane are calculated from the coordinates origin 'position.origin'. + The first parameter of plane is calculated on the axis 'position.axisX', the second parameter of plane is calculated on the axis 'position.axisY'. \n + A plane behaves like an infinite surface, although it has boundary parameter values umin, umax and vmin, vmax. + In contrast to other surfaces functions PointOn and Derive.. of plane don't correct + parameters when getting out of rectangular domain bounds. \n \n + Radius-vector of the surface is described by the vector function \n + r(u,v) = position.origin + (u position.axisX) + (v position.axisY). \n \~ + \ingroup Surfaces +*/ // --- +class MATH_CLASS MbPlane : public MbElementarySurface { + +public: + MbPlane (); + /// \ru Конструктор по локальной системе координат. \en Constructor by a local coordinate system. + MbPlane ( const MbPlacement3D & initPlane ); + /// \ru Конструктор по трем точкам. \en Constructor by three points. + MbPlane ( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2 ); + /// \ru Конструктор по центру и осям X и Z. \en Constructor by center and axes X and Z. + MbPlane ( const MbCartPoint3D & c0, const MbCartPoint3D & ax, const MbVector3D & aZ ); + /// \ru Конструктор по центру и осям X и Y. \en Constructor by center and axes X and Y. + MbPlane ( const MbCartPoint3D & c0, const MbVector3D & ax, const MbVector3D & ay ); + /// \ru Конструктор построения смещенной плоскости. \en Constructor of shifted plane. + MbPlane ( const MbPlacement3D &, double distance ); +protected: + MbPlane ( const MbPlane & ); +public: + virtual ~MbPlane(); + +public: + VISITING_CLASS( MbPlane ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /// \ru Инициализация по плоскости. \en Initialization by plane. + void Init( const MbPlane & ); + + /** \brief \ru Инициализация по системе координат и расстоянию. + \en Initialization by coordinate system and distance. \~ + \details \ru Инициализация плоскости системой координат init co сдвигом на + расстояние distance в направлении нормали (оси Z). + \en Initialization by coordinate system and translation by + the distance 'distance' in direction of the normal vector (Z axis). \~ + \param[in] init - \ru Система координат + \en Coordinate system \~ + \param[in] distance - \ru Расстояние + \en Distance \~ + */ + void Init( const MbPlacement3D & init, double distance ); + + /** \brief \ru Инициализация по точке и системе координат. + \en Initialization by point and coordinate system. \~ + \details \ru Инициализация по точке и системе координат.\n + В результате получаем плоскость с правой системой координат. + \en Initialization by point and coordinate system.\n + The result is a plane with right coordinate system. \~ + \param[in] p - \ru Точка, определяет положение начала системы координат плоскости + \en A point, it defines location of the plane origin. \~ + \param[in] init - \ru Система координат, определяет направление осей Z, X + \en A coordinate system, it defines direction of Z and X axes. \~ + */ + void Init( const MbCartPoint3D & p, const MbPlacement3D & init ); + + /** \brief \ru Инициализация по точке. + \en Initialize by point. \~ + \details \ru Инициализация по точке.\n + В результате получаем плоскость с правой системой координат.\n + Направление осей координат Z, X остается. + \en Initialization by point.\n + The result is a plane with right coordinate system.\n + Directions of Z and X axes remain. \~ + \param[in] p - \ru Точка, определяет положение начала системы координат плоскости + \en A point, it defines location of the plane origin. \~ + */ + void Init( const MbCartPoint3D & p ); + + /** \brief \ru Инициализация по системе координат, углу, кривой и параметру. + \en Initialization by coordinate system, angle, curve and parameter. \~ + \details \ru Инициализация по системе координат, углу, кривой и параметру.\n + В случае успеха получаем плоскость:\n + с правой системой координат;\n + центр системы координат определяет точка кривой curve с параметром t;\n + направление оси X показывает вектор производной кривой curve в точке с параметром t;\n + направление оси Z показывает ось Z системы координат init, повернутая вокруг оси с направлением - + осью X на угол angle. + \en Initialization by coordinate system, angle, curve and parameter.\n + In case of success we get a plane:\n + with right coordinate system,\n + center of coordinate system is defined by a point on a curve 'curve' with parameter t;\n + direction of the axis X is defined by the derivative vector of a curve 'curve' in the point with parameter t;\n + direction of Z axis is defined by Z axis of the coordinate system 'init' rotated around the axis with the direction of + X axis by the angle 'angle'. \~ + \param[in] init - \ru Система координат + \en Coordinate system \~ + \param[in] ang - \ru Угол + \en Angle \~ + \param[in] curve - \ru Кривая + \en Curve \~ + \param[in] t - \ru Параметр на кривой + \en Parameter on curve \~ + \return \ru true в случае успеха + \en Returns true in case of success. \~ + */ + bool Init( const MbPlacement3D & init, double ang, MbCurve3D & curve, double t = 0 ); + + /** \brief \ru Инициализация по точке, кривой и параметру. + \en Initialization by point, curve and parameter. \~ + \details \ru Инициализация по точке, кривой и параметру.\n + В случае успеха получаем плоскость:\n + с началом координат в точке на кривой curve с параметром t;\n + направление оси X показывает вектор производной кривой в точке с параметром t;\n + направление оси Y показывает вектор из точки на кривой в точку p. + \en Initialization by point, curve and parameter.\n + In case of success we get a plane:\n + with origin at the point of the curve with parameter t;\n + direction of the axis X is defined by the derivative vector of a curve in the point with parameter t;\n + direction of Y axis is defined by the vector from the point on the curve to point p. \~ + \param[in] p - \ru Точка + \en Point \~ + \param[in] curve - \ru Кривая + \en Curve \~ + \param[in] t - \ru Параметр на кривой + \en Parameter on curve \~ + \return \ru true в случае успеха + \en Returns true in case of success. \~ + */ + bool Init( const MbCartPoint3D & p, MbCurve3D & curve, double t = 0 ); + + /** \brief \ru Инициализация по точке, перпендикулярно кривой. + \en Initialization by point, perpendicularly to curve. \~ + \details \ru Инициализация по точке, перпендикулярно кривой. + \en Initialization by point, perpendicularly to curve. \~ + \param[in] p - \ru Точка + \en Point \~ + \param[in] curve - \ru Кривая + \en Curve \~ + \param[in] checkPlanar - \ru Использовать информацию о кривой, если он плоская. + \en Use curve information, if it's planar. \~ + */ + bool Init( const MbCurve3D & curve, const MbCartPoint3D & p, bool checkPlanar ); + + /// \ru Инициализация по локальной системе координат. \en Initialization by local coordinate system. + void Init( const MbPlacement3D & ); + /// \ru Инициализация по прямой и точке. \en Initialization by line and point. + bool Init( const MbLine3D &, const MbCartPoint3D & ); + /// \ru Инициализация по прямой и вектору. \en Initialization by line and vector. + bool Init( const MbLine3D &, const MbVector3D & ); + + /** \brief \ru Инициализация по двум прямым. + \en Initialization by two lines. \~ + \details \ru Инициализация по двум прямым. + В случа успеха инициализирует плоскость по первой прямой + и вектору - направлению второй прямой. + \en Initialization by two lines. + In case of success it initializes a plane by the first line + and direction of the second line. \~ + \param[in] line1 - \ru Первая прямая + \en First line. \~ + \param[in] line2 - \ru Вторая прямая + \en Second line \~ + */ + bool Init( const MbLine3D & line1, const MbLine3D & line2 ); + + /// \ru Инициализация плоскости по трем точкам. \en Initialization of plane by three points. + bool Init( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2 ); + + /** \brief \ru Инициализация по плейсменту и версии. + \en Initialization by placement and version. \~ + \details \ru Инициализация по плейсменту и версии. + \en Initialization by placement and version. \~ + \warning \ru Только для использования в КОМПАС-3D. + \en This can be used only in KOMPAS-3D. \~ + */ + void Update( const MbPlacement3D &, VERSION version ); // \ru Жёсткая привязка к плейсменту(детали) \en Rigid binding to a placement (a part) + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равными. \en Make equal. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin () const; + virtual double GetVMin () const; + virtual double GetUMax () const; + virtual double GetVMax () const; + virtual bool IsUClosed() const; + virtual bool IsVClosed() const; + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + В отличии от других поверхностей функции PointOn, Derive... плоскости не корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + In contrast to other surfaces functions PointOn and Derive.. of plane don't correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке. \en Values of derivatives at point. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Function of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + virtual void GetLimitPoint( ptrdiff_t number, MbCartPoint3D & pnt ) const; + virtual void GetLimitPoint( ptrdiff_t number, MbCartPoint & pnt ) const; + + virtual double CurvatureU ( double u, double v ) const; // \ru Кривизна линии u. \en Curvature of the line u. + virtual double CurvatureV ( double u, double v ) const; // \ru Кривизна линии v. \en Curvature of the line v. + + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской \en Whether a surface is planar. + + virtual MbSplineSurface * NurbsSurface( double u1, double u2, double v1, double v2, bool bmatch = false ) const; // \ru NURBS копия поверхности \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Creation of an offset surface. + + virtual MbCurve3D * CurveU ( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV ( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const \en A spatial copy of the line u = const. + virtual MbCurve3D * CurveUV( const MbLineSegment &, bool bApprox = true ) const; // \ru Пространственная копия линии по параметрической линии \en A spatial copy of line by parametric line. + + // \ru С какой стороны от плоскости находится точка. \en Point location relative to the plane. + // \ru Возвращает результат : \en Returns result: + // \ru iloc_InItem = 1 - точка находится над плоскостью, \en Iloc_InItem = 1 - point is located above the plane, + // \ru iloc_OnItem = 0 - точка находится на плоскости, \en Iloc_OnItem = 0 - point is located on the plane, + // \ru iloc_OutOfItem = -1 - точка находится под плоскостью. \en Iloc_OutOfItem = -1 - point is located below the plane. + virtual MbeItemLocation PointRelative ( const MbCartPoint3D & pnt, double eps = ANGLE_REGION ) const; + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & v, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Ближайшая проекция точки на поверхность в направлении вектора. \en The nearest projection of a point to the surface in direction of the vector. + virtual bool NearDirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vector, + double & u, double & v, bool ext, MbRect2D * uvRange = NULL, bool onlyPositiveDirection = false ) const; + // \ru Пересечения с линией. \en Intersection with a line. + virtual MbeNewtonResult CurveIntersectNewton( const MbCurve3D &, double funcEpsilon, size_t limit, + double & u, double & v, double & t, bool ext0, bool ext ) const; // \ru Нахождениe точки пересечения c кривой. \en Search of a point of intersection with curve. + virtual void CurveIntersection ( const MbCurve3D &, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; // \ru Все точки пересечения плоскости и кривой. \en All points of intersection between a plane and a curve. + // \ru Пересечение с поверхностью. \en Intersection with surface. + virtual MbeNewtonResult SurfaceIntersectNewton( const MbSurface & surf, MbeParamDir switchPar, double funcEpsilon, size_t limit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces are similar to merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + virtual double GetParamDelta() const; // \ru Дать максимальное приращение параметра. \en Get the maximum increment of parameter. + virtual double GetParamPrice() const; // \ru Дать мимнимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual void CalculateGabarit( MbCube &gab ) const; // \ru Выдать габарит поверхности. \en Get bounding box of surface. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + virtual void IncludePoint( double u, double v ); // \ru Включить точку в область определения. \en Include a point into domain. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If it equals true then all derivatives with respect to u which have more than first order are equal to null. + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If it equals true then all derivatives with respect to v which have more than first order are equal to null. + + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; // \ru Является ли объект смещением. \en Is the object a shift? + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces. + \{ */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /** \} */ + /** \ru \name Функции плоскости + \en \name Functions of plane. + \{ */ + /// \ru Пересекается ли габаритный куб поверхности с плоскостью. \en Whether the bounding cube of a surface intersects a plane. + bool CubeIntersection( const MbSurface & ) const; + /// \ru Пересекается ли плоскость с кубом. \en Whether a plane intersects a cube. + bool Intersect( const MbCube & c ) const; + + /** \brief \ru Установить пределы поверхности. + \en Set surface limits. \~ + \details \ru Установить пределы поверхности квадратом с центром в начале координат + и стороной, равной 2 * d. + \en Set surface limits by the square with a center in origin + and a side equal to 2 * d. \~ + */ + void SetLimit( double d ) { umax = vmax = ::fabs(d); umin = vmin = -::fabs(d); } + + /** \brief \ru Установить пределы поверхности. + \en Set surface limits. \~ + \details \ru Установить пределы поверхности прямоугольником с центром в начале координат, + шириной, равной 2 * u, и высотой, равной 2 * v. + \en Set surface limits by the rectangle with a center in origin, + width equal to 2 * u and height equal to 2 * v. \~ + */ + void SetLimit( double u, double v ) { umax = ::fabs(u); vmax = ::fabs(v); umin = -umax; vmin = -vmax; } + + /** \brief \ru Включить проекцию куба. + \en Include a cube projection. \~ + \details \ru Расширить пределы плоскости, добавив проекцию куба. + \en Extend the plane limits by adding of the cube projection. \~ + */ + bool IncludeCube( const MbCube & ); + + /** \brief \ru Установить проекцию куба. + \en Set cube projection. \~ + \details \ru Изменить пределы плоскости на проекцию куба на плоскость. + \en Change the limits of plane to the cube projection on plane. \~ + */ + bool AssignCube ( const MbCube & ); + + /// \ru Синус угла прямой с плоскостью. \en A sine of an angle between the line and the plane. + double GetNormalAngle( const MbLine3D & line ) const; + /// \ru Матрица для преобразования симметрии относительно плоскости. \en The matrix of symmetry transformation relative to the plane + void Symmetry ( MbMatrix3D & m ) const { position.Symmetry(m); } + /// \ru Инвертировать нормаль плоскости. \en Invert the normal of plane. + void Invert( MbMatrix * = NULL, MbRegTransform * ireg = NULL ); + + /// \ru Сделать систему координат правой. \en Make the coordinate system right. + void SetRightPlacement() { position.SetRight(); SetDirtyGabarit(); } + + /** \brief \ru Совместить с плейсментом. + \en Match with the placement. \~ + \details \ru Совместить с плейсментом путем вращения до параллельности и перемещения вдоль нормали плейсмента.\n + Центром плоскости становится проекция центра системы координат p.\n + Ось Z плоскости сохраняется.\n + Осью X плоскости становится проекция оси X системы координат p. + \en Match with the placement by rotation till the parallelism and translation along placement normal. + The projection of the coordinate system p origin becomes the center of a plane.\n + The axis Z of a plane remains.\n + The projection X axis of the coordinate system p becomes the axis X of the plane. \~ + \warning \ru Только для использования в КОМПАС-3D. + \en This can be used only in KOMPAS-3D. \~ + */ + void AdaptToPlace( const MbPlacement3D & p ) { position.AdaptToPlace(p); SetDirtyGabarit(); } + + /// \ru Установить систему координат. \en Set the coordinate system. + void SetPlacement( const MbPlacement3D & p ) { position.Init(p); SetDirtyGabarit(); } + + /** \brief \ru Точки пересечения плоскости и плоской кривой. + \en Intersection points of a plane and a planar curve. \~ + \details \ru Точки пересечения плоскости и плоской кривой. + \en Intersection points of a plane and a planar curve. \~ + \param[in] curvePlace - \ru Плейсмент кривой + \en Curve placement \~ + \param[in] curve - \ru Кривая + \en Curve \~ + \param[out] uv - \ru Точки пересечения на плоскости + \en Intersection points on plane \~ + \param[out] tt - \ru Параметры точек пересечения на кривой + \en Parameters of intersection points on curve \~ + \param[in] ext0 - \ru Признак поиска точек пересечения на продолжении плоскости + \en An attribute of search of intersection points on the plane extension \~ + \param[in] ext - \ru Признак поиска точек пересечения на продолжении кривой + \en An attribute of search of intersection points on the curve extension \~ + \param[in] touchInclude - \ru true, если нужны точки касания + \en True if tangency points are required \~ + */ + void PlaneCurveIntersection( const MbPlacement3D & curvePlace, MbCurve & curve, + SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + // \ru Подобные ли поверхности для объединения (слива) проверкой по угловым точкам \en Whether surfaces are similar to merge with check by angular points + /** \brief \ru Подобны ли плоскости для объединения. + \en Whether planes are similar to merge. \~ + \details \ru Подобны ли плоскости для объединения. + \en Whether planes are similar to merge. \~ + \param[in] plane - \ru Вторая плоскость + \en Second plane \~ + \param[in] rect0 - \ru Область параметров на первой плоскости + \en Parameter region on the first plane \~ + \param[in] rect1 - \ru Область параметров на второй плоскости + \en Parameter region on the second plane \~ + */ + bool IsSimilarPlanes( const MbPlane & plane, const MbRect & rect0, const MbRect & rect1 ) const; + + /// \ru Является ли габарит плоскости вырожденным. \en Whether the bounding box of a plane is degenerate. + bool IsAreaDegenerate() const; + /** \} */ + +private: + void operator = ( const MbPlane & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbPlane ) +}; // MbPlane + +IMPL_PERSISTENT_OPS( MbPlane ) + +//------------------------------------------------------------------------------ +// \ru Пересечение с граничным прямоугольником \en Intersection with the bounding rectangle. +// --- +bool LineClassification( const MbCartPoint & p, const MbVector & direct, + double umin, double vmin, double umax, double vmax, + double & tmin, double & tmax ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Пересечение или расстояние между бесконечной прямой и бесконечной плоскостью. + \en Intersection or distance between infinite line and infinite plane. \~ + \details \ru Пересечение бесконечной прямой и бесконечной плоскости\n + или расстояние между бесконечной прямой и бесконечной плоскостью. + \en Intersection of infinite line and infinite plane.\n + or distance between infinite line and infinite plane. \~ + \param[in] line1 - \ru Прямая + \en Line \~ + \param[in] plane2 - \ru Плоскость + \en Plane \~ + \param[out] p1 - \ru Точка пересечения на кривой + \en Intersection point on curve \~ + \param[out] p2 - \ru Точка пересечения на плоскости + \en Intersection point on plane \~ + \return \ru Расстояние между прямой и плоскостью + \en Distance between line and plane \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (double) LinePlaneNearestPoints( const MbLine3D & line1, const MbPlane & plane2, + MbCartPoint3D & p1, MbCartPoint3D & p2 ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Пересечение двух бесконечных плоскостей + \en Intersection of two infinite planes \~ + \details \ru Пересечение двух бесконечных плоскостей + \en Intersection of two infinite planes \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (MbLine3D *) PlanesIntersection( const MbPlane & plane1, const MbPlane & plane2 ); + + +#endif // __SURF_PLANE_H diff --git a/C3d/Include/surf_polysurface.h b/C3d/Include/surf_polysurface.h new file mode 100644 index 0000000..4ba7549 --- /dev/null +++ b/C3d/Include/surf_polysurface.h @@ -0,0 +1,401 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность, заданная прямоугольной матрицей точек. + \en A surface specified by rectangular matrix of points. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_POLYSURFACE_H +#define __SURF_POLYSURFACE_H + + +#include +#include +#include + + +struct MbNurbsPointInfo; +class MATH_CLASS MbSurfaceIntersectionCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность, заданная прямоугольной матрицей точек. + \en A surface specified by rectangular matrix of points. \~ + \details \ru Поверхность, заданная прямоугольной матрицей контрольных точек размерности vcount ucount, + является родительским классом NURBS поверхности MbSplineSurface. + \en A surface specified by rectangular matrix of control points with dimension vcount * ucont + is a parent class of NURBS surface MbSplineSurface. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbPolySurface : public MbSurface { +protected: + Array2 points; ///< \ru Матрица контрольных точек. \en A matrix of control points. + bool uclosed; ///< \ru Признак замкнутости по первому параметру u. \en An attribute of closedness by u-parameter. + bool vclosed; ///< \ru Признак замкнутости по второму параметру v. \en An attribute of closedness by v-parameter. + size_t ucount; ///< \ru Количество колонок. \en Count of columns. + size_t vcount; ///< \ru Количество строк. \en Count of rows. + +protected: + /// \ru Пустой конструктор. \en Empty constructor. + MbPolySurface(); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по матрице точек и замкнутости по u и v. + \en Constructor of surface by the matrix of points and closedness in directions of u and v. \~ + \param[in] vert - \ru Матрица точек. + \en Matrix of points. \~ + \param[in] ucl - \ru Замкнута ли поверхность по параметру u. + \en Whether a surface is closed in u-parameter direction. \~ + \param[in] vcl - \ru Замкнута ли поверхность по параметру v. + \en Whether a surface is closed in v-parameter direction. \~ + */ + MbPolySurface( Array2 & vert, bool ucl, bool vcl ); + /** \brief \ru Конструктор поверхности. + \en Constructor of surface. \~ + \details \ru Конструктор поверхности по массиву точек и замкнутости по u и v. Формирует матрицу точек по заданному массиву. + Заполняет сначала первую колонку сверх вниз, затем вторую и т.д. В массиве должно быть nu*nv элементов. + \en Surface constructor by points array and closedness in direction of u and v. It forms a points matrix by a given array. + It fills downward the first column at first, then the second column etc. Array should contain nu*nv elements. \~ + \param[in] nu - \ru Число колонок в матрице точек. + \en Columns count in points matrix. \~ + \param[in] nv - \ru Число колонок в матрице точек. + \en Columns count in points matrix. \~ + \param[in] vert - \ru Множество точек. + \en A set of points. \~ + \param[in] ucl - \ru Замкнута ли поверхность по параметру u. + \en Whether a surface is closed in u-parameter direction. \~ + \param[in] vcl - \ru Замкнута ли поверхность по параметру v. + \en Whether a surface is closed in v-parameter direction. \~ + */ + MbPolySurface( size_t nu, size_t nv, const SArray & vert, bool ucl, bool vcl ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbPolySurface( const MbPolySurface & ); +public: + virtual ~MbPolySurface(); + +public: + VISITING_CLASS( MbPolySurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента \en Type of element + virtual MbeSpaceType Type() const; // \ru Тип элемента \en Type of element + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Cделать копию элемента \en Make a copy of an element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными \en Determine whether objects are equal + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным \en Make equal + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице \en Transform element according to the matrix + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг \en Translation + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси \en Rotate about an axis + + virtual void GetProperties( MbProperties & ) = 0; // \ru Выдать свойства объекта \en Get properties of the object + virtual void SetProperties( const MbProperties & ) = 0; // \ru Записать свойства объекта \en Set properties of the object + virtual void GetBasisPoints( MbControlData3D & ) const = 0; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ) = 0; // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const = 0; + virtual double GetVMin() const = 0; + virtual double GetUMax() const = 0; + virtual double GetVMax() const = 0; + virtual bool IsUClosed() const; // \ru Замкнута ли поверхность по параметру u. \en Whether a surface is closed in u-parameter direction. + virtual bool IsVClosed() const; // \ru Замкнута ли поверхность по параметру v. \en Whether a surface is closed in v-parameter direction. + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const = 0; // \ru Точка на поверхности \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const = 0; // \ru Первая производная по u \en First derivative with respect to u + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Первая производная по v \en First derivative with respect to v + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по u \en Second derivative with respect to u + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по v \en Second derivative with respect to v + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const = 0; // \ru Вторая производная по uv \en Second derivative with respect to u and v + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const = 0; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const = 0; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const = 0; + /** \} */ + + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + /// \ru Установить признак замкнутости по U. \en Set the attribute of closedness in direction of u. + virtual void SetUClosed( bool cls ); + /// \ru Установить признак замкнутости по V. \en Set the attribute of closedness in direction of v. + virtual void SetVClosed( bool cls ); + /// \ru Перестроить поверхность. \en Rebuild a surface. + virtual void Rebuild() = 0; + + /// \ru Вернуть количество строк в матрице точек. \en Return rows count in points matrix. + size_t GetPointsLines () const { return points.Lines(); } + /// \ru Вернуть количество столбцов в матрице точек. \en Return columns count in points matrix. + size_t GetPointsColumns() const { return points.Columns(); } + /** \brief \ru Выдать точку, расположенную в i строке, j колонке. + \en Get the point located at row i and column j. \~ + \details \ru Выдать точку, расположенную в i строке, j колонке.\n + \en Get the point located at row i and column j.\n \~ + \param[in] i - \ru Строка. + \en String. \~ + \param[in] j - \ru Колонка. + \en Column. \~ + \param[in,out] pnt - \ru Запрашиваемая точка. + \en Requested point. \~ + */ + void GetPoint ( size_t i, size_t j, MbCartPoint3D & pnt ) const { pnt = points( i, j ); } + /** \brief \ru Сдвинуть точку, расположенную в i строке, j колонке на заданный вектор. + \en Translate the point located at row i and column j by the given vector. \~ + \details \ru Сдвинуть точку, расположенную в i строке, j колонке на заданный вектор.\n + \en Translate the point located at row i and column j by the given vector.\n \~ + \param[in] i - \ru Строка. + \en String. \~ + \param[in] j - \ru Колонка. + \en Column. \~ + \param[in] v - \ru Вектор перемещения точки. + \en A vector of point translation. \~ + */ + void MovePoint( size_t i, size_t j, const MbVector3D & v ) { points(i,j).Move(v); } + + /// \ru Получить количество колонок. \en Get count of columns. + size_t GetPointsUCount() const { return ucount; } + /// \ru Получить количество строк. \en Get count of rows. + size_t GetPointsVCount() const { return vcount; } + /** \brief \ru Заполнить матрицу точек. + \en Fill points matrix. \~ + \details \ru Заполнить матрицу точек.\n + \en Fill points matrix.\n \~ + \param[in] pnts - \ru Матрица точек. + \en Matrix of points. \~ + */ + bool GetPoints( Array2 & pnts ) const { return pnts.Init( points ); } + /** \brief \ru Выдать массив отрезков. + \en Get the array of segments. \~ + \details \ru В функции строятся все горизонтальные отрезки между соседними точками и все вертикальные отрезки между соседними точками. + \en The function constructs all horizontal segments between neighboring points and all vertical segments between neighboring points. \~ + \param[in] segments - \ru Множество для хранения отрезков. + \en Set for segments storage. \~ + */ + void GetLineSegments( RPArray & segments ) const; + /** \} */ + + /** \ru \name Функции, предоставляющие интерфейс поверхности для сплайновой формы. + \en \name Functions performing an interface for a surface of spline form. + \{ */ + + /** \brief \ru Получить узловой вектор по выбранному параметру. + \en Get a knot vector by the chosen parameter. \~ + \details \ru Получить узловой вектор по выбранному параметру.\n + \en Get a knot vector by the chosen parameter.\n \~ + \param[in] isU - \ru Определяет, по какой координате запрашивается узловой вектор: true - по u, false - по v. + \en Determines the requested coordinate of a knot vector: true - u, false - v. \~ + \param[in,out] knots - \ru Матрица для хранения узлового вектора. + \en Matrix for knot vector storage. \~ + */ + virtual void GetKnots( bool isU, SArray & knots ) const = 0; + /** \brief \ru Получить матрицу весов вершин. + \en Get the matrix of vertices weights. \~ + \details \ru Получить матрицу весов вершин.\n + \en Get the matrix of vertices weights.\n \~ + \param[in,out] wts - \ru Матрица для заполнения значений весов. + \en A matrix for weights values filling. \~ + */ + virtual void GetWeights( Array2 & wts ) const = 0; + /** \brief \ru Вернуть массив узловых точек и их видимость для операции редактирования как сплайна. + \en Return an array of knot points and their visibility for the operation of editing as spline. \~ + \details \ru Вернуть массив узловых точек и их видимость для операции редактирования как сплайна.\n + \en Return an array of knot points and their visibility for the operation of editing as spline.\n \~ + \param[in,out] params - \ru Матрица контрольных точек с указанием видимости каждой контрольной точки для редактирования. + \en A matrix of control points with specifying of visibility of each control point for editing. \~ + */ + virtual void GetPointsWithVisible ( Array2 & params ) const = 0; + /** \brief \ru Вычисление точек на поверхности, соответствующих узлам. + \en Calculation of points on surface corresponding to knots. \~ + \details \ru Вычисление точек на поверхности, соответствующих узлам.\n + \en Calculation of points on surface corresponding to knots.\n \~ + \param[in,out] params - \ru Матрица для хранения точек на поверхности, соответствующих контрольным точкам. + \en A matrix for keeping of points on surface corresponding to control points. \~ + */ + virtual void CalculateUVParameters( Array2 & params ) const = 0; + /** \brief \ru Вычисление точки на поверхности, соответствующей контрольной точке. + \en Calculation of point on surface corresponding to control point. \~ + \details \ru Вычисление точки на поверхности, соответствующей контрольной точке.\n + \en Calculation of point on surface corresponding to control point.\n \~ + \param[in] uIndex - \ru Столбец контрольной точки. + \en A column of control point. \~ + \param[in] vIndex - \ru Строка контрольной точки. + \en A row of control point. \~ + \param[in,out] point - \ru Точка на поверхности. + \en A point on surface. \~ + \return \ru true, если точка на поверхности успешно найдена. + \en True if a point on surface was successfully found. \~ + */ + virtual bool CalculateUVParameterForKnot( size_t uIndex, size_t vIndex, MbCartPoint & point ) const = 0; + /** \brief \ru Удаление столбца контрольных точек без изменения поверхности. + \en Deletion of a column of control points without changing of a surface. \~ + \details \ru Удаление столбца контрольных точек без изменения поверхности.\n + \en Deletion of a column of control points without changing of a surface.\n \~ + \param[in] rowId - \ru Номер первого удаляемого столбца. + \en Index of the first deleted column. \~ + \param[in] num - \ru Количество удаляемых столбцов. + \en Count of deleted columns. \~ + \param[in] absEps - \ru Погрешность аппроксимации. + \en Approximation tolerance. \~ + \return \ru Число столбцов, которые удалось удалить. + \en Count of columns which are succeeded to delete. \~ + */ + virtual size_t RemoveUKnots( ptrdiff_t & rowId, ptrdiff_t num = 1, double absEps = Math::lengthEpsilon ) = 0; + + /** \brief \ru Удаление строки контрольных точек без изменения поверхности. + \en Deletion of a row of control points without changing of a surface. \~ + \details \ru Удаление строки контрольных точек без изменения поверхности.\n + \en Deletion of a row of control points without changing of a surface.\n \~ + \param[in] rowId - \ru Номер первой удаляемой строки. + \en Index of the first deleted row. \~ + \param[in] num - \ru Количество удаляемых строк. + \en Count of deleted rows. \~ + \param[in] absEps - \ru Погрешность аппроксимации. + \en Approximation tolerance. \~ + \return \ru Число строк, которые удалось удалить. + \en Count of rows which are succeeded to delete. \~ + */ + virtual size_t RemoveVKnots( ptrdiff_t & rowId, ptrdiff_t num = 1, double absEps = Math::lengthEpsilon ) = 0; + /** \brief \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по u. + \en Insertion of a row after the row with the index idBegin without changing of a surface by u. \~ + \details \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по u.\n + \en Insertion of a row after the row with the index idBegin without changing of a surface by u.\n \~ + \param[in] idBegin - \ru Номер ряда, после которого будет вставлен новый ряд. + \en An index of the row a new row will be inserted after. \~ + \param[in] num - \ru Количество вставляемых рядов. + \en Count of inserted rows. \~ + */ + virtual void InsertUKnotsInRegion( ptrdiff_t idBegin, ptrdiff_t num = 1 ) = 0; + /** \brief \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по v. + \en Insertion of a row after the row with the index idBegin without changing of a surface by v. \~ + \details \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по v.\n + \en Insertion of a row after the row with the index idBegin without changing of a surface by v.\n \~ + \param[in] idBegin - \ru Номер ряда, после которого будет вставлен новый ряд. + \en An index of the row a new row will be inserted after. \~ + \param[in] num - \ru Количество вставляемых рядов. + \en Count of inserted rows. \~ + */ + virtual void InsertVKnotsInRegion( ptrdiff_t idBegin, ptrdiff_t num = 1 ) = 0; + /** \brief \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface. + \en Change the order of NURBS by construction of a surface by the function NurbsSurface. \~ + \details \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface.\n + \en Change the order of NURBS by construction of a surface by the function NurbsSurface.\n \~ + \param[in] newDegree - \ru Новый порядок поверхности по u. + \en New surface degree by u. \~ + \return \ru true, если аппроксимация выполнена успешно. + \en True if approximation is succeeded. \~ + */ + virtual bool ChangeUDegreeApprox ( size_t newDegree ) = 0; + /** \brief \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface. + \en Change the order of NURBS by construction of a surface by the function NurbsSurface. \~ + \details \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface.\n + \en Change the order of NURBS by construction of a surface by the function NurbsSurface.\n \~ + \param[in] newDegree - \ru Новый порядок поверхности по v. + \en New surface degree by v. \~ + \return \ru true, если аппроксимация выполнена успешно. + \en True if approximation is succeeded. \~ + */ + virtual bool ChangeVDegreeApprox ( size_t newDegree ) = 0; + + /** \brief \ru Изменить порядок и количество узлов nurbs путем перестроения поверхности с помощью функции NurbsSurface. + \en Change the order and the number of knots of NURBS by construction of a surface by the function NurbsSurface. \~ + \details \ru Изменить порядок и количество узлов nurbs путем перестроения поверхности с помощью функции NurbsSurface.\n + \en Change the order and the number of knots of NURBS by construction of a surface by the function NurbsSurface.\n \~ + \param[in] nUDegree - \ru Новый порядок поверхности по u. + \en New surface degree by u. \~ + \param[in] nVDegree - \ru Новый порядок поверхности по v. + \en New surface degree by v. \~ + \param[in] nUCount - \ru Количество контрольных точек по u. + \en A number of control points in U direction. \~ + \param[in] nVCount - \ru Количество контрольных точек по v. + \en A number of control points in V direction. \~ + \return \ru true, если аппроксимация выполнена успешно. + \en True if approximation is succeeded. \~ + */ + virtual bool ChangeParametersApprox ( size_t nUDegree, size_t nVDegree, ptrdiff_t nUCount, ptrdiff_t nVCount ) = 0; + /** \brief \ru Вычисление фиксированных контрольных точек. + \en Calculation of fixed control points. \~ + \details \ru Вычисление узлов, которые должны быть неподвижны, чтобы при деформации поверхности кривые из + заданного массива не деформаровались. + \en Calculation of knots which should be fixed to forbid the deformation of curves in the given array when a surface + deforms. \~ + \param[in] curves - \ru Множество кривых. + \en A set of curves. \~ + \param[in,out] fixedPoints - \ru Матрица, в которую заносятся данные о необходимости фиксации узлов + для сохранения кривых. Если элемент матрицы равен true - соответствующая ему + контрольная точка должна быть фиксирована. + \en A matrix where the data about necessity of angles fixation is written + to save curves. If an element of matrix equals true then the control point + corresponding to it should be fixed. \~ + \return \ru true, вычисления выполнены успешно. + \en True if calculations are successfully performed. \~ + */ + virtual bool CalculateFixedPoints( const RPArray & curves, Array2 & fixedPoints ) const = 0; + /** \brief \ru Вычисление доли смещения узлов при перемещении со сглаживанием. + \en Calculation of a shift part of knots during the translation with blending. \~ + \details \ru Известно перемещение одной контрольной точки. Перемещение остальных точек, помеченных как подвижные в + матрице movedPoints, зависит от направления ее перемещения, расстояния точки от линии перемещения (moveVector) + и функции сглаживания. Есть три режима сглаживания: выпуклый, вогнутый и плавный переход. + \en A translation of one control point is known. Translation of other points which marked as movable in + the matrix movedPoints depends on the direction of its translation, the distance from the points to the translation line (moveVector) + and the function of blending. There are three modes of blending: convex, concave and smooth transition. \~ + \param[in] movedPoints - \ru Матрица, содержащая данные о перемещаемых точках. + Если элемент матрицы равен 1 - соответствующая ему контрольная точка может быть перемещена, + иначе - неподвижна. + \en A matrix containing data about moved points. + If an element of the matrix equals 1 then the corresponding control point can be moved, + otherwise - it is fixed. \~ + \param[in] uIndex - \ru Столбец перемещаемой контрольной точки, относительно которой будет сглаживание. + \en A column of a moved control point relative to which there will be the blending. \~ + \param[in] vIndex - \ru Строка перемещаемой контрольной точки, относительно которой будет сглаживание. + \en A row of a moved control point relative to which there will be the blending. \~ + \param[in] moveVector - \ru Вектор, по направлению которого смещается контрольная точка. + \en A vector in direction of which the control point is translated. \~ + \param[in] smoothType - \ru Тип сглаживания. \n + dst_None - без сглаживания, dst_Convex - выпуклый, dst_Concave - вогнутый, dst_Smooth - плавный переход. + \en The type of blending. \n + dst_None - no blending, dst_Convex - convex, dst_Concave - concave, dst_Smooth - smooth transition. \~ + \param[in] smoothDegree - \ru Степень функции сглаживания. Положительное число. + \en A degree of the blending function. A positive value. \~ + \param[in,out] partsPoints - \ru Матрица с данными о долях смещения каждой точки относительно смещения перемещаемой точки. + \en A matrix with the data about a part of shift of each point relative to the moved point. \~ + \return \ru true, если вычисления проведены успешно. + \en True if the calculations were successfully performed.. \~ + */ + virtual bool CalculatePartsForSpecMove( const Array2 & movedPoints, + size_t uIndex, size_t vIndex, + const MbVector3D & moveVector, + MbeDirectSmoothType smoothType, + double smoothDegree, + Array2 & partsPoints ) const = 0; + +private: + void operator = ( const MbPolySurface & ); // \ru Не реализовано. \en Not implemented. + /** \} */ + + DECLARE_PERSISTENT_CLASS( MbPolySurface ) +}; + +IMPL_PERSISTENT_OPS( MbPolySurface ) + +#endif // __SURF_POLYSURFACE_H diff --git a/C3d/Include/surf_revolution_surface.h b/C3d/Include/surf_revolution_surface.h new file mode 100644 index 0000000..99521bf --- /dev/null +++ b/C3d/Include/surf_revolution_surface.h @@ -0,0 +1,481 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность вращения. + \en Revolution surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_REVOLUTION_SURFACE_H +#define __SURF_REVOLUTION_SURFACE_H + + +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceContiguousData; +class MATH_CLASS MbOffsetSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность вращения. + \en Revolution surface. \~ + \details \ru Поверхность вращения является кинематической поверхностью с образующей в форме дуги окружности. + Поверхность вращения получена путем движения образующей кривой curve по окружности или её дуге. + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + M(v)(curve(u) - position.origin), \n + где M(v) - матрица поворота точки вокруг оси position.axisZ. \n + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с углом поворота образующей кривой. + \en A revolution surface is a swept surface with generatrix in a circle arc form. + A revolution surface is obtained by moving of the generatrix 'curve' along the circle or its arc. + Radius-vector of line surface is described by the vector function \n + r(u,v) = position.origin + M(v)(curve(u) - position.origin), \n + where M(v) - rotate matrix by axis position.axisZ. \n + The first surface parameter coincides with the parameter of generatrix. + The second surface parameter coincides with the rotation angle of generatrix. \~ + \ingroup Surfaces +*/ // --- +class MATH_CLASS MbRevolutionSurface : public MbSweptSurface { +private: + MbPlacement3D position; ///< \ru Местная система координат (position.axisZ - ось вращения). \en Local coordinate system ('position.axisZ' is rotation axis). + double uPoleMin; ///< \ru Значение параметра U в полюсе поверхности, если он есть. \en A value of U parameter in the pole of a surface if it exists. + double uPoleMax; ///< \ru Значение параметра U в полюсе поверхности, если он есть. \en A value of U parameter in the pole of a surface if it exists. + bool poleMin; ///< \ru Наличие полюса при umin. \en Existence of a pole at umin. + bool poleMax; ///< \ru Наличие полюса при umax. \en Existence of a pole at umax. + bool planeData; ///< \ru Кривая лежит в плоскости, содержащей ось вращения, (частный случай). \en A curve is located on a plane which contains the rotation axis (special case). + MbMatrix3D into; ///< \ru Матрица преобразования в систему position. \en Matrix of transformation to the system 'position'. + MbMatrix3D from; ///< \ru Матрица преобразования из системы position. \en Matrix of transformation from the system 'position'. + double uMinNormDelta; ///< \ru Величина отступа от минимального параметра u при подсчете нормали в полюсе. \en A value of indent from the minimum value of u in the calculation of normal vector in pole. + double uMaxNormDelta; ///< \ru Величина отступа от максимального параметра u при подсчете нормали в полюсе. \en A value of indent from the maximum value of u in the calculation of normal vector in pole. + +protected: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbRevolutionSurfaceAuxiliaryData : public AuxiliaryData { + public: + DPtr data; ///< \ru Дополнительные данные о поверхности. \en Additional data about a surface. + MbRevolutionSurfaceAuxiliaryData(); + MbRevolutionSurfaceAuxiliaryData( const MbRevolutionSurfaceAuxiliaryData & init ); + virtual ~MbRevolutionSurfaceAuxiliaryData(); + }; + + mutable CacheManager cache; + +public: + + /** \brief \ru Конструктор по образующей, началу и оси Z локальной системы координат и углу. + \en Constructor by generatrix, origin, Z axis of the local coordinate system and angle. \~ + \details \ru Конструктор по образующей, началу и оси Z локальной системы координат и углу. + \en Constructor by generatrix, origin, Z axis of the local coordinate system and angle. \~ + \param[in] c - \ru Образующая кривая + \en Generating curve \~ + \param[in] p - \ru Начало оси вращения + \en Origin of rotation axis \~ + \param[in] a - \ru Направление оси вращения + \en Rotation axis direction \~ + \param[in] angle - \ru Угол вращения + \en Rotation angle \~ + \param[in] same - \ru Признак использования оригинала образующей кривой, а не её копии. + \en Attribute of using the original of generating curve instead of its copy. \~ + */ + MbRevolutionSurface( const MbCurve3D & c, const MbCartPoint3D & p, const MbVector3D & a, double angle, bool same ); + + /** \brief \ru Конструктор по образующей, оси вращения и углу. + \en Constructor by generatrix, rotation axis and angle. \~ + \details \ru Конструктор по образующей, оси вращения и углу. + \en Constructor by generatrix, rotation axis and angle. \~ + \param[in] c - \ru Образующая кривая + \en Generating curve \~ + \param[in] a - \ru Ось вращения + \en Rotation axis \~ + \param[in] angle - \ru Угол вращения + \en Rotation angle \~ + \param[in] same - \ru Признак использования оригинала образующей кривой, а не её копии. + \en Attribute of using the original of generating curve instead of its copy. \~ + */ + MbRevolutionSurface( const MbCurve3D & c, const MbAxis3D & a, double angle, bool same ); + + /** \brief \ru Конструктор по образующей, оси вращения, минимальному и максимальному углу. + \en Constructor by generatrix, rotation axis, minimal and maximal angles. \~ + \details \ru Конструктор по образующей, оси вращения, минимальному и максимальному углу. + \en Constructor by generatrix, rotation axis, minimal and maximal angles. \~ + \param[in] c - \ru Образующая кривая + \en Generating curve \~ + \param[in] a - \ru Ось вращения + \en Rotation axis \~ + \param[in] anMin - \ru Минимальное значение угла + \en Minimal value of angle \~ + \param[in] anMax - \ru Максимальное значение угла + \en Maximal value of angle \~ + \param[in] same - \ru Признак использования оригинала образующей кривой, а не её копии. + \en Attribute of using the original of generating curve instead of its copy. \~ + */ + MbRevolutionSurface( const MbCurve3D & c, const MbAxis3D & a, double anMin, double anMax, bool same ); + +protected: + MbRevolutionSurface( const MbRevolutionSurface &, MbRegDuplicate * ); +private: + // \ru Конструктор для создания эквидистанты \en Constructor for offset creation + MbRevolutionSurface( const MbRevolutionSurface &, MbCurve3D & offsetCurve, bool same ); +public: + virtual ~MbRevolutionSurface(); + +public: + VISITING_CLASS( MbRevolutionSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Function of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии u. \en Curvature of u line. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v line. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v \en Get the number of polygons in v-direction. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru NURBS копия поверхности \en NURBS copy of surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности \en Creation of an offset surface + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const \en A spatial copy of the line u = const. + + // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection on the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection on the surface. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces are similar to merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + // \ru Подобные ли поверхности для объединения (слива) \en Whether the surfaces are similar to merge + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; // \ru Специальный случай \en Special case + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether the surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether a surface is convex. + virtual bool GetCylinderAxis( MbAxis3D & axis ) const ; // \ru Дать ось поверхности. \en Get the axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether a pole exists on parametric region boundary of spline curve. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + + virtual bool IsRectangular() const; // \ru Если true производные по u и v ортогональны. \en If true then derivatives with respect to u and v are orthogonal. + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If it equals true then all derivatives with respect to u which have more than first order are equal to null. + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + /** \} */ + /** \ru \name Функции поверхности вращения + \en \name Function of revolution surface. + \{ */ + double GetAngle() const { return vmax - vmin; } ///< \ru Угол вращения. \en Rotation angle. + MbAxis3D GetAxis () const; ///< \ru Ось вращения. \en Rotation axis. + const MbCartPoint3D & GetOrigin() const { return position.GetOrigin(); } ///< \ru Центр локальной системы координат. \en Center of the local coordinate system. + const MbVector3D & GetAxisZ () const { return position.GetAxisZ(); } ///< \ru Направление оси вращения. \en Rotation axis direction. + const MbPlacement3D & GetPlacement() const { return position; } ///< \ru Локальная система координат. \en Local coordinate system. + void SetAxis( const MbAxis3D & initAxis ); ///< \ru Установить ось вращения. \en Set rotation axis. + + /// \ru Лежит ли образующая кривая в плоскости, содержащей ось вращения. \en Whether generating curve lies on a plane containing the rotation axis. + bool IsPlaneData() const { return planeData; } + + /** \brief \ru Единичный вектор - направление оси X локальной системы координат. + \en Unit vector - direction of the X axis of the local coordinate system. \~ + \details \ru Единичный вектор - направление оси X локальной системы координат.\n + В случае, если образующая кривая лежит в плоскости, содержащей ось вращения, + вектор является единичным вектором в плоскости образующей кривой. + \en Unit vector - direction of the X axis of the local coordinate system.\n + In a case when generating curve lies on a plane containing rotation axis + the vector is a unit vector in a plane of generating curve. \~ + \param[out] axis - \ru Вектор - результат + \en A vector - the result \~ + \result \ru true, если образующая кривая лежит в плоскости, содержащей ось вращеOния, и + локальная система координат поверхности является ортогональной и изотропной по осям. + \en True if generating curve lies on a plane containing rotation axis and + the local coordinate system of a surface is orthogonal and isotropic by the axes. \~ + */ + bool GetPlaneDataAxis( MbVector3D & axis ) const; + + /** \brief \ru Создание эквидистантной поверхности. + \en Creation of an offset surface. \~ + \details \ru Создание поверхности типа st_OffsetSurface, совпадающей с данной поверхностью.\n + Если образующая кривая является эквидистантной кривой на плоскости, + то, используя ее базовую кривую в качестве образующей, создается поверхность + вращения и по ней эквидистантная поверхность.\n + Поверхность строится в случае, если образующая кривая лежит в плоскости, содержащей ось вращения.\n + Используется только в конвертерах. + \en Creation of a surface of the type OffsetSurface coincident with the given surface. \n + If the generating curve is an offset curve on a plane + then using its basis curve as generatrix a revolution surface is created + and an offset surface is created by it. \n + A surface is constructed in case when generating curve lies on a plane containing rotation axis. \n + This is used only in converters. \~ + */ + MbOffsetSurface * GetSurfaceFromPlaneCurveOffset() const; + + /// \ru Дать максимальный радиус поверхности, если это возможно. \en Get maximum radius of surface if it possible or null. + double GetMaxRadius() const; + /** \} */ + +private: // \ru Внутренние функции поверхности. \en Internal functions of surface. + void Init( const MbCartPoint3D & origin, const MbVector3D & axisZ, double v1, double v2 ); // \ru Продолжение конструктора. \en Continuation of constructor. + void InitNormDeltaU(); // \ru Посчитать величины отступа от uMin и uMax при подсчете нормали. \en Calculate indent values from uMin and uMax when calculation of a normal vector. + void InitPosition( const MbCartPoint3D & origin, const MbVector3D & axisZ ); + void ExactNormal( double u, double v, const MbVector3D & derU, const MbVector3D & derV, MbVector3D & nor ) const; // \ru Нормаль. \en Normal. + void CheckPoles(); // \ru Проверить полюса. \en Check poles. + inline void CheckParam ( double &u, double &v ) const; // \ru Проверить параметры. \en Check parameters. + inline void CheckParam_( double &u ) const; // \ru Проверить параметр. \en Check parameter. + inline void RotateVector ( double sinV, double cosV, MbVector3D & v ) const; + inline void RotateDeriveV ( double sinV, double cosV, MbVector3D & v ) const; + inline void RotateDeriveVV ( double sinV, double cosV, MbVector3D & v ) const; + inline void RotateDeriveVVV( double sinV, double cosV, MbVector3D & v ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRevolutionSurface ) + OBVIOUS_PRIVATE_COPY( MbRevolutionSurface ) // \ru Не реализовано. \en Not implemented. +}; + +IMPL_PERSISTENT_OPS( MbRevolutionSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbRevolutionSurface::CheckParam ( double & u, double & v ) const +{ + if (v < vmin) { + if ( vclosed ) + v -= ( ::floor((v - vmin) * Math::invPI2) * M_PI2 ); + else + v = vmin; + } + if ( v > vmax ) { + if ( vclosed ) + v -= ( ::floor((v - vmin) * Math::invPI2) * M_PI2 ); + else + v = vmax; + } + if ( poleMin && (u < umin) ) + u = umin; + if ( poleMax && (u > umax) ) + u = umax; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbRevolutionSurface::CheckParam_( double & u ) const +{ + if ( poleMin && (u < umin) ) + u = umin; + if ( poleMax && (u > umax) ) + u = umax; + + // BUG_58512 + if ( !poleMin && (uPoleMin != UNDEFINED_DBL) ) { + if ( uPoleMin < umin && u < uPoleMin ) + u = uPoleMin; + } + if ( !poleMax && (uPoleMax != UNDEFINED_DBL) ) { + if ( uPoleMax > umax && u > uPoleMax ) + u = uPoleMax; + } +} + + +//------------------------------------------------------------------------------ +// \ru Поворот вектора вокруг оси спирали \en Rotation of vector around spiral axis +// --- +inline void MbRevolutionSurface::RotateVector( double sinV, double cosV, MbVector3D & _vector ) const +{ +// if ( planeData ) { +// double r = _vector * axisX; +// _vector.Set( axisX, r * cosV, axisY, r * sinV, axis.GetAxisZ(), _vector * axis.GetAxisZ() ); +// } +// else { +// _vector.Set( _vector, cosV, axis.GetAxisZ(), (_vector * axis.GetAxisZ()) * (1.0 - cosV), (axis.GetAxisZ() | _vector), sinV ); +// } + _vector.Transform( into ); + double x = (_vector.x * cosV) - (_vector.y * sinV); + double y = (_vector.x * sinV) + (_vector.y * cosV); + _vector.x = x; + _vector.y = y; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Первая производная поворота вектора вокруг оси спирали \en First derivative of vector of rotation around the spiral axis +// --- +inline void MbRevolutionSurface::RotateDeriveV( double sinV, double cosV, MbVector3D & _vector ) const +{ +// if ( planeData ) { +// double r = _vector * axisX; +// _vector.Set( axisX, -r * sinV, axisY, r * cosV ); +// } +// else { +// _vector.Set( _vector, -sinV, axis.GetAxisZ(), (_vector * axis.GetAxisZ()) * sinV, (axis.GetAxisZ() | _vector), cosV ); +// } + _vector.Transform( into ); + double x = - (_vector.x * sinV) - (_vector.y * cosV); + double y = (_vector.x * cosV) - (_vector.y * sinV); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Вторая производная поворота вектора вокруг оси спирали \en Second derivative of vector of rotation around spiral axis +// --- +inline void MbRevolutionSurface::RotateDeriveVV( double sinV, double cosV, MbVector3D & _vector ) const +{ +// if ( planeData ) { +// double r = _vector * axisX; +// _vector.Set( axisX, -r * cosV, axisY, -r * sinV ); +// } +// else { +// _vector.Set( _vector, -cosV, axis.GetAxisZ(), (_vector * axis.GetAxisZ()) * cosV, (axis.GetAxisZ() | _vector), -sinV ); +// } + _vector.Transform( into ); + double x = - (_vector.x * cosV) + (_vector.y * sinV); + double y = - (_vector.x * sinV) - (_vector.y * cosV); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Третья производная поворота вектора вокруг оси спирали \en Third derivative of vector of rotation around spiral axis +// --- +inline void MbRevolutionSurface::RotateDeriveVVV( double sinV, double cosV, MbVector3D & _vector ) const +{ +// if ( planeData ) { +// double r = _vector * axisX; +// _vector.Set( axisX, r * sinV, axisY, -r * cosV ); +// } +// else { +// _vector.Set( _vector, sinV, axis.GetAxisZ(), -(_vector * axis.GetAxisZ()) * sinV, (axis.GetAxisZ() | _vector), -cosV ); +// } + _vector.Transform( into ); + double x = (_vector.x * sinV) + (_vector.y * cosV); + double y = - (_vector.x * cosV) + (_vector.y * sinV); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +#endif // __SURF_REVOLUTION_SURFACE_H diff --git a/C3d/Include/surf_ruled_surface.h b/C3d/Include/surf_ruled_surface.h new file mode 100644 index 0000000..90117d0 --- /dev/null +++ b/C3d/Include/surf_ruled_surface.h @@ -0,0 +1,386 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Линейчатая поверхность. + \en Ruled surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_RULED_SURFACE_H +#define __SURF_RULED_SURFACE_H + + +#include +#include + + +class MATH_CLASS MbMatrix; +class MATH_CLASS MbConeSurface; +class MATH_CLASS MbExtrusionSurface; + + +//------------------------------------------------------------------------------ +/** \brief \ru Линейчатая поверхность. + \en Ruled surface. \~ + \details \ru Линейчатая поверхность построена по двум кривым путём соединения их соответствующих точек отрезками прямой. + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = (1 - v) curve(u) + v sline(w(u)). \n + Первый параметр поверхности совпадает с параметром кривой curve. + Параметр w кривой sline пропорционален первому параметру поверхности. + Вдоль второго параметра поверхность прямолинейна. + \en A ruled surface is constructed on two curves by connection of its corresponding points by linear segments. + Radius-vector of surface is described by the vector function \n + r(u,v) = (1 - v) curve(u) + v sline(w(u)). \n + First parameter of surface coincides with parameter of 'curve' curve. + Parameter w of 'sline' curve is proportional to first parameter of surface. + Surface is linear along the second parameter. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbRuledSurface : public MbSweptSurface { +public: + + /** \brief \ru Типы линейчатой поверхности. + \en Types of ruled surface. \~ + */ + enum RuledSurfaceType { + rld_Unset = 0, ///< \ru Тип поверхности не установлен. \en Surface type isn't set. + rld_Planar, ///< \ru Геометрия плоскости. \en Planar. + rld_Line, ///< \ru Образующие кривые прямолинейны. \en Generating curves are straight lines. + rld_Cone, ///< \ru Геометрия конической поверхности. \en Conical surface. + rld_PoleMin, ///< \ru Кривая curve вырождена в точку. \en 'curve' curve is degenerated to a point. + rld_PoleMax, ///< \ru Кривая sline вырождена в точку. \en 'sline' curve is degenerated to a point. + rld_Offset, ///< \ru Геометрия поверхности выдавливания с уклоном. \en Extrusion surface with taper. + rld_Swept, ///< \ru Геометрия поверхности выдавливания. \en Extrusion surface. + rld_Arbitrary, ///< \ru Произвольная линейчатая поверхность. \en Arbitrary ruled surface. + }; + +private: + RuledSurfaceType type; ///< \ru Тип линейчатой поверхности. \en Type of ruled surface. + MbCurve3D * sline; ///< \ru Вторая образующая кривая (первой является curve). \en The second generating curve ('curve' is first one). + double tmin; ///< \ru Начальный параметр sline. \en Start parameter of 'sline'. + double dt; ///< \ru Производная параметра кривой sline по параметру u (dt * (u - umin) = t_sline - tmin_sline). \en Derivative of parameter of 'sline' curve by u parameter (dt * (u - umin) = t_sline - tmin_sline). + bool poleMin; ///< \ru Полюс при umin. \en Pole at umin. + bool poleMax; ///< \ru Полюс при umax. \en Pole at umax. + double uMinNormDelta; // \ru Отступ при наличии касательного полюса umin. \en Indent in the presence of umin tangent pole. + double uMaxNormDelta; // \ru Отступ при наличии касательного полюса umax. \en Indent in the presence of umax tangent pole. + double uminExt; // \ru Минимальное разрешенное значение по u. \en Minimal allowed value by u. + double umaxExt; // \ru Максимальное разрешенное значение по u. \en Maximal allowed value by u. + double vminExt; // \ru Минимальное разрешенное значение по v. \en Minimal allowed value by v. + double vmaxExt; // \ru Максимальное разрешенное значение по u. \en Maximal allowed value by v. + +public: + + /** \brief \ru Конструктор по двум кривым. + \en Constructor by two curves. \~ + \details \ru Конструктор по двум кривым. + \en Constructor by two curves. \~ + \param[in] c1 - \ru Первая образующая кривая + \en First generating curve \~ + \param[in] c2 - \ru Вторая образующая кривая. + \en Second generating curve. \~ + \param[in] same - \ru Признак использования оригинала образующих кривых, а не их копий. + \en Attribute of usage of original of generating curves, not a copies. \~ + */ + MbRuledSurface( const MbCurve3D & c1, const MbCurve3D & c2, bool same ); + + /** \brief \ru Конструктор по двум кривым и параметрам по V. + \en Constructor by two curves and parameters by V. \~ + \details \ru Конструктор по двум кривым и параметрам по V.\n + Используется только в конвертерах. + \en Constructor by two curves and parameters by V.\n + Used only in converters. \~ + \param[in] vin - \ru Минимальный параметр по V + \en Minimal parameter by V \~ + \param[in] vax - \ru Максимальный параметр по V + \en Maximal parameter by V \~ + \param[in] c1 - \ru Первая образующая кривая + \en First generating curve \~ + \param[in] c2 - \ru Вторая образующая кривая + \en Second generating curve \~ + */ + // \ru Используется только в конверторах для эллипса и цилиндра в orthosur \en Used only in converters for ellipse and cylinder in 'orthosur' + MbRuledSurface( double vin, double vax, const MbCurve3D & c1, const MbCurve3D & c2 ); + +protected: + MbRuledSurface( const MbRuledSurface &, MbRegDuplicate * ); +public: + virtual ~MbRuledSurface (); + +public: + VISITING_CLASS( MbRuledSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Move. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties &properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUPeriod() const; // \ru Вернуть период. \en Return period. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... of surfaces correct parameters + when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en The point on the surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface's domain + functions _PointOn, _Derive... of surfaces don't correct + parameters when they are out of bounds of rectangular domain of parameters. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en The point on the extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en The first derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en The first derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en The second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en The second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en The second derivative with respect to uv. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en The derivative of normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии по u. \en Curvature of line by u. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v-line. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether the surface is planar. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the count of polygons by u. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the count of polygons by v. + + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + + // \ru Ближайшая проекция точки на поверхность. \en The nearest point projection onto the surface. + virtual bool NearPointProjection( const MbCartPoint3D & p, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + + // \ru Пересечение с кривой. \en Intersection with curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + virtual void CalculateGabarit( MbCube & ) const; // \ru Выдать габарит. \en Get the bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к.. \en Calculate bounding box relative to the local coordinate system. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Построить смещенную поверхность. \en Create a shifted surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en Spatial copy of 'v = const'-line. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en Spatial copy of 'u = const'-line. + virtual MbCurve3D * CurveUV( const MbLineSegment &, bool bApprox = true ) const; // \ru Пространственная копия линии по параметрической линии. \en Spatial copy of line by parametric line. + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + virtual bool GetCylinderAxis( MbAxis3D &axis ) const; // \ru Дать ось вращения для поверхности \en Get a rotation axis of a surface + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces to union (joining) are similar. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Подобные ли поверхности для объединения (слива). Специальный случай. Для внутреннего использования. \en Whether the surfaces are similar to merge. Special case. For internal use only. + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional transformation matrix from own parametric region to parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether there is pole on boundary of parametric region of spline curve. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is special. + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine splitting of parametric region of surface by vertical and horizontal lines. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If true, then all the derivatives by U higher the first one are equal to zero. + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If true, then all the derivatives by V higher the first one are equal to zero. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving along the surface + \{ */ + /// \ru Дать вторую образующую кривую. \en Get second generating curve. + const MbCurve3D & GetSline() const { return *sline; } + /// \ru Дать вторую образующую кривую для изменения. \en Get second generating curve for changing. + MbCurve3D & SetSline() { return *sline; } + + /// \ru Тип линейчатой поверхности. \en Type of ruled surface. + inline RuledSurfaceType GetType() const { C3D_ASSERT( type != rld_Unset ); return type; } + /// \ru Обновить тип линейчатой поверхности. \en Update type of ruled surface. + inline void UpdateType(); + /** \} */ + + inline double SlineParameterFrom( const double & u ) const; + inline double SlineParameterInto( const double & t ) const; + +private: + inline void CheckParam( double & u, double & v ) const; // \ru Проверить параметры. \en Check parameters. + inline void CheckPoleParam( double & u, double & v ) const; + + void InitNormDeltaU(); // \ru Посчитать величины отступа от uMin и uMax при подсчете нормали \en Calculate indent values from uMin and uMax in calculation of normal + void InitTabooUV(); // \ru Вычислить ограничения по u и v \en Calculate constraints by u and v + // \ru Пересечение с прямолинейной кривой \en Intersection with rectilinear curve + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext ) const; + RuledSurfaceType CheckType(); + MbConeSurface * GetConeSurface() const; + bool IsPlane() const; // \ru НЕ ИСПОЛЬЗОВАТЬ СНАРУЖИ !!! \en NOT USE OUTSIDE !!! + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbRuledSurface ) +OBVIOUS_PRIVATE_COPY( MbRuledSurface ) +}; + +IMPL_PERSISTENT_OPS( MbRuledSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbRuledSurface::CheckParam( double & u, double & v ) const +{ + if (u < umin) { + if ( uclosed ) { + double pRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / pRgn) * pRgn ); + } + else + u = umin; + } + else if ( u > umax) { + if ( uclosed ) { + double pRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / pRgn) * pRgn ); + } + else + u = umax; + } + if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +//------------------------------------------------------------------------------ +// \ru Корректировка параметров \en Correct parameters +// --- +inline void MbRuledSurface::CheckPoleParam( double & u, double & v ) const +{ + if ( (type == rld_PoleMin) && (v < vmin) ) + v = vmin; + else if ( v < vminExt ) + v = vminExt; + + if ( (type == rld_PoleMax) && (v > vmax) ) + v = vmax; + else if ( v > vmaxExt ) + v = vmaxExt; + + if ( u < umin ) { + if ( poleMin ) + u = umin; + else if ( u < uminExt ) + u = uminExt; + } + if ( u > umax ) { + if ( poleMax ) + u = umax; + else if ( u > umaxExt ) + u = umaxExt; + } +} + + +//------------------------------------------------------------------------------ +// \ru Обновить тип линейчатой поверхности. \en Update type of ruled surface. +// --- +inline void MbRuledSurface::UpdateType() +{ + type = rld_Unset; + CheckType(); +} + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра curve в параметр sline \en Convert 'curve' parameter to 'sline' parameter +// --- +inline double MbRuledSurface::SlineParameterFrom( const double & u ) const { + return tmin + (u - umin) * dt; +} + + +//------------------------------------------------------------------------------ +// \ru Перевод параметра sline в параметр curve \en Convert 'sline' parameter to 'curve' parameter +// --- +inline double MbRuledSurface::SlineParameterInto( const double & t ) const { + double du = (::fabs(dt) > EXTENT_EQUAL) ? 1.0 / dt : 1.0; + return umin + (t - tmin) * du; +} + + +//------------------------------------------------------------------------------ +// \ru Являются ли поверхости геометрически одинаковыми \en Whether surfaces are similar +// --- +bool IsSameRuledExtrusion( const MbRuledSurface & ruled, const MbExtrusionSurface & extrusion, + MbMatrix * matr ); + + +#endif // __SURF_RULED_SURFACE_H diff --git a/C3d/Include/surf_sector_surface.h b/C3d/Include/surf_sector_surface.h new file mode 100644 index 0000000..27a4291 --- /dev/null +++ b/C3d/Include/surf_sector_surface.h @@ -0,0 +1,226 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Секториальная поверхность. + \en Sectorial surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SECTOR_SURFACE_H +#define __SURF_SECTOR_SURFACE_H + + +#include + + +#define SECT_NUMB 3 + + +//------------------------------------------------------------------------------ +/** \brief \ru Секториальная поверхность. + \en Sectorial surface. \~ + \details \ru Секториальная поверхность построена по кривой и точке. + Секториальная поверхность является частным случаем линейчатой поверхности с вырожденной в точку второй кривой. + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = (1 - v) curve(u) + v origin. \n + Первый параметр поверхности совпадает с параметром кривой curve. + Вдоль второго параметра поверхность прямолинейна. + \en Sectorial surface is created by curve and point. + Sectorial surface is special case of ruled surface with a second curve degenerated to a point. + Radius-vector of line surface is described by the vector function \n + r(u,v) = (1 - v) curve(u) + v origin. \n + The first surface parameter coincides with the parameter of curve 'curve'. + A surface is rectilinear along the second parameter. \~ + \ingroup Surfaces +*/ // --- +class MATH_CLASS MbSectorSurface : public MbSweptSurface { +private: + MbCartPoint3D origin; ///< \ru Точка вместо второй кривой. \en Point instead of the second curve. + +public: + + /** \brief \ru Конструктор по точке и кривой. + \en Constructor by point and curve. \~ + \details \ru Конструктор по точке и кривой. + \en Constructor by point and curve. \~ + \param[in] initCurve - \ru Кривая + \en Curve \~ + \param[in] p - \ru Точка + \en Point \~ + \param[in] same - \ru Признак использования оригинала кривой, а не копии + \en Attribute of using the original of a curve instead of the copy. \~ + */ + MbSectorSurface( const MbCurve3D & initCurve, const MbCartPoint3D & p, bool same = false ); +protected: + MbSectorSurface( const MbSectorSurface &, MbRegDuplicate * ); +private: + MbSectorSurface( const MbSectorSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbSectorSurface(); + +public: + VISITING_CLASS( MbSectorSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента. \en Make a copy of an element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать. \en Transform. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void TangentU ( double & u, double & v, MbVector3D & ) const; + virtual void TangentV ( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _TangentU ( double u, double v, MbVector3D & ) const; + virtual void _TangentV ( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; + virtual void _NormalV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving over the surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v line. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether a surface is planar. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя. \en Changing of carrier. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru NURBS копия поверхности. \en NURBS copy of surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en A spatial copy of the line u = const. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + virtual void CalculateGabarit( MbCube & ) const; // \ru Вычислить габарит кривой. \en Calculate bounding box of a curve. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + // \ru Существует ли полюс на границе параметрической области. \en Whether a pole exists on parametric region boundary. + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; + + virtual bool IsLineV() const; // \ru Если true все производные по V выше первой равны нулю. \en If it equals true then all derivatives with respect to v which have more than first order are equal to null. + /** \} */ + /** \ru \name Функции секториальной поверхности + \en \name Functions of sectorial surface. + \{ */ + /// \ru Изменить точку. \en Change point. + void SetOrigin( MbCartPoint3D & p ) { origin = p; } + /// \ru Дать точку. \en Get point. + void GetOrigin( MbCartPoint3D & p ) const { p = origin; } + /// \ru Дать точку. \en Get point. + const MbCartPoint3D & GetOrigin() const { return origin; } + /** \} */ +private: + inline void CheckParam( double & u, double & v ) const; // \ru Проверить параметры. \en Check parameters. + void operator = ( const MbSectorSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSectorSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSectorSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbSectorSurface::CheckParam( double & u, double & v ) const +{ + if ( u < umin ) { + if ( uclosed ) { + double pRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / pRgn) * pRgn ); + } + else + u = umin; + } + else if ( u > umax ) { + if ( uclosed ) { + double pRgn = ( umax - umin ); + u -= ( ::floor((u - umin) / pRgn) * pRgn ); + } + else + u = umax; + } + + if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +#endif // __SURF_SECTOR_SURFACE_H diff --git a/C3d/Include/surf_smooth_surface.h b/C3d/Include/surf_smooth_surface.h new file mode 100644 index 0000000..301b469 --- /dev/null +++ b/C3d/Include/surf_smooth_surface.h @@ -0,0 +1,410 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность сопряжения. + \en Smooth surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SMOOTH_SURFACE_H +#define __SURF_SMOOTH_SURFACE_H + + +#include + + +#define _EVEN_ false // \ru Неравномерная параметризация по дуге при u = const \en Uneven parameterization along an arc where u = const + + +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbSurfaceIntersectionCurve; + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность сопряжения. + \en Smooth surface. \~ + \details \ru Поверхность сопряжения соединяет две кривые curve1 и curve2 на сопрягаемых поверхностях. + Поверхность сопряжения является родительским классом поверхности скругления MbFilletSurface и поверхности фаски MbCamferSurface. + В отличие от других поверхностей Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр (u) при его выходе за пределы определения параметров (umin umax). + \en A smooth surface connects two curves ('curve1' and 'curve2') on interfacing surfaces. + Smooth surface is the parent class of fillet surface (MbFilletSurface) and chamfer surface (MbChamferSurface). + In contrast to other surfaces functions PointOn and Derive.. of smooth surface don't correct + the first parameter (u) when getting out of domain bounds (umin and umax). \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbSmoothSurface : public MbSurface { +protected: + MbSurfaceCurve * curve1; ///< \ru Опорная кривая на первой поверхности (всегда не NULL). \en Support curve on the first surface (it never equals NULL). + MbSurfaceCurve * curve2; ///< \ru Опорная кривая на второй поверхности (всегда не NULL). \en Support curve on the second surface (it never equals NULL). + MbeSmoothForm form; ///< \ru Тип сопряжения. \en Conjugation type. + double distance1; ///< \ru Радиус скругления или "катет" фаски со знаком для поверхности кривой curve1. \en Fillet radius or chamfer "cathetus" with sign for surface of curve1 curve. + double distance2; ///< \ru Радиус скругления или "катет" фаски со знаком для поверхности кривой curve2. \en Fillet radius or chamfer "cathetus" with sign for surface of curve2 curve. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + bool uclosed; ///< \ru Признак замкнутости по параметру u. \en An attribute of closedness in u-parameter direction. + bool poleMin; ///< \ru Наличие полюса при umin. \en Existence of a pole at umin. + bool poleMax; ///< \ru Наличие полюса при umax. \en Existence of a pole at umax. + +protected: + + /** \brief \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and conjugation type. \~ + \details \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and conjugation type. \~ + \param[in] crv1 - \ru Опорная кривая на первой поверхности + \en Support curve on the first surface. \~ + \param[in] crv2 - \ru Опорная кривая на второй поверхности + \en Support curve on the second surface. \~ + \param[in] fm - \ru Тип сопряжения (0 - скругление, 1 - фаска) + \en Conjugation type (0 - fillet, 1 - chamfer) \~ + */ + MbSmoothSurface( MbSurfaceCurve & crv1, MbSurfaceCurve & crv2, MbeSmoothForm fm, double d1, double d2 ); + + /** \brief \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and conjugation type. \~ + \details \ru Конструктор по двум кривым и типу сопряжения. + \en Constructor by two curves and conjugation type. \~ + \param[in] surf1 - \ru Первая поверхность + \en First surface. \~ + \param[in] curv1 - \ru Кривая в области определения первой поверхности + \en A curve in domain of the first surface \~ + \param[in] surf2 - \ru Вторая поверхность + \en Second surface. \~ + \param[in] curv2 - \ru Кривая в области определения второй поверхности + \en A curve in domain of the second surface \~ + \param[in] fm - \ru Тип сопряжения (0 - скругление, 1 - фаска) + \en Conjugation type (0 - fillet, 1 - chamfer) \~ + */ + MbSmoothSurface( MbSurface &surf1, MbCurve &curv1, MbSurface &surf2, MbCurve &curv2, MbeSmoothForm fm, double d1, double d2 ); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSmoothSurface( const MbSmoothSurface &, MbRegDuplicate * ); + /// \ru Конструктор копирования с теми же опорными поверхностями. \en Copy constructor with the same support surfaces. + MbSmoothSurface( const MbSmoothSurface * ); // \ru Для CurvesDuplicate() \en For CurvesDuplicate() +private: + MbSmoothSurface( const MbSmoothSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbSmoothSurface(); + +public: + VISITING_CLASS( MbSmoothSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + + /** \brief \ru Коррекция средней линии поверхности скругления. + \en Correction of the middle line of fillet surface. \~ + \details \ru Коррекция средней линии поверхности скругления. + \en Correction of the middle line of fillet surface. \~ + \param[in] tmin - \ru Новый минимальный параметр средней линии + \en New minimal parameter of the middle line. \~ + \param[in] tmax - \ru Новый максимальный параметр средней линии + \en New maximal parameter of the middle line. \~ + \param[in] insertPoints - \ru Увеличить число контрольных точек средней кривоф. + \en Insert control points for middle cerve0. \~ + */ + virtual void Init0( double tmin, double tmax, bool insertPoints = true ) = 0; + + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента. \en A type of element. + virtual MbeSpaceType Type() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties &properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; // \ru Вернуть минимальное значение параметра u. \en Get the minimum value of u. + virtual double GetUMax() const; // \ru Вернуть максимальное значение параметра u. \en Get the maximum value of u. + virtual double GetVMin() const; // \ru Вернуть минимальное значение параметра v. \en Get the minimum value of v. + virtual double GetVMax() const; // \ru Вернуть максимальное значение параметра v. \en Get the maximum value of v. + virtual bool IsUClosed() const; // \ru Проверка замкнутости по параметру u. \en Check of surface closedness in u direction. + virtual bool IsVClosed() const; // \ru Проверка замкнутости по параметру v. \en Check of surface closedness in v direction. + virtual double GetUPeriod() const; // \ru Вернуть период. \en Return period. + + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether a pole exists on parametric region boundary of spline curve. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр при его выходе за пределы определения параметров. + \en \name Functions for working at surface domain + Functions PointOn and Derive... of smooth surfaces don't correct + the first parameter when getting out of domain bounds. + \{ */ + virtual void PointOn ( double &u, double &v, MbCartPoint3D & ) const = 0; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double &u, double &v, MbVector3D & ) const = 0; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveUUV( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveUVV( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveVVV( double &u, double &v, MbVector3D & ) const = 0; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const = 0; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving over the surface + \{ */ + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + // \ru Определениe точки пересечения поверхности и кривой. \en Determination of a point of intersection between a surface and a curve. + virtual MbeNewtonResult CurveIntersectNewton( const MbCurve3D &, double funcEpsilon, size_t iterLimit, + double &u0, double &v0, double &t1, bool ext0, bool ext1 ) const; + // \ru Дать максимальное приращение параметра. \en Get the maximum increment of parameter. + virtual double GetParamDelta() const; + // \ru Дать мимнимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + virtual double GetParamPrice() const; + // \ru Построить NURBS-копию поверхности. \en Construct a NURBS copy of a surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + + /** \} */ + /** \ru \name Функции поверхности сопряжения + \en \name Functions of smooth surface + \{ */ + /// \ru Копия с теми же опорными поверхностям. \en A copy with the same support surfaces. + virtual MbSmoothSurface & CurvesDuplicate() const = 0; + /// \ru Сделать полное копирование поверхности. \en Perform a full copying of a surface. + MbSurface & TotalDuplicate() const; + /// \ru Дать радиус. \en Get radius. + virtual double GetSmoothRadius() const = 0; + /// \ru Дать радиусы со знаком. \en Get radii with a sign. + virtual void GetDistances( double u, double &d1, double &d2 ) const = 0; + /// \ru Дать радиус со знаком. \en Get radius with a sign. + virtual double GetDistance( bool s ) const = 0; + + /** \brief \ru Объединить поверхности путём включения поверхности init в данную поверхность. + \en Combine surfaces by inclusion of the surface 'init' into the given surface. \~ + \details \ru Объединить поверхности путём включения поверхности init в данную поверхность. + \en Combine surfaces by inclusion of the surface 'init' into the given surface. \~ + \param[in] edge - \ru Кривая разделяющего ребра + \en A curve of the splitting edge. \~ + \param[in] init - \ru Поверхность, которую нужно добавить в данную + \en A surface which should be added into the given one \~ + \param[in] add - \ru Добавить в конец (true), добавить в начало (false) + \en Add to end (true) or add to start (false) \~ + \param[in] matr - \ru Матрица преобразования объектов с init в данную поверхность, + \en A matrix of transformation of objects from 'init' to the given surface, \~ + \param[in] seam - \ru Кривая другого разделяющего ребра (может быть NULL) + \en A curve of another splitting edge (possibly it is NULL) \~ + */ + virtual bool SurfacesCombine( const MbSurfaceIntersectionCurve & edge, + const MbSurface & init, bool add, MbMatrix & matr, + const MbSurfaceIntersectionCurve * seam ); + + /// \ru Дать коэффициент для радиуса. \en Get coefficient for radius. + virtual double DistanceRatio( bool firstCurve, MbCartPoint3D & p, double distance ) const; + + /// \ru Опорная кривая на первой поверхности. \en Support curve on the first surface. + const MbSurfaceCurve & GetCurve1() const { return *curve1; } + /// \ru Опорная кривая на второй поверхности. \en Support curve on the second surface. + const MbSurfaceCurve & GetCurve2() const { return *curve2; } + /// \ru Дать опорную кривую на первой поверхности для изменения. \en Get the support curve on the first surface for changing. + MbSurfaceCurve & SetCurve1() const { return *curve1; } + /// \ru Дать опорную кривую на второй поверхности для изменения. \en Get the support curve on the second surface for changing. + MbSurfaceCurve & SetCurve2() const { return *curve2; } + + /** \brief \ru Построить граничную кривую вдоль поверхности (V = const). + \en Construct boundary curve along a surface (V = const). \~ + \details \ru Построить граничную кривую вдоль поверхности (V = const). + \en Construct boundary curve along a surface (V = const). \~ + \param[in] s - \ru Если true, то вдоль минимального значения V,\n + если false, то вдоль максимального значения V + \en If it equals true then construct along the minimal value of V,\n + otherwise construct along the maximal value of V \~ + */ + MbCurve * CreateBound( bool s ) const; + + /** \brief \ru Вид опорных кривых. + \en Type of support curves. \~ + \details \ru Вид опорных кривых. + \en Type of support curves. \~ + \return \ru cbt_Specific если кривые построены по отдельным точкам\n + cbt_Ordinary если кривые аналитические + \en Cbt_Specific if the curves have been constructed by the separate points\n + cbt_Ordinary if the curves are analytical \~ + */ + MbeCurveBuildType GetBuildType() const; + + /** \brief \ru Форма поверхности. + \en Form of a surface. \~ + \details \ru Форма поверхности. + \en Form of a surface. \~ + \return \ru 0 в случае поверхности скругления\n + 1 в случае поверхности фаски + \en 0 in a case of fillet\n + 1 in a case of chamfer \~ + */ + MbeSmoothForm Form() const { return form; } + + /** \brief \ru Добавить точку в опорные кривые границы. + \en Add a point to the support curves of the boundary. \~ + \details \ru Добавить точку в опорные кривые границы.\n + Точка будет добавлена в кривую, если она имеет тип pt_LineSegment, pt_CubicSpline или pt_Hermit. + \en Add a point to the support curves of the boundary.\n + A point will be added into a curve if it has a type pt_LineSegment, pt_CubicSpline or pt_Hermit. \~ + \param[out] t1 - \ru Параметр точки на первой кривой (если add1 = true) + \en Parameter of a point on the first curve (if add1 equals true) \~ + \param[in] p1 - \ru Точка на первой кривой + \en Point on the first curve \~ + \param[in] add1 - \ru Нужно ли добавлять точку в первую кривую + \en Whether to add a point to the first curve \~ + \param[out] t2 - \ru Параметр точки на второй кривой (если add2 = true) + \en Parameter of a point on the second curve (if add2 equals true) \~ + \param[in] p2 - \ru Точка на второй кривой + \en Point on the second curve \~ + \param[in] add2 - \ru Нужно ли добавлять точку во вторую кривую + \en Whether to add a point to the second curve \~ + */ + virtual bool InsertPoints( double & t1, const MbCartPoint & p1, bool add1, + double & t2, const MbCartPoint & p2, bool add2 ); + + /** \brief \ru Продлить поверхность. + \en Prolong surface. \~ + \details \ru Построить и добавить точки в опорные кривые до или после границы, удлиннив поверхность.\n + Точки будут построены и добавлены в кривые, если они имеют тип pt_Hermit. + \en Build and add points to the support curves of the boundary.\n + A points will be builded and added into curves if they have a type pt_Hermit. \~ + \param[in] t - \ru Первый параметр поверхности + \en First parameter of surface \~ + \param[in] p1 - \ru Точка на первой кривой + \en Point on the first curve \~ + \param[in] p2 - \ru Точка на второй кривой + \en Point on the second curve \~ + \param[in] anyCase - \ru Штатная работа со значением false (true исключение). + \en Regular work with the value false (true exception). \~ + */ + bool ProlongSurface( double u, const MbCartPoint & p1, const MbCartPoint & p2, bool anyCase ); + + /** \brief \ru Скорректировать кривые. + \en Correct curves. \~ + \details \ru Скорректировать опорные кривые после вставки точек.\n + Кривая будет скорректирована, если поверхность имеет полюс на краю, опорная кривая имеет тип pt_Hermit и содержит опорную точку с заданным параметром. + Корректируется опорная точка кривой, ближайшая к точке с заданным параметром со стороны полюса поверхности. + \en Correct the support curves after inserting of the points.\n + A curve will be corrected if the surface has a pole on the boundary, a support curve has the type pt_Hermit and contains the support point with the given parameter. + The curve support point which is the nearest to the point with the given parameter from the side of the surface pole is corrected. \~ + \param[in] t1 - \ru Параметр точки на первой опорной кривой. + \en Parameter of a point on the first support curve. \~ + \param[in] t2 - \ru Параметр точки на второй опорной кривой. + \en Parameter of a point on the second support curve. \~ + */ + bool CurveStraighten( double t1, double t2 ); + /// \ru Дать свойства объекта. \en Get the object properties. + void AddProperties( MbProperties &properties ); + /// \ru Проверить полюса. \en Check poles. + void SetPole(); + /** \} */ +protected: + /// \ru Корректировка параметров. \en Correction of parameters. + inline void CheckParam ( double &u, double &v ) const; + + void InitSmoothSurface ( const MbSmoothSurface & ); + void Init ( const MbSmoothSurface & ); + +private: + // \ru Определениe точки пересечения края поверхности и кривой на смежной поверхности. \en Determination of intersection point between the surface boundary and the adjacent surface. + MbeNewtonResult TangentIntersection( const MbSurfaceIntersectionCurve &, + size_t iterLimit, double &u, double &v, double &t, bool ext0, bool ext1 ) const; + MbeNewtonResult CurveTangentIntersection( const MbCurve3D &, double funcEpsilon, size_t iterLimit, + double &u, double &v, double &t, bool ext0, bool ext1 ) const; + bool IsSameSurface( const MbCurve3D &, double &u, double &v, double &t ) const; // \ru Идентификация кривой. \en Identification of a curve. + + void operator = ( const MbSmoothSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS( MbSmoothSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSmoothSurface ) + +//------------------------------------------------------------------------------ +// \ru Корректировка параметров \en Correction of parameters +// --- +inline void MbSmoothSurface::CheckParam( double &u, double &v ) const { + if ( v < vmin ) + v = vmin; + else + if ( v > vmax ) + v = vmax; + + if ( uclosed ) { + if ( (u < umin) || (u > umax ) ) { + double tmp = umax - umin; + u -= ::floor((u - umin) / tmp) * tmp; + } + } + else { + if ( poleMin && uumax ) + u = umax; + } +} + + +//------------------------------------------------------------------------------ +// Скорректировать крайние точки контейнеров, если они лежат в полюсах поверхности. +// --- +void CorrectPolePoins(const MbSurface & surface, SArray & points ); + + +//------------------------------------------------------------------------------ +// \ru Наполнить массив параметров для кривых на поверхностях \en Fill an array of parameters for the curves on surfaces +// --- +void CreateParams( const MbSurface & surface1, SArray & points1, + const MbSurface & surface2, SArray & points2, + SArray * values, SArray * valuesDerive, + bool °enerate1, bool °enerate2, ptrdiff_t & begN, ptrdiff_t & endN, + SArray & params ); + + +//------------------------------------------------------------------------------ +// \ru Создать кривые на поверхности \en Create curves on a surface. +// --- +void CreateSurfaceCurves( const MbSurface & surface1, SArray & points1, + const MbSurface & surface2, SArray & points2, + MbeSmoothForm form, bool firstFree, double distance1, double distance2, + bool insert, ptrdiff_t begN, ptrdiff_t endN, VERSION version, + MbSurfaceCurve *& curve1, MbSurfaceCurve *& curve2 ); + + +//------------------------------------------------------------------------------ +// \ru Создать поверхность \en Create a surface +// --- +MbSmoothSurface * CreateSmoothSurface( const MbSurface & surface1, SArray & points1, + const MbSurface & surface2, SArray & points2, + MbeSmoothForm form, bool firstFree, double distance1, double distance2, + double conic, bool even, ptrdiff_t begN, ptrdiff_t endN, VERSION version ); + + +#endif // __SURF_SMOOTH_SURFACE_H diff --git a/C3d/Include/surf_sphere_surface.h b/C3d/Include/surf_sphere_surface.h new file mode 100644 index 0000000..9151acb --- /dev/null +++ b/C3d/Include/surf_sphere_surface.h @@ -0,0 +1,331 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cферическая поверхность. + \en Spherical surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SPHERE_SURFACE_H +#define __SURF_SPHERE_SURFACE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Сферическая поверхность. + \en Spherical surface. \~ + \details \ru Сфера описывается радиусом radius, заданными в локальной системе координат position.\n + Первый параметр поверхности отсчитывается по дуге от оси position.axisX в направлении оси position.axisY. + Первый параметр поверхности u принимает значения на отрезке: umin<=u<=umax. + Значения u=0 и u=2pi соответствуют точке на плоскости XZ локальной системы координат. + Поверхность может быть замкнутой по первому параметру. + У замкнутой поверхности umax-umin=2pi, у не замкнутой поверхности umax-umin<2pi. \n + Второй параметр поверхности отсчитывается по дуге от плоскости XY локальной системы координат поверхности в направлении оси position.axisZ. + Второй параметр поверхности v принимает значения на отрезке: vmin<=v<=vmax. + Значение v=0 соответствует точке на плоскости XY локальной системы координат поверхности. + Поверхность не замкнута по второму параметру. \n + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + (radius (cos(u) position.axisX + sin(u) position.axisY)) + (radius sin(v) position.axisZ). \n + Радиус сферы должен быть больше нуля: radius>0. + Сфера имеет полюсы для параметра v=pi/2 и v=–pi/2. \n + Для граничных параметров поверхности должны соблюдаться неравенства: umin=–pi/2.\n + Локальная система координат position может быть как правой, так и левой. + Если локальная система координат правая, то нормаль направлена наружу сферы, + если локальная система координат левая, то нормаль направлена внутрь сферы. \n + \en A sphere is described by the radius 'radius' given in a local coordinate system 'position'.\n + The first parameter of a surface is measured by an arc from the axis 'position.axisX' in direction of the axis 'position.axisY'. + The first parameter of a surface u takes values on the segment: umin<=u<=umax. + Values u=0 and u=2pi correspond to the point on the plane XZ of a local coordinate system. + A surface may be closed in direction of the first parameter. + If a surface is closed, then umax-umin=2pi, otherwise umax-umin<2pi. \n + The second parameter of a surface is measured by an arc from the plane XY of the surface local coordinate system in direction of the axis 'position.axisZ'. + The second parameter of a surface v takes values on the segment: vmin<=v<=vmax. + The value v=0 corresponds to a point on the plane XY of the surface local coordinate system. + A surface is not closed in direction of the second parameter. \n + Radius-vector of line surface is described by the vector function \n + r(u,v) = position.origin + (radius (cos(u) position.axisX + sin(u) position.axisY)) + (radius sin(v) position.axisZ). \n + Radius of sphere must be positive: radius>0. + A sphere has the poles for the parameters v=pi/2 and v=-pi/2 \n + The following inequalities must be satisfied for the parameters of surface boundary: umin=-pi/2.\n + Local coordinate system 'position' can be both right and left. + If the local coordinate system is right then the normal is directed outside the sphere, + if the local coordinate system is left then the normal is directed inside the sphere. \n \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbSphereSurface : public MbElementarySurface { +private: + double radius; ///< \ru Радиус сферы. \en Radius of sphere. + bool uclosed; ///< \ru Признак замкнутости по первому параметру u. \en An attribute of closedness in u-parameter direction. + +public: + /// \ru Конструктор по локальной системе координат и радиусу. \en Constructor by local coordinate system and radius. + MbSphereSurface ( const MbPlacement3D & pl, double r ); + + /** \brief \ru Конструктор по радиусу и локальной системе координат. + \en Constructor by local coordinate system and radius. \~ + \details \ru Конструктор по радиусу и локальной системе координат. + \en Constructor by local coordinate system and radius. \~ + \warning \ru Используется только в конвертерах. + \en This is used only in converters. \~ + */ + MbSphereSurface ( double r, const MbPlacement3D & pl ); // \ru Используется только в конверторах \en This is used only in converters + + /** \brief \ru Конструктор по трем точкам. + \en Constructor by three points. \~ + \details \ru Конструктор по трем точкам.\n + Первая точка определяет центр сферической поверхности.\n + Длина вектора, направленного из первой точки во вторую, равна радиусу сферы,\n + его направление показывает направление оси Z. + \en Constructor by three points.\n + The first point defines the center of spherical surface.\n + Length of the vector directed from the first point to the second one is equal to the sphere radius,\n + its direction shows the direction of the axis Z. \~ + */ + MbSphereSurface ( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2 ); + + /// \ru Конструктор по центру и радиусу. \en Constructor by center and radius. + MbSphereSurface ( const MbCartPoint3D & centre, double r ); + +protected: + explicit MbSphereSurface ( const MbSphereSurface & ); + +public: + virtual ~MbSphereSurface(); + +public: + VISITING_CLASS( MbSphereSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /// \ru Инициализация по сферической поверхности. \en Initialization by spherical surface. + void Init( const MbSphereSurface & ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin () const; + virtual double GetVMin () const; + virtual double GetUMax () const; + virtual double GetVMax () const; + virtual bool IsUClosed() const; + virtual bool IsVClosed() const; + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void TangentU ( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке. \en Values of derivatives at point. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна вдоль u. \en Curvature in u direction. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature in v direction. + // \ru Определение точки касания поверхностей с одним неподвижным параметром. \en Determination of tangency point of surfaces with one fixed parameter. + virtual MbeNewtonResult SurfaceTangentNewton( const MbSurface & surf1, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + // \ru Определение точки касания поверхности и кривой. \en Determination of tangency point between a surface and a curve. + virtual MbeNewtonResult CurveTangentNewton( const MbCurve3D & curv, double funcEpsilon, size_t iterLimit, + double & u, double & v, double & t, bool ext0, bool ext1 ) const; + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Creation of an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en A spatial copy of the line u = const. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Пересечение с кривой. \en Intersection with a curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + virtual bool GetCylinderAxis( MbAxis3D & axis ) const; // \ru Дать ось вращения для поверхности. \en Get rotation axis of a surface. + + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces are similar to merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Изменение носимых двумерных кривых (точек) поверхности путем проецирования на совпадающую поверхность. \en Changing of two-dimensional curves (points) of a surface by projection to coincident surface. + virtual bool ProjectCurveOnSimilarSurface( const MbCurve3D & spaceCurve, const MbCurve & curve, const MbSurface & surfNew, MbCurve *& curveNew ) const; + + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether a surface is fillet. + virtual MbeParamDir GetFilletDirection() const; // \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether a surface is convex. + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + virtual void CalculateGabarit( MbCube & ) const; // \ru Выдать габарит. \en Get bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D &, MbCube & ) const; // \ru Рассчитать габарит относительно л.с.к. \en Calculate bounding box relative to the local coordinate system. + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + virtual void IncludePoint( double u, double v ); // \ru Включить точку в область определения. \en Include a point into domain. + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether a pole exists on parametric region boundary of spline curve. + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + virtual double GetRadius() const; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + /// \ru Выдать центр сферической поверхности. \en Give the center of sphere surface. + virtual bool GetCentre( MbCartPoint3D & c ) const; + + // \ru Является ли объект смещением. \en Is the object a shift? + virtual bool IsShift ( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces. + \{ */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /** \} */ + /** \ru \name Функции конической поверхности + \en \name Functions of conical surface + \{ */ + /// \ru Дать внутренний радиус. \en Get inner radius. + double GetR() const { return radius; } + /// \ru Выдать радиус параллели, соответствующей 'V'. \en Get the radius of parallel corresponding to 'V'. + double GetR( double v ) const { return radius * ::cos(v); } + /// \ru Изменение внутреннего радиуса. \en Changing of inner radius. + void SetR( double r ) { radius = r; SetDirtyGabarit(); } + /// \ru Являются ли сферы пространственно идентичными. \en Whether surfaces are spatially identical. + bool IsSpaceSame( const MbSpaceItem &, double eps ) const; + /** \} */ + +private: + inline void CheckParam( double &u, double &v ) const; // \ru Проверка параметров \en Check parameters + inline void CheckParam( double &v ) const; + // \ru Пересечение с прямолинейной кривой \en Intersection with rectilinear curve + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, bool ext0, bool ext ) const; + void operator = ( const MbSphereSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSphereSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSphereSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметры \en Check parameters +// --- +inline void MbSphereSurface::CheckParam( double & u, double & v ) const +{ + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) + u -= ::floor( (u - umin) * Math::invPI2 ) * M_PI2; + else if ( u < umin ) + u = umin; + else if ( u > umax ) + u = umax; + } + if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; +} + + +//------------------------------------------------------------------------------ +// \ru Проверить параметр \en Check parameter +// --- +inline void MbSphereSurface::CheckParam( double &v ) const +{ + if ( v < -M_PI_2 ) + v = -M_PI_2; + else if ( v > M_PI_2 ) + v = M_PI_2; +} + + +#endif // __SURF_SPHERE_SURFACE_H diff --git a/C3d/Include/surf_spine.h b/C3d/Include/surf_spine.h new file mode 100644 index 0000000..db0cdb6 --- /dev/null +++ b/C3d/Include/surf_spine.h @@ -0,0 +1,520 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Криволинейная направляющая для кинематической поверхности (поверхности заметания). + \en Curvilinear spine for sweep surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SPINE_H +#define __SURF_SPINE_H + + +#include +#include +#include +#include + + +const VERSION SPINE_ALG_VERSION1 = 0x0A000000L; // \ru Добавлена optionalCurve и новый алгоритм вычисления direction \en Added curve "optionalCurve" and the new algorithm to calculate "direction" +const VERSION SPINE_ALG_VERSION2 = 0x0D000023L; // \ru Добавлено создание optionalCurve в общем случае \en Added creation of "optionalCurve" in general case + + +//------------------------------------------------------------------------------ +/** \brief \ru Криволинейная направляющая для кинематической поверхности. + \en Curvilinear spine for sweep surface. \~ + \details \ru Криволинейная направляющая для кинематической поверхности (поверхности заметания) служит для расчёта в каждой точке направляющей кривой локальной система координат. \n + Локальная ось 0 ориентирована по касательной кривой "curve". \n + Локальная ось 1 ориентирована в сторону вектора "direction" или в сторону кривой "optionalCurve". \n + Локальная ось 2 дополняет локальную систему до правой системы координат. + \en Curvilinear spine for sweep surface serves for calculation of a spine curve in the local coordinate system at each point. \n + The local axis 0 is oriented in direction of the curve "curve" tangent. \n + The local axis 1 is oriented in direction of the vector "direction" or of the curve "optionalCurve". \n + The local axis 2 complements the local system to the right coordinate system. \~ + \ingroup Surface_Modeling +*/ // --- +class MATH_CLASS MbSpine : public MbRefItem, public TapeBase { +public: + /// \ru Способы движения локальной системы координат вдоль направляющей кривой "curve". \en Methods of movement of the local coordinate system along the guide curve "curve". + enum LocalAxises { + la_planeParallel = 0, ///< \ru Плоскопараллельный, сохраняющий исходную ориентацию осей. \en Plane-parallel, preserving the original orientation of the axes. + la_culcDirection = 1, ///< \ru Вектор "direction" рассчитан объектом. Ось 0 ориентирована по касательной кривой "curve", ось 1 - в сторону вектора "direction". \en Vector "direction" was calculated by object. Axis 0 is oriented along the tangent of the curve "curve", the axis 1 in the direction of the vector "direction". + la_userDirection = 2, ///< \ru Вектор "direction" задан конструктору. Ось 0 ориентирована по касательной кривой "curve", ось 1 - в сторону вектора "direction". \en Vector "direction" was sent to conctructor. Axis 0 is oriented along the tangent of the curve "curve", the axis 1 in the direction of the vector "direction". + la_surfaceNormal = 3, ///< \ru Ось 0 ориентирована по касательной кривой на поверхности "curve", ось 1 - по нормали поверхности кривой "curve". \en The 0 axis is oriented along the tangent curve on the curve surface, the 1 axis is oriented along the normal of the curve surface. + la_optionalCurve = 4, ///< \ru Ось 0 ориентирована по касательной кривой "curve", ось 1 - в сторону кривой "optionalCurve". \en Axis 0 is oriented along the tangent of the curve "curve", the axis 1 in the direction of the curve "optionalCurve". + }; + +private: + MbCurve3D * curve; ///< \ru Направляющая кривая - всегда не NULL. \en Spine curve - it is always not NULL. + MbVector3D direction; ///< \ru Вектор ориентации матрицы преобразования. \en Vector of transformation matrix orientation. + MbCurve3D * optionalCurve; ///< \ru Кривая векторa ориентации матрицы преобразования (может быть NULL для простой траектории). \en A curve of the transformation matrix orientation (it may be NULL for a simple trajectory). + MbSurface * spineSurface; ///< \ru Поверхность направляющей кривой, если "curve" - кривая на поверхности, или NULL. \en The surface of the "curve", if it is curve on surface, or NULL. + MbCurve * featureCurve; ///< \ru Двумерная кривая, если "curve" - кривая на поверхности, или NULL. \en Two-dimensional curve of the "curve", if it is curve on surface, or NULL. + LocalAxises localAxises; ///< \ru Способы ориентации локальной системы координат вдоль направляющей кривой "curve". \en Methods of orientation of the local coordinate system along the guide curve "curve". + double crossSize; ///< \ru Поперечный масштаб при построении optionalCurve. \en Transverse scale in construction of "optionalCurve". + double ortParam; ///< \ru Параметр кривой, для которой расчитаны ort0, ort1, ort2. \en Parameter of a curve with evaluated ort0, ort1 and ort2. + MbVector3D ort0; ///< \ru Вектор базиса в точке ortParam направляющей. \en A basis vector in the point ortParam of the spine. + MbVector3D ort1; ///< \ru Вектор базиса в точке ortParam направляющей. \en A basis vector in the point ortParam of the spine. + MbVector3D ort2; ///< \ru Вектор базиса в точке ortParam направляющей. \en A basis vector in the point ortParam of the spine. + VERSION version; ///< \ru Версия расчета вектора direction. \en Version of vector "direction" calculation. + + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbSpineAuxiliaryData : public AuxiliaryData { + public: + double t0; ///< \ru Исходный параметр. \en Initial parameter. + double t; ///< \ru Модифицированный параметр. \en Modified parameter. + bool ext; ///< \ru Флаг расчета на продолжении. \en Extension flag. + MbMatrix3D matrix0; ///< \ru Матрица преобразования из местной системы координат \en Transformation matrix from the local coordinate system. + MbMatrix3D matrix1; ///< \ru Первая производная матрицы преобразования \en First derivative of transformation matrix. + MbMatrix3D matrix2; ///< \ru Вторая производная матрицы преобразования \en Second derivative of transformation matrix. + + public: + MbSpineAuxiliaryData(); + MbSpineAuxiliaryData( const MbSpineAuxiliaryData & ); + virtual ~MbSpineAuxiliaryData(); + + bool IsChanged( double pmin, double pmax, double p, bool pext ) const + { + bool changed = false; + if ( p != t0 ) + changed = true; + else if ( ext != pext ) { + changed = true; + if ( pmin <= p && p <= pmax ) + changed = false; + } + return changed; + } + void Init(); + void Init( const MbSpineAuxiliaryData & ); + void Move( const MbVector3D & ); + }; + + mutable CacheManager cache; + +protected: + + /** \brief \ru Конструктор по направляющей кривой. + \en Constructor by spine curve. \~ + \details \ru Конструктор по направляющей кривой.\n + \en Constructor by spine curve.\n \~ + \param[in] cur - \ru Направляющая кривая. + \en A spine curve. \~ + \param[in] par - \ru Признак параллельного переноса. + \en Attribute of parallel translation. \~ + \param[in] same - \ru Признак использования оригинала направляющей кривой, а не ее копии. + \en Attribute of using the original of spine curve instead of its copy. \~ + \param[in] vers - \ru Версия операции. + \en Version of operation. \~ + */ + MbSpine( const MbCurve3D & cur, bool par, bool same, VERSION vers = Math::DefaultMathVersion() ); + + /** \brief \ru Конструктор по направляющей кривой и вектору ориентации матрицы преобразования. + \en Constructor by spine curve and a vector of transformation matrix orientation. \~ + \details \ru Конструктор по направляющей кривой и вектору ориентации матрицы преобразования.\n + \en Constructor by spine curve and a vector of transformation matrix orientation.\n \~ + \param[in] cur - \ru Направляющая кривая. + \en A spine curve. \~ + \param[in] same - \ru Признак использования оригинала направляющей кривой, а не ее копии. + \en Attribute of using the original of spine curve instead of its copy. \~ + \param[in] dir - \ru Вектор ориентации матрицы преобразования. + \en Vector of transformation matrix orientation. \~ + \param[in] par - \ru Признак параллельного переноса. + \en Attribute of parallel translation. \~ + \param[in] vers - \ru Версия вычисления осей локальной системы координат. + \en Version of calculation the local coordinate system. \~ + */ + MbSpine( const MbCurve3D & cur, bool same, const MbVector3D & dir, bool par, VERSION vers = Math::DefaultMathVersion() ); + + /** \brief \ru Конструктор по направляющей кривой и кривой векторa ориентации матрицы преобразования. + \en Constructor by spine curve and a curve of the vector of transformation matrix orientation. \~ + \details \ru Конструктор по направляющей кривой и кривой векторa ориентации матрицы преобразования.\n + \en Constructor by spine curve and a curve of the vector of transformation matrix orientation.\n \~ + \param[in] cur - \ru Направляющая кривая + \en A spine curve \~ + \param[in] same - \ru Признак использования оригинала направляющей кривой, а не ее копии + \en Attribute of using the original of spine curve instead of its copy \~ + \param[in] opt - \ru Кривая векторa ориентации матрицы преобразования + \en A curve of the vector of transformation matrix orientation \~ + \param[in] sameO - \ru Признак использования оригинала кривой векторa ориентации матрицы преобразования, а не ее копии + \en Attribute of using the original of a curve of the vector of transformation matrix orientation instead of its copy \~ + \param[in] par - \ru Признак параллельного переноса. + \en Attribute of parallel translation. \~ + \param[in] vers - \ru Версия вычисления осей локальной системы координат. + \en Version of calculation the local coordinate system. \~ + */ + MbSpine( const MbCurve3D & cur, bool same, const MbCurve3D & opt, bool sameO, bool par, VERSION vers = Math::DefaultMathVersion() ); + +protected: + MbSpine( const MbSpine &, MbRegDuplicate * ); +public: + virtual ~MbSpine(); + +public: + VISITING_CLASS( MbSpine ); + + /** \} */ + /** \ru \name Базовые функции + \en \name Base functions + \{ */ + /// \ru Тип элемента. \en A type of element. + MbeSpaceType IsA() const { return curve->IsA(); } + /// \ru Сделать копию элемента. \en Create a copy of the element. + MbSpine & Duplicate( MbRegDuplicate * = NULL ) const; + /// \ru Сделать равным. \en Make equal. + bool SetEqual( const MbSpine & ); + /// \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + bool IsSimilar( const MbSpine & ) const; + /// \ru Равны ли объекты. \en Whether the objects are equal. + bool IsSame ( const MbSpine & other, double accuracy = LENGTH_EPSILON ) const; + /// \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Сдвиг. \en Translation. + void Move ( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Повернуть вокруг оси. \en Rotate around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + /// \ru Изменить направление. \en Change the direction. + void Inverse( MbRegTransform * iReg = NULL ); + /// \ru Сбросить временные данные объекта. \en Reset temporary data of an object. + void Reset(); + /** \} */ + /** \ru \name Общие описания области определения направляющей кривой + \en \name General descriptions of a spine curve domain + \{ */ + /// \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter. + double GetTMax() const { return curve->GetTMax(); } + /// \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter. + double GetTMin() const { return curve->GetTMin(); } + /// \ru Проверка замкнутости кривой. \en Check for curve closedness + bool IsClosed() const { return curve->IsClosed(); } + /** \} */ + /** \ru \name Функции для работы в области определения направляющей кривой + Функции PointOn, FirstDer... корректируют параметры + при выходе их за пределы области определения параметров направляющей кривой. + \en \name Functions for working in the spine curve's domain. + Functions PointOn, FirstDer... correct parameters + when getting out of the spine curve domain bounds. + \{ */ + /// \ru Точка на кривой. \en Point on the curve. + void PointOn ( double & t, MbCartPoint3D & p ) const { curve->PointOn(t,p); } + /// \ru Первая производная. \en The first derivative. + void FirstDer ( double & t, MbVector3D & p ) const { curve->FirstDer(t,p); } + /// \ru Вторая производная. \en The second derivative. + void SecondDer( double & t, MbVector3D & p ) const { curve->SecondDer(t,p); } + /// \ru Третья производная. \en Third derivative. + void ThirdDer ( double & t, MbVector3D & p ) const { curve->ThirdDer(t,p); } + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения направляющей кривой + функции _PointOn, _FirstDer... корректируют параметры + при выходе их за пределы области определения параметров направляющей кривой. + \en \name Functions for working inside and outside the spine curve's domain + functions _PointOn, _FirstDer... correct parameters + when getting out of the spine curve domain bounds. + \{ */ + /// \ru Точка на кривой. \en Point on the curve. + void _PointOn ( double t, MbCartPoint3D & p ) const { curve->_PointOn(t,p); } + /// \ru Первая производная. \en The first derivative. + void _FirstDer ( double t, MbVector3D & p ) const { curve->_FirstDer(t,p); } + /// \ru Вторая производная. \en The second derivative. + void _SecondDer( double t, MbVector3D & p ) const { curve->_SecondDer(t,p); } + /// \ru Третья производная. \en Third derivative. + void _ThirdDer ( double t, MbVector3D & p ) const { curve->_ThirdDer(t,p); } + /// \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~ + virtual void Explore( double & t, bool ext, + MbCartPoint3D & pnt, MbVector3D & fir, MbVector3D * sec, MbVector3D * thir ) const + { curve->Explore( t, ext,pnt, fir, sec, thir ); } + /** \} */ + /** \ru \name Функции движения по направляющей кривой + \en \name Function of moving by spine curve + \{ */ + /// \ru Вычисление шага аппроксимации по величине прогиба. \en Calculation of the approximation step by the value of sag. + double Step( double t, double sag ) const; + /// \ru Вычисление шага аппроксимации по углу отклонения нормали. \en Calculation of the approximation step by the deviation angle of the normal vector. + double DeviationStep( double t, double angle ) const; + /** \} */ + /** \ru \name Функции изменения и доступа к данным + \en \name Functions for changing data and access to data + \{ */ + + /** \brief \ru Определение матрицы переноса для образующей. + \en Determination of a transfer matrix for generatrix. \~ + \details \ru Определение матрицы переноса для образующей.\n + \en Determination of a transfer matrix for generatrix.\n \~ + \param[in] v - \ru Параметр на направляющей кривой + \en Parameter on spine curve \~ + \param[out] matrix - \ru Результат - матрица + \en The result is a matrix \~ + */ + void TransformMatrix( double v, MbMatrix3D & matrix ) const; + + /** \brief \ru Определение вектора переноса для образующей. + \en Determination of a transfer vector for generatrix. \~ + \details \ru Определение вектора переноса для образующей.\n + \en Determination of a transfer vector for generatrix.\n \~ + \param[in] v - \ru Параметр на направляющей кривой + \en Parameter on spine curve \~ + \param[out] vect - \ru Результат - вектор + \en The result is a vector \~ + */ + void MoveVector( double & v, MbVector3D & vect ) const; // \ru Определение вектора переноса для образующей \en Determination of a transfer vector for generatrix + + /** \brief \ru Первой вектор базиса в рассчитанной направляющей. + \en The first vector of basis in the calculated spine. \~ + \details \ru Первой вектор базиса в рассчитанной направляющей.\n + \en The first vector of basis in the calculated spine.\n \~ + \return \ru Вектор + \en A vector \~ + */ + const MbVector3D & GetOrt0() const { return ort0; } + + /** \brief \ru Вычисление матриц преобразования. + \en Calculation of transformation matrices. \~ + \details \ru Вычисление матриц преобразования радиуса-вектора (matrix0) и его первой и второй производных (matrix1, matrix2) для параметра на направляющей. + При ext==true функция переносит параметр v в область определения направляющей кривой. + \en Calculation of transformation matrices for radius vector (matrix0) and for first and second derivatives (matrix1, matrix2) for the parameter on a spine. + The function moves the parameter v inside the spine curve domain when ext==true. \~ + \param[in, out] v - \ru Параметр на направляющей кривой + \en Parameter on spine curve \~ + */ + void CalculateMatrix ( double & v, bool ext, MbMatrix3D & matrix0, MbMatrix3D & matrix1, MbMatrix3D & matrix2 ) const; + // \ru Вычисление матриц преобразования радиуса-вектора и его первой производной. \en Calculation of transformation matrices for radius vector and for first derivative. \~ + void CalculateMatrix ( double & v, bool ext, MbMatrix3D & matrix0, MbMatrix3D & matrix1 ) const; + // \ru Вычисление матрицы преобразования радиуса-вектора. \en Calculation of transformation matrix for radius vector. \~ + void CalculateMatrix0( double & v, bool ext, MbMatrix3D & matrix0 ) const; + // \ru Вычисление матрицы преобразования первой производной радиуса-вектора. \en Calculation of transformation matrix for first derivative of radius vector. \~ + void CalculateMatrix1( double & v, bool ext, MbMatrix3D & matrix1 ) const; + // \ru Вычисление матрицы преобразования второй производной радиуса-вектора. \en Calculation of transformation matrix for second derivative of radius vector. \~ + void CalculateMatrix2( double & v, bool ext, MbMatrix3D & matrix2 ) const; + + /** \brief \ru Построить плейсмент в заданной точке. + \en Construct placement in the given point. \~ + \details \ru Построить плейсмент в заданной точке.\n + \en Construct placement in the given point.\n \~ + \param[in] v - \ru Параметр на направляющей кривой + \en Parameter on spine curve \~ + */ + MbPlacement3D GetPlacement( double v ) const; + /// \ru Направляющая кривая. \en The spine curve. + const MbCurve3D & GetCurve() const { return *curve; } + /// \ru Дать направляющую кривую для изменения. \en Get spine curve for editing. + MbCurve3D & SetCurve() { cache.Reset( true ); return *curve; } + + /// \ru Ориентирующая кривая. \en Direction curve. + const MbCurve3D * GetDirectionCurve() const { return optionalCurve; } + + /// \ru Версия расчета вектора ориентации матрицы преобразования. \en A version of calculation of the vector of transformation matrix orientation. + VERSION GetVersion() const { return version; } + + /// \ru Изменить направляющую кривую. \en Change the spine curve. + void ChangeCurve( const MbCurve3D & c ); + /// \ru Изменить ориентирующую кривую. \en Change the direction curve. + void ChangeOptionalCurve( const MbCurve3D * d ); + + /// \ru Вектор ориентации матрицы преобразования. \en Vector of transformation matrix orientation. + const MbVector3D & GetDirection() const { return direction; } + /// \ru Изменить вектор ориентации матрицы преобразования. \en Change the vector of transformation matrix orientation. + bool SetDirection( const MbVector3D & d, bool checkBySpineCurve = false ); + + /// \ru Лать способ ориентации локальной системы координат. \en Пуе еhe method of orientation of the local coordinate system. \~ + LocalAxises GetLocalAxisMethod() const { return localAxises; } + /// \ru Лать способ ориентации локальной системы координат. \en Пуе еhe method of orientation of the local coordinate system. \~ + void SetLocalAxisMethod( LocalAxises la ) { localAxises = la; } + /// \ru Признак параллельного переноса. \en Attribute of plane-parallel translation. + bool IsParallel() const { return localAxises == MbSpine::la_planeParallel; } + /// \ru Признак пользовательского направления. \en Attribute of user direction. + bool IsUserDirection() const { return ( localAxises >= MbSpine::la_userDirection ); } + + /// \ru Параметр кривой, для которой расчитан базис направляющей. \en Parameter of a curve with calculated basis of spine. + double GetOrtParam() const { return ortParam; } + /// \ru Установить параметр кривой, для которой расчитан базис направляющей. \en Set the parameter of a curve with calculated basis of spine. + void SetOrtParam( double t ); + + /// \ru Количество сегментов направляющей кривой. \en The number of segments of the spine curve. + size_t GetSegmentsCount() const; + + /** \brief \ru Функция регистрации по количеству ссылок для предотвращения многократной записи. + \en Function of registration by the number of references to avoid multiple writing. \~ + \details \ru Функция регистрации по количеству ссылок для предотвращения многократной записи.\n + \en Function of registration by the number of references to avoid multiple writing.\n \~ + */ + void PrepareWrite() { SetRegistrable( (GetUseCount() > 1) ? registrable : noRegistrable ); } + /** \} */ + + /** \brief \ru Конструктор по направляющей кривой. + \en Constructor by spine curve. \~ + \details \ru Конструктор по направляющей кривой.\n + \en Constructor by spine curve.\n \~ + \param[in] c - \ru Направляющая кривая + \en A spine curve \~ + \param[in] parallel - \ru Признак параллельного переноса + \en Attribute of parallel translation. \~ + \param[in] same - \ru Признак использования оригинала направляющей кривой, а не ее копии + \en Attribute of using the original of spine curve instead of its copy \~ + \param[in] vers - \ru Версия вычисления осей локальной системы координат. + \en Version of calculation the local coordinate system. \~ + */ + static MbSpine & Create( const MbCurve3D & c, bool parallel, bool same, VERSION vers = Math::DefaultMathVersion() ); + /** \brief \ru Конструктор по направляющей кривой и вектору ориентации матрицы преобразования. + \en Constructor by spine curve and a vector of transformation matrix orientation. \~ + \details \ru Конструктор по направляющей кривой и вектору ориентации матрицы преобразования.\n + \en Constructor by spine curve and a vector of transformation matrix orientation.\n \~ + \param[in] c - \ru Направляющая кривая + \en A spine curve \~ + \param[in] same - \ru Признак использования оригинала направляющей кривой, а не ее копии + \en Attribute of using the original of spine curve instead of its copy \~ + \param[in] direction - \ru Вектор ориентации матрицы преобразования. + \en Vector of transformation matrix orientation. \~ + \param[in] parallel - \ru Признак параллельного переноса + \en Attribute of parallel translation. \~ + \param[in] vers - \ru Версия вычисления осей локальной системы координат. + \en Version of calculation the local coordinate system. \~ + */ + static MbSpine * Create( const MbCurve3D & c, bool same, const MbVector3D & dir, bool parallel, VERSION vers = Math::DefaultMathVersion() ); + /** \brief \ru Конструктор по направляющей кривой и кривой векторa ориентации матрицы преобразования. + \en Constructor by spine curve and a curve of the vector of transformation matrix orientation. \~ + \details \ru Конструктор по направляющей кривой и кривой векторa ориентации матрицы преобразования.\n + \en Constructor by spine curve and a curve of the vector of transformation matrix orientation.\n \~ + \param[in] sp - \ru Направляющая кривая + \en A spine curve \~ + \param[in] sameS - \ru Признак использования оригинала направляющей кривой, а не ее копии + \en Attribute of using the original of spine curve instead of its copy \~ + \param[in] dc - \ru Кривая векторa ориентации матрицы преобразования + \en A curve of the vector of transformation matrix orientation \~ + \param[in] sameD - \ru Признак использования оригинала кривой векторa ориентации матрицы преобразования, а не ее копии + \en Attribute of using the original of a curve of the vector of transformation matrix orientation instead of its copy \~ + \param[in] parallel - \ru Признак параллельного переноса + \en Attribute of parallel translation. \~ + \param[in] vers - \ru Версия вычисления осей локальной системы координат. + \en Version of calculation the local coordinate system. \~ + */ + static MbSpine * Create( const MbCurve3D & sp, bool sameS, const MbCurve3D & dc, bool sameD, bool parallel, VERSION vers = Math::DefaultMathVersion() ); + +private: + void InitDirection(); // \ru Вычисление direction; разбор частных случаев типа плоских кривых, дуг окружности и т.п. \en Calculation of "direction"; analysis of such special cases as planar curves, circle arcs etc. + bool CalculateSurface(); // \ru Для кривой на поверхности вять поверхность и двумерную кривую. \en Get "spineSurface" and "featureCurve" if "curve" is a curve on surface. + void CheckParam( double & v ) const ; // \ru Функция переносит параметр v в область определения направляющей кривой. \en The function moves the parameter v inside the spine curve domain. + void CalculateVector1( double & v, bool ext, + MbVector3D & vector0, MbVector3D & vector1, MbVector3D & vector2, + MbVector3D & derive0, MbVector3D & derive1, MbVector3D & derive2 ) const; // \ru Вычисление векторов для матриц преобразования. \ en Vectors сalculation for matrix. + void CalculateVector2( double & v, bool ext, + MbVector3D & vector0, MbVector3D & vector1, MbVector3D & vector2, + MbVector3D & derive0, MbVector3D & derive1, MbVector3D & derive2, + MbVector3D & second0, MbVector3D & second1, MbVector3D & second2 ) const; // \ru Вычисление векторов для матриц преобразования. \ en Vectors сalculation for matrix. + void CalculateDirection( double v, MbVector3D & direct ) const; // \ru Вектор ориентации матрицы преобразования. \en Vector of transformation matrix orientation. + + bool InitOptionalCurve( bool exactOnly ); // \ru Вычисление optionalCurve; использовать, если нетривиальный случай. \en Calculation of "optionalCurve"; use if the case is nontrivial. + void Multiplication( const MbVector3D & vector0, const MbVector3D & vector1, const MbVector3D & vector2, + MbMatrix3D & matrix ) const; // \ru Определение матрицы преобразования. \en Determination of transformation matrix. + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSpine ) +OBVIOUS_PRIVATE_COPY( MbSpine ) +}; + + +IMPL_PERSISTENT_OPS( MbSpine ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Направляющая кривая и её окружение. + \en A spine curve and its neighborhood. \~ + \details \ru Направляющая кривая и её окружение.\n + \en A spine curve and its neighborhood.\n \~ + \ingroup Surface_Modeling +*/ // --- +struct SpineData { + MbSpine & spine; ///< \ru Направляющая кривая. \en A spine curve. + MbCartPoint3D point; ///< \ru Положение характерной точки сечения в начале направляющей. \en Position of characteristic point of the section at the beginning of the spine. + MbVector3D vect; ///< \ru Вектор оси поворота сечения. \en Vector of the section rotation axis. + MbVector3D norm; ///< \ru Вектор нормали сечения в начале направляющей. \en Normal vector of section at the beginning of the spine. + double angle; ///< \ru Угол поворота сечения в начале направляющей. \en Rotation angle of section at the beginning of the spine. + //double range; ///< \ru Эквидистантное смещение точек образующей кривой в конце траектории. \en The offset range of generating curve on the end of spine curve. \~ + + SpineData( MbSpine & sp, const MbCartPoint3D & org, const MbVector3D & v, const MbVector3D & n, double ang )//, double ran ) + : spine( sp ) + , point( org ) + , vect ( v ) + , norm ( n ) + , angle( ang ) + //, range( ran ) + { + } + virtual ~SpineData() {} + +OBVIOUS_PRIVATE_COPY( SpineData ) +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Создание массива направляющих по контуру направляющих. + \en Creation of array of spines by the contour of spines. \~ + \details \ru Создание массива направляющих по контуру направляющих с согласованными. + векторами ориентации матрицы преобразования.\n + Для внутреннего использования. + \en Creation of array of spines by the contour of spines with the consistent + vectors of transformation matrix orientation.\n + For internal use only. \~ + \param[in] sp - \ru Контур направляющих + \en Contour of spines \~ + \param[out] items - \ru Массив направляющих. + \en Array of spines. \~ +*/ // --- +MATH_FUNC (void) MakeSpines( const MbSpine & sp, SArray & items ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Удалить неиспользованные направляющие. + \en Delete unused spines. \~ + \details \ru Удалить неиспользованные направляющие.\n + Для внутреннего использования. + \en Delete unused spines.\n + For internal use only. \~ + \param[in,out] items - \ru Массив направляющих. + \en An array of spines. \~ +*/ // --- +MATH_FUNC (void) DeleteNonUsedSpines( SArray & items ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Поиск вектора ориентации матрицы преобразования. + \en Search of vector for transformation matrix orientation. \~ + \details \ru Поиск вектора ориентации матрицы преобразования. \n + Для внутреннего использования. + \en Search of vector for transformation matrix orientation. \n + For internal use only. \~ + \param[in] curve - \ru Кривая. + \en A curve. \~ + \param[out] direction - \ru Вектор, который не совпадает с касательной к кривой. + \en A vector which is not coincident with the curve tangent. \~ + \param[in] version - \ru Версия. + \en Version. \~ + \return \ru ts_positive или ts_neutral, если максимально подходящий вектор направления direction найден. + \en It equals ts_positive or ts_neutral if the most suitable direction vector "direction" was found. \~ +*/ // --- +MATH_FUNC (ThreeStates) InitSpineDirection( const MbCurve3D & curve, MbVector3D & direction, VERSION version ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить вектор ориентации матрицы преобразования. + \en Check a vector for transformation matrix orientation. \~ + \details \ru Проверить вектор ориентации матрицы преобразования. \n + Для внутреннего использования. + \en Check a vector for transformation matrix orientation. \n + For internal use only. \~ + \param[in] curve - \ru Кривая. + \en A curve. \~ + \param[in] direction - \ru Вектор, который не должен совпадать с касательной к кривой. + \en A vector which must not be coincident with the curve tangent. \~ + \return \ru true, если вектор не совпадает с касательной к кривой. + \en It equals true if the vector is not coincident with the curve tangent. \~ +*/ // --- +MATH_FUNC (bool) CheckSpineDirection( const MbCurve3D & curve, const MbVector3D & direction ); + + +#endif //__SURF_SPINE_H diff --git a/C3d/Include/surf_spiral_surface.h b/C3d/Include/surf_spiral_surface.h new file mode 100644 index 0000000..e1f9bf2 --- /dev/null +++ b/C3d/Include/surf_spiral_surface.h @@ -0,0 +1,400 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Спиральная поверхность. + \en Spiral surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SPIRAL_SURFACE_H +#define __SURF_SPIRAL_SURFACE_H + + +#include +#include +#include + + +class MATH_CLASS MbConeSpiral; + + +//------------------------------------------------------------------------------ +/** \brief \ru Спиральная поверхность. + \en Spiral surface. \~ + \details \ru Спиральная поверхность получена путем движения образующей кривой curve по цилиндрической спирали. + Спиральная поверхность является частным случаем кинематической поверхности. + Ось спирали направлена вдоль оси Z локальной системы координат. + Второй параметр поверхности отсчитывается от оси position.axisX локальной системы координат. + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + (M(v) (curve(u) - origin)), \n + где M(v) - матрица вращения. \n + Первый параметр поверхности совпадает с параметром образующей кривой. + Второй параметр поверхности совпадает с углом поворота точки спирали вокруг её оси. + \en A spiral surface is obtained by moving of a generating curve along a cylindrical spiral. + Spiral surface is a special case of sweep surface. + A spiral axis is directed along the Z-axis of the local coordinate system. + The second parameter of a surface is measured from the axis "position.axisX" of the local coordinate system. + Radius-vector of the surface is described by the vector function \n + r(u,v) = position.origin + (M(v) (curve(u) - origin)), \n + where M(v) is rotation matrix. \n + The first surface parameter coincides with the parameter of generatrix. + The second surface parameter coincides with rotation angle of a spiral point around its axis. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbSpiralSurface : public MbSweptSurface { +private: + MbPlacement3D position; ///< \ru Местная система координат (position.axisZ - ось спирали). \en Local coordinate system ('position.axisZ' is axis of spiral). + double radius; ///< \ru Радиус спирали. \en A spiral radius. + double step; ///< \ru Шаг спирали. \en A pitch of spiral. + MbCartPoint3D origin; ///< \ru Центр тяжести образующей. \en Center of gravity of generatrix. + MbMatrix3D into; ///< \ru Матрица преобразования в систему position. \en Matrix of transformation to the system 'position'. + MbMatrix3D from; ///< \ru Матрица преобразования из системы position. \en Matrix of transformation from the system 'position'. + double stepd2pi; ///< \ru Шаг приходящийся на период. \en A step corresponding to period. + +public: + + /** \brief \ru Конструктор по образующей, локальной системе координат, радиусу спирали, шагу спирали. + \en Constructor by generatrix, local coordinate system, spiral radius and spiral pitch. \~ + \details \ru Конструктор по образующей, локальной системе координат, радиусу спирали, шагу спирали. + \en Constructor by generatrix, local coordinate system, spiral radius and spiral pitch. \~ + \param[in] c - \ru Образующая + \en Generatrix \~ + \param[in] pos - \ru Локальная система координат + \en Local coordinate system \~ + \param[in] r - \ru Радиус спирали + \en Spiral radius \~ + \param[in] s - \ru Шаг спирали + \en Spiral pitch \~ + \param[in] t1 - \ru Начальный параметр спирали + \en Start parameter of spiral \~ + \param[in] t2 - \ru Конечный параметр спирали + \en End parameter of spiral \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не ее копии + \en Attribute of using the original of generatrix instead of its copy. \~ + */ + MbSpiralSurface( const MbCurve3D & c, const MbPlacement3D & pos, double r, double s, double t1, double t2, + bool sameCurve ); + + /** \brief \ru Конструктор по образующей и спирали. + \en Constructor by generatrix and spiral. \~ + \details \ru Конструктор по образующей и спирали. + \en Constructor by generatrix and spiral. \~ + \param[in] c - \ru Образующая + \en Generatrix \~ + \param[in] s - \ru Спираль + \en Spiral \~ + \param[in] sameCurve - \ru Признак использования оригинала образующей, а не ее копии + \en Attribute of using the original of generatrix instead of its copy. \~ + */ + MbSpiralSurface( const MbCurve3D & c, const MbConeSpiral & s, bool sameCurve ); + +protected: + MbSpiralSurface( const MbSpiralSurface &, MbRegDuplicate * ); +private: + MbSpiralSurface( const MbSpiralSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbSpiralSurface(); + +public: + VISITING_CLASS( MbSpiralSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными. \en Determine whether the objects are similar. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна линии по u. \en Curvature of line in u direction. + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether a surface is planar. + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); // \ru Изменение носителя \en Changing of carrier + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of surface. + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности \en Creation of an offset surface + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en A spatial copy of the line u = const. + + // \ru Найти проекцию точки на поверхность. \en Find the projection of a point onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & pnt, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + + // \ru Построить касательные и нормальные плейсменты конструктивных плоскостей. \en Construct tangent and normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces are similar to merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + virtual bool IsLineU() const; // \ru Если true все производные по U выше первой равны нулю. \en If it equals true then all derivatives with respect to u which have more than first order are equal to null. + /** \} */ + /** \ru \name Функции спиральной поверхности + \en \name Functions of spiral surface + \{ */ + + /** \brief \ru Определение матрицы переноса для образующей. + \en Determination of a transfer matrix for generatrix. \~ + \details \ru Определение матрицы при переносе образующей + из параметра vmin в параметр v. + \en Determination of matrix when transferring the generatrix + from the parameter vmin to the parameter v. \~ + \param[in] v - \ru Новый параметр на спирали + \en A new parameter on the spiral \~ + \param[out] matr - \ru Матрица-резцультат + \en A matrix - the result \~ + */ + void TransformMatrix( double v, MbMatrix3D & matr ) const; + + /// \ru Внутренний радиус витков. \en Internal radius of coils. + double GetSpiralR() const { return radius; } + /// \ru Внутренний шаг витков. \en Internal pitch of coils. + double GetStep() const { return step; } + + /// \ru Физический радиус витков. \en Physical radius of coils. + double GetSpiralRadius() const; + /// \ru Физический шаг витков. \en Physical pitch of coils. + double GetSpiralStep() const; + + /// \ru Местная система координат (ось position.axisZ - ось спирали). \en Local coordinate system ('position.axisZ' is axis of spiral). + const MbPlacement3D & GetPlacement() const { return position; } + /// \ru Центр тяжести образующей. \en Center of gravity of generatrix. + const MbCartPoint3D & GetOrigin() const { return origin; } + + /// \ru Построить спираль. \en Construct a spiral. + MbConeSpiral & CreateSpiral() const; + + /// \ru Является ли локальная система координат поверхности ортонормированной. \en Whether the local coordinate system of a surface is orthonormalized. + bool IsPositionNormal() const { return ( position.IsNormal() ); } + /// \ru Является ли локальная система координат поверхности ортогональной с равными по длине осями X,Y. \en Whether the local coordinate system of a surface is orthogonal with X and Y axes equal by length. + bool IsPositionCircular() const { return ( position.IsCircular() ); } + /// \ru Является ли локальная система координат поверхности ортогональной и изотропной по осям. \en Whether the local coordinate system of a surface is orthogonal and isotropic by the axes. + bool IsPositionIsotropic() const { return ( position.IsIsotropic() ); } + /// \ru Является ли образующая кривая окружностью. \en Whether a generatrix is a circle. + bool IsCircleType() const; + + /// \ru Оценить рабочий диапазон для проецирования. \en Estimate the projection range along V. + bool GetProjectionRange( const MbCartPoint3D & pnt, bool ext, const MbRect2D * userRange, MbRect2D & resRange ) const; + /// \ru Скорректировать разбивку для проецирования точки. \en Correct the number of splittings by v-parameter for point projection. + bool CorrectVCount( double vbeg, double vend, size_t & cntv ) const; + /** \} */ +private: + + void Init(); // \ru Инициализация. \en Initialization. + inline void CheckParam ( double & v ) const; + inline void RotateVector ( const double & sin_V, const double & cos_V, MbVector3D & ) const; + inline void RotateDeriveV ( const double & sin_V, const double & cos_V, MbVector3D & ) const; + inline void RotateDeriveVV ( const double & sin_V, const double & cos_V, MbVector3D & ) const; + inline void RotateDeriveVVV( const double & sin_V, const double & cos_V, MbVector3D & ) const; + inline void DirectrixPointOn ( const double & v, const double & sinV, const double & cosV, MbCartPoint3D & ) const; + inline void DirectrixDeriveV ( const double & sinV, const double & cosV, MbVector3D & ) const; + inline void DirectrixDeriveVV ( const double & sinV, const double & cosV, MbVector3D & ) const; + inline void DirectrixDeriveVVV( const double & sinV, const double & cosV, MbVector3D & ) const; + + void operator = ( const MbSpiralSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSpiralSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSpiralSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверить параметр \en Check parameter +// --- +inline void MbSpiralSurface::CheckParam( double & v ) const +{ + if ( v < vmin ) + v = vmin; + else + if ( v > vmax ) + v = vmax; +} + + +//------------------------------------------------------------------------------ +// \ru Выдать физический радиус спирали \en Get physical radius of spiral +// --- +inline double MbSpiralSurface::GetSpiralStep() const +{ + if ( position.IsNormal() ) + return step; + else if ( position.IsOrthogonal() ) { + return (step * position.GetAxisZ().Length()); + } + return 0.0; +} + + +//------------------------------------------------------------------------------ +// \ru Поворот вектора вокруг оси спирали \en Rotation of vector around spiral axis +// --- +inline void MbSpiralSurface::RotateVector( const double & sin_V, const double & cos_V, MbVector3D & _vector ) const +{ + _vector.Transform( into ); + double x = (_vector.x * cos_V) - (_vector.y * sin_V); + double y = (_vector.x * sin_V) + (_vector.y * cos_V); + _vector.x = x; + _vector.y = y; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Первая производная поворота вектора вокруг оси спирали \en First derivative of vector rotation around the spiral axis +// --- +inline void MbSpiralSurface::RotateDeriveV( const double & sin_V, const double & cos_V, MbVector3D & _vector ) const +{ + _vector.Transform( into ); + double x = - (_vector.x * sin_V) - (_vector.y * cos_V); + double y = (_vector.x * cos_V) - (_vector.y * sin_V); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Вторая производная поворота вектора вокруг оси спирали \en Second derivative of vector rotation around spiral axis +// --- +inline void MbSpiralSurface::RotateDeriveVV( const double & sin_V, const double & cos_V, MbVector3D & _vector ) const +{ + _vector.Transform( into ); + double x = - (_vector.x * cos_V) + (_vector.y * sin_V); + double y = - (_vector.x * sin_V) - (_vector.y * cos_V); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------- +// \ru Третья производная поворота вектора вокруг оси спирали \en Third derivative of vector rotation around spiral axis +// --- +inline void MbSpiralSurface::RotateDeriveVVV( const double & sin_V, const double & cos_V, MbVector3D & _vector ) const +{ + _vector.Transform( into ); + double x = (_vector.x * sin_V) + (_vector.y * cos_V); + double y = - (_vector.x * cos_V) + (_vector.y * sin_V); + _vector.x = x; + _vector.y = y; + _vector.z = 0.0; + _vector.Transform( from ); +} + + +//------------------------------------------------------------------------------ +// \ru Точка спирали \en A point of spiral +// --- +inline void MbSpiralSurface::DirectrixPointOn( const double & v, const double & sinV, const double & cosV, MbCartPoint3D & p ) const { + p = position.GetOrigin(); + p.Add( position.GetAxisZ(), (stepd2pi * v), position.GetAxisX(), (radius * cosV), position.GetAxisY(), (radius * sinV) ); +} + + +//------------------------------------------------------------------------------- +// \ru Первая производная спирали \en First derivative of spiral +// --- +inline void MbSpiralSurface::DirectrixDeriveV( const double & sinV, const double & cosV, MbVector3D & d ) const { + d.Set( position.GetAxisZ(), stepd2pi, position.GetAxisX(), -(radius * sinV), position.GetAxisY(), (radius * cosV) ); +} + + +//------------------------------------------------------------------------------- +// \ru Вторая производная спирали \en Second derivative of spiral +// --- +inline void MbSpiralSurface::DirectrixDeriveVV( const double & sinV, const double & cosV, MbVector3D & d ) const { + d.Set( position.GetAxisX(), -(radius * cosV), position.GetAxisY(), -(radius * sinV) ); +} + + +//------------------------------------------------------------------------------- +// \ru Третья производная спирали \en Third derivative of spiral +// --- +inline void MbSpiralSurface::DirectrixDeriveVVV( const double & sinV, const double & cosV, MbVector3D & d ) const { + d.Set( position.GetAxisX(), (radius * sinV), position.GetAxisY(), -(radius * cosV) ); +} + + +#endif // __SURF_SPIRAL_SURFACE_H diff --git a/C3d/Include/surf_spline_surface.h b/C3d/Include/surf_spline_surface.h new file mode 100644 index 0000000..0fe4664 --- /dev/null +++ b/C3d/Include/surf_spline_surface.h @@ -0,0 +1,978 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru NURBS поверхность. + \en NURBS surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SPLINE_SURFACE_H +#define __SURF_SPLINE_SURFACE_H + + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbSurfaceCurve; +class MATH_CLASS MbSurfaceContiguousData; +class MbSplineWorkingData; + + +//------------------------------------------------------------------------------ +/** \brief \ru Веса NURBS поверхности. + \en Weights of a NURBS surface. \~ + \details \ru Веса NURBS поверхности. + \en Weights of a NURBS surface. \~ + \ingroup Data_Structures +*/ // --- +class MbWeightMatrix { +private: + size_t linesCnt; ///< \ru Количество строк матрицы. \en A number of matrix lines. + size_t columnsCnt; ///< \ru Количество столбцов матрицы. \en A number of matrix columns. + double commonWeight; ///< \ru Общий вес контрольных точек. \en A common weight of control points. + Array2 weights; ///< \ru Матрица весов контрольных точек. \en A matrix of control points weights. +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbWeightMatrix() : linesCnt( 0 ), columnsCnt( 0 ), commonWeight( UNDEFINED_DBL ), weights() {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbWeightMatrix( const MbWeightMatrix & wm ); + ~MbWeightMatrix() {} +public: + // Количество строк. + size_t Lines() const { return linesCnt; } + // Количество столбцов. + size_t Columns() const { return columnsCnt; } + // Общий вес? + bool IsCommonWeight() const; + // Инициализация по общему весу. + bool InitWeights( double wt, size_t linesCnt, size_t columnsCnt ); + // Инициализация по матрице весов. + bool InitWeights( const Array2 & wts ); + // Инициализация по матрице весов. + void InitWeights( const MbWeightMatrix & wm ); + // Получить веса. + void GetWeights( Array2 & wts ) const; + // Установить веса. + bool SetWeights( const Array2 & wts ) { return InitWeights( wts ); } + // Получить вес. + double GetWeight( size_t lineIndex, size_t columnIndex ) const; + // Установить вес. + bool SetWeight( size_t lineIndex, size_t columnIndex, double wt ); + + // Вставить строку. + void InsertLine ( size_t k, double wt = 1.0 ); + // Вставить столбец. + void InsertColumn( size_t k, double wt = 1.0 ); + // Добавить строку. + void AddLine( double wt = 1.0 ) { InsertLine( linesCnt, wt ); } + // Добавить столбец. + void AddColumn( double wt = 1.0 ) { InsertColumn( columnsCnt, wt ); }; + // Удалить строку. + void RemoveLine( size_t k ); + // Удалить столбец. + void RemoveColumn( size_t k ); + + // Получить указатель на строку, если не используется общий вес. Иначе возвращает NULL. + const double * _GetLine( size_t k ) const; + // Можно ли оптимизировать расход памяти. + bool CanAdjust( const Array2 & wts ) const; + // Оптимизировать расход памяти. + bool Adjust(); + // Оператор присваивания. + MbWeightMatrix & operator = ( const MbWeightMatrix & wm ) { InitWeights( wm ); return *this; } + // Оператор присваивания. + MbWeightMatrix & operator = ( const Array2 & wm ) { InitWeights( wm ); return *this; } +protected: + // Сформировать полную матрицу весов, если используется общий вес. + bool FillArray2(); +private: + MbWeightMatrix( const Array2 & ); // не реализовано, запрещено +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru NURBS поверхность. + \en NURBS surface. \~ + \details \ru NURBS поверхность строится по заданной матрице контрольных точек. + Каждая контрольная точка имеет вес, который задан в матрице весов (по умолчанию все веса равны 1). \n + Аббревиатура NURBS получена из первых букв словосочетания Non-Uniform Rational B-Spline. + NURBS поверхность не проходит через свои контрольные точки. + Расчет поверхности в каждой точке производится на основе двух семейств нормированных неоднородных В-сплайнов. \n + Каждое семейство В-сплайнов определяется заданной неубывающей последовательностью узловых параметров и заданным порядком B-сплайна. + Для не замкнутой по первому параметру поверхности узловой вектор uknots должен содержать количество столбцов матрицы контрольных точек плюс udegree. + Для замкнутой по первому параметру поверхности узловой вектор uknots должен содержать количество столбцов матрицы контрольных точек плюс 2*udegree-1. + Для не замкнутой по второму параметру поверхности узловой вектор vknots должен содержать количество строк матрицы контрольных точек плюс vdegree. + Для замкнутой по второму параметру поверхности узловой вектор vknots должен содержать количество строк матрицы контрольных точек плюс 2*vdegree-1. + \en NURBS surface is constructed by a given matrix relative to control points. + Each control point has a weight which is given in the matrix of weights (by default all weights are equal to 1). \n + Abbreviation of NURBS is obtained from the first letters of the Non-Uniform Rational B-Spline phrase. + NURBS surface doesn't pass through its control points. + Calculation of a surface at each point is performed on the basis of two families of normalized non-uniform B-splines. \n + Each family of B-splines is defined by the given nondecreasing sequence of knot parameters and the given order of B-spline. + For an unclosed by the first parameter surface the knot vector 'uknots' should contain a count of columns of matrix control points plus udegree. + For a closed by the first parameter surface the knot vector 'uknots' should contain a count of columns of matrix control points plus 2*udegree-1. + For an unclosed by the second parameter surface the knot vector 'vknots' should contain a count of rows of matrix control points plus vdegree. + For a closed by the second parameter surface the knot vector 'vknots' should contain a count of rows of matrix control points plus 2*vdegree-1. \~ + \ingroup Surfaces +*/ // --- +class MATH_CLASS MbSplineSurface : public MbPolySurface { + +private: + size_t udegree; ///< \ru Порядок В-сплайна по u (порядок = степень + 1). \en Order of B-spline by u (order = degree + 1). + size_t vdegree; ///< \ru Порядок В-сплайна по v (порядок = степень + 1). \en Order of B-spline by v (order = degree + 1). + SArray uknots; ///< \ru Узлы по u. \en Knots in u direction. + SArray vknots; ///< \ru Узлы по v. \en Knots in v direction. + MbWeightMatrix weights; ///< \ru Матрица весов контрольных точек. \en A matrix of control points weights. + +private: + //------------------------------------------------------------------------------ + /** \brief \ru Вспомогательные данные. + \en Auxiliary data. \~ + \details \ru Вспомогательные данные служат для ускорения работы объекта. + \en Auxiliary data are used for fast calculations. \n \~ + */ + // --- + class MbSplineSurfaceAuxiliaryData : public AuxiliaryData { + public: + double uc; ///< \ru Параметр u, при котором насчитаны значения. \en Parameter u for the calculated values. + double vc; ///< \ru Параметр v, при котором насчитаны значения. \en Parameter v for the calculated values. + MbVector3D rc[sdt_CountNor]; ///< \ru Расчитанные в точке (uc,vc) значения. \en Values calculated in the point (uc, vc). + + DPtr data; ///< \ru Дополнительные данные о поверхности. \en Additional data about a surface. + DPtr wdata; ///< \ru Рабочие данные для расчета поверхности. \en Working data for the calculation of a surface. + double * wc; ///< \ru Рассчитанные в точке (uc,vc) значения весов (может быть NULL). \en Weights values calculated in the point (uc, vc) (may be NULL). + + MbSplineSurfaceAuxiliaryData(); + MbSplineSurfaceAuxiliaryData( const MbSplineSurfaceAuxiliaryData & init ); + virtual ~MbSplineSurfaceAuxiliaryData(); + void FreeMemory(); + bool CatchMemory( const size_t &, const size_t &, bool ); + }; + + + mutable CacheManager cache; + +public: + /// \ru Пустой конструктор. \en Empty constructor. + MbSplineSurface(); + + /** \brief \ru Конструктор NURBS поверхности. + \en Constructor of NURBS surface. \~ + \details \ru Конструктор NURBS поверхности. \n + \en Constructor of NURBS surface. \n \~ + \param[in] uDeg - \ru Порядок сплайнов по u. + \en Splines order by U. \~ + \param[in] vDeg - \ru Порядок сплайнов по v. + \en Splines order by V. \~ + \param[in] uCls - \ru Замкнутость поверхности по u. + \en Closedness of a surface in u direction. \~ + \param[in] vCls - \ru Замкнутость поверхности по v. + \en Closedness of a surface in v direction. \~ + \param[in] initPoints - \ru Матрица контрольных точек. + \en A matrix of control points. \~ + \param[in] initUKnots - \ru Узловой вектор по u. + \en A knot vector by U. \~ + \param[in] initVKnots - \ru Узловой вектор по v. + \en A knot vector by V. \~ + */ + MbSplineSurface( size_t uDeg, size_t vDeg, bool uCls, bool vCls, const Array2 & initPoints, + const SArray & initUKnots, const SArray & initVKnots ); + + /** \brief \ru Конструктор NURBS поверхности. + \en Constructor of NURBS surface. \~ + \details \ru Конструктор NURBS поверхности. \n + \en Constructor of NURBS surface. \n \~ + \param[in] uDeg - \ru Порядок сплайнов по u. + \en Splines degree by U. \~ + \param[in] vDeg - \ru Порядок сплайнов по v. + \en Splines degree by V. \~ + \param[in] uCls - \ru Замкнутость поверхности по u. + \en Closedness of a surface in u direction. \~ + \param[in] vCls - \ru Замкнутость поверхности по v. + \en Closedness of a surface in v direction. \~ + \param[in] initPoints - \ru Матрица контрольных точек. + \en A matrix of control points. \~ + \param[in] initWeights - \ru Матрица весов точек. + \en Matrix of point weights. \~ + \param[in] initUKnots - \ru Узловой вектор по u. + \en A knot vector by U. \~ + \param[in] initVKnots - \ru Узловой вектор по v. + \en A knot vector by V. \~ + */ + MbSplineSurface( size_t uDeg, size_t vDeg, bool uCls, bool vCls, const Array2 & initPoints, const Array2 & initWeights, + const SArray & initUKnots, const SArray & initVKnots ); + + /** \brief \ru Конструктор NURBS поверхности по четырем углам при обходе против часовой стрелки. + \en Constructor of NURBS surface by four angles of counterclockwise traverse. \~ + \details \ru Заданы углы поверхности. Остальные точки равномерно распределены внутри прямоугольника, заданного угловыми точками. + \en Surface angles are given. Other points are uniformly distributed inside the rectangle which is given by angular points. \~ + \param[in] p1 - \ru Левый нижний угол. Соответствует точке (0, 0). + \en Left bottom angle. It corresponds to the point (0,0). \~ + \param[in] p2 - \ru Правый нижний угол. Соответствует точке (1, 0). + \en Right bottom angle. It corresponds to the point (1, 0). \~ + \param[in] p3 - \ru Правый верхний угол. Соответствует точке (1, 1). + \en Right top angle. It corresponds to the point (1, 1). \~ + \param[in] p4 - \ru Левый верхний угол. Соответствует точке (0, 1). + \en Left top angle. It corresponds to the point (0, 1). \~ + \param[in] iDegreeU - \ru Порядок сплайнов по u. + \en Splines degree by U. \~ + \param[in] iDegreeV - \ru Порядок сплайнов по v. + \en Splines degree by V. \~ + \param[in] iCountU - \ru Количество точек по u (Число столбцов в матрице точек). + \en The number of points by u (the number of columns in the points matrix). \~ + \param[in] iCountV - \ru Количество точек по v (Число строк в матрице точек). + \en The number of points by v (the number of rows in the points matrix). \~ + */ + MbSplineSurface( const MbCartPoint3D & p1, const MbCartPoint3D & p2, // p4---p3 + const MbCartPoint3D & p3, const MbCartPoint3D & p4, // | | + size_t iDegreeU, size_t iDegreeV, size_t iCountU, size_t iCountV ); // p1---p2 +protected: + /// \ru Конструктор копирования. \en Copy-constructor. + MbSplineSurface( const MbSplineSurface & ); +public: + virtual ~MbSplineSurface (); + +public: + VISITING_CLASS( MbSplineSurface ); + +public: + + /// \ru Инициализация по другой поверхности. \en The initialization by another surface. + void Init( const MbSplineSurface & ); + + /** \brief \ru Инициализация заполненной поверхности. + \en Initialization of filled surface. \~ + \details \ru Инициализация заполненной поверхности.\n + \en Initialization of filled surface.\n \~ + \param[in] cPoints - \ru Матрица контрольных точек. + \en A matrix of control points. \~ + \param[in] pWeights - \ru Матрица весов точек. + \en Matrix of point weights. \~ + */ + bool Init( const Array2 & cPoints, + const Array2 & pWeights ); + /** \brief \ru Инициализация заполненной поверхности. + \en Initialization of filled surface. \~ + \details \ru Инициализация заполненной поверхности.\n + \en Initialization of filled surface.\n \~ + \param[in] iDegreeU - \ru Новая степень сплайнов по u. + \en New degree of splines by u. \~ + \param[in] iDegreeV - \ru Новая степень сплайнов по v. + \en New degree of splines by v. \~ + \param[in] iClosedU - \ru Замкнутость поверхности по u. + \en Closedness of a surface in u direction. \~ + \param[in] iClosedV - \ru Замкнутость поверхности по v. + \en Closedness of a surface in v direction. \~ + */ + bool Init( size_t iDegreeU, size_t iDegreeV, bool iClosedU, bool iClosedV ); + /** \brief \ru Заполнить сплайновую поверхность по данным parasolid. + \en Fill spline surface by parasolid data. \~ + \details \ru Заполнить сплайновую поверхность по данным parasolid.\n + \en Fill spline surface by parasolid data.\n \~ + \param[in] uCls - \ru Замкнутость поверхности по u. + \en Closedness of a surface in u direction. \~ + \param[in] vCls - \ru Замкнутость поверхности по v. + \en Closedness of a surface in v direction. \~ + \param[in] brational - \ru Является ли поверхность рациональной. true - строится NURBS поверхность, false - поверхность Безье. + \en Whether a surface is rational. true - NURBS surface is constructed, false - Bezier surface. \~ + \param[in] uDgr - \ru Степень сплайнов по u. + \en Splines degree by U. \~ + \param[in] vDgr - \ru Степень сплайнов по v. + \en Splines degree by V. \~ + \param[in] uCnt - \ru Количество точек по u. + \en A number of points by U direction. \~ + \param[in] vCnt - \ru Количество точек по v. + \en A number of points by V direction. \~ + \param[in] vcs - \ru Множество координат точек. Если сплайн рациональный, четвертая координата - вес точки. + \en A set of points coordinates.. If spline is rational, then the fourth coordinate is the weight of a point. \~ + \param[in] vcsCnt - \ru Количество элементов в массиве vcs. + \en Count of elements in the array vcs. \~ + \param[in] uKMul - \ru Множество с данными о кратности каждого узла по u. + \en A set with the data about the multiplicity of each knot by u. \~ + \param[in] uKMulCnt - \ru Количество элементов в массиве uKMul. + \en Count of elements in the array uKMul. \~ + \param[in] vKMul - \ru Множество с данными о кратности каждого узла по v. + \en A set with the data about the multiplicity of each knot by v. \~ + \param[in] vKMulCnt - \ru Количество элементов в массиве vKMul. + \en Count of elements in the array vKMul. \~ + \param[in] uKnt - \ru Множество со значениями узлов по u. Каждое значение представлено один раз. + Информация о кратности узла лежит в элементе массива uKMul с тем же номером. + \en A set with values of knots by u. Each value is represented once. + Information about knot multiplicity is in the element of 'uKMul' array with the same index. \~ + \param[in] uKntCnt - \ru Количество элементов в массиве uKnt. + \en Count of elements in the array uKnt. \~ + \param[in] vKnt - \ru Множество со значениями узлов по v. Каждое значение представлено один раз. + Информация о кратности узла лежит в элементе массива vKMul с тем же номером. + \en A set with values of knots by v. Each value is represented once. + Information about knot multiplicity is in the element of 'vKMul ' array with the same index. \~ + \param[in] vKntCnt - \ru Количество элементов в массиве vKnt. + \en Count of elements in the array vKnt. \~ + \param[in] scl - \ru Коэффициент масштабирования. + \en Scale factor. \~ + */ + bool InitParasolid( bool uCls, + bool vCls, + bool brational, + size_t uDgr, + size_t vDgr, + ptrdiff_t uCnt, + ptrdiff_t vCnt, + const CcArray & vcs, + ptrdiff_t vcsCnt, + const CcArray & uKMul, + ptrdiff_t uKMulCnt, + const CcArray & vKMul, + ptrdiff_t vKMulCnt, + const CcArray & uKnt, + ptrdiff_t uKntCnt, + const CcArray & vKnt, + ptrdiff_t vKntCnt, + double scl ); + + /** \ru \name Общие функции геометрического объекта. + \en \name Common functions of geometric object. + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const; // \ru Cделать копию элемента. \en Make a copy of an element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + /** \} */ + + /** \ru \name Функции описания области определения поверхности. + \en \name Functions for surface domain description. + \{ */ + virtual double GetUMin() const; + virtual double GetVMin() const; + virtual double GetUMax() const; + virtual double GetVMax() const; + + virtual bool IsUClosed() const; // \ru Замкнута ли гладко поверхность по параметру u без учета граничного контура. \en Whether the surface is smoothly closed by parameter u without regard to the boundary contour. + virtual bool IsVClosed() const; // \ru Замкнута ли гладко поверхность по параметру v без учета граничного контура. \en Whether the surface is smoothly closed by parameter v without regard to the boundary contour. + virtual bool IsUTouch() const; // \ru Замкнута ли фактически поверхность по параметру u независимо от гладкости. \en Whether the surface is actually closed by parameter u regardless of the smoothness. + virtual bool IsVTouch() const; // \ru Замкнута ли фактически поверхность по параметру v независимо от гладкости. \en Whether the surface is actually closed by parameter v regardless of the smoothness. + virtual bool IsUPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру u. \en Whether the surface is smoothly closed by parameter u. + virtual bool IsVPeriodic() const; // \ru Замкнута ли гладко поверхность по параметру v. \en Whether the surface is smoothly closed by parameter v. + + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether a pole exists on parametric region boundary of spline curve. + virtual bool GetPoleUMin() const; + virtual bool GetPoleUMax() const; + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. \n + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по u. \en Second derivative with respect to u. + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uuv. \en Third derivative with respect to uuv. + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по uvv. \en Third derivative with respect to uvv. + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; // \ru Третья производная по v. \en Third derivative with respect to v. + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + За пределами параметрической области поверхность продолжается по касательной. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + Outside the limits of parametric region a surface is extended along a tangent. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; // \ru Третья производная по u. \en Second derivative with respect to u. + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uuv. \en Third derivative with respect to uuv. + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по uvv. \en Third derivative with respect to uvv. + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; // \ru Третья производная по v. \en Third derivative with respect to v. + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + /** \} */ + + /** \ru \name Функции движения по поверхности. + \en \name Functions of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по U. \en Calculation of the approximation step with consideration of the curvature radius by U. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны по V. \en Calculation of the approximation step with consideration of the curvature radius by V. + + virtual double DeviationStepU( double u, double v, double sag ) const; // \ru Вычисление шага по u при пересечении поверхностей. \en Calculation of a step in direction of u for surfaces intersection. + virtual double DeviationStepV( double u, double v, double sag ) const; // \ru Вычисление шага по v при пересечении поверхностей. \en Calculation of a step in direction of v for surfaces intersection. + /** \} */ + + /** \ru \name Общие функции поверхности. + \en \name Common functions of surface. + \{ */ + virtual void SetUClosed( bool cls ); // \ru Установить признак замкнутости по U. \en Set the attribute of closedness in direction of u. + virtual void SetVClosed( bool cls ); // \ru Установить признак замкнутости по V. \en Set the attribute of closedness in direction of v. + + virtual MbSplineSurface * NurbsSurface( double umin, double umax, double vmin, double vmax, bool bmatch = false ) const; // \ru NURBS-копия поверхности. \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; // \ru NURBS-копия поверхности с заданными параметрами. \en NURBS copy of surface with given parameters. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en A spatial copy of the line u = const. + + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + virtual void Rebuild(); // \ru Инициализация поверхности. \en Initialization of surface. + + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + + /** \brief \ru Проверить параметры. Аналог глобальной функции _CheckParams, оптимизированный под использование кэшей. + \en Check parameters. Analogue of the global function _CheckParams, optimized for caches usage. \~ + \details \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + \en Check parameters and move them inside domain if parameter is out of pole. \~ + \param[in] surface - \ru Поверхность. \en Surface. \~ + \param[in] u - \ru Первый параметр. \en First parameter. \~ + \param[in] v - \ru Второй параметр. \en Second parameter. \~ + */ + virtual void CheckSurfParams( double & u, double & v ) const; + + /** \brief \ru Построить усеченную поверхность. + \en Construct a trimmed surface. \~ + \details \ru Построить усеченную поверхность. + \en Construct a trimmed surface. \~ + \param[in] uBeg - \ru Параметр U, соответствующий началу усеченной поверхности. + \en Parameter U corresponding to start of a trimmed surface. \~ + \param[in] uEnd - \ru Параметр U, соответствующий концу усеченной поверхности. + \en Parameter U corresponding to end of a trimmed surface. \~ + \param[in] vBeg - \ru Параметр V, соответствующий началу усеченной поверхности. + \en Parameter V corresponding to start of a trimmed surface. \~ + \param[in] vEnd - \ru Параметр V, соответствующий концу усеченной поверхности. + \en Parameter V corresponding to end of a trimmed surface. \~ + \result \ru Построенная усеченная поверхность. + \en A constructed trimmed surface. \~ + */ + MbSplineSurface * Trimmed( double uBeg, double uEnd, double vBeg, double vEnd ) const; + + virtual bool IsPlanar() const; // \ru Является ли поверхность плоской. \en Whether a surface is planar. + + // \ru Найти ближайшую проекцию точки на поверхность или ее продолжение по заданному начальному приближению. \en Find the neares projection of a point onto the surface. + virtual bool NearPointProjection ( const MbCartPoint3D & pnt, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + // \ru Являются ли узловые векторы равными? \en Are knotVectos equal? + bool IsKnotsTheSame( const MbSplineSurface & e, bool sameDir, double precision ) const; + // \ru Являются ли точки и веса равными? \en Are points and weights equal? + bool IsPointsTheSame( const MbSplineSurface & e, bool sameDir, bool uBeg, bool vBeg, double precision ) const; + // \ru Определить, подобны ли поверхности для объединения. \en Define whether the surfaces are similar for merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + /** \brief \ru Изменение веса одной вершины. + \en Changing of one point weight \~ + \details \ru Изменение веса одной вершины.\n + \en Changing of one point weight \n \~ + \param[in] i - \ru Номер строки. + \en Row index. \~ + \param[in] j - \ru Номер столбца. + \en Column index. \~ + \param[in] w - \ru Новое значение веса. + \en New value of weight. \~ + */ + void ChangeWeight ( ptrdiff_t i, ptrdiff_t j, double w ); + /** \brief \ru Изменение порядка поверхности. + \en Changing of surface order. \~ + \details \ru Изменение порядка поверхности.\n + \en Changing of surface order.\n \~ + \param[in] isU - \ru Определяет, по какой координате надо изменить порядок: true - по u, false - по v. + \en Determines a coordinate of the order changing: true - u, false - v. \~ + \param[in] order - \ru Новый порядок поверхности. + \en A new surface order. \~ + */ + void SetDegree ( bool isU, ptrdiff_t order ); + /** \brief \ru Установить область изменения параметров. + \en Set the range of parameters. \~ + \details \ru Установить область изменения параметров.\n + \en Set the range of parameters.\n \~ + \param[in] pmin - \ru Минимальное значение по u. + \en The minimal parameter value by U. \~ + \param[in] pmax - \ru Максимальное значение по u. + \en The maximal parameter value by U. \~ + \param[in] qmin - \ru Минимальное значение по v. + \en The minimal parameter value by V. \~ + \param[in] qmax - \ru Максимальное значение по v. + \en The maximal parameter value by V. \~ + */ + MbMatrix SetLimitParam( double pmin, double pmax, double qmin, double qmax ); + + /// \ru Получить порядок В-сплайна по u. \en Get the order of B-spline by u. + size_t GetUDegree () const { return udegree; } + /// \ru Получить порядок В-сплайна по v. \en Get the order of B-spline by v. + size_t GetVDegree () const { return vdegree; } + /// \ru Получить количество строк в матрице весов. \en Get rows count in weights matrix. + size_t GetWeightsLines() const { return weights.Lines(); } + /// \ru Получить количество столбцов в матрице весов. \en Get columns count in weights matrix. + size_t GetWeightsColumns() const { return weights.Columns(); } + /** \brief \ru Получить вес вершины. + \en Get vertex weight. \~ + \details \ru Получить вес вершины.\n + \en Get vertex weight.\n \~ + \param[in] i - \ru Номер строки. + \en Row index. \~ + \param[in] j - \ru Номер столбца. + \en Column index. \~ + \return \ru Значение веса. + \en A value of weight. \~ + */ + double GetWeight( ptrdiff_t i, ptrdiff_t j ) const { return weights.GetWeight( i, j ); } + + // \ru Получить матрицу весов вершин. \en Get the matrix of vertices weights. + virtual void GetWeights( Array2 & wts ) const { weights.GetWeights( wts ); } + + /** \brief \ru Получить количество элементов в узловом векторе. + \en Get the number of elements in a knot vector. \~ + \details \ru Получить количество элементов в узловом векторе.\n + \en Get the number of elements in a knot vector.\n \~ + \param[in] isU - \ru Определяет, по какой координате запрашивается узловой вектор: true - по u, false - по v. + \en Determines the requested coordinate of a knot vector: true - u, false - v. \~ + \return \ru Количество элементов в узловом векторе. + \en The number of elements in a knot vector. \~ + */ + size_t GetKnotsCount( bool isU ) const { return (isU ? uknots.Count() : vknots.Count()); } + + // \ru Получить узловой вектор по выбранному параметру. \en Get a knot vector by the chosen parameter. + virtual void GetKnots( bool isU, SArray & knots ) const { knots = (isU ? uknots : vknots); } + /** \brief \ru Получить значение одного узла. + \en Get the value of one knot. \~ + \details \ru Получить значение одного узла.\n + \en Get the value of one knot.\n \~ + \param[in] isU - \ru Определяет, по какой координате запрашивается узловой вектор: true - по u, false - по v. + \en Determines the requested coordinate of a knot vector: true - u, false - v. \~ + \param[in] i - \ru Номер элемента в узловом векторе. + \en The index of an element in a knot vector. \~ + \return \ru Значение узла. + \en A value of knot. \~ + */ + double GetKnot( bool isU, size_t i ) const; + + // \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по u. \en Insertion of a row after the row with the index idBegin without changing of a surface by u. + virtual void InsertUKnotsInRegion( ptrdiff_t idBegin, ptrdiff_t num = 1 ); + + /** \brief \ru Вставка ряда со значением узла newKnot без изменения поверхности по u. + \en Insertion of a row with the value of the knot newKnot without changing of a surface by u. \~ + \details \ru Вставка ряда со значением узла newKnot без изменения поверхности по u.\n + \en Insertion of a row with the value of the knot newKnot without changing of a surface by u.\n \~ + \param[in] newKnot - \ru Значение узла. + \en A value of knot. \~ + \param[in] multiplicity - \ru Количество вставляемых рядов. + \en Count of inserted rows. \~ + */ + void InsertUKnots( double & newKnot, ptrdiff_t multiplicity ); // + + // \ru Вставка ряда после ряда с номером idBegin без изменения поверхности по v. \en Insertion of a row after the row with the index idBegin without changing of a surface by v. + virtual void InsertVKnotsInRegion( ptrdiff_t idBegin, ptrdiff_t num = 1 ); + + /** \brief \ru Вставка ряда со значением узла newKnot без изменения поверхности по v. + \en Insertion of a row with the value of the knot newKnot without changing of a surface by v. \~ + \details \ru Вставка ряда со значением узла newKnot без изменения поверхности по v.\n + \en Insertion of a row with the value of the knot newKnot without changing of a surface by v.\n \~ + \param[in] newKnot - \ru Значение узла. + \en A value of knot. \~ + \param[in] multiplicity - \ru Количество вставляемых рядов. + \en Count of inserted rows. \~ + */ + void InsertVKnots( double & newKnot, ptrdiff_t multiplicity ); // + + // \ru Вычисление точек на поверхности, соответствующих узлам. \en Calculation of points on surface corresponding to knots. + virtual void CalculateUVParameters( Array2 & params ) const; + // \ru Вычисление точки на поверхности, соответствующей контрольной точке. \en Calculation of point on surface corresponding to control point. + virtual bool CalculateUVParameterForKnot( size_t uIndex, size_t vIndex, MbCartPoint & point ) const; + + // \ru Вычисление доли смещения узлов при перемещении со сглаживанием. \en Calculation of a shift part of knots during the translation with blending. + virtual bool CalculatePartsForSpecMove( const Array2 & movedPoints, + size_t uIndex, size_t vIndex, + const MbVector3D & moveVector, + MbeDirectSmoothType smoothType, + double smoothDegree, + Array2 & partsPoints ) const; + + // \ru Вычисление фиксированных контрольных точек. \en Calculation of fixed control points. + virtual bool CalculateFixedPoints( const RPArray & curves, Array2 & fixedPoints ) const; + + bool CalculateFixedLimits( const MbSurfaceCurve & curve, ptrdiff_t & u1, ptrdiff_t & u2, ptrdiff_t & v1, ptrdiff_t & v2 ) const; + + // \ru Удаление столбца контрольных точек без изменения поверхности. \en Deletion of a column of control points without changing of a surface. + virtual size_t RemoveUKnots( ptrdiff_t & rowId, ptrdiff_t num = 1, double absEps = Math::lengthEpsilon ); // \ru Удаление узла в u \en Deletion of knot in u direction + // \ru Удаление строки контрольных точек без изменения поверхности. \en Deletion of a row of control points without changing of a surface. + virtual size_t RemoveVKnots( ptrdiff_t & rowId, ptrdiff_t num = 1, double absEps = Math::lengthEpsilon ); // \ru Удаление узла в v \en Deletion of knot in v direction + // \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface. \en Change an order of NURBS by construction of a surface by the function NurbsSurface. + virtual bool ChangeUDegreeApprox ( size_t newDegree ); + // \ru Изменить порядок nurbs путем перестроения поверхности с помощью функции NurbsSurface. \en Change an order of NURBS by construction of a surface by the function NurbsSurface. + virtual bool ChangeVDegreeApprox ( size_t newDegree ); + // \ru Изменить порядок и количество узлов nurbs путем перестроения поверхности с помощью функции NurbsSurface. \en Change an order and a number of knots of NURBS by construction of a surface by the function NurbsSurface. + virtual bool ChangeParametersApprox ( size_t nUDegree, size_t nVDegree, ptrdiff_t nUCount, ptrdiff_t nVCount ); + /** \brief \ru Перестроить поверхность с помощью функции NurbsSurface без кратных узлов. + \en Rebuild a surface by the function NurbsSurface without multiple knots. \~ + \details \ru Перестроить поверхность с помощью функции NurbsSurface без кратных узлов.\n + \en Rebuild a surface by the function NurbsSurface without multiple knots.\n \~ + \return \ru true, если аппроксимация выполнена успешно. + \en True if approximation is succeeded. \~ + */ + bool ApproxSurfWithoutMultKnots (); + + // \ru Вернуть массив узловых точек и их видимость для операции редактирования как сплайна. \en Return an array of knot points and their visibility for the operation of editing as spline. + virtual void GetPointsWithVisible ( Array2 & params ) const; + /** \brief \ru Модифицировать массив узловых точек с учетом перемещения невидимых точек. + \en Modify an array of knot points considering the moving of invisible points. \~ + \details \ru Модифицировать массив узловых точек с учетом перемещения невидимых точек.\n + \en Modify an array of knot points considering the moving of invisible points.\n \~ + \param[in] oldPoints - \ru Матрица контрольных точек. + \en A matrix of control points. \~ + \param[in,out] newPoints - \ru Матрица контрольных точек после корректирования положения невидимых точек. + \en A matrix of control points after the correction of invisible points location. \~ + */ + void ModifyPointsWithVisible ( const Array2 & oldPoints, Array2 & newPoints ) const; + + /** \brief \ru Зажать или разжать узловой вектор. + \en Whether to clamp a knot vector. \~ + \details \ru Преобразовать узловой вектор по u в зажатый, если поверхность замкнута по u и clm = false. + Если не замкнута и clm = true - преобразовать узловой вектор в разжатый. + \en Make a knot vector by u clamped if a surface is closed in u direction and clm = false. + If it is not closed and clm = true then make knot vector unclamped. \~ + \param[in] clm - \ru Зажать или разжать узловой вектор. + \en Whether to clamp a knot vector. \~ + */ + bool UnClampedU( bool clm ); + /** \brief \ru Зажать или разжать узловой вектор. + \en Whether to clamp a knot vector. \~ + \details \ru Преобразовать узловой вектор по v в зажатый, если поверхность замкнута по v и clm = false. + Если не замкнута и clm = true - преобразовать узловой вектор в разжатый. + \en Make a knot vector by v clamped if a surface is closed in v direction and clm = false. + If it is not closed and clm = true then make knot vector unclamped. \~ + \param[in] clm - \ru Зажать или разжать узловой вектор. + \en Whether to clamp a knot vector. \~ + */ + bool UnClampedV( bool clm ); + + /// \ru Делаем зажатый узловой вектор. \en Make a clumped knot vector. + void SetClampedU(); + /// \ru Делаем зажатый узловой вектор. \en Make a clumped knot vector. + void SetClampedV(); + + /** \brief \ru Установить типы границ поверхности. + \en Set types of surfaces boundaries. \~ + \details \ru Установить типы границ поверхности. Используется в конвертерах. + \en Set types of surfaces boundaries. This is used in converters. \~ + \param[in] cuMin - \ru Тип поверхности при u - минимальном. + \en A type of surface when u is minimal. \~ + \param[in] cuMax - \ru Тип поверхности при u - максимальном. + \en A type of surface when u is maximal. \~ + \param[in] cvMin - \ru Тип поверхности при v - минимальном. + \en A type of surface when v is minimal. \~ + \param[in] cvMax - \ru Тип поверхности при v - максимальном. + \en A type of surface when v is maximal. \~ + */ + void SetBordersTypes( bool cuMin, bool cuMax, bool cvMin, bool cvMax ); + + /** \brief \ru Проверить является ли точка полюсной и убрать разрыв в первой производной. + \en Check whether a point is a pole and remove discontinuity of the first derivative. \~ + \details \ru Проверить является ли точка полюсной и убрать разрыв в первой производной.\n + \en Check whether a point is a pole and remove discontinuity of the first derivative.\n \~ + \param[in] pnt - \ru Точка, в которой производится проверка. + \en A point where the check is performed. \~ + \param[in] absEps - \ru Точность. + \en Tolerance. \~ + \param[in] bSet - \ru Замещать ли контрольные точки, соответствующие полюсу и + совпадающие с указанной точностью с точкой pnt, точкой pnt. + \en Whether to replace control points corresponding to the pole and + coincident with the given tolerance with the point pnt. \~ + */ + bool CheckPolePoint( const MbCartPoint3D & pnt, double absEps, bool bSet ); + + /// \ru Если поверхность касается по U - убрать разрыв в первой производной. \en If surface is touched by U then remove the discontinuity of the first derivative. + void SoftUTouch(); + /// \ru Если поверхность касается по V - убрать разрыв в первой производной. \en If surface is touched by V then remove the discontinuity of the first derivative. + void SoftVTouch(); + + virtual bool IsLineU() const; // \ru Если true, то все производные по U выше первой равны нулю. \en If it equals true, then all derivatives with respect to u which have more than first order are equal to null. + virtual bool IsLineV() const; // \ru Если true, то все производные по V выше первой равны нулю. \en If it equals true, then all derivatives with respect to v which have more than first order are equal to null. + + /// \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible. + virtual double GetRadius() const; + /// \ru Дать радиус скругления, если поверхность является поверхностью скругления. \en Get fillet radius if the surface is a fillet surface. + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; + /// \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual MbeParamDir GetFilletDirection() const; + /// \ru Дать ось вращения для поверхности. \en Get rotation axis of a surface. + virtual bool GetCylinderAxis( MbAxis3D & ) const; + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + /// \ru Проверить, является ли поверхность рациональной, но не регулярной. \en Check whether a surface is rational but not regular. + bool IsRational() const; + + /// \ru Удалить временную структуру данных - разбивку поверхности. \en Delete the temporary data structure - surface tesselation. + void DeleteTesselation() const; + + /** \brief \ru Создать двумерную кривую, если пространственная кривая является границей поверхности. + \en Create a two-dimensional curve if a space curve is a surface boundary. \~ + \details \ru Создать двумерную кривую, если пространственная кривая является границей поверхности.\n + \en Create a two-dimensional curve if a space curve is a surface boundary.\n \~ + \param[in] curve - \ru Заданная пространственная кривая. + \en A given space curve. \~ + \return \ru Ссылка на двумерную кривую на поверхности или NULL, если построить ее не удалось. + \en A reference to the two-dimensional curve on a surface or NULL if the construction of it is failed. \~ + */ + MbCurve * IsSplineBorder( const MbCurve3D & curve ) const; + + /** \brief \ru Области поверхности, параллельные направлению. + \en Regions of a surface parallel to the direction. \~ + \details \ru Области поверхности, наборы точек в которой параллельны заданному направлению. + \en Regions of a surface the point sets of which are parallel to the given direction. \~ + \param[in] direction - \ru Направление. + \en Direction. \~ + \param[out] collinearRects - \ru Найденные области внутри области определения поверхности. + \en Found regions inside the domain of a surface. \~ + \warning \ru В разработке. + \en Under development. \~ + */ + void DirectParallelRects( const MbVector3D & direction, std::vector & parallelRects ) const; + +private: + bool CheckPoles( MbSplineSurfaceAuxiliaryData * ) const; // \ru Проверить наличие полюсов. \en Check poles existence. + + void SetClosed( bool isU, bool cls ); // \ru Установить признак замкнутости. \en Set attribute of closedness. + + void SetKnots ( size_t degree, ptrdiff_t count, bool close, SArray & knots ); // \ru Установка значений узлового вектора \en Setting of knot vector values. + void OpenKnotsVector ( size_t degree, ptrdiff_t count, SArray & knots ); // \ru Переопределение базисного узлового вектора из Close в Open. \en Redetermination of the basis knot vector from Close to Open. + void CloseKnotsVector ( size_t degree, ptrdiff_t count, SArray & knots, double ); // \ru Переопределение базисного узлового вектора из Open в Close. \en Redetermination of the basis knot vector from Open to Close. + + bool InitPatch ( MbSplineSurfaceAuxiliaryData * ) const; + void CalculatePatch ( double & u, double & v, MbSplineSurfaceAuxiliaryData * ) const; + void CalculateSpline ( int, MbSplineSurfaceAuxiliaryData * ) const; // \ru Расчет вектора точки и его первых, вторых и третьих производных. \en Calculation of the point vector and its first, second and third derivatives + void CalculateSplineWeight( int, MbSplineSurfaceAuxiliaryData * ) const; + + bool CatchMemory( MbSplineSurfaceAuxiliaryData * ) const; + void FreeMemory ( MbSplineSurfaceAuxiliaryData * ) const; + + void ResetCache(); + + void operator = ( const MbSplineSurface & ); // \ru Не реализовано. \en Not implemented. + + double GetMeanParam( bool isU, double, double ) const; // \ru Получить среднее расстояние между band-ами. \en Get the middle distance between 'band'-s. + double GetKoef( bool isU ) const; // \ru Получить коэффициент пересчета из длины в параметры. \en Get a coefficient of recalculation of the length to the parameters. + + // \ru Служебные аналоги публичных функций, которые используют заданный кэш. \en Service analogs of public functions that use a given cache. + void DeriveU ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Первая производная по u. \en First derivative with respect to u. + void DeriveV ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Первая производная по v. \en First derivative with respect to v. + void DeriveUU ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + void DeriveVV ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + void DeriveUUU ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по u. \en Second derivative with respect to u. + void DeriveVVV ( double & u, double & v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по v. \en Third derivative with respect to v. + void DeriveUV ( double & u, double & v, MbVector3D & , MbSplineSurfaceAuxiliaryData * ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + void DeriveUUV ( double & u, double & v, MbVector3D & , MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по uuv. \en Third derivative with respect to uuv. + void DeriveUVV ( double & u, double & v, MbVector3D & , MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по uvv. \en Third derivative with respect to uvv. + bool IsRational ( MbSplineSurfaceAuxiliaryData * ) const; // \ru Проверить, является ли поверхность рациональной, но не регулярной. \en Check whether a surface is rational but not regular. + size_t GetUCount ( MbSplineSurfaceAuxiliaryData * ) const; + size_t GetVCount ( MbSplineSurfaceAuxiliaryData * ) const; + double DeviationStepV ( double u, double v, double sag, MbSplineSurfaceAuxiliaryData * ) const; // \ru Вычисление шага по v при пересечении поверхностей. \en Calculation of a step in direction of v for surfaces intersection. + double DeviationStepU ( double u, double v, double sag, MbSplineSurfaceAuxiliaryData * ) const; // \ru Вычисление шага по u при пересечении поверхностей. \en Calculation of a step in direction of u for surfaces intersection. + void CheckSurfParams ( double & u, double & v, MbSplineSurfaceAuxiliaryData * ) const; // \ru Проверить параметры. \en Check parameters. + void _DeriveU ( double u, double v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Первая производная по u. \en First derivative with respect to u. + void _DeriveV ( double u, double v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Первая производная по v. \en First derivative with respect to v. + void _DeriveUV ( double u, double v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + void _DeriveUUV ( double u, double v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по uuv. \en Third derivative with respect to uuv. + void _DeriveUVV ( double u, double v, MbVector3D &, MbSplineSurfaceAuxiliaryData * ) const; // \ru Третья производная по uvv. \en Third derivative with respect to uvv. + bool GetPoleUMin ( MbSplineSurfaceAuxiliaryData * ) const; + bool GetPoleUMax ( MbSplineSurfaceAuxiliaryData * ) const; + bool GetPoleVMin ( MbSplineSurfaceAuxiliaryData * ) const; + bool GetPoleVMax ( MbSplineSurfaceAuxiliaryData * ) const; + bool IsPole ( double u, double v, MbSplineSurfaceAuxiliaryData * ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + + double StepD ( bool isU, double u, double v, double sag, bool checkAngle, double angle, MbSplineSurfaceAuxiliaryData * ) const; + double StepDPlus ( bool isU, double u, double v, double sag, bool checkAngle, double angle, MbSplineSurfaceAuxiliaryData * ) const; + double DeviationStep ( bool isU, double u, double v, double angle, MbSplineSurfaceAuxiliaryData * ) const; + double DeviationStepPlus ( bool isU, double u, double v, double angle, MbSplineSurfaceAuxiliaryData * ) const; + void TypedStepPlus ( double u, double v, bool alongU, const MbStepData & stepData, double & step, MbSplineSurfaceAuxiliaryData * ) const; + double GetMinStep ( bool isU, const double * pRng = NULL ) const; + + bool ApproxAsPlane() const; // \ru Можно ли аппроксимировать поверхность как плоскость. \en Whether a surface can be approximated by a plane. + // \ru Вычислить аппроксимацию поверхности, считая, что ее можно аппроксимировать как плоскость. \en Calculate an approximation of surface assuming that it can be approximated by a plane. + MbSplineSurface * CalcApproxAsPlane( size_t nUDegree, size_t nVDegree, ptrdiff_t nUCount, ptrdiff_t nVCount ) const; + bool UseMultiplKnots() const; + + void PoleDerive( double u, double v, MbVector3D & vDerU, MbVector3D & vDerV, MbSplineSurfaceAuxiliaryData * ) const; + + inline void CheckParam( const SArray & knots, const ptrdiff_t & degree, const bool & closed, double & t ) const; + + // \ru Создать двумерную кривую, если пространственная кривая является границей поверхности. \en Create a two-dimensional curve if a space curve is surface boundary. + MbCurve * IsFullSplineBorder( const MbCurve3D & curve ) const; + MbCurve * IsPartSplineBorder( const MbCurve3D & curve ) const; + + void GetVertecisRects( const MbVector3D & direction, bool u, + std::vector > & vertecesRects ) const; + private: + void CalculateDerivativesAlong( double & u, double & v, bool isU, MbVector3D & tDer, MbVector3D & ttDer, + MbSplineSurfaceAuxiliaryData * ) const; + void CalculateDerivativesAlong( double & u, double & v, bool isU, MbVector3D & tDer, MbVector3D & ttDer, MbVector3D & tttDer, + MbSplineSurfaceAuxiliaryData * ) const; + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbSplineSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSplineSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверка нахождения параметра в области определения и корректировка. \en Check that parameter is within the domain and correction. +// --- + inline void MbSplineSurface::CheckParam( const SArray & knots, const ptrdiff_t& degree, const bool& closed, double & t ) const +{ + const double & tmin = knots[degree - 1]; + const double & tmax = knots[knots.Count() - degree]; + + if ( closed ) { + if ( (t < tmin) || (t > tmax) ) { + double trgn = tmax - tmin; + t -= ::floor( (t - tmin) / trgn ) * trgn; + } + } + else if ( t < tmin ) + t = tmin; + else if ( t > tmax ) + t = tmax; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить параметрическое распределение точек для построения NURBS поверхности, проходящей через эти точки. + \en Determine a parametric distribution of points for the construction of NURBS surface passing through these points. \~ + \details \ru Определить параметрическое распределение точек для построения NURBS поверхности, проходящей через эти точки. + Параметр, для которого определяется распределение точек, задается переменной alongLines + (если true - то распределение по v, иначе по u). Определяется усредненное распределение по всем рядам (строкам). + \en Determine a parametric distribution of points for the construction of NURBS surface passing through these points. + The parameter for which distribution of points is determined is set by the variable alongLines. + (if true then there is a distribution by v, otherwise - by u). An average distribution by all rows is determined. \~ + \param[in] degree - \ru Порядок поверхности по заданному параметру. + \en An order of a surface by the given parameter. \~ + \param[in] closed - \ru Замыкание поверхности по заданному параметру. + \en A closure of a surface by the given parameter. \~ + \param[in] points - \ru Матрица точек, для которых надо определить параметрическое распределение. + \en A matrix of points for which the parametric distribution should be determined. \~ + \param[in] alongLines - \ru Определяет, по какому параметру ищется распределение (true - по v, false - по u). + \en Determines a parameter by which the distribution is sought (true - by v, false - by u). \~ + \param[in] spType - \ru Тип параметризации сплайновых объектов: \n + spt_Unstated - неустановленный, \n + spt_EquallySpaced - равномерная, \n + spt_ChordLength - по длине хорды (расстоянию между точками), \n + spt_Centripetal - центростремительная (квадратный корень расстояния между точками). + \en The parameterization type of spline objects: \n + spt_Unstated - unspecified, \n + spt_EquallySpaced - uniform, \n + spt_ChordLength - by chord length (by distance between the points), \n + spt_Centripetal - centripetal (square root of the distance between the points). \~ + \param[in] params - \ru Множество с искомым распределением. + \en A set with the required distribution. \~ + \return \ru true, если вычисления прошли успешно. + \en True if the calculations were successfully performed.. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) DefineThroughPointsParams( ptrdiff_t degree, bool closed, const Array2 & points, bool alongLines, + MbeSplineParamType spType, SArray & params ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Определить параметрическое распределение точек для построения NURBS поверхности, проходящей через эти точки. + \en Determine a parametric distribution of points for the construction of NURBS surface passing through these points. \~ + \details \ru Определить параметрическое распределение точек для построения NURBS поверхности, проходящей через эти точки. + Параметр, для которого определяется распределение точек, задается переменной alongLines + (если true - то распределение по v, иначе по u). + \en Determine a parametric distribution of points for the construction of NURBS surface passing through these points. + The parameter for which distribution of points is determined is set by the variable alongLines. + (if true then there is a distribution by v, otherwise - by u). \~ + \param[in] degree - \ru Порядок поверхности по заданному параметру. + \en An order of a surface by the given parameter. \~ + \param[in] closed - \ru Замыкание поверхности по заданному параметру. + \en A closure of a surface by the given parameter. \~ + \param[in] points - \ru Матрица точек, для которых надо определить параметрическое распределение. + \en A matrix of points for which the parametric distribution should be determined. \~ + \param[in] alongLines - \ru Определяет, по какому параметру ищется распределение (true - по v, false - по u). + \en Determines a parameter by which the distribution is sought (true - by v, false - by u). \~ + \param[in] rowInd - \ru Строка или столбец, по которому вычисляется распределение. + \en A row or a column by which the distribution is calculated. \~ + \param[in] spType - \ru Тип параметризации сплайновых объектов: \n + spt_Unstated - неустановленный, \n + spt_EquallySpaced - равномерная, \n + spt_ChordLength - по длине хорды (расстоянию между точками), \n + spt_Centripetal - центростремительная (квадратный корень расстояния между точками). + \en The parameterization type of spline objects: \n + spt_Unstated - unspecified, \n + spt_EquallySpaced - uniform, \n + spt_ChordLength - by chord length (by distance between the points), \n + spt_Centripetal - centripetal (square root of the distance between the points). \~ + \param[in] params - \ru Множество с искомым распределением. + \en A set with the required distribution. \~ + \return \ru true, если вычисления прошли успешно. + \en True if the calculations were successfully performed.. \~ + \ingroup Algorithms_3D +*/ +// --- +MATH_FUNC (bool) DefineThroughPointsParams( ptrdiff_t degree, bool closed, const Array2 & points, bool alongLines, ptrdiff_t rowInd, + MbeSplineParamType spType, SArray & params ); + + +//------------------------------------------------------------------------------ +// \ru Расчет точки поверхности. \en Calculation of surface point. +// --- +MATH_FUNC (bool) NurbsSurfacePoint( ptrdiff_t uDeg, const SArray & uKnots, bool uCls, double uCur, SArray & uSplines, + ptrdiff_t vDeg, const SArray & vKnots, bool vCls, double vCur, SArray & vSplines, + const Array2 & points, const Array2 * weights, + MbCartPoint3D & nsPnt ); + + +//------------------------------------------------------------------------------ +// \ru Корректна ли плоская сплайновая поверхность. \en Whether a planar spline surface is correct. +// --- +MATH_FUNC (bool) IsValidPlanar( const MbSplineSurface & ); + + +//------------------------------------------------------------------------------ +// \ru Корректна ли сплайновая поверхность с полюсами. \en Whether a spline surface with poles is correct. +// --- +MATH_FUNC (bool) IsValidPoles( const MbSplineSurface & newSurf, const MbSurface & oldSurf ); + + +#endif // __SURF_SPLINE_SURFACE_H diff --git a/C3d/Include/surf_swept_surface.h b/C3d/Include/surf_swept_surface.h new file mode 100644 index 0000000..bbe73f0 --- /dev/null +++ b/C3d/Include/surf_swept_surface.h @@ -0,0 +1,146 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность движения. + \en Swept surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_SWEPT_SURFACE_H +#define __SURF_SWEPT_SURFACE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность движения. + \en Swept surface. \~ + \details \ru Родительский класс поверхностей: MbEvolutionSurface, MbExtrusionSurface, MbRevolutionSurface, MbRuledSurface, MbSectorSurface, MbSpiralSurface. + Поверхность движения описывается движением образующей кривой. + Наследники поверхности отличаются разными траекториями движения образующей кривой. + Первый параметр наследников поверхности движения совпадает с параметром образующей кривой. + \en Parent class for surfaces: MbEvolutionSurface, MbExtrusionSurface, MbRevolutionSurface, MbRuledSurface, MbSectorSurface, MbSpiralSurface. + A swept surface is described by moving of the generating curve. + Inheritors of swept surface differ by various trajectories of generating curve moving. + The first parameter of swept surface inheritors coincides with the parameter of generatrix. \~ + \ingroup Surfaces +*/// --- +class MATH_CLASS MbSweptSurface : public MbSurface { +protected: + MbCurve3D * curve; ///< \ru Образующая кривая. \en Generating curve. + double umin; ///< \ru Минимальное значение параметра u. \en Minimal value of parameter u. + double vmin; ///< \ru Минимальное значение параметра v. \en Minimal value of parameter v. + double umax; ///< \ru Максимальное значение параметра u. \en Maximal value of parameter u. + double vmax; ///< \ru Максимальное значение параметра v. \en Maximal value of parameter v. + bool uclosed; ///< \ru Признак замкнутости по параметру u. \en An attribute of closedness in u-parameter direction. + bool vclosed; ///< \ru Признак замкнутости по параметру v. \en An attribute of closedness in v-parameter direction. + +protected: + /** \brief \ru Конструктор по образующей. + \en Constructor by generatrix. \~ + \details \ru Конструктор по образующей. + \en Constructor by generatrix. \~ + \param[in] same - \ru true, если нужно использовать ту же кривую, false, если нужно использовать копию + \en it equals true if it is required to use the same curve, it equals false if it is required to use the copy \~ + */ + MbSweptSurface( const MbCurve3D &, bool same ); + MbSweptSurface( const MbSweptSurface &, MbRegDuplicate * ); + MbSweptSurface() // \ru Используется только в конвертерах. \en This is used only in converters. + : curve( NULL ), umin( 0 ), vmin( 0 ), umax( 0 ), vmax( 0 ), uclosed( false ), vclosed( false ) {} + +private: + MbSweptSurface( const MbSweptSurface & ); // \ru Не реализовано. \en Not implemented. +public: + virtual ~MbSweptSurface(); + +public: + VISITING_CLASS( MbSweptSurface ); + + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента. \en A type of element. + virtual MbeSpaceType Type() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const= 0; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвиг. \en Translation. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate around an axis. + + virtual void GetProperties( MbProperties & properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the base objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin() const; // \ru Вернуть минимальное значение параметра u. \en Get the minimum value of u. + virtual double GetVMin() const; // \ru Вернуть минимальное значение параметра v. \en Get the minimum value of v. + virtual double GetUMax() const; // \ru Вернуть максимальное значение параметра u. \en Get the maximum value of u. + virtual double GetVMax() const; // \ru Вернуть максимальное значение параметра v. \en Get the maximum value of v. + virtual bool IsUClosed() const; // \ru Проверка замкнутости по параметру u. \en Check of surface closedness in u direction. + virtual bool IsVClosed() const; // \ru Проверка замкнутости по параметру v. \en Check of surface closedness in v direction. + virtual double GetUPeriod() const; // \ru Вернуть период . \en Return period. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. \n + \{ */ + virtual void PointOn ( double &u, double &v, MbCartPoint3D & ) const = 0; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double &u, double &v, MbVector3D & ) const = 0; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double &u, double &v, MbVector3D & ) const = 0; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveUUV( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveUVV( double &u, double &v, MbVector3D & ) const = 0; + virtual void DeriveVVV( double &u, double &v, MbVector3D & ) const = 0; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const = 0; + /** \} */ + /** \ru \name Функции поверхности движения + \en \name Functions of swept surface + \{ */ + /// \ru Дать образующую кривую. \en Get generating curve. + const MbCurve3D & GetCurve() const { return *curve; } + /// \ru Дать образующую кривую для изменения. \en Get generating curve for editing. + MbCurve3D & SetCurve() { return *curve; } + /** \} */ + +protected: + /// \ru Инициализация по поверхности движения. \en Initialization by swept surface. + void InitSwept( const MbSweptSurface & ); + /// \ru Проверить по граничным точкам, может ли поверхность оказаться плоской. \en Check by boundary points, whether a surface may be planar. + bool CheckPlaneByLimitPoints() const; + +private: + void operator = ( const MbSweptSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS( MbSweptSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSweptSurface ) + +//------------------------------------------------------------------------------ +// \ru Получить исходную кривую, возвращает true для прямолинейной направляющей \en Get initial curve, it returns true for the rectilinear guide curve. +// --- +bool GetSourceCurve( const MbCurve3D *& spineCurve, int & sense, + MbPlacement3D & spinePlace, SPtr & planeSpine, VERSION version = Math::DefaultMathVersion() ); + + +#endif // __SURF_SWEPT_SURFACE_H diff --git a/C3d/Include/surf_tessellation.h b/C3d/Include/surf_tessellation.h new file mode 100644 index 0000000..2d2a883 --- /dev/null +++ b/C3d/Include/surf_tessellation.h @@ -0,0 +1,463 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \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; + + // \\test-math\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 == NULL ) + resUU = true; + else if ( ders[sdt_DeriveUU].x != UNDEFINED_DBL ) { + uuDer->Init( ders[sdt_DeriveUU] ); + resUU = true; + } + if ( uvDer == NULL ) + resUV = true; + else if ( ders[sdt_DeriveUV].x != UNDEFINED_DBL ) { + uvDer->Init( ders[sdt_DeriveUV] ); + resUV = true; + } + if ( vvDer == NULL ) + resVV = true; + else if ( ders[sdt_DeriveVV].x != UNDEFINED_DBL ) { + vvDer->Init( ders[sdt_DeriveVV] ); + resVV = true; + } + if ( resUU && resUV && resVV ) { + if ( nor == NULL ) + 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 diff --git a/C3d/Include/surf_torus_surface.h b/C3d/Include/surf_torus_surface.h new file mode 100644 index 0000000..d9e0a22 --- /dev/null +++ b/C3d/Include/surf_torus_surface.h @@ -0,0 +1,362 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Tороидальная поверхность. + \en Toroidal surface. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURF_TORUS_SURFACE_H +#define __SURF_TORUS_SURFACE_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Tороидальная поверхность. + \en Toroidal surface. \~ + \details \ru Поверхность тора описывается радиусом центров majorRadius и радиусом трубки minorRadius, + заданными в локальной системе координат position.\n + Первый параметр поверхности отсчитывается по дуге от оси position.axisX в направлении оси position.axisY. + Первый параметр поверхности u принимает значения на отрезке: umin<=u<=umax. + Значения u=0 и u=2pi соответствуют точке на плоскости XZ локальной системы координат. + Поверхность может быть замкнутой по первому параметру. + У замкнутой поверхности umax-umin=2pi, у не замкнутой поверхности umax-umin<2pi.\n + Второй параметр поверхности отсчитывается по дуге от плоскости XY локальной системы координат поверхности в направлении оси position.axisZ. + Второй параметр поверхности v принимает значения на отрезке: vmin<=v<=vmax. + Значения v=0 и v=2pi соответствуют точке на плоскости XY локальной системы координат поверхности. + Поверхность может быть замкнутой по второму параметру при majorRadius>minorRadius. + У замкнутой поверхности vmax-vmin=2pi, у не замкнутой поверхности vmax-vmin<2pi. \n + Радиус-вектор поверхности описывается векторной функцией \n + r(u,v) = position.origin + ((majorRadius + (minorRadius cos(v)) (cos(u) position.axisX + sin(u) position.axisY)) + (minorRadius sin(v) position.axisZ).\n + Радиус трубки должен быть больше нуля: minorRadius>0. + Радиус центров должен быть не меньше радиуса трубки, взятого с обратным знаком: majorRadius>–minorRadius. + Если majorRadiusminorRadius. + If a surface is closed, then vmax-vmin=2pi, otherwise vmax-vmin<2pi. \n + Radius-vector of line surface is described by the vector function \n + r(u,v) = position.origin + ((majorRadius + (minorRadius cos(v)) (cos(u) position.axisX + sin(u) position.axisY)) + (minorRadius sin(v) position.axisZ).\n + Radius of tube must be positive: minorRadius>0. + Radius of centers must be not less than the radius of tube with the opposite sign: majorRadius>-minorRadius. + If majorRadius minorRadius - пончик, \en MajorRadius > minorRadius - a donut, + ///< \ru majorRadius <= minorRadius - яблоко, \en MajorRadius <= minorRadius - an apple, + ///< \ru (-minorRadius < majorRadius < 0.0) - лимон. \en (-minorRadius < majorRadius < 0.0) - a lemon. + +public: + /// \ru Конструктор по локальной системе координат, большому и малому радиусу. \en Constructor by local coordinate system, major and minor radii. + MbTorusSurface ( const MbPlacement3D & pl, double initMajorR, double initMinorR ); + + /** \brief \ru Конструктор по большому и малому радиусу, локальной системе координат, минимальному и максимальному параметрам по V. + \en Constructor by major and minor radii, local coordinate system, minimal and maximal parameters by V. \~ + \details \ru Конструктор по большому и малому радиусу, локальной системе координат, минимальному и максимальному параметрам по V. + \en Constructor by major and minor radii, local coordinate system, minimal and maximal parameters by V. \~ + \warning \ru Используется только в конвертерах. + \en This is used only in converters. \~ + */ + MbTorusSurface ( double initMajorR, double initMinorR, const MbPlacement3D & pl, double vin, double vax ); + + /** \brief \ru Конструктор по трем точкам. + \en Constructor by three points. \~ + \details \ru Первая точка - центр локальной системы координат поверхности.\n + Длина вектора, направленного из первой точки во вторую, равна большому радиусу,\n + его направление совпадает с направлением оси X.\n + Длина вектора, направленного из второй точки в третью, равна малому радиусу.\n + Ось Z лежит в плоскости точек и направлена в сторону вектора из первой точки в третью. + \en The first point is the center of the surface local coordinate system.\n + A length of a vector directed from the first point to the second point is equal to the major radius,\n + its direction coincides with the direction of the axis X.\n + A length of a vector directed from the second point to the third point is equal to the minor radius,\n + The axis Z lies on the plane of the points and directed to the side of the vector from the first point to the third point. \~ + */ + MbTorusSurface ( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2 ); + + /** \brief \ru Конструктор по трем точкам и малому радиусу. + \en Constructor by three points and minor radius. \~ + \details \ru Конструктор по трем точкам и малому радиусу.\n + Первая точка - центр локальной системы координат тороидальной поверхности.\n + Вектор из первой точки во вторую - направление оси Z. + Большой радиус равен длине проекции на ось Z вектора, направленного из первой точки в третью. + \en Constructor by three points and minor radius.\n + The first point is the center of the toroidal surface local coordinate system.\n + A vector from the first point to the second point - direction of the axis Z. + Major radius is equal to the length of the projection to the axis Z of the vector directed from the first point to the third point. \~ + */ + MbTorusSurface ( const MbCartPoint3D & c0, const MbCartPoint3D & c1, const MbCartPoint3D & c2, double initMinorR ); + +protected: + MbTorusSurface ( const MbTorusSurface & ); +public: + virtual ~MbTorusSurface(); + +public: + VISITING_CLASS( MbTorusSurface ); + + /** \ru \name Функции инициализации + \en \name Initialization functions + \{ */ + /// \ru Инициализация по тороидальной поверхности. \en The initialization by toroidal surface. + void Init( const MbTorusSurface & ); + /** \} */ + /** \ru \name Общие функции геометрического объекта + \en \name Common functions of a geometric object + \{ */ + virtual MbeSpaceType IsA() const; // \ru Тип элемента. \en A type of element. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const ; // \ru Сделать копию элемента. \en Create a copy of the element. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const; // \ru Равны ли объекты. \en Whether the objects are equal. + virtual bool SetEqual( const MbSpaceItem & ); // \ru Сделать равным. \en Make equal. + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * = NULL ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + + virtual void GetProperties( MbProperties & properties ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & properties ); // \ru Записать свойства объекта. \en Set properties of the object. + /** \} */ + /** \ru \name Функции описания области определения поверхности + \en \name Functions for surface domain description + \{ */ + virtual double GetUMin () const; + virtual double GetVMin () const; + virtual double GetUMax () const; + virtual double GetVMax () const; + virtual bool IsUClosed() const; + virtual bool IsVClosed() const; + virtual double GetUPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + virtual double GetVPeriod() const; // \ru Вернуть период для замкнутой функции. \en Return period for a closed function. + /** \} */ + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. + \{ */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & ) const; // \ru Точка на поверхности. \en A point on surface. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const; + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const; + virtual void Normal ( double & u, double & v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + /** \} */ + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & ) const; // \ru Точка на расширенной поверхности. \en A point on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; // \ru Первая производная по u. \en First derivative with respect to u. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; // \ru Первая производная по v. \en First derivative with respect to v. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по u. \en Second derivative with respect to u. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по v. \en Second derivative with respect to v. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; // \ru Вторая производная по uv. \en Second derivative with respect to u and v. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + virtual void _Normal ( double u, double v, MbVector3D & ) const; // \ru Нормаль. \en Normal. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; // \ru Производная нормали. \en Derivative of normal vector. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + /** \} */ + /** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметров поверхности. + \en \name Functions for get of the group of data inside and outside the surface's domain of parameters. + \{ */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; // \ru Значения производных в точке. \en Values of derivatives at point. + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving on surface + \{ */ + virtual double StepU ( double u, double v, double sag ) const; // \ru Вычисление шага по u по заданной стрелке прогиба. \en Calculation of the parameter step in u direction by the sag. + virtual double StepV ( double u, double v, double sag ) const; // \ru Вычисление шага по v по заданной стрелке прогиба. \en Calculation of the parameter step in v direction by the sag. + virtual double DeviationStepU( double u, double v, double angle ) const; // \ru Вычисление шага по u по заданному углу отклонения. \en Calculation of the parameter step in u direction by the deviation angle. + virtual double DeviationStepV( double u, double v, double angle ) const; // \ru Вычисление шага по v по заданному углу отклонения. \en Calculation of the parameter step in v direction by the deviation angle. + virtual double MetricStepU ( double u, double v, double length ) const; // \ru Вычисление шага по u по заданной длине. \en Calculation of the parameter step in u direction by the given length. + virtual double MetricStepV ( double u, double v, double length ) const; // \ru Вычисление шага по v по заданной длине. \en Calculation of the parameter step in v direction by the given length. + virtual size_t GetUCount() const; + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface + \{ */ + virtual double CurvatureU ( double u, double v ) const; // \ru Kривизна вдоль u. \en Curvature in u direction. + virtual double CurvatureV ( double u, double v ) const; // \ru Kривизна вдоль v. \en Curvature in v direction. + + virtual MbSplineSurface * NurbsSurface( double, double, double, double, bool bmatch = false ) const; // \ru NURBS копия поверхности. \en NURBS copy of surface. + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + virtual MbSurface * Offset( double d, bool same ) const; // \ru Создание эквидистантной поверхности. \en Creation of an offset surface. + + virtual MbCurve3D * CurveU( double v, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии v = const. \en A spatial copy of the line v = const. + virtual MbCurve3D * CurveV( double u, MbRect1D * pRgn, bool bApprox = true ) const; // \ru Пространственная копия линии u = const. \en A spatial copy of the line u = const. + // \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. \en Find all a point projection onto the surface along a vector in either of two directions. + virtual void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + // \ru Пересечение с кривой. \en Intersection with a curve. + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + // \ru Определение точки касания поверхностей с одним неподвижным параметром. \en Determination of tangency point of surfaces with one fixed parameter. + virtual MbeNewtonResult SurfaceTangentNewton( const MbSurface & surf1, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + // \ru Определениe точки касания поверхности и кривой. \en Determination of tangency point between a surface and a curve. + virtual MbeNewtonResult CurveTangentNewton( const MbCurve3D & curv, double funcEpsilon, size_t iterLimit, + double & u, double & v, double & t, bool ext0, bool ext1 ) const; + + virtual bool GetCylinderAxis( MbAxis3D & axis ) const; // \ru Дать ось вращения для поверхности. \en Get rotation axis of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; // \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + + // \ru Подобные ли поверхности для объединения (слива). \en Whether the surfaces are similar to merge. + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + // \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; // \ru Является ли поверхность скруглением. \en Whether a surface is fillet. + virtual ThreeStates Salient() const; // \ru Выпуклая ли поверхность. \en Whether a surface is convex. + // \ru Определение разбивки параметрической области поверхности вертикалями и горизонталями. \en Determine a splitting of parametric region of a surface by verticals and horizontals. + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + + virtual void IncludePoint( double u, double v ); // \ru Включить точку в область определения. \en Include a point into domain. + // \ru Существует ли полюс на границе параметрической области сплайновой кривой. \en Whether a pole exists on parametric region boundary of spline curve. + virtual bool GetPoleVMin() const; + virtual bool GetPoleVMax() const; + virtual bool IsPole( double u, double v ) const; // \ru Является ли точка особенной. \en Whether the point is singular. + + virtual size_t GetUMeshCount() const; // \ru Выдать количество полигонов по u. \en Get the number of polygons in u-direction. + virtual size_t GetVMeshCount() const; // \ru Выдать количество полигонов по v. \en Get the number of polygons in v-direction. + + virtual double GetUParamToUnit() const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; // \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; // \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; // \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + + // \ru Является ли объект смещением. \en Is the object a shift? + virtual bool IsShift( const MbSpaceItem &, MbVector3D &, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + virtual double GetRadius() const; // \ru Дать максимальный физический радиус объекта или ноль, если это невозможно. \en Get the maximum physical radius of the object or null if it impossible. + /** \} */ + /** \ru \name Функции элементарных поверхностей + \en \name Functions of elementary surfaces. + \{ */ + virtual bool GetPointProjection( const MbCartPoint3D & p, bool init, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /** \} */ + /** \ru \name Функции тороидальной поверхности + \en \name Functions of toroidal surface + \{ */ + /// \ru Дать физический главный радиус центров. \en Get physical major radius. + double GetMajorRadius() const; + /// \ru Дать физический меньший радиус. \en Get physical minor radius. + double GetMinorRadius() const; + + /// \ru Изменение главного радиуса. \en Changing of major radius. + void SetMajorR( double r ) { majorRadius = r; CheckTorusRadii(); CalculateAngle(); SetDirtyGabarit(); } + /// \ru Изменение меньшего радиуса. \en Changing of minor radius. + void SetMinorR( double r ) { minorRadius = r; CheckTorusRadii(); CalculateAngle(); SetDirtyGabarit(); } + /// \ru Главный радиус. \en Major radius. + double GetMajorR() const { return majorRadius; } + /// \ru Меньший радиус. \en Minor radius. + double GetMinorR() const { return minorRadius; } + /// \ru Радиус v-параллели. \en Radius of v-parallel. + double GetR( double v ) const { return majorRadius + minorRadius * ::cos(v); } + + /// \ru Дать центр u-линии тора. \en Get center of torus u-line. + void GetMinorCentre( double u, MbCartPoint3D & c ) const; + /// \ru Дать проекцию точки на линию центров малого радиуса. \en Get projection of the point to the line of centers of minor radius. + double MinorCentreProjection( MbCartPoint3D & p ) const; + + /** \brief \ru Определить положение полюсов. + \en Define position of the poles. \~ + \details \ru Определить положение полюсов. + \en Define position of the poles. \~ + \param[out] poleVMin, poleVMax - \ru Значения полюсов. + \en Values of the poles. \~ + \return \ru true, если полюса найдены. + \en True if the poles are found. \~ + */ + bool GetVPoles( double & poleVMin, double & poleVMax ) const; + +private: + void CheckTorusRadii(); + inline void CheckParam( double & u, double & v ) const; // \ru Проверка параметров \en Check parameters + bool _CheckParamV( double & v ) const; // \ru Проверить параметр \en Check parameter + // \ru Пересечение с прямолинейной кривой \en Intersection with rectilinear curve + bool StraightIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, bool ext0, bool ext ) const; + void CalculateAngle(); // \ru Вычислить угол \en Evaluate the angle + void operator = ( const MbTorusSurface & ); // \ru Не реализовано. \en Not implemented. + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbTorusSurface ) +}; + +IMPL_PERSISTENT_OPS( MbTorusSurface ) + +//------------------------------------------------------------------------------ +// \ru Проверка параметров \en Check parameters +// --- +inline void MbTorusSurface::CheckParam( double & u, double & v ) const +{ + if ( (u < umin) || (u > umax) ) { + if ( uclosed ) + u -= ::floor( (u - umin) * Math::invPI2 ) * M_PI2; + else if ( u < umin ) + u = umin; + else if ( u > umax ) + u = umax; + } + if ( (v < vmin) || (v > vmax) ) { + if ( vclosed ) + v -= ::floor( (v - vmin) * Math::invPI2 ) * M_PI2; + else if ( v < vmin ) + v = vmin; + else if ( v > vmax ) + v = vmax; + } +} + + +#endif // __SURF_TORUS_SURFACE_H diff --git a/C3d/Include/surface.h b/C3d/Include/surface.h new file mode 100644 index 0000000..a7d178a --- /dev/null +++ b/C3d/Include/surface.h @@ -0,0 +1,1957 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Поверхность. + \en Surface. \~ + \details \ru Поверхности являются представителями семейства трёхмерных геометрических объектов. + Поверхности играют главную роль в построении геометрической модели. Поверхностями описывают + гладкие участки геометрической формы моделируемых объектов. Поверхности строятся с помощью + аналитических функций, по набору точек, на базе кривых и на базе поверхностей. + \en Surfaces are members of a family of three-dimensional geometric objects. + Surfaces play a key role in construction of geometric model. Surfaces are used to describe + smooth parts of geometrical form of modeled objects. Surfaces are constructed by + analytical functions by a set of points on the basis of curves and on the basis of surfaces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SURFACE_H +#define __SURFACE_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCurve; +class MATH_CLASS MbContour; +class MATH_CLASS MbLineSegment; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbPolygon3D; +class MATH_CLASS MbSplineSurface; +class MATH_CLASS MbSurfaceData; +class MATH_CLASS MbMesh; +class MATH_CLASS MbGrid; +class MATH_CLASS MbStepData; +struct MATH_CLASS MbFormNote; +struct MbNurbsParameters; + + +class MATH_CLASS MbSurface; +namespace c3d // namespace C3D +{ +typedef SPtr SurfaceSPtr; +typedef SPtr ConstSurfaceSPtr; + +typedef std::vector SurfacesVector; +typedef std::vector ConstSurfacesVector; + +typedef std::vector SurfacesSPtrVector; +typedef std::vector ConstSurfacesSPtrVector; + +typedef std::set SurfacesSet; +typedef SurfacesSet::iterator SurfacesSetIt; +typedef SurfacesSet::const_iterator SurfacesSetConstIt; +typedef std::pair SurfacesSetRet; + +typedef std::set ConstSurfacesSet; +typedef ConstSurfacesSet::iterator ConstSurfacesSetIt; +typedef ConstSurfacesSet::const_iterator ConstSurfacesSetConstIt; +typedef std::pair ConstSurfacesSetRet; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Поверхность в трехмерном пространстве. + \en Surface in three-dimensional space. \~ + \details \ru Родительский класс всех поверхностей в трехмерном пространстве. + Поверхность представляет собой векторную функцию двух скалярных параметров, + принимающих значения на двумерной связной области. Поверхность представляет собой + непрерывное отображение двумерной связной области в трёхмерное пространство.\n + Для всех поверхностей, кроме MbCurveBoundedSurface, + областью определения является прямоугольник в двумерном пространстве параметров.\n + Поверхность используется:\n + для пространственного моделирования,\n + для построения граней тел в частных случаях. + \en The parent class for all surfaces in three-dimensional space. + A surface is a vector function of two scalar parameters, + taking values on the two-dimensional connected region. Surface represents + a continuous mapping of two-dimensional connected region to three-dimensional space. \n + For all surfaces, except MbCurveBoundedSurface, + the domain is a rectangle in two-dimensional parameter space. \n + A surface is used:\n + for spatial modeling,\n + for construction of solid faces in special cases. \~ + \ingroup Surfaces +*/ +// --- +class MATH_CLASS MbSurface : public MbSpaceItem { +protected : + /** \brief \ru Габаритный куб поверхности. + \en Bounding box of surface. \~ + \details \ru Габаритный куб поверхности рассчитывается только при запросе габарита объекта. Габаритный куб в конструкторе объекта и после модификации объекта принимает неопределенное значение. + \en Bounding box of surface is calculated only at the request. Bounding box of surface is undefined after object constructor and after object modifications \n \~ + */ + mutable MbCube cube; + +protected : + /// \ru Конструктор. \en Constructor. + MbSurface(); + /// \ru Конструктор копирования. \en Copy-constructor. + MbSurface( const MbSurface & ); +public: + /// \ru Деструктор. \en Destructor. + virtual ~MbSurface(); + +public: + /// \ru Реализация функции, инициирующей посещение объекта. \en Implementation of a function initializing a visit of an object. + VISITING_CLASS( MbSurface ); + + // \ru Общие функции геометрического объекта. \en Common functions of geometric object. + + virtual MbeSpaceType IsA() const = 0; // \ru Тип элемента. \en A type of element. + virtual MbeSpaceType Type() const; // \ru Групповой тип элемента. \en Group element type. + virtual MbeSpaceType Family() const; // \ru Семейство объекта. \en Family of object. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * = NULL ) const = 0; // \ru Сделать копию объекта. \en Create a copy of the object. + virtual bool IsSame ( const MbSpaceItem & other, double accuracy = LENGTH_EPSILON ) const = 0; // \ru Являются ли объекты равными. \en Determine whether objects are equal. + virtual bool SetEqual ( const MbSpaceItem & ) = 0; // \ru Сделать объекты равным. \en Make objects equal. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ) = 0; // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ) = 0; // \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ) = 0; // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & c ) const; // \ru Добавить габарит поверхности в куб. \en Add the surface bounding box into a cube. + virtual void Refresh(); // \ru Сбросить все временные данные. \en Reset all temporary data. + + /** \brief \ru Рассчитать временные (mutable) данные объекта. + \en Calculate temporary (mutable) data of an object. \~ + \details \ru Рассчитать временные данные объекта в зависимости от параметра forced. + Если параметр forced равен false, рассчитываются только ещё не насчитанные данные. + Если параметр forced равен true, перерасчитываются все временные данные объекта. + \en Calculate the temporary data of an object depending of the "forced" parameter. + Calculate only data that was not calculated earlier if parameter "forced" is equal false. + Recalculate all temporary data of an object if parameter "forced" is equal true. + \param[in] forced - \ru Принудительный перерасчёт. + \en Forced recalculation. \~ + */ + virtual void PrepareIntegralData( const bool forced ) const; + + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual MbProperty & CreateProperty( MbePrompt name ) const; // \ru Создать собственное свойство. \en Create a custom property. + virtual void GetProperties( MbProperties &properties ) = 0; // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties &properties ) = 0; // \ru Записать свойства объекта. \en Set properties of the object. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + + /** \ru \name Функции описания области определения поверхности. + \en \name Functions for surface domain description. + \{ */ + /// \ru Вернуть минимальное значение параметра u. \en Get the minimum value of u. + virtual double GetUMin() const = 0; + /// \ru Вернуть минимальное значение параметра v. \en Get the minimum value of v. + virtual double GetVMin() const = 0; + /// \ru Вернуть максимальное значение параметра u. \en Get the maximum value of u. + virtual double GetUMax() const = 0; + /// \ru Вернуть максимальное значение параметра v. \en Get the maximum value of v. + virtual double GetVMax() const = 0; + + /** \brief \ru Определить, замкнута ли поверхность по параметру u. + \en Determine whether a surface is closed in u-parameter direction. \~ + \details \ru Определить, замкнута ли гладко поверхность по u-параметру без учета граничного контура. + Всегда false для MbCurveBoundSurface. Рекомендуется использовать IsUPeriodic. + \en Determine whether a surface is closed smoothly in u-parameter direction without regard to the boundary contour. + It is always false for MbCurveBoundSurface. It is recommended to use IsUPeriodic. \~ + */ + virtual bool IsUClosed() const = 0; + + /** \brief \ru Определить, замкнута ли поверхность по параметру v. + \en Determine whether a surface is closed in v-parameter direction. \~ + \details \ru Определить, замкнута ли гладко поверхность по v-параметру без учета граничного контура. + Всегда false для MbCurveBoundSurface. Рекомендуется использовать IsVPeriodic. + \en Determine whether a surface is closed smoothly in v-parameter direction without regard to the boundary contour. + It is always false for MbCurveBoundSurface. It is recommended to use IsVPeriodic. \~ + */ + virtual bool IsVClosed() const = 0; + + /** \brief \ru Определить, замкнута ли фактически поверхность по u-параметру независимо от гладкости замыкания. + \en Determine whether a surface is closed in u-parameter direction regardless of the smoothness of the closure. \~ + \details \ru Определить, замкнута ли фактически поверхность по u-параметру независимо от гладкости замыкания. + \en Determine whether a surface is actually closed in u-parameter direction regardless of the smoothness of the closure. \~ + */ + virtual bool IsUTouch() const; + /** \brief \ru Определить, замкнута ли фактически поверхность по v-параметру независимо от гладкости замыкания. + \en Determine whether a surface is closed in v-parameter direction regardless of the smoothness of the closure. \~ + \details \ru Определить, замкнута ли фактически поверхность по v-параметру независимо от гладкости замыкания. + \en Determine whether a surface is actually closed in v-parameter direction regardless of the smoothness of the closure. \~ + */ + virtual bool IsVTouch() const; + + /** \brief \ru Определить, замкнута ли поверхность по параметру u. + \en Determine whether a surface is closed in u-parameter direction. \~ + \details \ru Определить, замкнута ли гладко поверхность по u-параметру без учета граничного контура. + \en Determine whether a surface is smoothly closed in u-parameter direction. \~ + */ + virtual bool IsUPeriodic() const; + /** \brief \ru Определить, замкнута ли поверхность по параметру v. + \en Determine whether a surface is closed in v-parameter direction. \~ + \details \ru Определить, замкнута ли гладко поверхность по v-параметру без учета граничного контура. + \en Determine whether a surface is smoothly closed in v-parameter direction. \~ + */ + virtual bool IsVPeriodic() const; + + /// \ru Вернуть период для гладко замкнутой поверхности или 0. \en Return period for smoothly closed surface or 0. + virtual double GetUPeriod() const; + /// \ru Вернуть период для гладко замкнутой поверхности или 0. \en Return period for smoothly closed surface or 0. + virtual double GetVPeriod() const; + + /** \brief \ru Вернуть период. + \en Return period. \~ + \details \ru Период вычисляется для гладко замкнутой поверхности по одному из параметров. + Если поверхность не замкнута по этому параметру, возвращается 0. + \en Period is calculated for smoothly closed surface in one of its parameters. + If a surface is not closed in this parameter then 0 is returned. \~ + \param[in] i - \ru Показывает направление: 0 - период по u, 1 - период по v. + \en Shows direction: 0 - period in u, 1 - period in v. \~ + */ + virtual double GetPeriod( ptrdiff_t i ) const; + + /** \brief \ru Определить периодичность. + \en Determine periodicity. \~ + \details \ru Является ли поверхность периодической. + \en Whether a surface is periodic. \~ + \return \ru 0 если не периодическая \n 1 если периодическая по U \n 2 если периодическая по V \n 3 если периодическая по U и V + \en 0 - it is not periodic \n 1 - it is periodic in U \n 2 - it is periodic in V \n 3 - it is periodic in U and V \~ + */ + virtual size_t Periodicity() const; + + /// \ru Существует ли полюс на границе параметрической области. \en Whether a pole exists on parametric region boundary. + virtual bool GetPoleUMin() const; + /// \ru Существует ли полюс на границе параметрической области. \en Whether a pole exists on parametric region boundary. + virtual bool GetPoleUMax() const; + /// \ru Существует ли полюс на границе параметрической области. \en Whether a pole exists on parametric region boundary. + virtual bool GetPoleVMin() const; + /// \ru Существует ли полюс на границе параметрической области. \en Whether a pole exists on parametric region boundary. + virtual bool GetPoleVMax() const; + /// \ru Является ли точка полюсом. \en Whether the point is a pole. + virtual bool IsPole( double u, double v ) const; + /// \ru Является ли точка полюсом. \en Whether the point is a pole. + bool IsPole( const MbCartPoint & uv ) const { return IsPole( uv.x, uv.y ); } + + /** \} */ + + /** \ru \name Функции для работы в области определения поверхности + Функции PointOn, Derive... поверхностей корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + Исключения составляют:\n + 1. MbPlane (плоскость)\n + Функции PointOn, Derive... плоскости не корректируют параметры + при выходе их за пределы прямоугольной области определения параметров.\n + 2. MbSmoothSurface и её наследники (поверхности скругления или фаски)\n + Функции PointOn и Derive... поверхностей сопряжения не корректируют + первый параметр при его выходе за пределы определения параметров. + \en \name Functions for working at surface domain + Functions PointOn, Derive... correct parameters + when getting out of rectangular domain bounds. \n + Exceptions:\n + 1. MbPlane (plane)\n + Functions PointOn, Derive... of plane don't correct parameters + when getting out of rectangular domain bounds. \n + 2. MbSmoothSurface and its inheritors (fillet of chamfer surfaces)\n + Functions PointOn and Derive... of smooth surfaces don't correct + the first parameter when getting out of domain bounds. + \{ */ + + /** \brief \ru Вычислить точку на поверхности. + \en Calculate a point on the surface. \~ + \details \ru Скорректировать параметры при выходе их за пределы прямоугольной области определения и вычислить точку на поверхности. + \en Correct parameters when getting out of rectangular domain bounds and Calculate a point on the surface. \~ + \param[in] u - \ru Первый параметр поверхности. + \en First surface parameter. \~ + \param[in] v - \ru Второй параметр поверхности. + \en Second surface parameter. \~ + \param[out] p - \ru Вычисленная точка на поверхности. + \en A point on the surface. \~ + \ingroup Surfaces + */ + virtual void PointOn ( double & u, double & v, MbCartPoint3D & p ) const = 0; + /// \ru Вычислить первую производную по u. \en Calculate first derivative with respect to u. + virtual void DeriveU ( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить первую производную по v. \en Calculate first derivative with respect to v. + virtual void DeriveV ( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить вторую производную по u. \en Calculate second derivative with respect to u. + virtual void DeriveUU ( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить вторую производную по v. \en Calculate second derivative with respect to v. + virtual void DeriveVV ( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить вторую производную. \en Calculate second derivative. + virtual void DeriveUV ( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void DeriveUUU( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void DeriveUUV( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void DeriveUVV( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить третью производную. \en Calculate third derivative. + virtual void DeriveVVV( double & u, double & v, MbVector3D & ) const = 0; + /// \ru Вычислить касательный вектор по u. \en Calculate tangent vector in u. + virtual void TangentU ( double & u, double & v, MbVector3D & ) const; + /// \ru Вычислить касательный вектор по v. \en Calculate tangent vector in v. + virtual void TangentV ( double & u, double & v, MbVector3D & ) const; + /// \ru Вычислить нормаль. \en Calculate normal. + virtual void Normal ( double & u, double & v, MbVector3D & ) const; + /// \ru Вычислить производную нормали по U. \en Calculate derivative of normal with respect to U. + virtual void NormalU ( double & u, double & v, MbVector3D & ) const; + /// \ru Вычислить производную нормали по V. \en Calculate derivative of normal with respect to V. + virtual void NormalV ( double & u, double & v, MbVector3D & ) const; + /** \} */ + + /** \ru \name Функции для работы внутри и вне области определения поверхности + функции _PointOn, _Derive... поверхностей не корректируют + параметры при выходе их за пределы прямоугольной области определения параметров. + \en \name Functions for working inside and outside the surface domain. + functions _PointOn, _Derive... of surfaces don't correct + parameters when getting out of rectangular domain bounds. + \{ */ + + /** \brief \ru Вычислить точку на поверхности. + \en Calculate a point on the surface. \~ + \details \ru Вычислить точку на поверхности в том числе и за пределами области определения параметров. + \en Calculate a point on the surface including the outside area determination parameters. \~ + \param[in] u - \ru Первый параметр поверхности. + \en First surface parameter. \~ + \param[in] v - \ru Второй параметр поверхности. + \en Second surface parameter. \~ + \param[out] p - \ru Вычисленная точка на поверхности. + \en A point on the surface or on extended surface. \~ + \ingroup Surfaces + */ + virtual void _PointOn ( double u, double v, MbCartPoint3D & p ) const; + /// \ru Вычислить первую производную по u на расширенной поверхности. \en Calculate first derivative with respect to u on extended surface. + virtual void _DeriveU ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить первую производную по v на расширенной поверхности. \en Calculate first derivative with respect to v on extended surface. + virtual void _DeriveV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную по u на расширенной поверхности. \en Calculate second derivative with respect to u on extended surface. + virtual void _DeriveUU ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную по v на расширенной поверхности. \en Calculate second derivative with respect to v on extended surface. + virtual void _DeriveVV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную на расширенной поверхности. \en Calculate second derivative on extended surface. + virtual void _DeriveUV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить третью производную на расширенной поверхности. \en Calculate third derivative on extended surface. + virtual void _DeriveUUU( double u, double v, MbVector3D & ) const; + /// \ru Вычислить третью производную на расширенной поверхности. \en Calculate third derivative on extended surface. + virtual void _DeriveUUV( double u, double v, MbVector3D & ) const; + /// \ru Вычислить третью производную на расширенной поверхности. \en Calculate third derivative on extended surface. + virtual void _DeriveUVV( double u, double v, MbVector3D & ) const; + /// \ru Вычислить третью производную на расширенной поверхности. \en Calculate third derivative on extended surface. + virtual void _DeriveVVV( double u, double v, MbVector3D & ) const; + /// \ru Вычислить касательный вектор по u на расширенной поверхности. \en Calculate tangent vector in u direction on extended surface. + virtual void _TangentU ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить касательный вектор по v на расширенной поверхности. \en Calculate tangent vector in v direction on extended surface. + virtual void _TangentV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить нормаль на расширенной поверхности. \en Calculate a normal on extended surface. + virtual void _Normal ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить производную нормали на расширенной поверхности. \en Calculate derivative of normal vector on extended surface. + virtual void _NormalU ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить производную нормали на расширенной поверхности. \en Calculate derivative of normal vector on extended surface. + virtual void _NormalV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную нормали на расширенной поверхности. \en Calculate second derivative of normal vector on extended surface. + virtual void _NormalUU ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную нормали на расширенной поверхности. \en Calculate second derivative of normal vector on extended surface. + virtual void _NormalUV ( double u, double v, MbVector3D & ) const; + /// \ru Вычислить вторую производную нормали на расширенной поверхности. \en Calculate second derivative of normal vector on extended surface. + virtual void _NormalVV ( double u, double v, MbVector3D & ) const; + + /// \ru Вычислить производную нормали в точке с параметрами u v вдоль линии du dv. \en Calculate derivative of normal vector at the point with the given parameters u and v along the line with the given direction (du,dv). + virtual void _NormalD ( double u, double v, double du, double dv, MbVector3D & der ) const; + + /** \brief \ru Вычислить значения точки и производных для заданных параметров. + \en Calculate point and derivatives of object for given parameters. \~ + \details \ru Значения точки и производных вычисляются в пределах области определения и на расширенной поверхности. + \en Values of point and derivatives are calculated on parameters area and on extended surface. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \param[in] ext - \ru В пределах области определения (false), на расширенной поверхности (true). + \en On parameters area (false), on extended surface (true). \~ + \param[out] pnt - \ru Точка. + \en Point. \~ + \param[out] uDer - \ru Производная по u. + \en Derivative with respect to u. \~ + \param[out] vDer - \ru Производная по v. + \en Derivative with respect to v. \~ + \param[out] uuDer - \ru Вторая производная по u, если не ноль. + \en Second derivative with respect to u, if not NULL. \~ + \param[out] vvDer - \ru Вторая производная по v, если не ноль. + \en Second derivative with respect to v, if not NULL. \~ + \param[out] uvDer - \ru Вторая производная по u и по v, если не ноль. + \en Second derivative with respect to u and v, if not NULL. \~ + \ingroup Surfaces + */ + virtual void Explore( double & u, double & v, bool ext, + MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, + MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; + + /** \brief \ru Вычислить значения всех производных в точке. + \en Calculate all derivatives at point. \~ + \details \ru Значения точки и производных вычисляются на расширенной поверхности. + \en Values of point and derivatives are calculated an extended surface. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \param[out] pnt - \ru Точка. + \en Point. \~ + \param[out] deru - \ru Производная по u. + \en Derivative with respect to u. \~ + \param[out] derv - \ru Производная по v. + \en Derivative with respect to v. \~ + \param[out] norm - \ru Нормаль. + \en Normal. \~ + \param[out] noru - \ru Производная нормали по u. + \en Derivative of normal vector with respect to u. \~ + \param[out] norv - \ru Производная нормали по v. + \en Derivative of normal vector with respect to v. \~ + \param[out] deruu - \ru Вторая производная по u. + \en Second derivative with respect to u. \~ + \param[out] dervv - \ru Вторая производная по v. + \en Second derivative with respect to v. \~ + \param[out] deruv - \ru Вторая производная по u и по v. + \en Second derivative with respect to u and v. \~ + \ingroup Surfaces + */ + virtual void _PointNormal( double u, double v, + MbCartPoint3D & pnt, MbVector3D & deru, MbVector3D & derv, + MbVector3D & norm, MbVector3D & noru, MbVector3D & norv, + MbVector3D & deruu, MbVector3D & dervv, MbVector3D & deruv ) const; + /** \} */ + /** \ru \name Функции движения по поверхности + \en \name Functions of moving on surface + \{ */ + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по величине прогиба + вдоль линии с постоянным значением v. + Вычисление шага проходит с учетом радиуса кривизны. + Шаг аппроксимации вдоль кривой выбирается таким образом, + чтобы отклонение кривой от ее полигона не превышало заданную величину прогиба. + \en Calculate parameter step for the surface approximation by its sag value + along a line with a constant value of v. + Calculation of the step is performed with consideration of curvature radius. + A step of surface approximation along a curve is chosen in such way, + that the deviation from its polygon does not exceed the given value of sag. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] sag - \ru Максимально допустимая величина прогиба. + \en Maximum feasible sag value. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double StepU( double u, double v, double sag ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по величине прогиба + вдоль линии с постоянным значением u. + Вычисление шага проходит с учетом радиуса кривизны. + Шаг аппроксимации вдоль кривой выбирается таким образом, + чтобы отклонение кривой от ее полигона не превышало заданную величину прогиба. + \en Calculate parameter step for the surface approximation by its sag value + along a line with a constant value of u. + Calculation of the step is performed with consideration of curvature radius. + A step of surface approximation along a curve is chosen in such way, + that the deviation from its polygon does not exceed the given value of sag. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] sag - \ru Максимально допустимая величина прогиба. + \en Maximum feasible sag value. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double StepV( double u, double v, double sag ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по углу отклонения касательной + вдоль линии с постоянным значением u. + Шаг аппроксимации вдоль кривой выбирается таким образом, + чтобы угловое отклонение касательной к кривой в следующей точке + не превышало заданную величину ang. + \en Calculate parameter step for the surface approximation by the deviation angle of the tangent vector + along a line with a constant value of u. + A step of surface approximation along a curve is chosen in such way, + that angular deviation of the tangent to the curve at the next point + does not exceed the given value ang. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] ang - \ru Максимально допустимый угол отклонения касательной. + \en The maximum feasible deviation angle of tangent. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double DeviationStepU( double u, double v, double angle ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по углу отклонения касательной + вдоль линии с постоянным значением v. + Шаг аппроксимации вдоль кривой выбирается таким образом, + чтобы угловое отклонение касательной к кривой в следующей точке + не превышало заданную величину ang. + \en Calculate parameter step for the surface approximation by the deviation angle of the tangent vector + along a line with a constant value of v. + A step of surface approximation along a curve is chosen in such way, + that angular deviation of the tangent to the curve at the next point + does not exceed the given value ang. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] ang - \ru Максимально допустимый угол отклонения касательной. + \en The maximum feasible deviation angle of tangent. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double DeviationStepV( double u, double v, double angle ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по заданной метрической длине шага + вдоль линии с постоянным значением u. + \en Calculate the parameter step for approximation of a surface by the given metric length of a step + along a line with a constant value of u. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] len - \ru Заданная метрическая длина. + \en The given metric length. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double MetricStepU( double u, double v, double length ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг параметра для аппроксимации поверхности по заданной метрической длине шага + вдоль линии с постоянным значением v. + \en Calculate the parameter step for approximation of a surface by the given metric length of a step + along a line with a constant value of v. \~ + \param[in] u - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] v - \ru Параметр, определяющий точку на поверхности. + \en A parameter defining a point on the surface. \~ + \param[in] len - \ru Заданная метрическая длина. + \en The given metric length. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + virtual double MetricStepV( double u, double v, double length ) const; + + /** \brief \ru Вычислить шаг параметра. + \en Calculate parameter step. \~ + \details \ru Вычислить шаг одного из параметров для аппроксимации поверхности или по угловому отклонению нормали, или по величине прогиба, или по метрической длине. + \en Calculate parameter step for the surface approximation: by diviation sngle of normal; or by its sag value; or by the metric length. \~ + \param[in] u - \ru Первый параметр поверхности. + \en First surface parameter. \~ + \param[in] v - \ru Второй параметр поверхности. + \en Second surface parameter. \~ + \param[in] alongU - \ru Вдоль первого (true) или второго (false) параметра поверхности. + \en Along the first (true) or second (false) surface parameter. \~ + \param[in] stepData - \ru Данные для вычисления шага. \n + \en Data for step calculation. \~ + \return \ru Величина шага по параметру в заданной точке. + \en A sag value by parameter at given point. \~ + \ingroup Surfaces + */ + double SurfaceStep( const double & u, const double & v, bool alongU, const MbStepData & stepData ) const; + + /// \ru Количество разбиений по параметру u для проверки событий. \en The number of splittings by u-parameter for a check of events. + virtual size_t GetUCount() const; + /// \ru Количество разбиений по параметру v для проверки событий. \en The number of splittings by v-parameter for a check of events. + virtual size_t GetVCount() const; + /** \} */ + /** \ru \name Общие функции поверхности + \en \name Common functions of surface. + \{ */ + /// \ru Дать себя (перегружена только у CurveBoundedSurface). \en Get itself (it is overloaded only in CurveBoundedSurface). + virtual const MbSurface & GetSurface() const; + /// \ru Дать базовую поверхность, если есть, или себя. \en Get the base surface if exists or itself. + virtual const MbSurface & GetBasisSurface() const; + /// \ru Дать себя (перегружена только у CurveBoundedSurface). \en Get itself (it is overloaded only in CurveBoundedSurface). + virtual MbSurface & SetSurface() ; + /// \ru Дать базовую поверхность, если есть, или себя. \en Get the base surface if exists or itself. + virtual MbSurface & SetBasisSurface(); + + // \ru Выдать граничную точку. \en Get the boundary point. + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить одну из точек, параметры которых принимают наибольшие или наименьшие значения. \n + \en Calculate one of the points where parameters take the maximum or the minimum values. \n \~ + \param[in] number - \ru Номер граничной точки. \n + 1 соответствует точке (umin, vmin)\n + 2 - точке (umax, vmin) \n + 3 - точке (umax, vmax) \n + 4 - точке (umin, vmax) + \en A number of a boundary point. \n + 1 corresponds to the point (umin, vmin)\n + 2 corresponds to the point (umax, vmin)\n + 3 corresponds to the point (umax, vmax)\n + 4 corresponds to the point (umin, vmax) \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + */ + virtual void GetLimitPoint( ptrdiff_t number, MbCartPoint3D & pnt ) const; // \ru Выдать граничную трехмерную точку. \en Get the boundary three-dimensional point. + + /** \brief \ru Вычислить двумерную граничную точку. + \en Calculate the boundary two-dimensional point. \~ + \details \ru Вычислить одну из точек, параметры которых принимают наибольшие или наименьшие значения. \n + \en Calculate one of the points where parameters take the maximum or the minimum values. \n \~ + \param[in] number - \ru Номер граничной точки. \n + 1 соответствует точке (umin, vmin) \n + 2 - точке (umax, vmin) \n + 3 - точке (umax, vmax) \n + 4 - точке (umin, vmax) + \en A number of a boundary point. \n + 1 corresponds to the point (umin, vmin)\n + 2 corresponds to the point (umax, vmin)\n + 3 corresponds to the point (umax, vmax)\n + 4 corresponds to the point (umin, vmax) \~ + \param[in, out] pnt - \ru Вычисленная точка. + \en A calculated point. \~ + */ + virtual void GetLimitPoint( ptrdiff_t number, MbCartPoint & pnt ) const; // \ru Выдать граничную двумерную точку (граничные параметры). \en Get the boundary two-dimensional point (boundary parameters). + + /** \brief \ru Вычислить граничную точку. + \en Calculate the boundary point. \~ + \details \ru Вычислить одну из точек, параметры которых принимают наибольшие или наименьшие значения. + \en Calculate one of the points where parameters take the maximum or the minimum values. \~ + \param[in] number - \ru Номер граничной точки. \n + 1 соответствует точке (umin, vmin) \n + 2 - точке (umax, vmin) \n + 3 - точке (umax, vmax) \n + 4 - точке (umin, vmax) + \en A number of a boundary point. \n + 1 corresponds to the point (umin, vmin)\n + 2 corresponds to the point (umax, vmin)\n + 3 corresponds to the point (umax, vmax)\n + 4 corresponds to the point (umin, vmax) \~ + \return \ru Вычисленная точка. + \en A calculated point. \~ + */ + MbCartPoint3D GetLimitPoint( ptrdiff_t number ) const; ///< \ru Выдать граничную трехмерную точку. \en Get the boundary three-dimensional point. + + /** \brief \ru Вычислить кривизну линии вдоль u. + \en Calculate line curvature along the direction of u. \~ + \details \ru Вычисляется кривизна линии вдоль u при v = const. + \en There is calculated a line curvature along the direction of u when v = const. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \return \ru Кривизна. + \en Curvature. \~ + */ + virtual double CurvatureU( double u, double v ) const; // \ru Kривизна линии u. \en Curvature of u line. + + /** \brief \ru Вычислить кривизну линии вдоль v. + \en Calculate line curvature along the direction of v. \~ + \details \ru Вычисляется кривизна линии вдоль v при u = const. + \en There is calculated a line curvature along the direction of v when u = const. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \return \ru Кривизна. + \en Curvature. \~ + */ + virtual double CurvatureV( double u, double v ) const; // \ru Kривизна линии v. \en Curvature of v line. + + /** \brief \ru Вычислить нормальную кривизну линии вдоль u. + \en Calculate a normal curvature of line along the direction of u. \~ + \details \ru Вычисляется нормальная кривизна координатной линии вдоль u. + \en Normal curvature of the coordinate line is calculated along the direction of u. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \return \ru Кривизна. + \en Curvature. \~ + */ + double NormalCurvatureU( double u, double v ) const; // \ru Нормальная кривизна поверхности вдоль линии u. \en A normal curvature of surface along the direction of u. + + /** \brief \ru Вычислить нормальную кривизну линии вдоль v. + \en Calculate a normal curvature of line along the direction of v. \~ + \details \ru Вычисляется нормальная кривизна координатной линии вдоль v. + \en Normal curvature of the coordinate line is calculated along the direction of v. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \return \ru Кривизна. + \en Curvature. \~ + */ + double NormalCurvatureV( double u, double v ) const; // \ru Нормальная кривизна поверхности вдоль линии v. \en A normal curvature of surface along the direction of v. + + /** \brief \ru Вычислить нормальную кривизну поверхности. + \en Calculate a normal curvature of surface. \~ + \details \ru Вычисляется нормальная кривизна поверхности вдоль линии du dv. + \en Normal curvature of surface is calculated along the line (du, dv). \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \param[in] du - \ru Задает направление линии, вдоль которой вычисляется нормальная кривизна. + \en Sets the direction of line a normal curvature is calculated along. \~ + \param[in] dv - \ru Задает направление линии, вдоль которой вычисляется нормальная кривизна. + \en Sets the direction of line a normal curvature is calculated along. \~ + \return \ru Кривизна. + \en Curvature. \~ + */ + double NormalCurvature ( double u, double v, double du, double dv ) const; // \ru Нормальная кривизна поверхности. \en Normal curvature of surface. + + /** \brief \ru Вычислить Среднюю и Гауссову кривизну. + \en Calculate the mean and the Gaussian curvature. \~ + \details \ru Средняя и Гауссова кривизна. + \en The mean and the Gaussian curvature. \~ + \param[in] u - \ru Параметр. + \en Parameter. \~ + \param[in] v - \ru Параметр. + \en Parameter. \~ + \param[out] mean - \ru Средняя кривизна. + \en Mean curvature. \~ + \param[out] gauss - \ru Гауссова кривизна. + \en Gaussian curvature. \~ + \return \ru true в случае успеха операции \n false в противном случае + \en True if the operation succeeded \n otherwise false. \~ + */ + bool MeanGaussCurvature( double u, double v, double & mean, double & gauss ) const; + + /// \ru Является ли базовая поверхность копией базовой поверхности данного объекта. \en Whether a base surface is a copy of the base surface of the given object. + virtual bool IsSameBase( const MbSurface & ) const; + /// \ru Является ли поверхность плоской. \en Whether a surface is planar. + virtual bool IsPlanar() const; + + /** \brief \ru Дать физический радиус объекта или ноль, если это невозможно. + \en Get the physical radius of the object or null if it impossible. \~ + \details \ru Метод выдает максимальный физический радиус по одному из изопараметрических направлений, если соответствующая изопараметрическая кривая является дугой окружности, в противном случае метод выдает ноль. + \en Method returns maximum physical radius by one of the parametric direction if the corresponding parametric curve is the arc, method returns zero otherwise. \~ + */ + virtual double GetRadius() const; + /// \ru Дать радиус скругления, если поверхность является поверхностью скругления. \en Get fillet radius if the surface is a fillet surface. + virtual double GetFilletRadius( const MbCartPoint3D & p ) const; + /// \ru Направление поверхности скругления. \en Direction of fillet surface. + virtual MbeParamDir GetFilletDirection() const; + /// \ru Дать ось вращения для поверхности. \en Get rotation axis of a surface. + virtual bool GetCylinderAxis( MbAxis3D & ) const; + /// \ru Выдать центр сферической поверхности. \en Give the center of sphere surface. + virtual bool GetCentre( MbCartPoint3D & c ) const; + /// \ru Дать осевые (центральные) линии для поверхности. \en Get center lines of a surface. + virtual bool GetCenterLines( std::vector & clCurves ) const; + + /** \brief \ru Изменение носителя. + \en Changing of carrier. \~ + \details \ru Используется для объединения компланарных граней. + \en It is used for union of coplanar faces. \~ + */ + virtual void ChangeCarrier( const MbSpaceItem & item, MbSpaceItem & init ); + + /** \brief \ru Изменение носимых элементов. + \en Changing of carrier elements. \~ + \details \ru Используется для объединения компланарных граней. Поверхности item и init должны быть подобны. + \en It is used for union of coplanar faces. The surfaces 'item' and 'init' must be similar. \~ + \param[in] item - \ru Изменяемая поверхность + \en Changed surface \~ + \param[in] init - \ru Новая поверхность + \en New surface \~ + \param[in] matr - \ru Матрица перехода из item в init + \en Transition matrix from 'item' to 'init' \~ + \return \ru true в случае успеха операции \n false в противном случае + \en True if the operation succeeded \n otherwise false. \~ + */ + virtual bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); + + /** \brief \ru Периодичность направляющей. + \en Periodicity of the guide. \~ + \return \ru true если у поверхности есть направляющая и она периодичная + \en True if a surface has a guide and it is periodic. \~ + */ + virtual bool IsSpinePeriodic() const; + + /** \brief \ru Построить NURBS копию поверхности. + \en Construct a NURBS copy of a surface. \~ + \details \ru Полученная поверхность всегда не замкнута как по u, так и по v. + Исключением является сама поверхность NURBS. + Если поверхность не требует пересчета, то выдается ее копия. + \en An obtained surface is always unclosed in u and in v. + The exception is the NURBS surface itself. + If the surface does not require recalculation, then a copy of it is returned. \~ + \param[in] bmatch - \ru true, если при преобразовании нужно сохранить однозначное сответствие параметрических областей + \en true, if it is required to keep one-to-one correspondence of parametric regions in mapping. \~ + */ + MbSplineSurface * NurbsSurface( bool bmatch = false ) const; + + /** \brief \ru Построить NURBS копию усеченной поверхности. + \en Construct a NURBS copy of trimmed surface. \~ + \details \ru Полученная поверхность всегда не замкнута как по u, так и по v. + Исключением является сама поверхность NURBS. + Если поверхность не требует пересчета, то выдается ее копия + Параметры u1, u2, v1, v2 - границы усечения поверхности. + \en An obtained surface is always unclosed in u and in v. + The exception is the NURBS surface itself. + If the surface does not require recalculation, then a copy of it is returned. + Parameters u1, u2, v1 and v2 are the bounds of surface trimming. \~ + \param[in] u1 - \ru Минимальный параметр по U + \en Minimum parameter in U. \~ + \param[in] u2 - \ru Максимальный параметр по U + \en Maximum parameter in U. \~ + \param[in] v1 - \ru Минимальный параметр по V + \en Minimum parameter in V. \~ + \param[in] v2 - \ru Максимальный параметр по V + \en Maximum parameter in V. \~ + \param[in] bmatch - \ru true, если при преобразовании нужно сохранить однозначное сответствие параметрических областей + \en true, if it is required to keep one-to-one correspondence of parametric regions in mapping. \~ + */ + virtual MbSplineSurface * NurbsSurface( double u1, double u2, double v1, double v2, bool bmatch = false ) const; + + /** \brief \ru Подготовить параметры для преобразования в NURBS поверхность. + \en Prepare parameters for the transformation to NURBS surface. \~ + \details \ru Подготовить параметры для преобразования в NURBS поверхность. + Число точек вдоль выбранного направления определяется в переменной tParam. + \en Prepare parameters for the transformation to NURBS surface. + The number of points along the chosen direction if defined by the variable tParam. \~ + \param[in] tParam - \ru Параметры преобразования поверхности в NURBS по одному из параметров. + \en Parameters for the transformation of a surface to NURBS with respect to one of parameters. \~ + \param[in] uParam - \ru Какой параметр поверхности рассматривается: \n + true - готовит аппроксимацию по u + false - готовит аппроксимацию по v. + \en Which parameter is considered: \n + true - prepares an approximation with respect to u. + false - prepares an approximation with respect to v. \~ + \param[in] op1 - \ru Минимальное значение второго параметра. + \en Minimal value of the second parameter. \~ + \param[in] op2 - \ru Максимальное значение второго параметра. + \en Maximal value of the second parameter. \~ + \param[out] isClosedNurbs - \ru true - если аппроксимирующая поверхность замкнута по выбранному направлению. + \en True - the approximating surface is closed in the chosen direction. \~ + \param[out] epsilon - \ru На выходе - параметрическая точность по выбранному направлению. + \en At the output - parametric tolerance in the given direction. \~ + \param[out] params - \ru Заполненный массив параметров разбиения вдоль выбранного направления. + \en A filled array of splitting parameters along the chosen direction. \~ + \return \ru true, если операция прошла успешно. + \en True if the operation succeeded. \~ + */ + bool NurbsParam( const MbNurbsParameters & tParam, bool uParam, double op1, double op2, + bool & isClosedNurbs, double & epsilon, SArray & params ) const; + + /** \brief \ru Выбрать точки для аппроксимации вдоль параметра. + \en Chose points for approximation along the parameter. \~ + \details \ru Выбрать точки на поверхности для аппроксимации nurbs вдоль параметра в случае незамкнутой по выбранному направлению поверхности. + Если поверхность аппроксимируется с заданным узловым вектором, то проверяются параметры разбиения + для того, чтобы между элементами узлового вектора содержалась бы хотя бы одна точка разбиения. + При необходимости список точек разбиения дополняется. + Если узловой вектор не задан (пустой), то вычисляется узловой вектор в соответствии с порядком, + количеством узлов и предложенным разбиением. + \en Chose points on a surface for NURBS approximation along the parameter in the case of unclosed in the chosen direction surface. + If a surface is approximated with the given knot vector, then splitting parameters are checked + in order to leave at least one splitting point between the elements of a knot vector. + If necessary, the list of splitting points is complemented. + If a knot vector is not set (empty), then the knot vector is calculated according to the order, + the number of knots and the proposed splitting. \~ + \param[in] isU - \ru Какой параметр поверхности рассматривается: \n + true - готовит аппроксимацию по u. + false - готовит аппроксимацию по v. + \en Which parameter is considered: \n + true - prepares an approximation with respect to u. + false - prepares an approximation with respect to v. \~ + \param[in] par - \ru Значение второго параметра. + \en A value of second parameter. \~ + \param[in] degree - \ru Порядок NURBS-поверхности по выбранному направлению. + \en An order of NURBS surface by a chosen direction. \~ + \param[in] pCount - \ru Количество узлов NURBS-поверхности по выбранному направлению. + \en A number of knots of NURBS surface by a chosen direction. \~ + \param[in,out] tList - \ru Параметры разбиения поверхности по выбранному направлению. Вычисляются в функции NurbsParam. + \en A splitting parameters of NURBS surface by a chosen direction. They are calculated in the NurbsParam function. \~ + \param[in,out] aKnots - \ru Узловой вектор NURBS-поверхности. + \en A knot vector of NURBS surface. \~ + */ + void CheckApproxPointParamsOpen( bool isU, double par, size_t degree, size_t pCount, + SArray & tList, SArray & aKnots ) const; + + /** \brief \ru Выбрать точки для аппроксимации вдоль параметра. + \en Chose points for approximation along the parameter. \~ + \details \ru Выбрать точки на поверхности для аппроксимации nurbs вдоль параметра в случае замкнутой по выбранному направлению поверхности. + Если поверхность аппроксимируется с заданным узловым вектором, то проверяются параметры разбиения + для того, чтобы между элементами узлового вектора содержалась бы хотя бы одна точка разбиения. + При необходимости список точек разбиения дополняется. + Если узловой вектор не задан (пустой), то вычисляется узловой вектор в соответствии с порядком, + количеством узлов и предложенным разбиением. + \en Chose points on a surface for NURBS approximation along the parameter in a case of closed in the chosen direction surface. + If a surface is approximated with the given knot vector then splitting parameters are checked + in order to leave at least one splitting point between the elements of a knot vector. + If necessary, the list of splitting points is complemented. + If a knot vector is not set (empty) then the knot vector is calculated according to the order, + the number of knots and the proposed splitting. \~ + \param[in] isU - \ru Какой параметр поверхности рассматривается: \n + true - готовит аппроксимацию по u + false - готовит аппроксимацию по v. + \en Which parameter is considered: \n + true - prepares an approximation with respect to u. + false - prepares an approximation with respect to v. \~ + \param[in] par - \ru Значение второго параметра. + \en A value of second parameter. \~ + \param[in] degree - \ru Порядок NURBS-поверхности по выбранному направлению. + \en An order of NURBS surface by a chosen direction. \~ + \param[in] pCount - \ru Количество узлов NURBS-поверхности по выбранному направлению. + \en A number of knots of NURBS surface by a chosen direction. \~ + \param[in,out] tList - \ru Параметры разбиения поверхности по выбранному направлению. Вычисляются в функции NurbsParam. + \en A splitting parameters of NURBS surface by a chosen direction. They are calculated in the NurbsParam function. \~ + \param[in,out] aKnots - \ru Узловой вектор NURBS-поверхности. + \en A knot vector of NURBS surface. \~ + */ + void CheckApproxPointParamsClosed( bool isU, double par, size_t degree, size_t pCount, + SArray & tList, SArray & aKnots ) const; + // \ru Построить NURBS-копию поверхности. \en Construct a NURBS copy of a surface. + /** \brief \ru Построить NURBS копию поверхности. + \en Construct a NURBS copy of a surface. \~ + \details \ru Строит NURBS поверхность, аппроксимирующую исходную с заданными параметрами по каждому направлению. + В параметрах можно задать степень и количество узлов сплайна, диапазон изменения параметра кривой. + Если в параметрах не задан флаг точной аппроксимации, то строит NURBS без кратных узлов. + \en Constructs a NURBS surface which approximates a given surface with the given parameters in each direction. + In parameters the degree and the number of knots of a spline and the range of curve's parameters changing may be set. + If the flag of accurate approximation is not set in parameters then NURBS without multiple knots is constructed. \~ + \param[in] uParam - \ru Параметры построения по направлению u. + \en Parameters of construction in u direction. \~ + \param[in] vParam - \ru Параметры построения по направлению v. + \en Parameters of construction in v direction. \~ + \result \ru Построенная NURBS поверхность или NULL при неуспешном построении. + \en The constructed NURBS surface or NULL in a case of failure. \~ + */ + virtual MbSurface * NurbsSurface( const MbNurbsParameters & uParam, const MbNurbsParameters & vParam ) const; + // \ru Построить эквидистантую поверхность. \en Create an offset surface. + /** \brief \ru Построить эквидистантую поверхность. + \en Create an offset surface. \~ + \param[in] d - \ru Расстояние по нормали от базовой до эквидистантной поверхности. + \en Distance by the normal vector from the base surface to the offset surface. \~ + \param[in] same - \ru Флаг, показывающий, использовать ли в эквидистантной поверхности текущую поверхность или ее копию. + \en A flag showing whether to use the current surface or its copy in offset surface. \~ + */ + virtual MbSurface * Offset( double d, bool same ) const; + + /** \brief \ru Построить пространственную копию линии v = const. + \en Construct spatial copy of the line v = const. \~ + \param[in] v - \ru Параметр по направлению V. + \en Parameter in V direction. \~ + \param[in] pRgn - \ru Диапазон параметров по U. + \en A range of u-parameters. \~ + \param[in] bApprox - \ru Если false, то вернет не ноль только в случае, если получится создать точную кривую. \n + Если true, то вернет не ноль, если кривая не вырождена. + \en If false, then it returns null only in a case when the exact curve has been successfully created. \n + If true, then it returns null in a case when the curve is not degenerate. \~ + \result \ru Построенная кривая. + \en Constructed curve. \~ + */ + virtual MbCurve3D * CurveU ( double v, MbRect1D * pRgn, bool bApprox = true ) const; + + /** \brief \ru Построить пространственную копию линии u = const. + \en Construct spatial copy of the line u = const. \~ + \param[in] u - \ru Параметр по направлению U. + \en Parameter in U direction. \~ + \param[in] pRgn - \ru Диапазон параметров по V. + \en A range of v-parameters. \~ + \param[in] bApprox - \ru Если false, то вернет не ноль только в случае, если получится создать точную кривую. \n + Если true, то вернет не ноль, если кривая не вырождена. + \en If false, then it returns null only in a case when the exact curve has been successfully created. \n + If true, then it returns null in a case when the curve is not degenerate. \~ + \result \ru Построенная кривая. + \en Constructed curve. \~ + */ + virtual MbCurve3D * CurveV ( double u, MbRect1D * pRgn, bool bApprox = true ) const; + + /** \brief \ru Построить пространственную копию линии по параметрической линии. + \en Construct spatial copy of line by parametric line. \~ + \param[in] segm - \ru Отрезок в параметрической плоскости поверхности, пространственную копию которого надо построить. + \en A segment in parametric plane of surface, a spatial copy of which is required to construct. \~ + \param[in] bApprox - \ru Если false, то вернет не ноль только в случае, если получится создать точную кривую. \n + Если true, то вернет не ноль, если кривая не вырождена. + \en If false, then it returns null only in a case when the exact curve has been successfully created. \n + If true, then it returns null in a case when the curve is not degenerate. \~ + */ + virtual MbCurve3D * CurveUV( const MbLineSegment & segm, bool bApprox = true ) const; + + /** \brief \ru Определить, с какой стороны от поверхности находится точка. + \en Get point location relative to the surface. \~ + \param[in] pnt - \ru Исследуемая точка. + \en The investigated point. \~ + \param[in] eps - \ru Точность определения попадания точки на поверхность. + \en Tolerance of getting a point onto a surface. \~ + \return \ru iloc_InItem = 1 - точка над поверхностью (со стороны нормали). \n + iloc_OnItem = 0 - точка на поверхности. \n + iloc_OutOfItem = -1 - точка под поверхностью. + \en Iloc_InItem = 1 - point is located over the surface (from the side of normal vector) \n + iloc_OnItem = 0 - point is located on the surface, \n + iloc_OutOfItem = -1 - point is located under the surface. \~ + */ + virtual MbeItemLocation PointRelative( const MbCartPoint3D & pnt, double eps = ANGLE_REGION ) const; + + /** \brief \ru Находятся ли точка в области, принадлежащей поверхности. + \en A point is located inside the region on a surface. \~ + \details \ru Исследуется двумерная точка в параметрической плоскости поверхности. + \en Investigated two-dimensional point in the parametric plane of a surface. \~ + \param[in] pnt - \ru Исследуемая точка. + \en The investigated point. \~ + \param[in] ignoreClosed - \ru Учитывать ли замкнутость поверхности. Если true, то замкнутость не учитывается. + \en Whether to consider the surface closedness. If true, then the closedness is not considered. \~ + \return \ru iloc_InItem - точка в области поверхности. \n + iloc_OnItem - точка на границе поверхности. \n iloc_OutOfItem - точка вне области поверхности. + \en Iloc_InItem - point is inside surface region. \n + iloc_OnItem - point belongs to surface boundary. \n iloc_OutOfItem - point is outside surface region. \~ + */ + virtual MbeItemLocation PointClassification( const MbCartPoint & pnt, bool ignoreClosed = false ) const; + + /** \brief \ru Вычислить параметрическое расстояние до ближайшей границы. + \en Calculate the parametric distance to the nearest boundary. \~ + \details \ru Найденное расстояние до ближайшей границы имеет положительное значение, если точка находится внутри, и отрицательное - если снаружи. + \en The calculated distance is positive if the point is inside, and is negative if it is outside. \~ + \param[in] point - \ru Исследуемая точка. + \en The investigated point. \~ + \param[in] epsilon - \ru Точность определения попадания точки на поверхность. + \en Tolerance of getting a point onto a surface. \~ + \return \ru Возвращает расстояние до границы. + \en Returns the distance to the boundary. \~ + */ + virtual double DistanceToBorder( const MbCartPoint & point, double & epsilon ) const; + + /** \brief \ru Определить точки пересечения кривoй с контурами поверхности. + \en Determine points of intersections between the curve and the surface contours. \~ + \details \ru Определить точки пересечения кривoй с границами поверхности + для нахождение частей кривой в пределах поверхности + и векторов для их сдвига в пределы поверхности. + Вектор сдвига определен для каждой точки пересечения. + Если вектор сдвига найти нельзя, то в массив сохраняется вектор нулевой длины. + Он может быть ненулевым, если поверхность замкнута хотя бы по одному из направлений. + Тогда вектор сдвига позволяет сдвинуть часть кривой на некоторое количество периодов так, + чтобы найденная точка пересечения кривой с границей находилась бы в пределах поверхности и + производная к кривой в этой точке была бы направлена внутрь поверхности. + С помощью вектора сдвига кривую можно сдвинуть на некоторое количество периодов. + То есть метрически кривая не изменится. + \en Determine points of intersections between the curve and the surface boundaries + in order to find parts of the curve inside the surface region + and vectors for their translation to the surface region. + Translation vector is defined for each intersection point. + If it is impossible to find a translation vector, then the vector with null size is saved into the array. + It can be non-null if a surface is closed at least in one of directions. + In this case the translation vector allows to move a part of a curve by a certain number of periods in such way + that the found point of intersection between the curve and the boundary is located inside the surface region and + the derivative of a curve at this point is directed inside the surface. + Using the translation vector a curve can be moved by a certain number of periods. + I.e. metrically the curve will not change. \~ + \param[in] curve - \ru Заданная кривая. + \en A given curve. \~ + \param[in,out] tcurv - \ru Множество параметров кривой, соответствующих точкам пересечения. + \en A set of curve parameters corresponding to the intersection points. \~ + \param[in,out] dir - \ru Множество векторов сдвига. + \en A set of translation vectors. \~ + \return \ru Количество пересечений. + \en The number of intersections. \~ + */ + virtual size_t CurveClassification( const MbCurve & curve, SArray & tcurv, SArray & dir ) const; + + /** \brief \ru Определить точки пересечения кривoй с контурами поверхности. + \en Determine points of intersections between the curve and the surface contours. \~ + \details \ru Определить точки пересечения кривoй с границами поверхности + для нахождение частей кривой в пределах поверхности + и векторов для их сдвига в пределы поверхности. + Вектор сдвига определен для каждой точки пересечения. + Если вектор сдвига найти нельзя, то в массив сохраняется вектор нулевой длины. + Он может быть ненулевым, если поверхность замкнута хотя бы по одному из направлений. + Тогда вектор сдвига позволяет сдвинуть часть кривой на некоторое количество периодов так, + чтобы найденная точка пересечения кривой с границей находилась бы в пределах поверхности и + производная к кривой в этой точке была бы направлена внутрь поверхности. + С помощью вектора сдвига кривую можно сдвинуть на некоторое количество периодов. + То есть метрически кривая не изменится. + \en Determine points of intersections between the curve and the surface boundaries + in order to find parts of a curve inside the surface region + and vectors for their translation to the surface region. + Translation vector is defined for each intersection point. + If it is impossible to find a translation vector then the vector with null size is saved into the array. + It can be non-null if a surface is closed at least in one of directions. + In this case the translation vector allows to move a part of a curve by a certain number of periods in such way + that the found point of intersection between the curve and the boundary is located inside the surface region and + the derivative of a curve at this point is directed inside the surface. + Using the translation vector a curve can be moved by a certain number of periods. + I.e. metrically the curve will not change. \~ + \param[in] curve - \ru Заданная кривая. + \en A given curve. \~ + \param[in,out] tcurv - \ru Множество параметров кривой, соответствующих точкам пересечения. + \en A set of curve parameters corresponding to the intersection points. \~ + \param[in,out] dir - \ru Множество векторов сдвига. + \en A set of translation vectors. \~ + \return \ru Количество пересечений. + \en The number of intersections. \~ + */ + size_t SurfaceBorderIntersection( const MbCurve & curve, SArray & tcurv, SArray & dir ) const; + /// \ru Нахождение проекции точки на поверхность. Для внутреннего использования. \en Finding of point projection on surface. For internal use only. + virtual MbeNewtonResult PointProjectionNewton( const MbCartPoint3D & p, size_t iterLimit, + double & u, double & v, bool ext ) const; + /** \brief \ru Найти проекцию точки на поверхность. + \en Find the projection of a point onto the surface. \~ + \details \ru Найти ближайшую проекцию точки на поверхность или ее продолжение по заданному начальному приближению. + Если задан диапазон изменения параметров uvRange, то надо найти проекцию в заданном диапазоне. + Диапазон параметров может выходить за область определения параметров поверхности. + Используется метод Ньютона. + \en Find the nearest point projection to the surface or its extension by the given initial approximation. + If the range of parameters changing 'uvRange' is set, then it is required to find a projection in the given range. + A range of parameters may not belong to the domain of a surface. + The Newton method is used. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in,out] u - \ru На входе - начальное приближение, на выходе - параметр, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a surface, corresponding to the nearest projection. \~ + \param[in,out] v - \ru На входе - начальное приближение, на выходе - параметр, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a surface, corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении поверхности (если true, то искать). + \en A flag defining whether to seek projection on the extension of the surface. \~ + \param[in] uvRange - \ru Диапазон изменения параметров, в котором надо найти решение. + \en A range of parameters changing in which the solution should be found. \~ + \result \ru true - если найдена проекция, удовлетворяющая всем входным условиям. + \en True - if there is found a projection which satisfies to all input conditions. \~ + */ + virtual bool NearPointProjection( const MbCartPoint3D & pnt, double & u, double & v, bool ext, MbRect2D * uvRange = NULL ) const; + /// \ru Нахождение проекции точки на поверхность в направлении вектора. Для внутреннего использования. \en Finding of point projections to the surface in direction of the vector. For internal use only. + virtual MbeNewtonResult DirectPointProjectionNewton( const MbCartPoint3D & p, const MbVector3D & vect, size_t iterLimit, + double & u, double & v, double & w, bool ext ) const; + + /** \brief \ru Найти все проекции точки на поверхность вдоль вектора в любом из двух направлений. + \en Find all a point projection onto the surface along a vector in either of two directions. \~ + \details \ru Вычислить все точки пересечения поверхности с лучом, выходящим из заданной точки p по направлению vect. + Если задан диапазон изменения параметров uvRange, то надо найти проекцию в заданном диапазоне. + Диапазон параметров может выходить за область определения параметров поверхности. + \en Calculate all points of intersection with the ray outgoing from the given point 'p' by the direction 'vect'. + If the range of parameters changing 'uvRange' is set, then it is required to find a projection in the given range. + A range of parameters may not belong to the domain of a surface. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] vect - \ru Вектор направления. + \en A direction vector. \~ + \param[in,out] uv - \ru Множество точек проекции. + \en A set of projection points. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \param[in] uvRange - \ru Диапазон изменения параметров, в котором надо найти решение. + \en A range of parameters changing in which the solution should be found. \~ + */ + virtual void DirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, SArray & uv, bool ext, MbRect2D * uvRange = NULL ) const; + + /** \brief \ru Найти ближайшую проекцию точки на поверхность в направлении вектора. + \en Find the nearest point projection to the surface in the vector direction. \~ + \details \ru Вычислить ближайшую точку пересечения поверхности с лучом, выходящим из заданной точки p по направлению vect. + Если задан диапазон изменения параметров uvRange - то надо найти проекцию в заданном диапазоне. + Диапазон параметров может выходить за область определения параметров поверхности. + \en Calculate the nearest point of intersection with the ray outgoing from the given point 'p' by the direction 'vect'. + If the range of parameters changing 'uvRange' is set, then it is required to find a projection in the given range. + A range of parameters may not belong to the domain of a surface. \~ + \param[in] pnt - \ru Заданная точка. + \en A given point. \~ + \param[in] vect - \ru Вектор направления. + \en A direction vector. \~ + \param[in,out] u - \ru На входе - начальное приближение, на выходе - параметр, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a surface, corresponding to the nearest projection. \~ + \param[in,out] v - \ru На входе - начальное приближение, на выходе - параметр, соответствующий ближайшей проекции. + \en Input - initial approximation, output - parameter of a surface, corresponding to the nearest projection. \~ + \param[in] ext - \ru Флаг, определяющий, искать ли проекцию на продолжении кривой (если true, то искать). + \en A flag defining whether to seek projection on the extension of the curve. \~ + \param[in] uvRange - \ru Диапазон изменения параметров, в котором надо найти решение. + \en A range of parameters changing in which the solution should be found. \~ + \result \ru true - если найдена проекция, удовлетворяющая всем входным условиям. + \en True - if there is found a projection which satisfies to all input conditions. \~ + */ + virtual bool NearDirectPointProjection( const MbCartPoint3D & pnt, const MbVector3D & vect, double & u, double & v, bool ext, + MbRect2D * uvRange = NULL, bool onlyPositiveDirection = false ) const; + /// \ru Решение системы уравнений для определения пересечения поверхности и кривой. Для внутреннего использования. \en Solution of equation system for determination of intersections between a surface and a curve. For internal use only. + virtual MbeNewtonResult CurveIntersectNewton( const MbCurve3D & curv1, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & t1, bool ext0, bool ext1 ) const; + /// \ru Решение системы уравнений для определения касания поверхности и кривой. Для внутреннего использования. \en Solution of equation system for determination of tangency between a surface and a curve. For internal use only. + virtual MbeNewtonResult CurveTangentNewton ( const MbCurve3D & curv1, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & t1, bool ext0, bool ext1 ) const; + + /** \brief \ru Определить точки пересечения поверхности и кривой. + \en Determine points of intersection between a surface and a curve. \~ + \details \ru Определить точки пересечения поверхности и кривой. \n + \en Determine points of intersection between a surface and a curve. \n \~ + \param[in] curv - \ru Заданная кривая. + \en A given curve. \~ + \param[in] uv - \ru Множество точек пересечения на поверхности. + \en A set of intersection points on the surface. \~ + \param[in,out] tt - \ru Множество точек пересечения на кривой. + \en A set of intersection points on the curve. \~ + \param[in] ext0 - \ru Флаг, определяющий, искать ли пересечения на расширенной поверхности (если true, то искать). + \en A flag defining whether to seek intersections on extended surface (if it is true, then seek). \~ + \param[in] ext - \ru Флаг, определяющий, искать ли пересечения на продолжении кривой (если true, то искать). + \en A flag defining whether to seek intersections on extended curve (if it is true, then seek). \~ + \param[in] touchInclude - \ru Считать ли касание пересечением. Если true, то считать. + \en Whether to consider tangency as intersection. If true, then consider. \~ + */ + virtual void CurveIntersection( const MbCurve3D & curv, SArray & uv, SArray & tt, + bool ext0, bool ext, bool touchInclude = false ) const; + + /// \ru Решение системы уравнений для определения пересечения поверхностей. Для внутреннего использования. \en Solution of equation system for determination of surfaces intersections. For internal use only. + virtual MbeNewtonResult SurfaceIntersectNewton( const MbSurface & surf1, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + /// \ru Решение системы уравнений для определения касания поверхностей. Для внутреннего использования. \en Solution of equation system for determination of surfaces tangency. For internal use only. + virtual MbeNewtonResult SurfaceTangentNewton( const MbSurface & surf1, MbeParamDir switchPar, double funcEpsilon, size_t iterLimit, + double & u0, double & v0, double & u1, double & v1, bool ext0, bool ext1 ) const; + /// \ru Решение системы уравнений для определение точек очерка поверхности. Для внутреннего использования. \en Solution of equation system for determination of surface silhouette points. For internal use only. + virtual MbeNewtonResult SilhouetteNewton( const MbVector3D & eye, bool perspective, const MbAxis3D * axis, MbeParamDir switchPar, + double funcEpsilon, size_t iterLimit, double & u, double & v, bool ext ) const; + + /** \brief \ru Определить, подобны ли поверхности для объединения. + \en Define whether the surfaces are similar for merge. \~ + \details \ru Поверхности подобны для объединения, если геометрически они совпадают или переходят одна в другую. + \en Surfaces are similar for merge if they coincide geometrically or one surface transits to another. \~ + \param[in] surf - \ru Заданная поверхность. + \en A given surface. \~ + \param[in] version - \ru Версия операции. + \en Version of operation. \~ + \param[in] precision - \ru Погрешность вычислений. + \en Precision of calculation. \~ + \result \ru true - если поверхности подобны. + \en True - if surfaces are similar. \~ + */ + virtual bool IsSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + /// \ru Подобные ли поверхности для объединения (слива). Специальный случай. Для внутреннего использования. \en Whether the surfaces are similar to merge. Special case. For internal use only. + virtual bool IsSpecialSimilarToSurface( const MbSurface & surf, VERSION version, double precision = METRIC_PRECISION ) const; + + /** \brief \ru Построение проекции поверхностной кривой на совпадающую поверхность. + \en Construction of projection of a surface curve on coincident surface. \~ + \details \ru Строится проекция кривой пересечения поверхностей на некоторую заданную поверхность. + В функции подразумевается, что заданная поверхность подобна одной из несущих поверхностей кривой пересечения, + но этот факт не проверяется. + \en A projection of surface intersection curve is constructed on a given surface. + It is implied that the given surface is similar to one of surfaces of the intersection curve + but this fact is not checked. \~ + \param[in] spaceCurve - \ru Заданная кривая пересечения. + \en A given intersection curve. \~ + \param[in] curve - \ru Двумерная кривая на поверхности. + \en A two-dimensional curve on a surface. \~ + \param[in] surfNew - \ru Новая поверхность. + \en New surface. \~ + \param[out] curveNew - \ru Полученная двумерная кривая на новой поверхности. + \en An obtained two-dimensional curve on new surface. \~ + \result \ru true - если операция прошла успешно. + \en True - if the operation succeeded. \~ + */ + virtual bool ProjectCurveOnSimilarSurface( const MbCurve3D & spaceCurve, const MbCurve & curve, const MbSurface & surfNew, MbCurve *& curveNew ) const; + /** \brief \ru Построение проекции поверхностной кривой на совпадающую поверхность. + \en Construction of projection of a surface curve on coincident surface. \~ + \details \ru Строится проекция кривой пересечения поверхностей на некоторую заданную поверхность. + В функции подразумевается, что заданная поверхность подобна одной из несущих поверхностей кривой пересечения, + но этот факт не проверяется. + \en A projection of surface intersection curve is constructed on a given surface. + It is implied that the given surface is similar to one of surfaces of the intersection curve + but this fact is not checked. \~ + \param[in] spaceCurve - \ru Заданная кривая пересечения. + \en A given intersection curve. \~ + \param[in] curve - \ru Двумерная кривая на поверхности. + \en A two-dimensional curve on a surface. \~ + \param[in] surfNew - \ru Новая поверхность. + \en New surface. \~ + \param[out] curveNew - \ru Полученная двумерная кривая на новой поверхности. + \en An obtained two-dimensional curve on new surface. \~ + \result \ru true - если операция прошла успешно. + \en True - if the operation succeeded. \~ + */ + bool ProjectCurveOnSimilarSurface( const MbCurve3D & spaceCurve, const MbCurve & curve, const MbSurface & surfNew, SPtr & curveNew ) const; + + /** \brief \ru Дать двумерную матрицу преобразования из своей параметрической области в параметрическую область surf. + \en Get two-dimensional matrix of transformation from its parametric region to the parametric region of 'surf'. \~ + \details \ru Вычисление матрицы преобразования из одной параметрической области в другую + осуществляется для поверхностей, подобных для объединения. + \en Calculation of matrix of transformation from one parametric region to another. + it is performed for the surfaces which are similar for merge. \~ + \param[in] surf - \ru Заданная поверхность. + \en A given surface. \~ + \param[out] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] version - \ru Версия операции. + \en Version of operation. \~ + \param[in] precision - \ru Погрешность вычислений. + \en Precision of calculation. \~ + \result \ru true - матрица вычислена. + \en True - matrix is calculated. \~ + */ + virtual bool GetMatrixToSurface( const MbSurface & surf, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + + /// \ru Определить, выпуклая ли поверхность. \en Determine whether the surface is convex. + virtual ThreeStates Salient() const; + + /** \brief \ru Вычислить ближайшее расстояние до кривой. + \en Calculate the nearest distance to a curve. \~ + \details \ru Вычисляется минимальное расстояние между кривой и поверхностью. + Определяются точки на поверхности и кривой, между которыми расстояние минимально. + \en Calculation of the minimum distance between a curve and a surface. + Determination of the points on a surface and a curve where the minimum distance is reached. \~ + \param[in] curve - \ru Заданная кривая. + \en A given curve. \~ + \param[out] u - \ru Координата вычисленной точки на поверхности. + \en Coordinate of the calculated point on surface. \~ + \param[out] v - \ru Координата вычисленной точки на поверхности. + \en Coordinate of the calculated point on surface. \~ + \param[in,out] t - \ru На входе - начальное приближение к искомой точке на кривой. + На выходе - параметр вычисленной точки на кривой. + \en Input - an initial approximation to the required point on a curve. + Output - a parameter of the calculated point on a curve. \~ + \param[in] tCalc - \ru Флаг, показывающий, использовать ли t в качестве начального приближения. + \en A flag showing whether to use t as initial approximation. \~ + \result \ru Минимальное расстояние между кривой и поверхностью. + \en The minimum distance between a curve and a surface. \~ + */ + virtual double DistanceToCurve( const MbCurve3D & curve, double & u, double & v, double & t, bool tCalc = false ) const; // \ru tCalc - флаг инициализации t \en TCalc - flag of initialization of t. + + /** \brief \ru Вычислить ближайшее расстояние до поверхности. + \en Calculate the nearest distance to a surface. \~ + \details \ru Вычисляется минимальное расстояние между двумя поверхностями. + Определяются точки на поверхностях, между которыми расстояние минимально. + \en Calculating of minimum distance between two surfaces. + Determination of the points on surfaces where the minimum distance is reached. \~ + \param[in] surf1 - \ru Заданная поверхность. + \en A given surface. \~ + \param[out] u0 - \ru Координата вычисленной точки на текущей поверхности. + \en Coordinate of the calculated point on the current surface. \~ + \param[out] v0 - \ru Координата вычисленной точки на текущей поверхности. + \en Coordinate of the calculated point on the current surface. \~ + \param[out] u1 - \ru Координата вычисленной точки на заданной поверхности. + \en Coordinate of the calculated point on the given surface. \~ + \param[out] v1 - \ru Координата вычисленной точки на заданной поверхности. + \en Coordinate of the calculated point on the given surface. \~ + \result \ru Минимальное расстояние между поверхностями. + \en Minimal distance between surfaces. \~ + */ + virtual double DistanceToSurface( const MbSurface & surf1, double & u0, double & v0, double & u1, double & v1 ) const; + + /// \ru Построить нормальные плейсменты конструктивных плоскостей. \en Construct normal placements of constructive planes. + virtual bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + /// \ru Построить касательные плейсменты конструктивных плоскостей. \en Construct tangent placements of constructive planes. + virtual bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + /// \ru Построить касательные плейсменты конструктивных плоскостей. Для внутреннего использования. \en Construct tangent placements of constructive planes. For internal use only. + MbeNewtonResult PlacementNewton( const MbVector3D & vec, double angle, MbeParamDir switchPar, size_t iterLimit, double & u, double & v ) const; + /// \ru Построить нормальные или касательные плейсменты на v-линиях. \en Construct the normal or tangent placements on v-lines. + bool CreateVconstPlacements ( const MbVector3D & axisZ, double angle, bool normalPlace, SArray & places ) const; + /// \ru Построить нормальные или касательные плейсменты на u-линиях. \en Construct the normal or tangent placements on u-lines. + bool CreateUconstPlacements ( const MbVector3D & axisZ, double angle, bool normalPlace, SArray & places ) const; + + + /// \ru Вычислить площадь области определения параметров. \en Calculate the area of parameters domain. + virtual double ParamArea() const; + + /** \brief \ru Вычислить U-пары от V. + \en Calculate U-pairs by V. \~ + \details \ru Вычислить значимые параметры u поверхности при заданном параметре v. + В случае поверхности общего вида - минимальное и максимальное значения параметра u. + \en Calculate significant u-parameters of a surface with the given parameter v. + In a case of general form - minimal and maximal values of u-parameter. \~ + \param[in] v - \ru Заданный параметр. + \en Given parameters. \~ + \param[out] u - \ru Множество значений u. + \en A set of values of u. \~ + \result \ru Количество вычисленных значений u. + \en The number of calculated values of u. \~ + */ + virtual size_t GetUPairs( double v, SArray & u ) const; + + /** \brief \ru Вычислить V-пары от U. + \en Calculate V-pairs by U. \~ + \details \ru Вычислить значимые параметры v поверхности при заданном параметре u. + В случае поверхности общего вида - минимальное и максимальное значения параметра v. + \en Calculate significant v-parameters of a surface with the given parameter u. + In case of a surface of general form - minimal and maximal values of v-parameter. \~ + \param[in] u - \ru Заданный параметр. + \en Given parameters. \~ + \param[out] v - \ru Множество значений v. + \en A set of values of v. \~ + \result \ru Количество вычисленных значений v. + \en The number of calculated values of v. \~ + */ + virtual size_t GetVPairs( double u, SArray & v ) const; + + /// \ru Определение параметров точки изоклины поверхности. Для внутреннего использования. \en Determination of parameters of a surface isocline point. For internal use only. + MbeNewtonResult IsoclinalNewton( const MbVector3D & dir, size_t iterLimit, double & u, double & v ) const; + + /** \brief \ru Найти все изоклины поверхности. + \en Find all isoclines of a surface. \~ + \details \ru Найти точки на поверхности, в которых касательная плоскость параллельна некоторой плоскости, + имеющей нормаль nor. + \en Find the points on a surface where the tangent plane is parallel to a plane + having a normal nor. \~ + \param[in] nor - \ru Вектор, задающий плоскость. + \en A vector which defines a plane. \~ + \param[out] uv - \ru Множество параметров точек с искомой касательной. + \en A set of parameters of points for the required tangent. \~ + */ + virtual void GetIsoclinal( const MbVector3D & nor, SArray & uv ) const; + + /// \ru Рассчитать габарит поверхности. Рекомендуется использовать GetGabarit. \en Calculate bounding box of surface. It is recommended to use GetGabarit. + virtual void CalculateGabarit( MbCube & cube ) const; + /// \ru Рассчитать габарит в локальной системе координат. \en Calculate bounding box in the local coordinate system. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; + + /// \ru Рассчитать габаритный куб поверхности. \en Calculate bounding box of surface. + const MbCube & GetGabarit() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube; } + /// \ru Вернуть сохраненный габаритный куб. Он должен быть пустой. Рекомендуется использовать GetGabarit. \en Return saved bounding box. It should be empty. It is recommended to use GetGabarit. + const MbCube & Cube() const { return cube; } + /// \ru Сделать габарит пустым. Для внутреннего использования. \en Make the bounding box empty. For internal use only. + void SetDirtyGabarit() const { cube.SetEmpty(); } + + /** \brief \ru Скопировать габаритный куб из копии. + \en Copy the bounding box from the copy. \~ + \details \ru Скопировать из копии готовые метрические оценки, которые в оригинале не были расчитаны. + \en Copy from the copy ready estimates which were not calculated in the original. \~ + \warning \ru Для скорости проверка идентичности оригинала и копии не выполняется! + \en A check of identity between a copy and an original is not performed for the time saving! \~ + \param[in] s - \ru Поверхность-копия. + \en A surface-copy. \~ + */ + void CopyGabarit( const MbSurface & s, const MbVector3D * to = NULL ) { cube = s.cube; if ( (to != NULL) && !cube.IsEmpty() ) { cube.Move( *to ); } } + /// \ru Вычислить диагональ габаритного куба. \en Calculate the diagonal of the bounding box. + double GetGabDiagonal() const { if ( cube.IsEmpty() ) CalculateGabarit( cube ); return cube.GetDiagonal(); } + + /** \brief \ru Вычислить прямоугольный габарит поверхности в заданной плоскости. + \en Calculate the rectangular bounding box of a surface in the given plane. \~ + \details \ru Выдать прямоугольный габарит поверхности в плоскости XOY плейсмента. + \en Get the rectangular bounding box of surfaces in the XAOY plane of the placement. \~ + \param[in] place - \ru Заданный плейсмент. + \en The given placement. \~ + \param[out] rect - \ru Вычисленный прямоугольник. + \en Calculated rectangle. \~ + */ + void CalculateRect( const MbPlacement3D & place, MbRect & rect ) const; + + /** \brief \ru Вернуть граничный двумерный контур. + \en Return the bounding two-dimensional contour. \~ + \details \ru Функция создает новый двумерный граничный контур. + После использования объект надо удалить. + \en The function creates new two-dimensional bounding contour. + The object should be deleted after using. \~ + \param[in] sense - \ru Совпадает ли направление контура с направлением обхода против часовой стрелки. + \en Whether the contour direction coincides with the counterclockwise traverse direction. \~ + \result \ru Граничный контур. + \en Bounding contour. \~ + */ + virtual MbContour & MakeContour( bool sense ) const; + + /** \brief \ru Вернуть сегмент граничного двумерного контура. + \en Return a segment of the bounding two-dimensional contour. \~ + \details \ru Функция создает сегмент граничного контура в соответствии с параметром i. \n + i = 0 - Отрезок границы при v = vmin \n + i = 1 - Отрезок границы при u = umax \n + i = 2 - Отрезок границы при v = vmax \n + i = 3 - Отрезок границы при u = umin \n + После использования объект надо удалить. + \en The function creates a segment of bounding contour according to the parameter i. \n + i = 0 - A segment of boundary where v = vmin \n + i = 1 - A segment of boundary where u = umax \n + i = 2 - A segment of boundary where v = vmax \n + i = 3 - A segment of boundary where u = umin \n + The object should be deleted after using. \~ + \param[in] i - \ru Номер сегмента. + \en An index of segment. \~ + \param[in] sense - \ru Совпадает ли направление контура с направлением обхода против часовой стрелки. + \en Whether the contour direction coincides with the counterclockwise traverse direction. \~ + \result \ru Граничная кривая. + \en A boundary curve. \~ + */ + virtual MbCurve & MakeSegment( size_t i, bool sense ) const; + + /** \brief \ru Вернуть сегмент граничного двумерного контура. + \en Return a segment of the bounding two-dimensional contour. \~ + \details \ru Функция находит крайние точки поверхности с помощью функции GetLimitPoint + и строит отрезок от точки с номером number1 до точки с номером number2. + После использования объект надо удалить. + \en The function finds the boundary points of a surface using the function GetLimitPoint + and constructs a segment from the point with the number 'number1' to the points with the number 'number2'. + The object should be deleted after using. \~ + \param[in] number1 - \ru Номер граничной точки поверхности. + \en A number of a boundary surface. \~ + \param[in] number2 - \ru Номер граничной точки поверхности. + \en A number of a boundary surface. \~ + \result \ru Граничная кривая. + \en A boundary curve. \~ + */ + MbCurve & MakeCurve( size_t number1, size_t number2 ) const; + + /// \ru Установить пределы поверхности. Для внутреннего использования. \en Set surface limits. For internal use only. + virtual void SetLimit( double u1, double v1, double u2, double v2 ); + /// \ru Установить пределы поверхности. Для внутреннего использования. \en Set surface limits. For internal use only. + void SetLimit( const MbRect & ); + + /// \ru Установить расширенные пределы поверхности. Для внутреннего использования. \en Set extended limits of surface. For internal use only. + virtual void SetExtendedParamRegion( double u1, double v1, double u2, double v2 ); + /// \ru Включить точку в область определения. Для внутреннего использования. \en Include a point into domain. For internal use only. + virtual void IncludePoint( double u, double v ); + + /// \ru Дать максимальное приращение параметра U. \en Get the maximum increment of U-parameter. + double GetMaxParamDeltaU() const { return GetURange() / c3d::COUNT_DELTA; } + /// \ru Дать максимальное приращение параметра V. \en Get the maximum increment of V-parameter. + double GetMaxParamDeltaV() const { return GetVRange() / c3d::COUNT_DELTA; } + /// \ru Дать максимальное приращение параметра. \en Get the maximum increment of parameter. + virtual double GetParamDelta() const; + /// \ru Дать минимально различимую величину параметра. \en Get the minimum distinguishable value of parameter. + virtual double GetParamPrice() const; + + /// \ru Дать приращение параметра u, осреднённо соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit() const; + /// \ru Дать приращение параметра v, осреднённо соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit() const; + /// \ru Дать приращение параметра u, соответствующее единичной длине в пространстве. \en Get increment of u-parameter, corresponding to the unit length in space. + virtual double GetUParamToUnit( double u, double v ) const; + /// \ru Дать приращение параметра v, соответствующее единичной длине в пространстве. \en Get increment of v-parameter, corresponding to the unit length in space. + virtual double GetVParamToUnit( double u, double v ) const; + /// \ru Дать приращение параметра u и параметра v, соответствующее единичной длине в пространстве. \en Get increment of parameters, corresponding to the unit length in space. + virtual void GetParamsToUnit( double u, double v, double & uParam, double & vParam ) const; + + /// \ru Дать минимально различимую величину параметра U. Соответствует длине в пространстве = Math::metricEpsilon. \en Get the minimum distinguishable value of u-parameter. It corresponds to the length Math::metricEpsilon in space. + double GetUEpsilon() const; + /// \ru Дать минимально различимую величину параметра V. Соответствует длине в пространстве = Math::metricEpsilon. \en Get the minimum distinguishable value of v-parameter. It corresponds to the length Math::metricEpsilon in space. + double GetVEpsilon() const; + /// \ru Дать минимально различимую величину параметра U. Соответствует длине в пространстве = Math::metricEpsilon. \en Get the minimum distinguishable value of u-parameter. It corresponds to the length Math::metricEpsilon in space. + double GetUEpsilon( double u, double v ) const; + /// \ru Дать минимально различимую величину параметра V. Соответствует длине в пространстве = Math::metricEpsilon. \en Get the minimum distinguishable value of v-parameter. It corresponds to the length Math::metricEpsilon in space. + double GetVEpsilon( double u, double v ) const; + + /// \ru Дать минимально различимую величину параметра U. Соответствует длине в пространстве = Math::metricRegion. \en Get the minimum distinguishable value of u-parameter. It corresponds to the length Math::metricRegion in space. + double GetURegion() const; + /// \ru Дать минимально различимую величину параметра V. Соответствует длине в пространстве = Math::metricRegion. \en Get the minimum distinguishable value of v-parameter. It corresponds to the length Math::metricRegion in space. + double GetVRegion() const; + /// \ru Дать минимально различимую величину параметра U. Соответствует длине в пространстве = Math::metricRegion. \en Get the minimum distinguishable value of u-parameter. It corresponds to the length Math::metricRegion in space. + double GetURegion( double u, double v ) const; + /// \ru Дать минимально различимую величину параметра V. Соответствует длине в пространстве = Math::metricRegion. \en Get the minimum distinguishable value of v-parameter. It corresponds to the length Math::metricRegion in space. + double GetVRegion( double u, double v ) const; + + /// \ru Выдать количество разбиений по u. \en The the number of splittings in u-direction. + virtual size_t GetUMeshCount() const; + /// \ru Выдать количество разбиений по v. \en The the number of splittings in v-direction. + virtual size_t GetVMeshCount() const; + + /** \brief \ru Рассчитать полигон по параметру U или V. + \en Calculate polygon by u or v. \~ + \details \ru В функции строится поверхностная кривая - отрезок вдоль выбранного направления + и считается полигон, аппроксимирующий эту кривую. + \en In the function the surface curve is constructed - a segment along the chosen direction + and after that a curve approximating polygon is calculated. \~ + \param[in] minPar - \ru Минимальное значение параметра по выбранному направлению. + \en Minimal value of parameter in the chosen direction. \~ + \param[in] maxPar - \ru Максимальное значение параметра по выбранному направлению. + \en Maximal value of parameter in the chosen direction. \~ + \param[in] constPar - \ru Значение второго параметра. + \en A value of second parameter. \~ + \param[in] dir - \ru Выбранное направление. \n + dir == pd_DirU - расчет производится по параметру u, v = const. \n + dir == pd_DirV - расчет производится по параметру v, u = const. + \en A chosen direction. \n + dir == pd_DirU - calculation is performed by u-parameter, v = const. \n + dir == pd_DirU - calculation is performed by v-parameter, u = const. \~ + \param[in] sag - \ru Величина прогиба, определяющая точность аппроксимации. + \en A sag value, defining the tolerance of approximation. \~ + \param[out] polygon - \ru Насчитанный полигон. + \en Calculated polygon. \~ + */ + void CalculatePolygon( double minPar, double maxPar, double constPar, MbeParamDir dir, + const MbStepData & stepData, MbPolygon3D & polygon ) const; + + /** \brief \ru Рассчитать сетку. + \en Calculate mesh. \~ + \details \ru В функции производится расчет сетки для отрисовки поверхности. + \en In the function the mesh calculation for surface drawing is performed. \~ + \param[in] sag - \ru Величина прогиба, определяющая точность. + \en A sag value, defining the tolerance.. \~ + \param[in] beg - \ru Номер первого узла, который попадет в сетку, по каждому из направлений. + Для построения сетки для всей поверхности beg == 0. + \en A number of the the first knot which gets into the mesh by each direction. + For the construction of mesh of the whole surface beg == 0. \~ + \param[out] mesh - \ru Насчитанный Фасетный объект. + \en A calculated mesh. \~ + \param[in] uMeshCount - \ru Количество u-линий отрисовочной сетки. + \en The number of u-mesh lines. \~ + \param[in] vMeshCount - \ru Количество v-линий отрисовочной сетки. + \en The number of v-mesh lines. \~ + */ + virtual void CalculateSurfaceWire( const MbStepData & stepData, size_t beg, MbMesh & mesh, + size_t uMeshCount = c3d::WIRE_MAX, size_t vMeshCount = c3d::WIRE_MAX ) const; + + /** \brief \ru Определить разбивку параметрической области поверхности вертикалями и горизонталями. + \en Determine a splitting of parametric region of a surface by verticals and horizontals. \~ + \details \ru Определить разбивку параметрической области поверхности вертикалями и горизонталями при триангуляции.\n + \en Determine a splitting of parametric region of a surface by verticals and horizontals during triangulation.\n \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] u1 - \ru Минимальное значение параметра u в области разбиения поверхности. + \en Minimal value of u-parameter in the region of surface splitting. \~ + \param[in] u2 - \ru Максимальное значение параметра u в области разбиения поверхности. + \en Maximal value of u-parameter in the region of surface splitting. \~ + \param[in] v1 - \ru Минимальное значение параметра v в области разбиения поверхности. + \en Minimal value of v-parameter in the region of surface splitting. \~ + \param[in] v2 - \ru Максимальное значение параметра v в области разбиения поверхности. + \en Maximal value of v-parameter in the region of surface splitting. \~ + \param[out] uu - \ru Множество параметров разбиения по u. + \en A set of parameters of splitting by u. \~ + \param[out] vv - \ru Множество параметров разбиения по v. + \en A set of parameters of splitting by v. \~ + */ + virtual void GetTesselation( const MbStepData & stepData, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + /** \brief \ru Определить разбивку параметрической области поверхности с учетом направления. + \en Determine splitting of the surface parametric region according to direction. \~ + \details \ru Определить разбивку параметрической области поверхности вертикалями и горизонталями. + Добавить параметры в массив в направлении dir. Если массивы uu или vv не пустые, то элементы из них не удаляются, + то есть происходит уточнение сетки в выбранном направлении. + \en Determine a splitting of parametric region of a surface by verticals and horizontals. + Add parameters into an array in the direction dir. If the arrays uu and vv are not empty then their elements are deleted. + i.e. a clarification of mesh in a given direction is performed. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] dir - \ru Выбранное направление. \n + dir == pd_DirU - расчет производится по параметру u, v = const. \n + dir == pd_DirV - расчет производится по параметру v, u = const. + \en A chosen direction. \n + dir == pd_DirU - calculation is performed by u-parameter, v = const. \n + dir == pd_DirU - calculation is performed by v-parameter, u = const. \~ + \param[in] u1 - \ru Минимальное значение параметра u в области разбиения поверхности. + \en Minimal value of u-parameter in the region of surface splitting. \~ + \param[in] u2 - \ru Максимальное значение параметра u в области разбиения поверхности. + \en Maximal value of u-parameter in the region of surface splitting. \~ + \param[in] v1 - \ru Минимальное значение параметра v в области разбиения поверхности. + \en Minimal value of v-parameter in the region of surface splitting. \~ + \param[in] v2 - \ru Максимальное значение параметра v в области разбиения поверхности. + \en Maximal value of v-parameter in the region of surface splitting. \~ + \param[out] uu - \ru Множество параметров разбиения по u. + \en A set of parameters of splitting by u. \~ + \param[out] vv - \ru Множество параметров разбиения по v. + \en A set of parameters of splitting by v. \~ + */ + void AddTesselation( const MbStepData & stepData, MbeParamDir dir, + double u1, double u2, double v1, double v2, + SArray & uu, SArray & vv ) const; + + /** \brief \ru Аппроксимировать поверхность треугольными пластинами. + \en Approximate a surface by triangular plates. \~ + \details \ru Аппроксимировать поверхность треугольными пластинами.\n + \en Approximate a surface by triangular plates.\n \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] sense - \ru Определяет совпадение нормалей поверхности и треугольников. + \en It determines the coincidence of normals of surfaces and triangles. \~ + \param[out] grid - \ru Результат разбиения. + \en The result of splitting. \~ + */ + virtual void CalculateSurfaceGrid( const MbStepData & stepData, bool sense, MbGrid & grid ) const; + + /// \ru Определить, ортогональны ли производные по u и v. \en Determine whether derivatives with respect to u and v are orthogonal. + virtual bool IsRectangular() const; + /// \ru Проверить, что все производные поверхности по U выше первой равны нулю. \en Check that all derivatives of surface with respect to u which have more than first order are equal to null. + virtual bool IsLineU() const; + /// \ru Проверить, что все производные поверхности по V выше первой равны нулю. \en Check that all derivatives of surface with respect to v which have more than first order are equal to null. + virtual bool IsLineV() const; + + /** \brief \ru Определить, является ли объект смещением. + \en Determine whether the object is a translation. \~ + \details \ru Определить, является ли объект смещением заданного объекта. + \en Determine whether the object is a translation of a given object. \~ + \param[in] obj - \ru Объект - образец. + \en A pattern object. \~ + \param[out] dir - \ru Вектор смещения, если объект является смещением. + \en A translation vector if the object is translation. \~ + \param[out] isSame - \ru На выходе true, если текущая поверхность и объект-образец идентичны. + \en True at the output if the current surface and the pattern object are identical. \~ + \result \ru true - если поверхность является смещением. + \en True - if a surface is translation \~ + */ + virtual bool IsShift( const MbSpaceItem & obj, MbVector3D & dir, bool & isSame, double accuracy = LENGTH_EPSILON ) const; + + /** \brief \ru Проверить параметры. Аналог глобальной функции _CheckParams, оптимизированный под использование кэшей. + \en Check parameters. Analogue of the global function _CheckParams, optimized for caches usage. \~ + \details \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + \en Check parameters and move them inside domain if parameter is out of pole. \~ + \param[in] surface - \ru Поверхность. \en Surface. \~ + \param[in] u - \ru Первый параметр. \en First parameter. \~ + \param[in] v - \ru Второй параметр. \en Second parameter. \~ + */ + virtual void CheckSurfParams( double & u, double & v ) const; + + /// \ru Дать плоскость (или только возможность ее выдачи). \en Get a plane (or only a possibility of getting a plane) + bool GetPlacement ( MbPlacement3D * place, bool exact = false ) const; + /// \ru Дать плоскость. \en Get a plane. + bool GetPlanePlacement( MbPlacement3D & place ) const; + /// \ru Дать плейсмент поверхности в средней точке. \en Get a placement of a surface at the middle point. + bool GetControlPlacement( MbPlacement3D & place, bool sameSense = true ) const; + /// \ru Сориентировать ось Х плейсмента вдоль линии его пересечения с поверхностью. \en Orient an axis X of a placement along the line of its intersection with surface. + bool OrientPlacement ( MbPlacement3D & place, bool normalSense = true ) const; + /// \ru Определить, лежит ли точка на плоскости. \en Determine whether a point is located on a surface or not. + bool IsPointOn ( const MbCartPoint3D &, double eps = METRIC_PRECISION ) const; + /// \ru Вычислить точку на поверхности в области определения поверхности. \en Calculate the point on a surface inside the domain of surface. + void PointOn ( MbCartPoint & uv, MbCartPoint3D & p ) const; + /// \ru Вычислить точку на продолженной поверхности. \en Calculate a point on a surface extension. + void _PointOn ( const MbCartPoint & uv, MbCartPoint3D & p ) const; + /// \ru Вычислить нормаль к поверхности в области определения поверхности. \en Calculate the normal vector to a surface inside the domain of surface. + void Normal ( MbCartPoint & uv, MbVector3D & v ) const; + + /** \brief \ru Найти матрицу преобразования для кривых на поверхности при изменении параметризации. + \en Find a matrix of transformation for the curves on a surface when the parameterization is changed. \~ + \details \ru Для поверхности устанавливается новый диапазон параметров. + Геометрически поверхность не изменяется. + Функция ищет матрицу преобразования для двумерных кривых на поверхности для перехода от старой параметризации к новой. + \en The new range of parameters is set for a surface. + A surface doesn't change geometrically. + The function searches a matrix of transformation for the two-dimensional curves on a surface for the transition from old parameterization to new parameterization. \~ + \param[in] xMin - \ru Новое минимальное значение параметра u. + \en The new minimum value of u. \~ + \param[in] xMax - \ru Новое максимальное значение параметра u. + \en The new maximum value of u. \~ + \param[in] yMin - \ru Новое минимальное значение параметра v. + \en The new minimum value of v. \~ + \param[in] yMax - \ru Новое максимальное значение параметра v. + \en The new maximum value of v. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + */ + bool GetMatrix( double xMin, double xMax, double yMin, double yMax, MbMatrix & matr ) const; + + /// \ru Среднее значение параметра u. \en The middle value of u. + double GetUMid() const { return ((GetUMin() + GetUMax()) * 0.5); } + /// \ru Среднее значение параметра v. \en The middle value of v. + double GetVMid() const { return ((GetVMin() + GetVMax()) * 0.5); } + /// \ru Параметрическая длина по u. \en Parametric length by u. + double GetURange() const { return (GetUMax() - GetUMin()); } + /// \ru Параметрическая длина по v. \en Parametric length by v. + double GetVRange() const { return (GetVMax() - GetVMin()); } + /// \ru Получить параметрические границы поверхности. \en Get parametric bounding box. + void GetRect( MbRect & r ) const { r.Set( GetUMin(), GetVMin(), GetUMax(), GetVMax() ); } + /// \ru Получить параметрические границы поверхности. \en Get parametric bounding box. + void GetRect( MbRect2D & r ) const { r.Init( GetUMin(), GetVMin(), GetUMax(), GetVMax() ); } + + /** \} */ + + // \ru Функции унификации объекта и вектора объектов в шаблонных функциях. \en Functions for compatibility of a object and a vector of objects in template functions. + size_t size() const { return 1; } ///< \ru Количество объектов при трактовке объекта как вектора объектов. \en Number of objects if object is interpreted as vector of objects. + const MbSurface * operator [] ( size_t ) const { return this; } ///< \ru Оператор доступа. \en An access operator. + +protected: + /// \ru Сдвинуть габарит. \en Move bounding box. + void MoveGabarit( const MbVector3D & v ) { if ( !cube.IsEmpty() ) cube.Move( v ) ; } + /// \ru Вычислить нормаль по известным производным uDer и vDer в точке с параметрами u, v. \en Normal calculation by derivatives uDer and vDer on point with parameters u, v. + void NormalCalculation( const MbVector3D & uDer, const MbVector3D & vDer, double u, double v, bool ext, MbVector3D & nor ) const; + /// \ru Вычислить шаг по параметру для заданного прогиба. \en Step calculation by sag. + double StepAlong( double u, double v, double sag, bool alongU, double stepMinCoeff, + const MbVector3D & der, const MbVector3D & sec ) const; + /// \ru Вычислить шаг по параметру для заданного углового отклонения нормали. \en Step calculation by normal deviation. + double DeviationStepAlong( double u, double v, double angle, bool alongU, + const MbVector3D & der, const MbVector3D & sec ) const; + +private: + /// \ru Найти аппроксимационную поверхность с помощью метода наименьших квадратов. \en Find an approximation surface using the method of least squares. + MbSplineSurface * NurbsSurfaceLSM( MbNurbsParameters & paramU, MbNurbsParameters & paramV, size_t uCount, size_t vCount ) const; + /// \ru Найти аппроксимационную поверхность с помощью метода наименьших квадратов. \en Find an approximation surface using the method of least squares. + MbSplineSurface * NurbsSurfaceThroughPoints( MbNurbsParameters & paramU, MbNurbsParameters & paramV, size_t uCount, size_t vCount ) const; + /// \ru Подготовить параметры для преобразования в NURBS поверхность при заданном узловом векторе для интерполяции. \en Prepare parameters for the transformation to NURBS surface with the given knot vector for the interpolation. + bool NurbsParamForKnots( const MbNurbsParameters & tParam, const SArray & knots, bool uParam, double op1, double op2, + bool & isClosedNurbs, double & epsilon, SArray & params ) const; + + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию \en Declaration without implementation of the assignment operator to prevent an assignment by default + void operator = ( const MbSurface & ); + + DECLARE_PERSISTENT_CLASS( MbSurface ) +}; + +IMPL_PERSISTENT_OPS( MbSurface ) + +//------------------------------------------------------------------------------ +// \ru Вычислить точку на поверхности. \en Calculate a point on a surface. +// --- +inline void MbSurface::PointOn( MbCartPoint & uv, MbCartPoint3D & p ) const { + PointOn( uv.x, uv.y, p ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить точку на продолженной поверхности. \en Calculate a point on a surface extension. +// --- +inline void MbSurface::_PointOn( const MbCartPoint & uv, MbCartPoint3D & p ) const { + _PointOn( uv.x, uv.y, p ); +} + + +//------------------------------------------------------------------------------ +// \ru Вычислить нормаль к поверхности в области определения поверхности. \en Calculate the normal vector to a surface inside the domain of surface. +// --- +inline void MbSurface::Normal( MbCartPoint & uv, MbVector3D & v ) const { + Normal( uv.x, uv.y, v ); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить параметры. Аналог MbSurface::CheckSurfParams. + \en Check parameters. Analogue of MbSurface::CheckSurfParams. \~ + \details \ru Проверить параметры и загнать в область определения, если параметр вышел за полюс. + \en Check parameters and move them inside domain if parameter is out of pole. \~ + \param[in] surface - \ru Поверхность. + \en Surface. \~ + \param[in] u - \ru Первый параметр. + \en First parameter. \~ + \param[in] v - \ru Второй параметр. + \en Second parameter. \~ +*/ +// --- +inline void _CheckParams( const MbSurface & surface, double & u, double & v ) +{ + if ( surface.GetPoleUMin() ) { + double umin = surface.GetUMin(); + if ( u < umin ) + u = umin; + } + if ( surface.GetPoleUMax() ) { + double umax = surface.GetUMax(); + if ( u > umax ) + u = umax; + } + if ( surface.GetPoleVMin() ) { + double vmin = surface.GetVMin(); + if ( v < vmin ) + v = vmin; + } + if ( surface.GetPoleVMax() ) { + double vmax = surface.GetVMax(); + if ( v > vmax ) + v = vmax; + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметры ближайших точек поверхности и кривой. + \en Calculate parameters of the nearest points of surface and curve. \~ + \details \ru Вычислить параметры ближайших точек поверхности и кривой и расстояние между этими точками. \n + \en Calculate parameters of the nearest points of surface and curve and the distance between these points. \n \~ + \param[in] surface - \ru Поверхность. + \en Surface. \~ + \param[in] ext0 - \ru Признак поиска на продолжении поверхности. + \en An attribute of search at the extension of surface. \~ + \param[in] curve - \ru Кривая. + \en A curve. \~ + \param[in] ext1 - \ru Признак поиска на продолжении кривой. + \en An attribute of search at the extension of curve. \~ + \param[in,out] u0 - \ru Параметр u точки поверхности. + \en U-parameter of surface point. \~ + \param[in,out] v0 - \ru Параметр v точки поверхности. + \en V-parameter of surface point. \~ + \param[in,out] t0 - \ru Параметр точки кривой. + \en A curve point parameter. \~ + \param[out] dmin - \ru Расстояние между точками. + \en The distance between points. \~ + \param[in] tCalc - \ru Флаг инициялизации t0 \n если true, то входные параметры u0, v0, t0 считаются начальными приближениями. + \en The initialization flag t0 \n if true, then the output parameters u0, v0 and t0 are considered as initial approximations. \~ + \return \ru Возвращает nr_Success (+1) или nr_Special(0) в случае успешного определения, в случае неудачи возвращает nr_Failure(-1). + \en Return nr_Success (+1) or nr_Special(0) in a case of successful defining, return nr_Failure(-1) in a case of failure. \~ + \ingroup Surfaces +*/ +// --- +MATH_FUNC (MbeNewtonResult) NearestPoints( const MbSurface & surface, bool ext0, + const MbCurve3D & curve, bool ext1, + double & u0, double & v0, double & t0, double & dmin, + bool t0Calculated = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметры ближайших точек поверхностей. + \en Calculate parameters of the nearest points of surfaces. \~ + \details \ru Вычислить параметры ближайших точек поверхностей и расстояние между этими точками. + \en Calculate parameters of the nearest points of surfaces and the distance between these points. \~ + \param[in] surface0 - \ru Поверхность. + \en Surface. \~ + \param[in] ext0 - \ru Признак поиска на продолжении поверхности surface0. + \en An attribute of search at the extension of a surface 'surface0'. \~ + \param[in] surface1 - \ru Поверхность. + \en Surface. \~ + \param[in] ext1 - \ru Признак поиска на продолжении поверхности surface1. + \en An attribute of search at the extension of a surface 'surface1'. \~ + \param[out] u0 - \ru Параметр u точки поверхности surface0. + \en U-parameter of a point on the surface 'surface0'. \~ + \param[out] v0 - \ru Параметр v точки поверхности surface0. + \en V-parameter of a point on the surface 'surface0'. \~ + \param[out] u1 - \ru Параметр u точки поверхности surface1. + \en U-parameter of a point on the surface 'surface1'. \~ + \param[out] v1 - \ru Параметр v точки поверхности surface1. + \en V-parameter of a point on the surface 'surface1'. \~ + \param[out] dmin - \ru Расстояние между точками поверхностей. + \en The distance between points on surfaces. \~ + \param[in] checkCurvilinearBounds - \ru Всегда проверять по криволинейным границам (если они есть). + \en Check for curvilinear boundaries (if they are). \~ + \return \ru Возвращает nr_Success (+1) или nr_Special(0) в случае успешного определения, в случае неудачи возвращает nr_Failure(-1). + \en Return nr_Success (+1) or nr_Special(0) in a case of successful defining, return nr_Failure(-1) in a case of failure. \~ + \ingroup Surfaces +*/ +// --- +MATH_FUNC (MbeNewtonResult) NearestPoints( const MbSurface & surface0, bool ext0, + const MbSurface & surface1, bool ext1, + double & u0, double & v0, double & u1, double & v1, double & dmin, + bool checkCurvilinearBounds ); + +//------------------------------------------------------------------------------ +/** \brief \ru Вычислить параметры ближайших точек поверхностей. + \en Calculate parameters of the nearest points of surfaces. \~ + \details \ru Вычислить параметры ближайших точек поверхностей и расстояние между этими точками. Криволинейные границы поверхностей не учитываются. + \en Calculate parameters of the nearest points of surfaces and the distance between these points. Curvilinear boundaries of surfaces are not taken into account. \~ + \param[in] surface0 - \ru Поверхность. + \en Surface. \~ + \param[in] ext0 - \ru Признак поиска на продолжении поверхности surface0. + \en An attribute of search at the extension of a surface 'surface0'. \~ + \param[in] surface1 - \ru Поверхность. + \en Surface. \~ + \param[in] ext1 - \ru Признак поиска на продолжении поверхности surface1. + \en An attribute of search at the extension of a surface 'surface1'. \~ + \param[out] u0 - \ru Параметр u точки поверхности surface0. + \en U-parameter of a point on the surface 'surface0'. \~ + \param[out] v0 - \ru Параметр v точки поверхности surface0. + \en V-parameter of a point on the surface 'surface0'. \~ + \param[out] u1 - \ru Параметр u точки поверхности surface1. + \en U-parameter of a point on the surface 'surface1'. \~ + \param[out] v1 - \ru Параметр v точки поверхности surface1. + \en V-parameter of a point on the surface 'surface1'. \~ + \param[out] dmin - \ru Расстояние между точками поверхностей. + \en The distance between points on surfaces. \~ + \param[in] checkCurvilinearBounds - \ru Всегда проверять по криволинейным границам (если они есть). + \en Check for curvilinear boundaries (if they are). \~ + \return \ru Возвращает nr_Success (+1) или nr_Special(0) в случае успешного определения, в случае неудачи возвращает nr_Failure(-1). + \en Return nr_Success (+1) or nr_Special(0) in a case of successful defining, return nr_Failure(-1) in a case of failure. \~ + \ingroup Surfaces +*/ +// --- +inline +DEPRECATE_DECLARE MbeNewtonResult NearestPoints( const MbSurface & surface0, bool ext0, + const MbSurface & surface1, bool ext1, + double & u0, double & v0, double & u1, double & v1, double & dmin ) +{ + return ::NearestPoints( surface0, ext0, surface1, ext1, u0, v0, u1, v1, dmin, false ); +} + + +#endif // __SURFACE_H diff --git a/C3d/Include/system_atomic.h b/C3d/Include/system_atomic.h new file mode 100644 index 0000000..90eaea1 --- /dev/null +++ b/C3d/Include/system_atomic.h @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Системозависимые атомарные операции. + Если требуются атомарные операции, должен использоваться этот файл ( не использовать!!!). + \en System-dependent atomic operations. + If atomic operations are required, this file should used ( must not be used!!!).\~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SYSTEM_ATOMIC_H +#define __SYSTEM_ATOMIC_H + +#include +#include +#include + +//------------------------------------------------------------------------------ +// \ru Использование атомарных операций согласно стандарту C++11. +// \en Using atomic operations according to C++11 standard. +// +//--- + +#ifdef STANDARD_C11 +#ifndef _NOT_USE_ATOMIC +#define STANDARD_C11_ATOMIC +#endif +#endif + +#ifdef STANDARD_C11_ATOMIC + +#include + +typedef std::atomic_ptrdiff_t use_count_type; // \ru Потокобезопасный тип счётчика ссылок. \en Thread-safe references count type. +typedef std::atomic_size_t serial_type; // \ru Потокобезопасный тип счётчика ссылок. \en Thread-safe references count type. +typedef std::atomic atomic_bool; // \ru Потокобезопасный логический тип. \en Thread-safe boolean type. + +//------------------------------------------------------------------------------ +/** \ru Получить значение. \en Get value. +*/ +//--- +template +Type LoadTypeValue( const AtomicType & v ) { + return v.load(); +} + +//------------------------------------------------------------------------------ +/** \ru Установить значение. \en Get value. +*/ +//--- +template +void StoreTypeValue( const AtomicType & src, AtomicType & dst ) { + dst.store( src.load() ); +} + +//------------------------------------------------------------------------------ +/** \ru Установить значение. \en Get value. +*/ +//--- +template +void StoreTypeValue( const Type src, AtomicType & dst ) { + dst.store( src ); +} + +//------------------------------------------------------------------------------ +/** \ru Получить значение. \en Get value. +*/ +//--- +inline serial_type SerialTypeValue( const serial_type & v ) { + return v.load(); +} +inline use_count_type UseCountValue( const use_count_type & v ) { + return v.load(); +} + +#else + +//------------------------------------------------------------------------------ +// \ru Шаблонный класс, работающий с целочисленными типами данных. Базовый класс для потокобезопасных счётчиков. +// \en Template class working with integer data types. Base class for thread-safe counters. +//-- +template< class Type > +class atomic_itype +{ +protected: + CommonMutex m_lock; + Type m_value; +public: + atomic_itype() {} + atomic_itype( const atomic_itype & t ) : m_value( t.m_value ) {} + atomic_itype( const Type t ) : m_value( t ) {} + + // \ru Операторы присваивания. \en Assignment operators. + atomic_itype & operator = ( const atomic_itype & t ) { ScopedLock l( &m_lock ); m_value = t.m_value; return *this; } + atomic_itype & operator = ( Type t ) { ScopedLock l( &m_lock ); m_value = t; return *this; } + + // \ru Операторы инкремента и декремента. \en Increment and decrement operators. + atomic_itype & operator ++ () { ScopedLock l( &m_lock ); ++m_value; return *this; } // prefix ++ + atomic_itype & operator -- () { ScopedLock l( &m_lock ); --m_value; return *this; } // prefix -- + Type operator ++ ( int ) { // postfix ++ + Type t = m_value; + { + ScopedLock l( &m_lock ); + ++m_value; + } + return t; + } + Type operator -- ( int ) { // postfix -- + Type t = m_value; + { + ScopedLock l( &m_lock ); + --m_value; + } + return t; + } + + // \ru Операторы сравнения. \en Comparison operators. + bool operator == ( const atomic_itype & t ) const { return m_value == t.m_value; } + bool operator != ( const atomic_itype & t ) const { return m_value != t.m_value; } + bool operator < ( const atomic_itype & t ) const { return m_value < t.m_value; } + bool operator > ( const atomic_itype & t ) const { return m_value > t.m_value; } + bool operator <= ( const atomic_itype & t ) const { return m_value <= t.m_value; } + bool operator >= ( const atomic_itype & t ) const { return m_value >= t.m_value; } + + // \ru Доступ к данным. \en Data access. + Type operator()() const { return m_value; } + +}; + +//------------------------------------------------------------------------------ +// \ru Потокобезопасный логический тип. \en Thread-safe boolean type. +//-- +class atomic_bool : public atomic_itype +{ +public: + atomic_bool() {} + + atomic_bool( const atomic_bool & t ) : atomic_itype( t.m_value ) {} + atomic_bool( const bool t ) : atomic_itype( t ? 1 : 0 ) {} + atomic_bool( const int t ) : atomic_itype( t != 0 ? 1 : 0 ) {} + + // \ru Операторы присваивания. \en Assignment operators. + atomic_bool & operator = ( const atomic_bool & t ) { ScopedLock l( &m_lock ); m_value = t.m_value; return *this; } + atomic_bool & operator = ( bool t ) { ScopedLock l( &m_lock ); m_value = t ? 1 : 0; return *this; } + atomic_bool & operator = ( int t ) { ScopedLock l( &m_lock ); m_value = t != 0 ? 1 : 0; return *this; } + + bool operator && ( bool t ) { return t == !!m_value; } + bool operator || ( bool t ) { return t || !!m_value; } + + // \ru Доступ к данным. \en Data access. + bool operator()() const { return !!m_value; } + +private: + // \ru Операторы инкремента и декремента не разрешены. \en Increment and decrement operators not allowed. + atomic_bool & operator ++ (); + atomic_bool & operator -- (); + bool operator ++ ( int ); + bool operator -- ( int ); +}; + +typedef atomic_itype serial_type; // \ru Потокобезопасный тип счётчика ссылок. \en Thread-safe references count type. +typedef atomic_itype use_count_type; // \ru Потокобезопасный тип счётчика ссылок. \en Thread-safe references count type. + +//------------------------------------------------------------------------------ +/** \ru Получить значение. \en Get value. +*/ +//--- +template +Type LoadTypeValue( const AtomicType & v ) { + return v(); +} + +//------------------------------------------------------------------------------ +/** \ru Установить значение. \en Get value. +*/ +//--- +template +void StoreTypeValue( const AtomicType & src, AtomicType & dst ) { + dst = src; +} + +//------------------------------------------------------------------------------ +/** \ru Установить значение. \en Get value. +*/ +//--- +template +void StoreTypeValue( const Type src, AtomicType & dst ) { + dst = src; +} + +//------------------------------------------------------------------------------ +/** \ru Получить значение. \en Get value. +*/ +//--- +inline size_t SerialTypeValue( const serial_type & v ) { + return v(); +} +inline ptrdiff_t UseCountValue( const use_count_type & v ) { + return v(); +} + +#endif // STANDARD_C11_ATOMIC + + +#endif // __SYSTEM_ATOMIC_H diff --git a/C3d/Include/system_cpp_standard.h b/C3d/Include/system_cpp_standard.h new file mode 100644 index 0000000..d04677a --- /dev/null +++ b/C3d/Include/system_cpp_standard.h @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Макросы стандартов C и C++. + \en C\C++ standards. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SYSTEM_CPP_STANDARD_H +#define __SYSTEM_CPP_STANDARD_H + +#include +#include + +// С11 +#if (defined(_MSC_VER) && (_MSC_VER > 1600)) || (defined(__INTEL_C) ) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || (defined(__BORLANDC__)) // BORLAND version? +#define STANDARD_C11 +#endif +// C11 with thread_local support +#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__INTEL_C) ) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || (defined(__BORLANDC__)) // BORLAND version? +#define STANDARD_C11_THREAD +#endif + +// С++11 +#if defined(__cplusplus) && (__cplusplus >= 201103L) // С++11 (fully supported) +#define STANDARD_CPP11 +#define STANDARD_C11_THREAD +#endif + +// GCC version (https://sourceforge.net/p/predef/wiki/Compilers/) +#if !defined(C3D_WINDOWS) // _MSC_VER + #if defined(__GNUC__) + #if defined(__GNUC_MINOR__) + #if defined(__GNUC_PATCHLEVEL__) + #define C3D_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + #else + #define C3D_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) + #endif + #else + #define #define C3D_GCC_VERSION (__GNUC__ * 10000) + #endif + #else + #define C3D_GCC_VERSION 0 + #endif +#else // C3D_WINDOWS + #define C3D_GCC_VERSION 0 +#endif // C3D_WINDOWS + +#if defined(__clang__) // Clang compiler + #define C3D_CLANG_COMPILER +#endif // Clang compiler + +// GNU glibc version. +#if defined(C3D_LINUX) // Linux + #include + #if defined(__GLIBC__) && defined(__GLIBC_MINOR__) + #define C3D_GLIBC_VERSION (__GLIBC__ * 1000 + __GLIBC_MINOR__) + #else + #define C3D_GLIBC_VERSION 0 + #endif +#else + #define C3D_GLIBC_VERSION 0 +#endif + +#if ( defined(STANDARD_C11) || defined(STANDARD_CPP11) ) +#define STANDARD_CPP11_RVALUE_REFERENCES +#endif + + +#endif // __SYSTEM_CPP_STANDARD_H diff --git a/C3d/Include/system_dependency.h b/C3d/Include/system_dependency.h new file mode 100644 index 0000000..8cee41c --- /dev/null +++ b/C3d/Include/system_dependency.h @@ -0,0 +1,259 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Системозависимые функции. + \en System-dependent functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SYSTEM_DEPENDENCY_H +#define __SYSTEM_DEPENDENCY_H + +#include +#include +#include + +#ifdef C3D_WINDOWS //_MSC_VER +#define LOG_PATH _T("C:\\Logs\\") +#else // C3D_WINDOWS +#define LOG_PATH _T("") +#endif // C3D_WINDOWS + +#ifndef C3D_WINDOWS //_MSC_VER + +#include +#include +#include +#include +#include +#include +#include + + +#if (C3D_GLIBC_VERSION >= 2023) // C3D_GLIBC_VERSION + #include + #define c3d_isnan(d) std::isnan(d) +#else // C3D_GLIBC_VERSION + #include + #define c3d_isnan(d) isnan(d) +#endif // C3D_GLIBC_VERSION + +#define _finite std::isfinite + + +//------------------------------------------------------------------------------ +// \ru RGB-цвет. \en RGB color. +// --- +typedef uint32 COLORREF; + + +//------------------------------------------------------------------------------ +// RGBs of int colors from WinApi +// --- +#define RGB(r, g ,b) ((uint32) (((uint8) (r) | ((uint16) (g) << 8)) | (((uint32) (uint8) (b)) << 16))) + + +//------------------------------------------------------------------------------ +// \ru Дать значение красного цвета в пределах 0 - 255. \en Get value of red color in range from 0 to 255. +// --- +inline uint8 GetRValue(COLORREF rgb_color) +{ + return (uint8) (rgb_color); +} + + +//------------------------------------------------------------------------------ +// \ru Дать значение зелёного цвета в пределах 0 - 255. \en Get value of green color in range from 0 to 255. +// --- +inline uint8 GetGValue(COLORREF rgb_color) +{ + return (uint8) (rgb_color >> 8); +} + + +//------------------------------------------------------------------------------ +// \ru Дать значение синего цвета в пределах 0 - 255. \en Get value of blue color in range from 0 to 255. +// --- +inline uint8 GetBValue(COLORREF rgb_color) +{ + return (uint8) (rgb_color >> 16); +} + + +// \ru Вывод сообщений об ошибках пока отключаем в Линуксе \en Output of error messages is temporary disabled in Linux +#define _RPT0(warnlvl, text) +#define _RPT1(a1, a2, a3) // \ru не реализовано \en not implemented +#define _CRT_WARN +#define _CRT_ASSERT + +#else // C3D_WINDOWS + + #define c3d_isnan(d) _isnan(d) + +#ifdef __BORLANDC__ +// \ru Вывод сообщений об ошибках пока отключаем в BORLAND \en Output of error messages is temporary disabled in BORLAND +#define _RPT0(warnlvl, text) +#define _RPT1(a1, a2, a3) // \ru не реализовано \en not implemented +#define _CRT_WARN +#define _CRT_ASSERT + +#else // __BORLANDC__ + +// \ru Одновременное определение _MBCS и _UNICODE недопустимо! \en Simultaneous definition of _MBCS and _UNICODE is not acceptable! +#if defined(_MBCS) && defined(_UNICODE) + #error Multibyte Character Sets (MBCS) not supported +#endif // _MBCS +#endif // __BORLANDC__ + +#endif // C3D_WINDOWS + +#include +#ifdef STANDARD_C11 +#include +// #error is not supported when compiling with /clr or /clr:pure. +// #include +#endif + +#ifndef threadLocal +# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ +# define threadLocal _Thread_local +# elif defined C3D_WINDOWS && ( \ + defined _MSC_VER || \ + defined __ICL || \ + defined __DMC__ || \ + defined __BORLANDC__ ) +# define threadLocal __declspec(thread) +/* note that ICC (linux) and Clang are covered by __GNUC__ */ +# elif defined __GNUC__ || \ + defined __SUNPRO_C || \ + defined __xlC__ +# define threadLocal __thread +# else +# error "Cannot define thread_local" +# endif +#endif + + +//------------------------------------------------------------------------------ +/** \brief \ru Высокоточный таймер. + \en High resolution timer. \~ + \details \ru Высокоточный таймер. + \en High resolution timer. \~ +\ingroup Base_Tools +*/ +// --- +class MbAccurateTimer { +#ifdef STANDARD_C11 + typedef std::chrono::high_resolution_clock::time_point TimePoint; +#endif +protected: + double lastTime; ///< \ru Время в секундах. \en Time in seconds. +private: +#ifdef STANDARD_C11 + TimePoint begTime; ///< \ru Засечка времени. \en Time stamp. +#endif + +public: + /// \ru Конструктор. \en Constructor. + MbAccurateTimer() : lastTime( 0.0 ) {} + virtual ~MbAccurateTimer() {} + + /// \ru Сброшен ли таймер. \en Is empty timer? + virtual bool IsEmpty () const { return !(lastTime > 0.0); } + /// \ru Сбросить таймер. \en Reset timer. + virtual void SetEmpty() { lastTime = 0.0; } + /// \ru Добавить значение. \en Add time value. + virtual bool SetTime ( double t ) { lastTime = t; return (t >= 0); } + /// \ru Начать отсчет. \en Start time measurement. + virtual void Begin (); + /// \ru Закончить отсчет. \en Finish time measurement. + virtual void End (); + /// \ru Получить значение времени. \en Get time value. + double GetLast() const { return lastTime; } + /// \ru Получить значение частоты. \en Get frequency value. + double PerSec () const { return (lastTime > 0.0 ? 1.0 / lastTime : 0.0); } +}; + + +//------------------------------------------------------------------------------ +// \ru Начать отсчет. \en Start time measurement. +//--- +inline void MbAccurateTimer::Begin() +{ +#ifdef STANDARD_C11 + begTime = std::chrono::high_resolution_clock::now(); +#endif +} + +//------------------------------------------------------------------------------ +// \ru Закончить отсчет. \en Finish time measurement. +// --- +inline void MbAccurateTimer::End() +{ +#ifdef STANDARD_C11 + TimePoint endTime = std::chrono::high_resolution_clock::now(); + double t = std::chrono::duration_cast< std::chrono::duration >(endTime - begTime).count(); + SetTime( t ); +#endif +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Таймер со статистикой. + \en Average timer. \~ + \details \ru Таймер со статистикой. + \en Average timer. \~ +\ingroup Base_Tools +*/ +// --- +class MbAverageTimer : public MbAccurateTimer +{ + double avgTime; ///< \ru Среднее время в секундах. \en Average time in seconds. + double minTime; ///< \ru Минимальное время в секундах. \en Min. time in seconds. + double maxTime; ///< \ru Максимальное время в секундах. \en Max. time in seconds. + uint runCount; ///< \ru Количество запусков. \en Number of samples. + +public: + /// \ru Конструктор. \en Constructor. + MbAverageTimer() : avgTime( 0.0 ), minTime( 0.0 ), maxTime ( 0.0 ), runCount( 0 ) {} + + virtual bool IsEmpty() const { return (runCount == 0); } + virtual void SetEmpty(); + virtual bool SetTime( double ); + double GetAvg() const { return avgTime; } + double GetMin() const { return minTime; } + double GetMax() const { return maxTime; } +}; + +//------------------------------------------------------------------------------ +// \ru Сбросить таймер. \en Reset timer. +//--- +inline void MbAverageTimer::SetEmpty() +{ + MbAccurateTimer::SetEmpty(); + avgTime = minTime = maxTime = 0.0; + runCount = 0; +} + +//------------------------------------------------------------------------------ +// \ru Добавить значение. \en Add value. +//--- +inline bool MbAverageTimer::SetTime( double t ) +{ + bool res = MbAccurateTimer::SetTime( t ); + + if ( IsEmpty() ) + avgTime = minTime = maxTime = t; + else + { + avgTime += (t - avgTime) / (runCount + 1); + minTime = (std::min)( minTime, t ); + maxTime = (std::max)( maxTime, t ); + } + + runCount++; + return res; +} + +#endif // __SYSTEM_DEPENDENCY_H diff --git a/C3d/Include/system_types.h b/C3d/Include/system_types.h new file mode 100644 index 0000000..a63100a --- /dev/null +++ b/C3d/Include/system_types.h @@ -0,0 +1,260 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Базовые типы данных. + \en Base types of data. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __SYSTEM_TYPES_H +#define __SYSTEM_TYPES_H + + +#include // \ru СМВ для компиляции ICC \en СМВ for compilation by ICC +#include + + +/** + \addtogroup Base_Tools + \{ +*/ + +#if defined(_DEBUG) || !defined(NDEBUG) + #define C3D_DEBUG +#endif + +//------------------------------------------------------------------------------ +// \ru Системные типы \en System types +//--- +#ifdef C3D_WINDOWS //_MSC_VER + +typedef signed char int8; ///< \ru int со знаком (1 байт). \en int with sign (1 byte). \~ +typedef unsigned char uint8; ///< \ru int без знака (1 байт). \en int without sign (1 byte). \~ + +typedef signed short int16; ///< \ru int со знаком (2 байта). \en int with sign (2 bytes). \~ +typedef unsigned short uint16; ///< \ru int без знака (2 байта). \en int without sign (2 bytes). \~ + +typedef signed long int32; ///< \ru int со знаком (4 байта). \en int with sign (4 bytes). \~ +typedef unsigned long uint32; ///< \ru int без знака (4 байта). \en int without sign (4 bytes). \~ + +typedef signed __int64 int64; ///< \ru int со знаком (8 байта). \en int with sign (8 bytes). \~ +typedef unsigned __int64 uint64; ///< \ru int без знака (8 байта). \en int without sign (8 bytes). \~ + +typedef unsigned int uint; ///< \ru int без знака. \en int without sign. \~ \ingroup Base_Tools + +typedef unsigned long VERSION; ///< \ru Версия. \en Version. \~ + + +#else // C3D_WINDOWS + +#include +#include + +typedef int8_t int8; +typedef uint8_t uint8; + +typedef int16_t int16; +typedef uint16_t uint16; + +typedef int32_t int32; +typedef uint32_t uint32; + +typedef int64_t int64; +typedef uint64_t uint64; + +typedef unsigned int uint; + +typedef uint32 VERSION; ///< \ru Версия. \en Version. \~ + + +#endif // _MSC_VER + +/** \} */ //addtogroup Base_Tools + +#include + +//------------------------------------------------------------------------------ +// \ru Умный указатель, единолично владеющий объектом. +// \en Smart pointer that solely owns the object. +//--- +#ifdef STANDARD_C11 +#define std_unique_ptr std::unique_ptr +#else +#define std_unique_ptr std::auto_ptr +#endif + +//------------------------------------------------------------------------------ +// \ru Системные лимиты \en System limits +//--- +#include // \ru для использования std_min() и std_max() \en for using in std_min() and std_max() + + +typedef ptrdiff_t refcount_t; // Возвращаемый тип счетчика ссылок. / The return type of the reference count. + +//#if defined(NOMINMAX) || !defined (_MSC_VER) +// +//const uint SYS_MAX_UINT = std::numeric_limits::max(); +//const size_t SYS_MAX_T = std::numeric_limits::max(); +//const ptrdiff_t SYS_MAX_ST = std::numeric_limits::max(); +//const ptrdiff_t SYS_MIN_ST = std::numeric_limits::min(); +// +//const uint8 SYS_MAX_UINT8 = std::numeric_limits::max(); +//const uint16 SYS_MAX_UINT16 = std::numeric_limits::max(); +//const uint32 SYS_MAX_UINT32 = std::numeric_limits::max(); +//const uint64 SYS_MAX_UINT64 = std::numeric_limits::max(); +// +//const int16 SYS_MAX_INT16 = std::numeric_limits::max(); +//const int32 SYS_MAX_INT32 = std::numeric_limits::max(); +//const int64 SYS_MAX_INT64 = std::numeric_limits::max(); +// +//const int16 SYS_MIN_INT16 = std::numeric_limits::min(); +//const int32 SYS_MIN_INT32 = std::numeric_limits::min(); +//const int64 SYS_MIN_INT64 = std::numeric_limits::min(); +// +//#else // NOMINMAX + +#if defined(PLATFORM_64) +/// \ru Максимальное значение uint. \en Maximum value of uint. \~ \ingroup Base_Tools +const uint SYS_MAX_UINT = 0xffffffff; // ((uint)-1) //-V112 +/// \ru Максимальное значение size_t. \en Maximum value of size_t. \~ \ingroup Base_Tools +const size_t SYS_MAX_T = 0xffffffffffffffff; // ((size_t)-1) //-V112 +/// \ru Максимальное значение ptrdiff_t. \en Maximum value of ptrdiff_t. \~ \ingroup Base_Tools +const ptrdiff_t SYS_MAX_ST = 0x7fffffffffffffff; //-V112 +/// \ru Минимальное значение ptrdiff_t. \en Minimum value of ptrdiff_t. \~ \ingroup Base_Tools +const ptrdiff_t SYS_MIN_ST = 0x8000000000000000; //-V112 +#else // PLATFORM_64 +/// \ru Максимальное значение uint. \en Maximum value of uint. \~ \ingroup Base_Tools +const uint SYS_MAX_UINT = 0xffffffff; // ((uint)-1) //-V112 +/// \ru Максимальное значение size_t. \en Maximum value of size_t. \~ \ingroup Base_Tools +const size_t SYS_MAX_T = 0xffffffff; // ((size_t)-1) //-V112 +/// \ru Максимальное значение ptrdiff_t. \en Maximum value of ptrdiff_t. \~ \ingroup Base_Tools +const ptrdiff_t SYS_MAX_ST = 0x7fffffff; //-V112 +/// \ru Минимальное значение ptrdiff_t. \en Minimum value of ptrdiff_t. \~ \ingroup Base_Tools +const ptrdiff_t SYS_MIN_ST = 0x80000000; //-V112 +#endif // PLATFORM_64 + +/// \ru Максимальное значение uint8. \en Maximum value of uint8. \~ \ingroup Base_Tools +const uint8 SYS_MAX_UINT8 = 0xFF; //-V112 +/// \ru Максимальное значение uint16. \en Maximum value of uint16. \~ \ingroup Base_Tools +const uint16 SYS_MAX_UINT16 = 0xFFFF; //-V112 +/// \ru Максимальное значение uint32. \en Maximum value of uint32. \~ \ingroup Base_Tools +const uint32 SYS_MAX_UINT32 = 0xFFFFFFFF; //-V112 +/// \ru Максимальное значение uint64. \en Maximum value of uint64. \~ \ingroup Base_Tools +const uint64 SYS_MAX_UINT64 = 0xFFFFFFFFFFFFFFFF; //-V112 + +/// \ru Максимальное значение int16. \en Maximum value of int16. \~ \ingroup Base_Tools +const int16 SYS_MAX_INT16 = 0x7FFF; //-V112 +/// \ru Максимальное значение int32. \en Maximum value of int32. \~ \ingroup Base_Tools +const int32 SYS_MAX_INT32 = 0x7FFFFFFF; //-V112 +/// \ru Максимальное значение int64. \en Maximum value of int64. \~ \ingroup Base_Tools +const int64 SYS_MAX_INT64 = 0x7FFFFFFFFFFFFFFF; //-V112 + +/// \ru Минимальное значение int16. \en Minimum value of int16. \~ \ingroup Base_Tools +const int16 SYS_MIN_INT16 = (int16)(uint16)0x8000; //-V112 +/// \ru Минимальное значение int32. \en Minimum value of int32. \~ \ingroup Base_Tools +const int32 SYS_MIN_INT32 = (int32)(uint32)0x80000000; //-V112 +/// \ru Минимальное значение int64. \en Minimum value of int64. \~ \ingroup Base_Tools +const int64 SYS_MIN_INT64 = (int64)(uint64)0x8000000000000000; //-V112 + +//#endif // NOMINMAX + + +//------------------------------------------------------------------------------ +// Integer byte, word and long word manipulation +//--- + +/// \ru Создать uint16 на основе двух uint8. \en Create uint16 by two uint8. \~ \ingroup Base_Tools +inline uint16 MkUint16( uint8 lo, uint8 hi ) { return uint16(lo | (uint16(hi) << 8)); } //-V112 +/// \ru Создать uint32 на основе двух uint16. \en Create uint32 by two uint16. \~ \ingroup Base_Tools +inline uint32 MkUint32( uint16 lo, uint16 hi ) { return lo | (uint32(hi) << 16); } //-V112 +/// \ru Создать uint64 на основе двух uint32. \en Create uint64 by two uint32. \~ \ingroup Base_Tools +inline uint64 MkUint64( uint32 lo, uint32 hi ) { return uint64((uint64)lo | (uint64(hi) << 32)); } //OV_x64 //-V112 + +/// \ru Выделить младшее слово uint32 из uint64. \en Get lower uint32 word from uint64. \~ \ingroup Base_Tools +inline uint32 LoUint32( uint64 u64 ) { return uint32(u64); } //OV_x64 +/// \ru Выделить младшее слово int32 из int64. \en Get lower int32 word from int64. \~ \ingroup Base_Tools +inline int32 LoInt32 ( uint64 u64 ) { return int32(u64); } //OV_x64 +/// \ru Выделить старшее слово uint32 из uint64. \en Get upper uint32 word from uint64. \~ \ingroup Base_Tools +inline uint32 HiUint32( uint64 u64 ) { return uint32(u64 >> 32); } //OV_x64 //-V112 +/// \ru Выделить старшее слово int32 из int64. \en Get upper int32 word from int64. \~ \ingroup Base_Tools +inline int32 HiInt32 ( uint64 u64 ) { return int32(u64 >> 32); } //OV_x64 //-V112 + +/// \ru Выделить младшее слово uint16 из uint32. \en Get lower int16 word from int32. \~ \ingroup Base_Tools +inline uint16 LoUint16( uint32 u32 ) { return uint16(u32); } +/// \ru Выделить младшее слово int16 из uint32. \en Get lower int16 word from uint32. \~ \ingroup Base_Tools +inline int16 LoInt16 ( uint32 u32 ) { return int16(u32); } +/// \ru Выделить старшее слово uint16 из uint32. \en Get upper uint16 word from uint32. \~ \ingroup Base_Tools +inline uint16 HiUint16( uint32 u32 ) { return uint16(u32 >> 16); } //-V112 +/// \ru Выделить старшее слово int16 из uint32. \en Get upper int16 word from uint32. \~ \ingroup Base_Tools +inline int16 HiInt16 ( uint32 u32 ) { return int16(u32 >> 16); } //-V112 + +/// \ru Выделить младшее слово uint8 из uint16. \en Get lower uint8 word from uint16. \~ \ingroup Base_Tools +inline uint8 LoUint8 ( uint16 u16 ) { return uint8(u16); } +/// \ru Выделить младшее слово int8 из uint16. \en Get lower int8 word from uint16. \~ \ingroup Base_Tools +inline int8 LoInt8 ( uint16 u16 ) { return int8(u16); } +/// \ru Выделить старшее слово uint8 из uint16. \en Get upper uint8 word from uint16. \~ \ingroup Base_Tools +inline uint8 HiUint8 ( uint16 u16 ) { return uint8(u16 >> 8); } //-V112 +/// \ru Выделить младшее слово int8 из uint16. \en Get upper int8 word from uint16. \~ \ingroup Base_Tools +inline int8 HiInt8 ( uint16 u16 ) { return int8(u16 >> 8); } //-V112 + + +//------------------------------------------------------------------------------ +/// \ru Неопределенный размер. \en Undefined size. \~ \ingroup Base_Tools +//--- +const size_t NSIZE = SYS_MAX_T; //OV_x64 (size_t)-1; + +//------------------------------------------------------------------------------ +/// \ru Неопределенная позиция (для 32 битных данных). \en Undefined position (for 32-bit data). \~ \ingroup Base_Tools +//--- +const uint NPOS32 = (uint)SYS_MAX_UINT32; // \ru КВН x64 -1 для работы с таблицами \en КВН x64 -1 for dealing with tables + + +//------------------------------------------------------------------------------ +/** \brief \ru Размер указателя в байтах. + \en Size of pointer in bytes. \~ + \details \ru Размер указателя в байтах. \n + \en Size of pointer in bytes. \n \~ + \ingroup Base_Tools +*/ +//--- +const size_t SIZE_OF_POINTER = sizeof(char *); + + +//------------------------------------------------------------------------------ +/** \brief \ru Модуль числа. + \en Absolute value. \~ + \details \ru Модуль числа. \n + \en Absolute value. \n \~ + \ingroup Base_Tools +*/ +//--- +template +SignedType abs_t( const SignedType x ) { return ((x >= 0) ? x : -x); } //KYA K13+ x64 + + +//------------------------------------------------------------------------------ +// \ru Подавить предупреждения \en Suppress warnings +//--- +#if defined (C3D_WINDOWS ) && !defined(ALL_WARNINGS) //_MSC_VER // Set warnings level + +// http://support.microsoft.com/kb/134980/ru +#pragma warning(disable: 4275) //AP non dll-interface class '1' used as base for dll-interface class '2' (deriving exported from non-exported) +#pragma warning(disable: 4251) //AP class '1' needs to have dll-interface to be used by clients of class '2' (using non-exported in exported) + +// have to be disabled +#pragma warning(disable: 4018) // W3: comparison : signed/unsigned mismatch + +#pragma warning(disable: 4201) // W4: nonstandard extension used : nameless struct/union +#pragma warning(disable: 4245) // W4: const conversion, signed/unsigned mismatch +#pragma warning(disable: 4365) // W4: value conversion, signed/unsigned mismatch +//#pragma warning(disable: 4516) // W4: access-declarations are deprecated; member using-declarations provide a better alternative +//#pragma warning(disable: 4786) // \ru Иначе map сыпет такое!!! _ANN_PARAM_MAP_ Чтобы не ругалась на урезание отладочной информации \en Otherwise map output such a things!!! _ANN_PARAM_MAP_ For not swearing on reduction of debugging information + +// The keyword -D_CRT_SECURE_NO_WARNINGS added. Pragma below were disable deprecated warnings. +//#pragma warning(disable: 4996) // This function or variable may be unsafe. Consider using strcpy_s instead. + +#endif // !ALL_WARNINGS + + +#endif // __SYSTEM_TYPES_H diff --git a/C3d/Include/templ_array2.h b/C3d/Include/templ_array2.h new file mode 100644 index 0000000..a205d26 --- /dev/null +++ b/C3d/Include/templ_array2.h @@ -0,0 +1,675 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Двумерный массив объектов. + \en Two-dimensional array of objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_ARRAY2_H +#define __TEMPL_ARRAY2_H + + +#include +#include +#include +#include +#include +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +class reader; +class writer; + +FORVARD_DECL_TEMPLATE_TYPENAME( class Array2 ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & operator >> ( reader & in, Array2 & ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & operator << ( writer & out, const Array2 & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & operator >> ( reader & in, Array2 *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & operator << ( writer & out, const Array2 * ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool realloc_line ( Type *& line, size_t oldSize, size_t newSize ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool assign_to_array( Array2 &, const Array2 & src ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool set_array_size ( Array2 &, size_t lSize, size_t cSize ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool insert_column_to_array ( Array2 &, size_t ind ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool add_column_to_array ( Array2 & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void remove_column_from_array( Array2 &, size_t ind ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void zero_array( Array2 & ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Двумерный массив объектов. + \en Two-dimensional array of objects. \~ + \details \ru Двумерный массив объектов. \n + \en Two-dimensional array of objects. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class Array2 { +protected : + Type ** parr; ///< \ru Указатель на первый элемент массива (элементами массива являются указатели на содержимое строк). \en Pointer to first element of array (elements of array are pointers to contents of rows). + size_t l; ///< \ru Количество строк массива. \en Count of rows in the array. + size_t c; ///< \ru Количество столбцов массива (то есть длина каждой строки). \en Count of columns of array (i.e. length of each row). + +protected: + /// \ru Конструктор по заданной размерности. \en The constructor by a given dimension. + Array2( size_t lsz, size_t csz ); +public: + /// \ru Конструктор. \en Constructor. + Array2() : parr( 0 ), l( 0 ), c( 0 ) {} + /// \ru Конструктор ограниченной размерности. \en The constructor of restricted dimension. + Array2( const uint16 & lsz, const uint16 & csz ); + /// \ru Конструктор копирования. \en Copy-constructor. + explicit Array2( const Array2 & ); + /// \ru Деструктор. \en Destructor. + ~Array2() { set_array_size( *this, 0, 0 ); } + +public: + /// \ru Создать массив заданной размерности (возвращает NULL в случае неудачи). + /// \en Create an array of a given dimension (returns NULL in case of failure). + static Array2 * Create( size_t lSize, size_t cSize ); + +public: // Общие методы матриц (двумерных массивов) + size_t Lines () const { return l; } ///< \ru Количество строк. \en Count of rows. + size_t Columns() const { return c; } ///< \ru Количество столбцов. \en Count of columns. + size_t Count () const { return (l*c); } ///< \ru Количество элементов. \en Count of elements. + c3d::IndicesPair GetSize() const { return c3d::IndicesPair( l, c ); } ///< \ru Дать размер массива. \en Give the size of the array. + bool SetSize( c3d::IndicesPair sz ) { return SetSize( sz.first, sz.second ); } ///< \ru Установить размер. \en Set size. + bool SetSize( size_t lsz, size_t csz ); ///< \ru Установить размер. \en Set size. + bool SetSize( size_t n ) { return SetSize( n, n ); } ///< \ru Установить размер. \en Set size. + + /// \ru Получить элемент массива. \en Get an element of the array. + const Type & GetElem( size_t ln, size_t cn ) const { PRECONDITION( !!parr && ln < l && cn < c ); return parr[ln][cn]; } + /// \ru Установить элемент массива. \en Set an element of the array. + void SetElem( size_t ln, size_t cn, const Type & v ) { PRECONDITION( !!parr && ln < l && cn < c ); parr[ln][cn] = v; } + /// \ru Оператор доступа по индексам. \en Access by indices operator. + const Type & operator () ( size_t i, size_t j ) const { PRECONDITION( i < l && j < c ); return parr[i][j]; } + /// \ru Расписать массив нулями. \en Assign zeros to array. + Array2 & SetZero() { zero_array( *this ); return *this; } + /// \ru Функция присваивания. \en An assignment function. + bool Init( const Array2 & src ) { return assign_to_array( *this, src ); } + /// \ru Оператор присваивания. \en The assignment operator. + Array2 & operator = ( const Array2 & src ) { Init( src ); return *this; } + /// \ru Поменять местами строки. \en Swap lines. + bool SwapLines( size_t ln1, size_t ln2 ); + +public: + /// \ru Оператор доступа по индексам. \en Access by indices operator. + Type & operator () ( size_t i, size_t j ) { PRECONDITION( i < l && j < c ); return parr[i][j]; } + /// \ru Выдать адрес начала строки. \en Get an address of the row start. + const Type * GetLine( size_t i = 0 ) const { PRECONDITION( i < l ); return parr[i]; } + /// \ru Выдать адрес начала строки. \en Get an address of the row start. + Type * SetLine( size_t i = 0 ) { PRECONDITION( i < l ); return parr[i]; } + /// \ru Инициировать элемент. \en Initiate an element. + void Init( size_t ln, size_t cn, const Type & v ) { PRECONDITION( !!parr && ln < l && cn < c ); parr[ln][cn] = v; } + + /// \ru Функции, выделяющие потенциально большие участки памяти, возвращают результат операции (успех/ошибка). + /// \en Functions that allocate potentially large memory, return the operation result (success/error). + bool InsertColumn( size_t i = 0 ); ///< \ru Вставить столбец перед указанным. \en Insert column before the specified one. + bool AddColumn(); ///< \ru Добавить столбец в конец массива. \en Add column to the end of the array. + void RemoveColumn( size_t i = 0 ); ///< \ru Удалить столбец из массива. \en Delete column from array. + + bool InsertLine ( size_t i = 0 ); ///< \ru Вставить строку перед указанной. \en Insert row before the specified one. + bool AddLine(); ///< \ru Добавить строку в конец массива. \en Add row to the end of the array. + void RemoveLine ( size_t i = 0 ); ///< \ru Удалить строку из массива. \en Delete row from array. +protected : + bool CatchLinePointers( size_t newCount ); ///< \ru Взять память под заданное кол-во указателей на строки. \en Allocate memory for the given count of pointers to rows. + + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & operator >> TEMPLATE_SUFFIX ( reader & in, Array2 & ptr ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & operator << TEMPLATE_SUFFIX ( writer & out, const Array2 & ref ); + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & operator >> TEMPLATE_SUFFIX ( reader & in, Array2 *& ptr ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & operator << TEMPLATE_SUFFIX ( writer & out, const Array2 * ptr ); + + /// \ru Перезахватить память под одну строку. \en Reallocate memory for one row. + TEMPLATE_FRIEND bool realloc_line TEMPLATE_SUFFIX ( Type *& line, size_t oldSize, size_t newSize ); + /// \ru Скопировать массив. \en Copy an array. + TEMPLATE_FRIEND bool assign_to_array TEMPLATE_SUFFIX ( Array2 &, const Array2 & src ); + /// \ru Установить размер массива. \en Set the size of the array. + TEMPLATE_FRIEND bool set_array_size TEMPLATE_SUFFIX ( Array2 &, size_t lSize, size_t cSize ); + /// \ru Вставить колонку перед указанной и заполнить ее нулями. \en Insert column before the specified one and fill it with zeros. + TEMPLATE_FRIEND bool insert_column_to_array TEMPLATE_SUFFIX ( Array2 &, size_t ind ); + /// \ru Добавить в массив колонку и заполнить ее нулями. \en Add column to array and fill it with zeros. + TEMPLATE_FRIEND bool add_column_to_array TEMPLATE_SUFFIX ( Array2 & ); + /// \ru Удалить колонку из массива. \en Delete column from array. + TEMPLATE_FRIEND void remove_column_from_array TEMPLATE_SUFFIX ( Array2 &, size_t ind ); + /// \ru Заполнить массив нулями. \en Fill the array with zeros. + TEMPLATE_FRIEND void zero_array TEMPLATE_SUFFIX ( Array2 & ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * Array2::operator new( size_t size ) { + return ::Allocate( size, typeid(Array2).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void Array2::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(Array2).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------ +// \ru конструктор массива \en constructor of an array +// --- +template +inline Array2::Array2( size_t lSize, size_t cSize ) + : parr( 0 ) + , l ( 0 ) + , c ( 0 ) +{ + if ( !::set_array_size( *this, lSize, cSize ) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + + PRECONDITION( !!parr || (lSize == 0 && cSize == 0) ); +} + + +//------------------------------------------------------------------------------ +// \ru конструктор массива \en constructor of an array +// --- +template +inline Array2::Array2( const uint16 & lSize, const uint16 & cSize ) + : parr( 0 ) + , l ( 0 ) + , c ( 0 ) +{ + if ( !::set_array_size( *this, lSize, cSize ) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + + PRECONDITION( !!parr || (lSize == 0 && cSize == 0) ); +} + + +//------------------------------------------------------------------------------ +// \ru конструктор копирования \en copy-constructor +// --- +template +inline Array2::Array2( const Array2 & source ) + : parr( 0 ) + , l ( 0 ) + , c ( 0 ) +{ + if ( !::assign_to_array( *this, source ) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + + PRECONDITION( !!parr || (l == 0 && c == 0) ); +} + + +//------------------------------------------------------------------------------ +// \ru Создать массив заданной размерности. \en Create an array of a given dimension. +// --- +template +inline Array2 * Array2::Create( size_t lSize, size_t cSize ) +{ + Array2 * arr = NULL; + if ( lSize * cSize < c3d::MATRIX_MAX_COUNT ) { + try { + arr = new Array2( lSize, cSize ); + } + catch ( const std::bad_alloc & ) { + arr = NULL; + } + } + return arr; +} + + +//------------------------------------------------------------------------------ +// \ru Установить размер массива \en Set the size of the array +// --- +template +inline bool Array2::SetSize( size_t lSize, size_t cSize ) { + return ::set_array_size( *this, lSize, cSize ); +} + +//------------------------------------------------------------------------------ +// \ru Поменять местами строки. \en Swap lines. +// --- +template +inline bool Array2::SwapLines( size_t ln1, size_t ln2 ) +{ + if ( !!parr && ln1 < l && ln2 < l ) { + Type * tmp = parr[ln1]; + parr[ln1] = parr[ln2]; + parr[ln2] = tmp; + return true; + } + PRECONDITION( false ); + return false; +} + + +//------------------------------------------------------------------------------ +// \ru вставить столбец перед указанным \en insert column before the specified one +// --- +template +inline bool Array2::InsertColumn( size_t ind ) { + return insert_column_to_array( *this, ind ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить столбец в конец массива \en add column to the end of the array +// --- +template +inline bool Array2::AddColumn() { + return add_column_to_array( *this ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить столбец \en delete column +// --- +template +inline void Array2::RemoveColumn( size_t ind ) { + remove_column_from_array( *this, ind ); +} + + +//------------------------------------------------------------------------------ +// \ru вставить строку перед указанной и заполнить ее нулями \en insert row before the specified one and fill it with zeros +// \ru если ind больше количества строк, то просто добавить строку в конец массива \en if 'ind' is greater than count of rows then simply add row to the end of the array +// --- +template +inline bool Array2::InsertLine( size_t ind ) +{ + bool res = true; + size_t oldL = l; // \ru прежнее кол-во строк \en previous count of rows + if ( AddLine() ) { // \ru кол-во строк увеличилось на 1 \en count of rows is increased by 1 + + if ( ind < oldL ) { + // \ru переставить новую строку с последнего места на указанное \en swap the new row from last position with row of the specified position + Type * newLine = parr[l - 1]; + // \ru переместить хвост на один элемент дальше \en move the tale by one element + memmove( parr + ind + 1, parr + ind, (oldL - ind) * SIZE_OF_POINTER ); + + parr[ind] = newLine; // \ru теперь это будет строка с индексом ind \en now it is the row with 'ind' index + } + } + else + res = false; + return res; +} + + +//------------------------------------------------------------------------------ +// \ru добавить строку в конец массива и заполнить ее нулями \en add to the end of the array and fill it with zeros +// --- +template +inline bool Array2::AddLine() +{ + bool res = CatchLinePointers( l + 1 ); + if ( res ) { // \ru добавить память для одного указателя на строку \en add memory for one pointer to row + // \ru (l увеличится на 1) \en (l will be increased by 1) + Type * newLine = 0; // \ru указатель на содержимое новой строки \en pointer to contents of new row + if ( c ) { + res = realloc_line( newLine, 0/*oldSize*/, c/*newSize*/ ); // \ru захватить память под строку \en allocate memory for one row + if ( res ) + memset( newLine, 0, c * sizeof(Type) ); + } + parr[l - 1] = newLine; // \ru записать указатель в массив \en store pointer to the array + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru удалить строку из массива \en delete row from the array +// --- +template +inline void Array2::RemoveLine( size_t ind ) +{ + PRECONDITION( ind < l ); + + if ( ind < l ) { + realloc_line( parr[ind], c/*oldSize*/, 0/*newSize*/ ); // \ru освободить память, занятую строкой \en free memory occupied by row + + // \ru передвинуть хвост ближе к началу на один элемент \en move tale closer to start by one element + size_t tail = l - (ind + 1); + if ( tail ) // \ru если это не последний указатель \en if it is not the last pointer, + memmove( parr + ind, parr + ind + 1, tail * SIZE_OF_POINTER ); + + CatchLinePointers( l - 1/*newCount*/ ); // \ru освободить память из-под последнего указателя на строку \en then free memory for last pointer to row + } +} + + +//------------------------------------------------------------------------------ +// \ru Взять память под заданное кол-во указателей на строки \en Allocate memory for the given count of pointers to rows +// \ru Если кол-во строк уменьшается, то память из-под лишних строк уже должна быть освобождена ! \en If count of rows decreases, then memory from excess rows has to be already released ! +// --- +template +inline bool Array2::CatchLinePointers( size_t newCount ) +{ + if ( l != newCount ) + { + // \ru половина адресного пространства для 64- и 32-разрядного приложения \en a half of address space for 64- and 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, newCount ) ) + { + try { +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void * oldParr = parr; + size_t oldSize = l; +#endif // __REALLOC_ARRAYS_STATISTIC_ + +#ifdef USE_REALLOC_IN_ARRAYS + parr = (Type**)REALLOC_ARRAY_SIZE( parr, newCount * SIZE_OF_POINTER, false/*clear*/ ); + // \ru ИР parr = (Type**) ::realloc( parr, newCount * SIZE_OF_POINTER ); \en ИР parr = (Type**) ::realloc( parr, newCount * SIZE_OF_POINTER ); +#else + Type ** p_tmp = newCount ? new Type*[newCount] : 0; + + if ( parr ) { + if ( p_tmp ) + memcpy( p_tmp, parr, std_min(l, newCount) * SIZE_OF_POINTER ); + + delete[] parr; + } + + parr = p_tmp; +#endif // USE_REALLOC_IN_ARRAYS + + l = newCount; + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldSize * SIZE_OF_POINTER, parr, newCount * SIZE_OF_POINTER, 2/*Array2*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ + } + catch ( const std::bad_alloc & ) { + C3D_CONTROLED_THROW; + return false; + } + catch ( ... ) { + if ( newCount == 0 ) {// \ru Не смогли удалить parr. \en Failed to delete parr. + parr = NULL; + l = c = 0; + } + C3D_CONTROLED_THROW; + return false; + } + } + else { + PRECONDITION( false ); // \ru не бывает столько памяти \en incorrect size of memory + C3D_CONTROLED_THROW_EX( std::bad_alloc() ); + return false; + } + } + return true; +} + + +//------------------------------------------------------------------------------ +/// \ru Перезахватить память под одну строку. \en Reallocate memory for one row. +// --- +template +inline bool realloc_line( Type *& line, size_t oldSize, size_t newSize ) +{ + if ( oldSize != newSize ) + { + size_t sizeOfType = sizeof(Type); + + // \ru половина адресного пространства для 64- и 32-разрядного приложения \en a half of address space for 64- and 32-bit application + if ( ::TestNewSize( sizeOfType, newSize ) ) + { + try { +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void * oldParr = line; +#endif // __REALLOC_ARRAYS_STATISTIC_ + +#ifdef USE_REALLOC_IN_ARRAYS + line = (Type *) REALLOC_ARRAY_SIZE( line, newSize * sizeOfType, false/*clear*/ ); +#else + Type * p_tmp = newSize ? new Type[newSize] : 0; + + if ( line ) + { + if ( p_tmp ) + memcpy( p_tmp, line, std_min(oldSize, newSize) * sizeOfType ); + + delete [] line; + } + + line = p_tmp; +#endif // USE_REALLOC_IN_ARRAYS + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldSize * sizeOfType, line, newSize * sizeOfType, 2/*Array2*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ + } + catch ( const std::bad_alloc & ) { + C3D_CONTROLED_THROW; + return false; + } + catch ( ... ) { + if ( newSize == 0 )// \ru Не смогли удалить line. \en Failed to delete line. + line = NULL; + C3D_CONTROLED_THROW; + return false; + } + } + else { + PRECONDITION( false ); // \ru не бывает столько памяти \en incorrect size of memory + C3D_CONTROLED_THROW_EX( std::bad_alloc() ); + return false; + } + } + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Присвоить массиву новое содержимое, заменив его текущее содержимое. +// \en Assign new contents to the array, replacing its current contents. +// --- +template +bool assign_to_array( Array2 & arr, const Array2 & source ) +{ + if ( set_array_size( arr, source.l, source.c ) ) { + if ( arr.l && arr.c ) { + Type ** aParr = arr.parr; + Type ** sParr = source.parr; + size_t n = arr.c * sizeof(Type); + for ( size_t i = 0; i < arr.l; i++, aParr++, sParr++ ) + ::memcpy( *aParr, *sParr, n ); + } + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +bool set_array_size( Array2 & arr, size_t lSize, size_t cSize ) +{ + bool res = false; + + if ( lSize*cSize <= c3d::MATRIX_MAX_COUNT ) { + size_t i, oldL = arr.l; + res = true; + + if ( arr.l != lSize ) { + // \ru Если кол-во строк уменьшается - освободить память из-под лишних строк \en If count of rows decreases then release memory from excess rows + if ( arr.c && oldL && lSize < oldL ) { + size_t removeLines = oldL - lSize; + for ( i = 1; i <= removeLines; i++ ) + realloc_line( arr.parr[oldL-i], arr.c/*oldSize*/, 0/*newSize*/ ); // \ru освободить память, занятую строкой \en free memory occupied by row + } + + // \ru Взять память под заданное кол-во указателей на строки (изменится arr.l) \en Allocate memory for the given count of pointers to rows (arr.l tro be changed) + res = arr.CatchLinePointers( lSize ); + for ( i = oldL; res && i < arr.l/*\ru уже изменено \en already changed */; i++ ) + arr.parr[i] = 0; // \ru обнулить добавленные указатели \en set added pointers to null + } + + if ( arr.c != cSize ) { + // \ru Перезахватить память под каждую строку \en Reallocate memory for each row + for ( i = 0; res && i < arr.l/*\ru уже изменено \en already changed */; i++ ) + res = realloc_line( arr.parr[i], arr.c/*oldSize*/, cSize/*newSize*/ ); + + if ( res ) + arr.c = cSize; + } + else if ( arr.l > oldL && arr.c > 0 ) { // \ru BUG_46010 KYA K12 А кто будет выделять память для новых строк \en BUG_46010 KYA K12 And who will allocate memory for new rows + Type * newLine = 0; // \ru указатель на содержимое новой строки \en pointer to contents of new row + for ( i = oldL; res && i < arr.l; i++ ) { + newLine = NULL; + res = ::realloc_line( newLine, 0, arr.c ); // \ru захватить память под строку \en allocate memory for one row + if ( res ) { + ::memset( newLine, 0, arr.c * sizeof(Type) ); + arr.parr[i] = newLine; // \ru записать указатель в массив \en store pointer to the array + } + } + } + } + + PRECONDITION( res ); + return res; +} + + +//------------------------------------------------------------------------------ +/// \ru Вставить колонку перед указанной и заполнить ее нулями \en Insert column before specified one and fill it with zeros +// \ru если ind больше количества колонок, то просто добавить колонку в конец массива \en if 'ind' is greater than count of columns, then simply add the column to the end of the array +// --- +template +bool insert_column_to_array( Array2 & arr, size_t ind ) +{ + bool res = true; + if ( arr.l ) { + size_t oldC = arr.c; // \ru прежнее кол-во колонок \en previous count of columns + if ( add_column_to_array( arr ) ) { // \ru добавить колонку в конец строк (увеличилось arr.c) \en add column to the end of rows (arr.c increased) + if ( ind < oldC ) { + size_t tail = oldC - ind; // \ru кол-во колонок, которые нужно сдвинуть \en count of columns to be moved + for ( size_t i = 0; i < arr.l; i++ ) { + Type * line = arr.parr[i]; + // \ru передвинуть хвосты всех строк ближе к концу на один элемент (при этом \en move tales of all rows by one element closer to end (thus + // \ru затрем добавленный обнуленный элемент) \en erase added nullified element) + memmove( line + ind + 1, line + ind, tail * sizeof(Type) ); + // \ru обнулить элемент ind \en set 'ind' element to null + memset( line + ind, 0, sizeof(Type) ); + } + } + } + else + res = false; + } + return res; +} + + +//------------------------------------------------------------------------------ +/// \ru Добавить в массив колонку (последнюю) и обнулить ее. \en Add (last) column to array and fill it with zeros. +// --- +template +bool add_column_to_array( Array2 & arr ) +{ + bool res = true; + if ( arr.l ) { + // \ru увеличить память под каждой строкой на 1 элемент \en increase memory under each row by 1 element + size_t newSize = arr.c + 1; + for ( size_t i = 0; res && i < arr.l; i++ ) { + res = realloc_line( arr.parr[i]/*\ru здесь может меняться!!! \en can be changed!!! */, arr.c/*oldSize*/, newSize ); + // \ru обнулить добавленную ячейку (последний элемент в строке) \en set added cell (last element in row) to zero + if ( res ) + memset( arr.parr[i] + arr.c/*\ru еще не увеличенное \en not yet increased */, 0, sizeof(Type) ); + } + if ( res ) + arr.c = newSize; + } + return res; +} + + +//------------------------------------------------------------------------------ +/// \ru Убрать из массива колонку по индексу. \en Delete column from array by the index. +// --- +template +void remove_column_from_array( Array2 & arr, size_t ind ) +{ + PRECONDITION( ind < arr.c ); + + if ( ind < arr.c ) { + // \ru передвинуть хвосты всех строк ближе к началу на один элемент \en move tales of all rows closer to start by one element + size_t tail = arr.c - (ind + 1); + if ( tail ) { // \ru это не последняя колонка в строке \en this is not last column in row + for ( size_t i = 0; i < arr.l; i++ ) { + Type *line = arr.parr[i]; + memmove( line + ind, line + ind + 1, tail * sizeof(Type) ); + } + } + + // \ru уменьшить память под каждой строкой на 1 элемент \en decrease memory under each row by 1 element + size_t newSize = arr.c - 1; + for ( size_t i = 0; i < arr.l; i++ ) + realloc_line( arr.parr[i], arr.c/*oldSize*/, newSize ); + + arr.c = newSize; + } + +} + + +//------------------------------------------------------------------------------ +/// \ru Заполнить массив нулями. \en Fill the array with zeros. +// --- +template +void zero_array( Array2 & arr ) +{ + size_t n = arr.c * sizeof(Type); + if ( n ) { + Type ** parr = arr.parr; + for ( size_t i = 0; i < arr.l; i++, parr++ ) + memset( *parr, 0, n ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Транспонирование матрицы. + \en Transpose a matrix. \~ + \details \ru Транспонирование матрицы. \n + \en Transpose a matrix. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +void Transpose( const Array2 & srcMtr, Array2 & dstMtr ) +{ + const size_t l = srcMtr.Lines(); + const size_t c = srcMtr.Columns(); + dstMtr.SetSize( c, l ); + for ( size_t nc = 0; nc < c; nc++ ) { + for ( size_t nl = 0; nl < l; nl++ ) + dstMtr( nc, nl ) = srcMtr( nl, nc ); + } +} + + +#endif // __TEMPL_ARRAY2_H diff --git a/C3d/Include/templ_balance_tree.h b/C3d/Include/templ_balance_tree.h new file mode 100644 index 0000000..0287f1b --- /dev/null +++ b/C3d/Include/templ_balance_tree.h @@ -0,0 +1,1032 @@ +////////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cбалансированное дерево. + \en Balanced tree. \~ + +*/ +// \ru Никлаус Вирт "Алгоритмы и структуры данных" \en Niklaus Wirth "Algorithms and Data Structures" +// \ru Построение сбалансированного дерева (АВЛ- дерево). Разновидность бинарного дерева. \en Construction of balanced tree (AVL-tree). There is a sort of binary tree. +// \ru Из узла выходит не более двух поддеревьев. \en Each node contains at most two child subtrees. +// \ru Дерево называется сбалансированным, когда высоты двух поддеревьев из его вершин \en Tree is balanced if heights of two child subtrees of any node +// \ru отличаются не более чем на единицу. \en differ by at most one. +// +// \ru BalanceTreeNode - Узел сбалансированного дерева \en BalanceTreeNode - Node of balanced tree +// \ru BalanceTree - Сбалансированное дерево \en BalanceTree - Balanced tree +// \ru BalanceTreeIterator - Класс итератора для сбалансированного дерева \en BalanceTreeIterator - Balanced tree iterator class +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef __BALANCETREE_H +#define __BALANCETREE_H + +#include +#include "templ_delete_define.h" +#include "templ_three_states.h" +#include "templ_s_array.h" + + +template class BalanceTree; + + +//----------------------------------------------------------------------------- +// \ru сравниваем указатели \en compare pointers +// --- +template +ThreeStates SimplePointCompFuncT( const Type * t1, const Type * t2 ) { + return size_t(t1) == size_t(t2) ? ts_neutral : size_t(t1) < size_t(t2) ? ts_negative : ts_positive; +} + + +//----------------------------------------------------------------------------- +// \ru сравниваем указатели \en compare pointers +// --- +template +ThreeStates SimplePointCompFuncV( const Type * t1, const void * t2 ) { + return size_t(t1) == size_t(t2) ? ts_neutral : size_t(t1) < size_t(t2) ? ts_negative : ts_positive; +} + + +FORVARD_DECL_TEMPLATE_TYPENAME( class BalanceTreeNode ); +FORVARD_DECL_TEMPLATE_TYPENAME( void destroy_tree_node ( BalanceTreeNode &, DelType del ) ); + +//----------------------------------------------------------------------------- +/** \brief \ru Узел сбалансированного дерева. + \en Node of balanced tree. \~ + \details \ru Узел сбалансированного дерева. \n + \en Node of balanced tree. \n \~ + \ingroup Base_Tools +*/ +// --- +template +class BalanceTreeNode { +public: + BalanceTree & parent_m; ///< \ru Родитель узла. \en Parent of node. + BalanceTreeNode * left_m; ///< \ru Левое поддерево. \en Left subtree. + BalanceTreeNode * right_m; ///< \ru Правое поддерево. \en Right subtree. + ThreeStates balance_m; ///< \ru Признак сбалансированности. \en Attribute of balance. + Type * content_m; ///< \ru Указатель на элемент. \en Pointer to element. + +public: + /// \ru Конструктор. \en Constructor. + BalanceTreeNode( BalanceTree & parent, Type * content ); + /// \ru Деструктор. \en Destructor. + virtual ~BalanceTreeNode(); + /// \ru Установить левую ветвь. \en Set left branch. + void SetLeft ( BalanceTreeNode * p ); + /// \ru Установить правую ветвь. \en Set right branch. + void SetRight( BalanceTreeNode * p ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +private: + TEMPLATE_FRIEND void destroy_tree_node TEMPLATE_SUFFIX ( BalanceTreeNode &, DelType del ); + void operator = ( const BalanceTreeNode & ); +}; + + +FORVARD_DECL_TEMPLATE_TYPENAME( class BalanceTree ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * find_tree( const BalanceTree &, void * content, bool compT ) ); + +//----------------------------------------------------------------------------- +/** \brief \ru Cбалансированное дерево. + \en Balanced tree. \~ + \details \ru Cбалансированное дерево. \n + \en Balanced tree. \n \~ + \ingroup Base_Tools +*/ +// --- +template +class BalanceTree { +public: + BalanceTreeNode * root_m; ///< \ru Корень дерева. \en Root of tree. + size_t allCount_m; ///< \ru Количество. \en Count. + bool owns_m; ///< \ru Можно ли удалять элементы. \en Whether it is possible to delete elements. + bool isBranchGrew_m; ///< \ru Флаг роста дерева. \en Flag of growth of a tree. + +public: + typedef ThreeStates (*Compare_t)( const Type *, const Type * ); + typedef ThreeStates (*Compare_v)( const Type *, const void * ); + + Compare_t compT_m; ///< \ru Функция сортировки используется при добавлении объекта. \en Sorting function is used while adding an object. + Compare_v compV_m; ///< \ru Функция сортировки используется при поиске объекта. \en Sorting function is used while search an object. + +#ifdef C3D_DEBUG +static size_t countIsSame; ///< \ru Число сравнений (для отладки) \en Count of comparisons (for debug) +#endif // C3D_DEBUG + +public: + /// \ru Конструктор. \en Constructor. + BalanceTree( Compare_t c_t = SimplePointCompFuncT, Compare_v c_v = NULL/*SimplePointCompFuncV*/, + bool shouldDelete = true ); + /// \ru Деструктор. \en Destructor. + virtual ~BalanceTree(); + +public: + bool Add ( Type * ); ///< \ru Добавить элемент. \en Add element. + size_t Count () const { return allCount_m; } ///< \ru Получить количество элементов. \en Set count of elements. + void Flush ( DelType = defDelete ); ///< \ru Удалить все элементы. \en Delete all elements. + bool Remove ( Type * delObject, DelType = defDelete ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + bool FindIt ( const Type * ) const; ///< \ru Найти элемент по указателю. \en Find an element by a pointer + Type * Find ( void * ) const; ///< \ru Найти элемент. \en Find an element. + bool Detach ( const Type * ); ///< \ru Отсоединить объект. \en Detach an object. + + typedef void (*IterFunc) ( Type &, void *); + void ForEach ( IterFunc f, void *pars ); // \ru НЕ классный итератор \en Iterator IS OUT OF a class + +protected: + /// \ru Добавить объект в дерево. \en Add object to tree. + bool AddToBalanceTree ( Type & content, BalanceTreeNode *& node, + bool & isBranchGrew ); + /// \ru Удалить объект из дерева. \en Delete an object from tree. + bool DeleteFromBalanceTree( Type & content, BalanceTreeNode *& node, bool & isBranchGrew, DelType del ); + /// \ru Балансировать левую ветвь. \en Balance left branch. + void BalanceL ( BalanceTreeNode *& node, bool & isBranchGrew ); + /// \ru Балансировать правую ветвь. \en Balance right branch. + void BalanceR ( BalanceTreeNode *& node, bool & isBranchGrew ); + // \ru Исключить из сбалансированного дерева. \en Exclude from balanced tree. + bool DelFromBalanceTree ( BalanceTreeNode *& q, BalanceTreeNode *& r, bool & isBranchGrew ); + +private: + void DoubleTurningRL ( BalanceTreeNode *& node, BalanceTreeNode * p1, + BalanceTreeNode *& p2 ); + void DoubleTurningLR ( BalanceTreeNode *& node, BalanceTreeNode * p1, + BalanceTreeNode *& p2 ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +private: + TEMPLATE_FRIEND Type * find_tree TEMPLATE_SUFFIX ( const BalanceTree &, void * content, bool compT ); + void for_each_in_tree( BalanceTreeNode &, typename BalanceTree::IterFunc f, void *pars ); // \ru неклассный \en out of class +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * BalanceTree::operator new( size_t size ) { + return ::Allocate( size, typeid(BalanceTree).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void BalanceTree::operator delete ( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(BalanceTree).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//----------------------------------------------------------------------------- +// \ru Узел \en Node +// --- +template +class PPNode { +public: + /// \ru Типы движения по дереву. \en Types of moving in the tree. + enum PPNodeType { + iRoot = 0, // \ru текущий this \en current 'this' + iLeft = 1, // \ru текущий Left \en current 'Left' + iRight = 2, // \ru текущий Right \en current 'Right' + iRemove = 3 // \ru удалять \en remove + }; + + BalanceTreeNode * node_m; + PPNodeType typeRAB_m; +public: + PPNode( BalanceTreeNode * node = NULL, PPNodeType t = iRoot ) + : node_m(node) + , typeRAB_m(t) + {} + PPNode( PPNode & other ) + : node_m( other.node) + , typeRAB_m( other.typeRAB_m ) + {} + void Init( BalanceTreeNode * node, PPNodeType t ) { node_m = node; typeRAB_m = t; } +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru Итератор сбалансированного дерева. + \en Iterator of balanced tree. \~ + \details \ru Итератор сбалансированного дерева. \n + \en Iterator of balanced tree. \n \~ + \ingroup Base_Tools +*/ +// --- +template +class BalanceTreeIterator { +public: +/// \ru Типы движения по дереву. \en Types of moving through the tree. +enum IteratorType { + /// \ru Умолчательный. \en Default. + iDeforder = 0, + /// \ru Сверху вниз R(корень), A(слева), B(справа). \en Top-down R(root), A(at the left), B(at the right). + iPreorder = 1, + /// \ru Слева направо A(слева), R(корень), B(справа) по возрастанию. \en From left to right A(at the left), R(root), B(at the right) in ascending order. + iInorder = 2, + /// \ru Снизу вверх A(слева), B(справа), R(корень). \en Bottom-up A(at the left), B(at the right), R(root). + iPostorder = 3, + /// \ru Справа налево B(справа), R(корень), A(слева) по убыванию. \en From right to left B(at the right), R(root), A(at the left) in descending order. + iBackorder = 4 //-V112 +}; + +protected: + BalanceTree & m_tree; ///< \ru Дерево, по которому движемся. \en Tree to move through. + IteratorType m_iterType; ///< \ru Тип движения. \en Type of move. + SArray< PPNode > m_PPNodes; ///< \ru Последовательный список узлов итератора(имитация рекурсии). \en Sequential list of iterator nodes (imitation of recursion). + PPNode m_PPNode; ///< \ru Для наполнения. \en For filling. + + BalanceTreeNode * m_CurNode; ///< \ru Текущий узел. \en Current node. + +public: + BalanceTreeIterator( BalanceTree & tree, IteratorType t = iPreorder ) + : m_tree ( tree ) + , m_iterType( t ) + , m_PPNodes ( 0x100, 0x100 ) + , m_PPNode ( ) + { + Restart( m_iterType ); + } + virtual ~BalanceTreeIterator() + {} +public: + Type * operator ++ (int); + virtual operator Type * () const; + + virtual void Restart( IteratorType t = iDeforder ); + // \ru КВН K8+ Будет работать правильно, если делать Restart. Чтобы работало в цикле, нужно набирать \en КВН K8+ Will correctly work if doing Restart. For working in cycle it is necessary to gather + // \ru КВН K8+ удаляемые объекты в список и удалять в конце цикла или по Restart \en КВН K8+ deleted objects to list and remove it at the end of cycle or by Restart + // \ru КВН K8+ bool Remove ( DelType = defDelete ); // удалить элемент списка и продвинуть вперед \en КВН K8+ bool Remove ( DelType = defDelete ); // remove element from list and move ahead + // \ru КВН K8+ bool Detach (); // отсоединить элемент списка \en КВН K8+ bool Detach (); // detach element of list + +protected: + void Iterate ( BalanceTreeNode * node ); + typename + PPNode::PPNodeType GetNodeType ( bool add, typename PPNode::PPNodeType oldTypeRAB ); + +private: + void operator = ( const BalanceTreeIterator & ); +}; + + +//------------------------------------------------------------------------------ +// +//--- +#ifdef C3D_DEBUG +template +size_t BalanceTree::countIsSame = 0; +#endif // C3D_DEBUG + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru BalanceTreeNode - узел сбалансированного дерева \en BalanceTreeNode - node of balanced tree +// +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * BalanceTreeNode::operator new( size_t size ) { + return ::Allocate( size, typeid(BalanceTreeNode).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void BalanceTreeNode::operator delete ( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(BalanceTreeNode).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------- +// \ru конструктор узла дерева \en constructor of node of tree +// --- +template +inline BalanceTreeNode::BalanceTreeNode( BalanceTree & parent, Type * content ) : + parent_m ( parent ), + left_m ( NULL ), + right_m ( NULL ), +// \ru КВН K8+ count_m ( 0 ), \en КВН K8+ count_m ( 0 ), + balance_m ( ts_neutral ), + content_m ( content ) +{ +} + + +//------------------------------------------------------------------------------ +// \ru деструктор узла дерева \en destructor of node of tree +// --- +template +inline BalanceTreeNode::~BalanceTreeNode() +{ + destroy_tree_node( *this, defDelete ); +} + +//----------------------------------------------------------------------------- +// +// --- +template +inline void BalanceTreeNode::SetLeft ( BalanceTreeNode * p ){ + left_m = p; +} + +//----------------------------------------------------------------------------- +// +// --- +template +inline void BalanceTreeNode::SetRight( BalanceTreeNode * p ){ + right_m = p; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru BalanceTree - сбалансированное дерево \en BalanceTree - balanced tree +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------- +// \ru конструктор дерева \en constructor of tree +// --- +template +inline BalanceTree::BalanceTree( Compare_t c_t, Compare_v c_v, bool shouldDelete ) : + root_m ( NULL ), + allCount_m ( 0 ), + owns_m ( shouldDelete ), + isBranchGrew_m( false ), + compT_m ( c_t ), + compV_m ( c_v ) +{ + if ( !compV_m && compT_m == (Compare_t) SimplePointCompFuncT ) + compV_m = SimplePointCompFuncV; + +#ifdef C3D_DEBUG + countIsSame = 0; +#endif // C3D_DEBUG +} + + +//------------------------------------------------------------------------------ +// \ru деструктор дерева \en destructor of tree +// --- +template +inline BalanceTree::~BalanceTree() { + delete root_m; +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент в конец массива \en add 1 element at the end of array +// --- +template +inline bool BalanceTree::Add( Type * ent ) { + +#ifdef C3D_DEBUG + countIsSame = 0; +#endif // C3D_DEBUG + + bool res = false; + if ( ent && compT_m ) { + res = AddToBalanceTree( *ent, root_m, isBranchGrew_m ); + } + return res; +} + + +//------------------------------------------------------------------------------ +// \ru обнулить количество элементов \en set to null the count of elements +// --- +template +inline void BalanceTree::Flush( DelType del ) { + if( root_m ) { + destroy_tree_node( *root_m, del ); + delete root_m; + root_m = NULL; + } + + allCount_m = 0; + isBranchGrew_m = false; +} + + +//----------------------------------------------------------------------------- +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline bool BalanceTree::Remove( Type * delObject, DelType del ) { + +#ifdef C3D_DEBUG + countIsSame = 0; +#endif // C3D_DEBUG + + bool res = false; + if ( delObject && compT_m ) + res = DeleteFromBalanceTree( *delObject, root_m, isBranchGrew_m, del ); + + return res; +} + + +//----------------------------------------------------------------------------- +// \ru отсоединить объект \en detach an object +// --- +template +inline bool BalanceTree::Detach( const Type *d ){ + return Remove( (Type*)d, noDelete ); +} + + +//----------------------------------------------------------------------------- +// \ru найти элемент по указателю \en find an element by a pointer +// --- +template +inline bool BalanceTree::FindIt ( const Type * content ) const { + +#ifdef C3D_DEBUG + countIsSame = 0; +#endif // C3D_DEBUG + + + Type * t = compT_m ? find_tree( *this, (void *)content, true/*compT*/ ) : NULL; + return !!t; +} + + +//----------------------------------------------------------------------------- +// \ru найти элемент \en find an element +// --- +template +inline Type * BalanceTree::Find ( void * content ) const { + +#ifdef C3D_DEBUG + countIsSame = 0; +#endif // C3D_DEBUG + + return compV_m ? find_tree( *this, content, false/*compT*/ ) : NULL; +} + + +//------------------------------------------------------------------------------ +// \ru не классный \en out of class +// --- +template +inline void BalanceTree::for_each_in_tree( BalanceTreeNode& node, typename BalanceTree::IterFunc f, void *pars ) { + if ( node.left_m ) + for_each_in_tree( *node.left_m, f, pars ); + + PRECONDITION( f ); + (*f)( *node.content_m, pars ); + + if ( node.right_m ) + for_each_in_tree( *node.right_m, f, pars ); +} + + +//------------------------------------------------------------------------------ +// \ru не классный \en out of class +// --- +template +inline void BalanceTree::ForEach( IterFunc f, void *pars ) { + if ( root_m && f ) + for_each_in_tree( *root_m, f, pars ); +} + + +//----------------------------------------------------------------------------- +// \ru двойной RL-поворот \en double RL-rotation +// --- +template +inline void BalanceTree::DoubleTurningRL ( BalanceTreeNode *& node, + BalanceTreeNode * p1, + BalanceTreeNode *& p2 ) { + p2 = p1->left_m; + if ( p2 ) { + p1 ->SetLeft( p2->right_m ); + p2 ->SetRight( p1 ); + node->SetRight( p2->left_m ); + p2 ->SetLeft( node ); + node->balance_m = ( p2->balance_m == ts_positive ) ? ts_negative : ts_neutral; + p1->balance_m = ( p2->balance_m == ts_negative ) ? ts_positive : ts_neutral; + node = p2; + } +} + + +//----------------------------------------------------------------------------- +// \ru двойной LR-поворот \en double LR-rotation +// --- +template +inline void BalanceTree::DoubleTurningLR ( BalanceTreeNode *& node, + BalanceTreeNode * p1, + BalanceTreeNode *& p2 ) { + p2 = p1->right_m; + if ( p2 ) { + p1 ->SetRight( p2->left_m ); + p2 ->SetLeft( p1 ); + node->SetLeft( p2->right_m ); + p2 ->SetRight( node ); + node->balance_m = ( p2->balance_m == ts_negative ) ? ts_positive : ts_neutral; + p1->balance_m = ( p2->balance_m == ts_positive ) ? ts_negative : ts_neutral; + node = p2; + } +} + + +//----------------------------------------------------------------------------- +// \ru Построение идеально сбалансированного дерева \en Creation of ideally balanced tree +// --- +template +inline bool BalanceTree::AddToBalanceTree( Type & content, BalanceTreeNode *& node, + bool & isBranchGrew ) { + bool isAdd = false; + if ( !node ) { + node = new BalanceTreeNode( *this, &content ); + isAdd = true; + isBranchGrew = true; + allCount_m++; // \ru подсчитываем общее кол-во узлов \en compute the total count of nodes + } + else { + ThreeStates compRres = compT_m( (Type*)node->content_m, (Type*)&content ); + +#ifdef C3D_DEBUG + countIsSame++; +#endif // C3D_DEBUG + + if ( compRres != ts_neutral ) { + if ( compRres == ts_positive ) { + isAdd = AddToBalanceTree( content, node->left_m, isBranchGrew ); + // \ru выросла левая ветвь \en left branch is grew up. + if ( isAdd && isBranchGrew ) { + switch ( node->balance_m ) { + case ts_positive : node->balance_m = ts_neutral; isBranchGrew = false; break; + case ts_neutral : node->balance_m = ts_negative; break; + // \ru балансировка \en balancing + case ts_negative : { + BalanceTreeNode * p1 = NULL; + BalanceTreeNode * p2 = NULL; + p1 = node->left_m; + if ( p1 ){ + if ( p1->balance_m == ts_negative ) { // \ru однократный LL поворот \en single LL rotation + node->SetLeft( p1->right_m ); + + p1->SetRight( node ); + + node->balance_m = ts_neutral; + node = p1; + + } + // \ru двойной LR-поворот \en double LR-rotation + else { + DoubleTurningLR( node, p1, p2 ); + } + } + + node->balance_m = ts_neutral; + isBranchGrew = false; + } break; + } + } + } + else { + isAdd = AddToBalanceTree( content, node->right_m, isBranchGrew ); + if ( isAdd && isBranchGrew ) { + switch ( node->balance_m ) { + case ts_negative : node->balance_m = ts_neutral; isBranchGrew = false; break; + case ts_neutral : node->balance_m = ts_positive; break; + // \ru балансировка \en balancing + case ts_positive : { + BalanceTreeNode * p1 = NULL; + BalanceTreeNode * p2 = NULL; + p1 = node->right_m; + if ( p1 ) { + if ( p1->balance_m == ts_positive ) { // \ru однократный RR поворот \en single RR rotation + node->SetRight( p1->left_m ); + + p1->SetLeft( node ); + + node->balance_m = ts_neutral; + node = p1; + } + else { // \ru двойной RL-поворот \en double RL-rotation + DoubleTurningRL( node, p1, p2 ); + } + } + + node->balance_m = ts_neutral; + isBranchGrew = false; + } break; + } + } + } + } + } + + return isAdd; +} + + +//----------------------------------------------------------------------------- +// \ru Балансировка слева \en Balancing at the left +// --- +template +inline void BalanceTree::BalanceL( BalanceTreeNode *& node, bool & isBranchGrew ) { + switch ( node->balance_m ) { + case ts_negative : node->balance_m = ts_neutral; break; + case ts_neutral : node->balance_m = ts_positive; isBranchGrew = false; break; + // \ru балансировка \en balancing + case ts_positive : { + BalanceTreeNode * p1 = NULL; + BalanceTreeNode * p2 = NULL; + p1 = node->right_m; + if ( p1 ) { + if ( p1->balance_m >= ts_neutral ) { // \ru однократный RR поворот \en single RR rotation + node->SetRight( p1->left_m ); + p1->SetLeft( node ); + if ( p1->balance_m == ts_neutral ) { + node->balance_m = ts_positive; + p1->balance_m = ts_negative; + isBranchGrew = false; + } + else { + node->balance_m = ts_neutral; + p1->balance_m = ts_neutral; + } + node = p1; + } + else { // \ru двойной RL-поворот \en double RL-rotation + DoubleTurningRL( node, p1, p2 ); + if( p2 ) + p2->balance_m = ts_neutral; + } + } + } break; + } +} + + +//----------------------------------------------------------------------------- +// \ru Балансировка справа \en Balancing at the right +// --- +template +inline void BalanceTree::BalanceR( BalanceTreeNode *& node, bool & isBranchGrew ) { + switch ( node->balance_m ) { + case ts_positive : node->balance_m = ts_neutral; break; + case ts_neutral : node->balance_m = ts_negative; isBranchGrew = false; break; + // \ru балансировка \en balancing + case ts_negative : { + BalanceTreeNode * p1 = NULL; + BalanceTreeNode * p2 = NULL; + p1 = node->left_m; + if ( p1 ) { + if ( p1->balance_m <= ts_neutral ) { // \ru однократный LL поворот \en single LL rotation + node->SetLeft( p1->right_m ); + p1->SetRight( node ); + if ( p1->balance_m == ts_neutral ) { + node->balance_m = ts_negative; + p1->balance_m = ts_positive; + isBranchGrew = false; + } + else { + node->balance_m = ts_neutral; + p1->balance_m = ts_neutral; + } + node = p1; + } + else { // \ru двойной LR-поворот \en double LR-rotation + DoubleTurningLR( node, p1, p2 ); + if( p2 ) + p2->balance_m = ts_neutral; + } + } + } break; + } +} + + +//----------------------------------------------------------------------------- +// \ru Исключение из сбалансированного дерева \en Exclude from balanced tree +// --- +template +inline bool BalanceTree::DelFromBalanceTree( BalanceTreeNode *& q, BalanceTreeNode *& r, bool & isBranchGrew ) { + bool res = false; + if ( r->right_m ) { + res = DelFromBalanceTree( q, r->right_m, isBranchGrew ); + if ( res && isBranchGrew ) + BalanceR( r, isBranchGrew ); + } + else { + Type * content = q->content_m; + q->content_m = r->content_m; + r->content_m = content; + // \ru КВН K8+ q->count_m = r->count_m; \en КВН K8+ q->count_m = r->count_m; + q = r; + r = r->left_m; + isBranchGrew = true; + } + return res; +} + + +//----------------------------------------------------------------------------- +// \ru Исключение из сбалансированного дерева \en Exclude from balanced tree +// --- +template +inline bool BalanceTree::DeleteFromBalanceTree( Type & content, BalanceTreeNode *& node, + bool & isBranchGrew, DelType del ) { + bool res = false; + if ( node && node->content_m ) { + ThreeStates compRres = compT_m( (Type*)node->content_m, (Type*)&content ); + +#ifdef C3D_DEBUG + countIsSame++; +#endif // C3D_DEBUG + + switch ( compRres ) { + case ts_positive : { + res = DeleteFromBalanceTree( content, node->left_m, isBranchGrew, del ); + if ( res && isBranchGrew ) + BalanceL( node, isBranchGrew ); + break; + } + case ts_negative : { + res = DeleteFromBalanceTree( content, node->right_m, isBranchGrew, del ); + if ( res && isBranchGrew ) + BalanceR( node, isBranchGrew ); + break; + } + case ts_neutral : { // \ru исключение node \en exclude node + BalanceTreeNode * q = node; + if ( !q->right_m ) { + node = q->left_m; + isBranchGrew = true; + } + else if ( !q->left_m ) { + node = q->right_m; + isBranchGrew = true; + } + else { + // \ru удаляемый узел имеет двух потомков. В этом случае нужно "спуститься" вдоль правой ветви \en deleted node has two descendants. In this case it is necessary to "go down" through right branch + // \ru левого поддерева, найти самый правый узел-лист. Перенести информацию из него в node, \en of left subtree and find most right leaf node. Transfer information from it to node, + // \ru информацию из node в этот лист( content ). Переуказать q на этот лист, чтобы удалить узел-лист. \en transfer information from node to this leaf ( content ). Re-point q to this leaf to delete the leaf node. + res = DelFromBalanceTree( q, q->left_m, isBranchGrew ); + if ( res && isBranchGrew ) + BalanceL( node, isBranchGrew ); + } + bool oldowns = owns_m; + owns_m = del == Delete ? true : del == noDelete ? false : owns_m; + q->left_m = NULL; + q->right_m = NULL; + delete q; + owns_m = oldowns; + allCount_m--; // \ru подсчитываем общее кол-во узлов \en compute the total count of nodes + res = true; + break; + } + + } + } + return res; +} + + +//------------------------------------------------------------------------------- +// \ru удаление всех указателей, собранных в поддереве \en delete all pointers collected in subtree +// --- +template +void destroy_tree_node( BalanceTreeNode& treeNode, DelType del ) { + + delete treeNode.left_m; + treeNode.left_m = NULL; + delete treeNode.right_m; + treeNode.right_m = NULL; + + bool shouldDelete = del == Delete || ( del == defDelete && treeNode.parent_m.owns_m ); + if ( shouldDelete ) { + delete treeNode.content_m; + treeNode.content_m = NULL; + } +} + + +//----------------------------------------------------------------------------- +// \ru найти элемент по указателю \en find an element by a pointer +// --- +template +Type * find_tree( const BalanceTree& tree, void * content, bool compT ) { + Type * res = NULL; + const BalanceTreeNode * node = tree.root_m; + if ( node ) { + ThreeStates compRres = ts_negative; + while ( node && compRres != ts_neutral ) { + if ( compT ) + compRres = tree.compT_m( (Type*)node->content_m, (Type*)content ); + else + compRres = tree.compV_m( (Type*)node->content_m, content ); + +#ifdef C3D_DEBUG + BalanceTree::countIsSame++; +#endif // C3D_DEBUG + + switch ( compRres ) { + case ts_negative : node = node->right_m; break; + case ts_positive : node = node->left_m; break; + case ts_neutral : res = node->content_m; break; + } + } + } + return res; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru BalanceTreeIterator - класс итератора для сбалансированного дерева \en BalanceTreeIterator - balanced tree iterator class +// +//////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// +// --- +template +inline void BalanceTreeIterator::Restart( IteratorType t ) { + if ( t ) + m_iterType = t; + + m_PPNodes.Flush(); + m_CurNode = m_tree.root_m; + if ( m_CurNode ) + Iterate( m_CurNode ); +} + + +//----------------------------------------------------------------------------- +// \ru взять и сместиться \en displace +// --- +template +inline Type * BalanceTreeIterator::operator ++(int) { + Type * res = m_CurNode ? m_CurNode->content_m : NULL; + if ( m_CurNode ) + Iterate( m_CurNode ); + + return res; +} + + +//----------------------------------------------------------------------------- +// \ru приведение \en conversion +// --- +template +inline BalanceTreeIterator::operator Type * () const { + return m_CurNode ? m_CurNode->content_m : NULL; +} + + +//----------------------------------------------------------------------------- +// \ru сверху вниз R(корень), A(слева), B(справа) \en top-down R(root), A(at the left), B(at the right) +// \ru слева на право A(слева), R(корень), B(справа) по возрастанию \en from left to right A(at the left), R(root), B(at the right) in ascending order +// \ru снизу вверх A(слева), B(справа), R(корень) \en bottom-up A(at the left), B(at the right), R(root) +// \ru справа на лево B(справа), R(корень), A(слева) по убыванию \en from right to left B(at the right), R(root), A(at the left) in descending order +// --- +template +inline typename PPNode::PPNodeType BalanceTreeIterator::GetNodeType( bool add, typename PPNode::PPNodeType oldTypeRAB ) { + typename PPNode::PPNodeType res = PPNode::iRoot; + if ( add ) { // \ru при добавлении в список \en at addition to list + switch ( m_iterType ) { + case iPreorder : res = PPNode::iRoot; break; // \ru сверху вниз R(корень), A(слева), B(справа) \en top-down R(root), A(at the left), B(at the right) + case iPostorder : // \ru снизу вверх A(слева), B(справа), R(корень) \en bottom-up A(at the left), B(at the right), R(root) + case iInorder : res = PPNode::iLeft; break; // \ru слева на право A(слева), R(корень), B(справа) по возрастанию \en from left to right A(at the left), R(root), B(at the right) in ascending order + case iBackorder : res = PPNode::iRight; break; // \ru справа на лево B(справа), R(корень), A(слева) по убыванию \en from right to left B(at the right), R(root), A(at the left) in descending order + default: break; + } + } + else { + switch ( m_iterType ) { + case iPreorder : { // \ru сверху вниз R(корень), A(слева), B(справа) \en top-down R(root), A(at the left), B(at the right) + switch ( oldTypeRAB ) { + case PPNode::iRoot : res = PPNode::iLeft; break; + case PPNode::iLeft : res = PPNode::iRight; break; + case PPNode::iRight: res = PPNode::iRemove; break; + default: break; + } + break; + } + case iPostorder : { // \ru снизу вверх A(слева), B(справа), R(корень) \en bottom-up A(at the left), B(at the right), R(root) + switch ( oldTypeRAB ) { + case PPNode::iLeft : res = PPNode::iRight; break; + case PPNode::iRight: res = PPNode::iRoot; break; + case PPNode::iRoot : res = PPNode::iRemove; break; + default: break; + } + break; + } + case iInorder : { // \ru слева на право A(слева), R(корень), B(справа) по возрастанию \en from left to right A(at the left), R(root), B(at the right) in ascending order + switch ( oldTypeRAB ) { + case PPNode::iLeft : res = PPNode::iRoot; break; + case PPNode::iRoot : res = PPNode::iRight; break; + case PPNode::iRight: res = PPNode::iRemove; break; + default: break; + } + break; + } + case iBackorder : { // \ru справа на лево B(справа), R(корень), A(слева) по убыванию \en from right to left B(at the right), R(root), A(at the left) in descending order + switch ( oldTypeRAB ) { + case PPNode::iRight: res = PPNode::iRoot; break; + case PPNode::iRoot : res = PPNode::iLeft; break; + case PPNode::iLeft : res = PPNode::iRemove; break; + default: break; + } + break; + } + default: break; + } + } + + return res; +} + + +//----------------------------------------------------------------------------- +// \ru Продвинуться. \en Move ahead. +// \ru сверху вниз R(корень), A(слева), B(справа) \en top-down R(root), A(at the left), B(at the right) +// \ru слева на право A(слева), R(корень), B(справа) по возрастанию \en from left to right A(at the left), R(root), B(at the right) in ascending order +// \ru снизу вверх A(слева), B(справа), R(корень) \en bottom-up A(at the left), B(at the right), R(root) +// \ru справа на лево B(справа), R(корень), A(слева) по убыванию \en from right to left B(at the right), R(root), A(at the left) in descending order +// --- +template +inline void BalanceTreeIterator::Iterate( BalanceTreeNode * node ) { + if ( node ) { + ptrdiff_t /*OV_x64 int*/index = m_PPNodes.MaxIndex(); + + if ( index < 0 || m_PPNodes[index].node_m != node ) { + m_PPNode.Init( node, GetNodeType(true, PPNode::iRoot) ); + m_PPNodes.Add( m_PPNode ); + + index = m_PPNodes.MaxIndex(); + } + + bool fRepeat = true; + while ( fRepeat ) { + switch ( m_PPNodes[index].typeRAB_m ) { + case PPNode::iRoot : { + m_CurNode = node; + m_PPNodes[index].typeRAB_m = GetNodeType( false/*add*/, m_PPNodes[index].typeRAB_m ); + fRepeat = false; + break; + } + case PPNode::iLeft : { + if ( node->left_m ) { + Iterate( node->left_m ); + fRepeat = false; + } + m_PPNodes[index].typeRAB_m = GetNodeType( false/*add*/, m_PPNodes[index].typeRAB_m ); + break; + } + case PPNode::iRight : { + if ( node->right_m ) { + Iterate( node->right_m ); + fRepeat = false; + } + m_PPNodes[index].typeRAB_m = GetNodeType( false/*add*/, m_PPNodes[index].typeRAB_m ); + break; + } + case PPNode::iRemove : { + index = m_PPNodes.MaxIndex(); + if ( index >= 0 ) { + m_PPNodes.RemoveInd( index-- ); + if ( index >= 0 ) { + m_CurNode = m_PPNodes[index].node_m; + if ( m_CurNode ) + Iterate( m_CurNode ); + } + else + m_CurNode = NULL; + } + else + m_CurNode = NULL; + fRepeat = false; + break; + } + } + } + } +} + +#endif // __BALANCETREE_H + diff --git a/C3d/Include/templ_c_array.h b/C3d/Include/templ_c_array.h new file mode 100644 index 0000000..a83e941 --- /dev/null +++ b/C3d/Include/templ_c_array.h @@ -0,0 +1,236 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Динамический одномерный массив без счетчика количества элементов. + \en Dynamic one-dimensional array without counter of elements number. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_C_ARRAY_H +#define __TEMPL_C_ARRAY_H + + +#include +#ifndef _INC_STDLIB + #include +#endif +#include "tool_quick_sort.h" +#include "io_define.h" +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class CcArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void fill_array( CcArray &, const Type & fillData, size_t cnt ) ); + + +//----------------------------------------------------------------------------- +/** \brief \ru Динамический одномерный массив без счетчика количества элементов. + \en Dynamic one-dimensional array without counter of elements number. \~ + \details \ru Динамический одномерный массив без счетчика количества элементов. \n + Применяется для выделения памяти под массив, когда не требуется знать размер + массива. Под отладкой контролируется некорректное обращение по индексу за + пределы массива. + \en Dynamic one-dimensional array without counter of elements number. \n + It is used to allocate memory for array when there is not required to know a size + of array. In debug mode there is performed a control of incorrect reference by index out of + array bounds. \~ + \warning \ru Класс остался для поддержки старых кодов. Вместо него можно использовать массивы из STL. + \en The class is left to support old codes. Arrays from STL can be used instead of it. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class CcArray +{ + Type * parr; ///< \ru Указатель на первый элемент массива. \en A pointer to the first array element. +#if defined(C3D_DEBUG) + size_t count; ///< \ru Количество элементов массива (для отладки). \en A number of elements in array (for debugging). +#endif + +public : + /// \ru Конструктор. \en Constructor. + CcArray( size_t /*count*/ ); + /// \ru Деструктор. \en Destructor. + ~CcArray() { SetArraySize( 0 ); } + + /// \ru Заполнить массив значениями. \en Fill an array. + void Fill( const Type &data, size_t cnt ) { fill_array( *this, data, cnt ); } + /// \ru Копировать в себя (со смещением offset) cnt значений из from. \en Copy to itself (with the shift 'offset') 'cnt' values from 'from'. + void Copy( const void * from, size_t cnt, size_t offset = 0 ); + /// \ru Перераспределить память. \en Reallocate memory. + bool SetArraySize( size_t newCount ); + /// \ru Освободить память. \en Free memory. + void FreeMemory() { SetArraySize( 0 ); } + /// \ru Оператор доступа. \en An access operator. + Type & operator []( size_t idx ) const { +#if defined(C3D_DEBUG) + PRECONDITION( idx < count ); +#endif + return parr[idx]; + } + /// \ru Выделена ли память? \en Is memory allocated? + bool IsNull () const { return parr == NULL; } + /// \ru Выдать адрес начала массива. \en Get address of the beginning of an array. + const Type * GetAddr() const { return parr; } + + /// \ru Заполнить cnt элементов массива значением fillData. \en Fill 'cnt' elements of an array by the values of 'fillData'. + TEMPLATE_FRIEND void fill_array TEMPLATE_SUFFIX ( CcArray &, const Type & fillData, size_t cnt ); + +private: + CcArray( const CcArray & ); // \ru запрещено \en forbidden + void operator = ( const CcArray & ); // \ru запрещено \en forbidden + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * CcArray::operator new( size_t size ) { + return ::Allocate( size, typeid(CcArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void CcArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(CcArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------ +// \ru Конструктор массива \en Constructor of an array. +// --- +template +inline CcArray::CcArray( size_t _count ) + : parr( 0 ) +#if defined(C3D_DEBUG) + , count( 0 ) +#endif +{ + if ( !SetArraySize( _count ) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void CcArray::Copy( const void * from, size_t cnt, size_t offset ) +{ +#if defined(C3D_DEBUG) + PRECONDITION( (offset + cnt <= count) && (cnt ? from != NULL : true) ); +#endif + memcpy( parr + offset, from, cnt * sizeof(Type) ); +} + + +//------------------------------------------------------------------------------ +// \ru перераспределить память \en reallocate memory. +// --- +template +inline bool CcArray::SetArraySize( size_t newCount ) +{ + if ( ::TestNewSize(sizeof(Type), newCount) ) + { + try { +#ifdef C3D_DEBUG +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void * oldParr = parr; + size_t oldSize = count; +#endif // __REALLOC_ARRAYS_STATISTIC_ +#endif + +#ifdef USE_REALLOC_IN_ARRAYS + if ( parr != NULL || newCount != 0 ) { + // \ru показывает утечки памяти, если parr==0 и newCount==0 \en Memory leaks happen if parr==0 and newCount==0 + parr = static_cast( REALLOC_ARRAY_SIZE(parr, newCount * sizeof(Type), true/*clear*/) ); + } +#else + Type * p_tmp = newCount ? new Type[newCount] : NULL; + + delete[] parr; // \ru Удалять parr, если оператор new выполнился успешно. \en Delete parr if operator new is succeeded. + parr = p_tmp; +#endif // USE_REALLOC_IN_ARRAYS + +#if defined(C3D_DEBUG) + count = newCount; +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldSize * sizeof(Type), parr, newCount * sizeof(Type), 4/*CcArray*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ +#endif // C3D_DEBUG + } + catch ( const std::bad_alloc & ) { + C3D_CONTROLED_THROW; + return false; + } + catch ( ... ) { + if ( newCount == 0 )// \ru Не смогли удалить parr. \en Failed to delete parr. + parr = NULL; + C3D_CONTROLED_THROW; + return false; + } + } + else { + PRECONDITION( false ); // \ru не бывает столько памяти \en incorrect size of memory + C3D_CONTROLED_THROW_EX( std::bad_alloc() ); + return false; + } + return true; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +void fill_array( CcArray & arr, const Type & fillData, size_t cnt ) +{ +#if defined(C3D_DEBUG) + PRECONDITION( cnt <= arr.count ); +#endif + for ( size_t i = 0; i < cnt; i++ ) + memcpy( &arr[i], &fillData, sizeof(Type) ); +} + + +//------------------------------------------------------------------------------ +// \ru Инициализировать массив символов с присланной строки \en Initialize an array of symbols from a given string +// --- +inline void InitCharArray( CcArray & array, const char * text ) +{ + if ( text ) { + size_t len = ::strlen( text ) + 1; + if ( array.SetArraySize( len ) ) + array.Copy( text, len ); + } + else { + if ( array.SetArraySize( 1 ) ) + array[0] = 0; + } +} + + +//-- __PRECOMPILED_HEADER_OPTIMIZE ------------------------------------------------- +#ifdef _PCH_OPT +#pragma message( "----" __FILE__ ) +#endif + + +#endif // __TEMPL_C_ARRAY_H diff --git a/C3d/Include/templ_csp_array.h b/C3d/Include/templ_csp_array.h new file mode 100644 index 0000000..3005fc3 --- /dev/null +++ b/C3d/Include/templ_csp_array.h @@ -0,0 +1,327 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный одномерный массив указателей. + \en Ordered one-dimensional array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_CSP_ARRAY_H +#define __TEMPL_CSP_ARRAY_H + + +#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class CSPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void qp_sort( CSPArray & arr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, CSPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const CSPArray & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Упорядоченный одномерный массив. + \en Ordered one-dimensional array. \~ + \details \ru Упорядоченный одномерный массив указателей. \n + У объектов массива должны быть операторы "==" и "<". + Имеется возможность добавлять несортированные данные через функцию AddNoSort, + но при первом обращении к функциям Add и Find произойдет сортировка + Одинаковые объекты не добавляются. + \en Ordered one-dimensional array of pointers. \n + Elements of the array should have operators "==" and "<". + The unsorted data can be added by the function 'AddNoSort', + but the sorting starts after the first call of functions Add and Find. + The similar objects are not added. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class CSPArray : protected SPArray { +public: + typedef bool (*LessFuncPtr)( const Type &, const Type & ); ///< \ru Тип указателя на функцию выбора удаляемого элемента из двух одинаковых. \en The type of pointer to selection function of the item to remove from the two identical. + +private: + bool m_sort; ///< \ru Признак сортированности массива. \en Attribute of an array being sorted. + bool m_keepEq; ///< \ru Признак запрет удаления одинаковых элементов. \en Attribute of forbiddance to delete similar elements. + LessFuncPtr m_lessFunc; ///< \ru Функция выбора удаляемого элемента из двух одинаковых. \en The function of selecting the item to remove from the two identical. + +public: + + /// \ru Конструктор. \en Constructor. + CSPArray( size_t maxCnt = 0, uint16 delt = 1, bool shouldDelete = true, bool _keepEq = false, LessFuncPtr func = NULL ) + : SPArray( maxCnt, delt, shouldDelete ) + , m_sort( true ) + , m_keepEq( _keepEq ) + , m_lessFunc( func ) + {} + + using SPArray::OwnsElem; + using SPArray::Delta; + using SPArray::Flush; + using SPArray::Upper; + using SPArray::HardFlush; + using SPArray::Adjust; + using SPArray::RemoveInd; + using SPArray::Count; + using SPArray::MaxIndex; + using SPArray::operator[]; + using SPArray::Reserve; + using SPArray::SetSize; + using SPArray::GetLast; + + using SPArray::begin; + + /// \ru Задать метод выбора удаляемого элемента из двух одинаковых. \en Set the selection method of the item to remove from the two identical. + void SetLessFunc( LessFuncPtr func ) { m_lessFunc = func; } + /// \ru Добавить массив без сортировки. \en Add array without sorting. + bool AddArray( const RPArray & arr ) { m_sort = false; return SPArray::AddArraySimple( arr ); } + /// \ru Добавить элемент без сортировки \en Add element without sorting. + void AddNoSort( Type * ent ) { SPArray::AddSimple( ent ); m_sort = false; } + Type * Add ( Type * ); ///< \ru Добавить элемент с упорядочиванием по массиву \en Add element with sorting. + Type * Add ( Type *, size_t & indexEnt ); ///< \ru Добавить элемент с упорядочиванием по массиву, возвращает индекс \en Add element with sorting, returns index of the element. + size_t Find( const Type * ); ///< \ru Найти элемент в упорядоченном массиве \en Find an element in ordered array. + void Sort(); ///< \ru Сортировать массив, если не сортирован \en Sort array if it is not sorted + Type * RemoveObj( Type * delObject, DelType del ); ///< \ru Удалить элемент. \en Delete element. + + TEMPLATE_FRIEND void qp_sort TEMPLATE_SUFFIX ( CSPArray & arr ); + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, CSPArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const CSPArray & ref ); + +private: + /// \ru Сортировка с выбором удаляемого элемента из двух одинаковых. \en Sort with the choice of the element to remove from the two identical. + void Sort( LessFuncPtr isLess ); + void operator = ( const CSPArray & ); // \ru запрещено !!! \en forbidden !!! + CSPArray( const CSPArray & other ); // \ru запрещено !!! \en forbidden !!! +}; + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type* CSPArray::Add( Type * el ) +{ + //::qp_sort( *this ); + Sort(); + return SPArray::Add( el ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type* CSPArray::Add( Type * el, size_t & indexEl ) +{ + //::qp_sort( *this ); + Sort(); + return SPArray::Add( el, indexEl ); +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// --- +template +inline size_t /*OV_x64 int*/ CSPArray::Find( const Type * el ) +{ + // ::qp_sort( *this ); + Sort(); + return SPArray::Find( el ); +} + + +//------------------------------------------------------------------------------- +// \ru сортировать массив, если не сортирован \en sort array if it is not sorted +// --- +template +inline void CSPArray::Sort() +{ + if ( m_lessFunc ) + Sort( m_lessFunc ); + else + ::qp_sort( *this ); +} + +//------------------------------------------------------------------------------- +// \ru Сортировать массив с проверкой, какой из двух одинаковых элементов удалять. Для проверки используется сравнительная функция isLess. +// \en Sort an array with checking which of the two identical items to remove. Comparative function isLess used for the checking. +// --- +template +inline void CSPArray::Sort( LessFuncPtr lessFunc ) +{ + if ( !m_sort ) + { + if ( Count() > 1 ) + { + qp_sort_r( *this ); + + // \ru удаление одинаковых \en deletion of similar objects + if ( !m_keepEq ) { + for ( ptrdiff_t i = MaxIndex(); i >= 1; i-- ) { + if ( *operator[](i) == *operator[](i-1) ) { + if ( !lessFunc || lessFunc(*operator[](i), *operator[](i-1)) ) + RemoveInd( i ); + else + RemoveInd( i - 1 ); + } + } + } + } + + m_sort = true; + } +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива (по указателю) \en delete an element from array (by the pointer) +// --- +template +inline Type* CSPArray::RemoveObj( Type *delObject, DelType del ) { + C3D_ASSERT( SPArray::nowDeletedElem == 0 ); // \ru Bременно, для отладки \en Temporarily, for debugging. + size_t i = Find( delObject ); + return ( i != SYS_MAX_T ) ? RemoveInd(i, del) : 0; +} + + +//----------------------------------------------------------------------------- +// \ru Н.Вирт "Алгоритмы и структуры данных" 2е издание, Санкт-Петербург, 2001г., стр.111 \en see N.Wirth "Algorithms and Data Structures" +// --- +template +//OV_x64 void qp_sort_r( CSPArray & arr, ptrdiff_t /*OV_x64 int*/ minInd, ptrdiff_t /*OV_x64 int*/ maxInd ) +void qp_sort_r( CSPArray & arr, size_t minInd = SYS_MAX_T, size_t maxInd = SYS_MAX_T ) +{ +//OV_x64 ===================== + if ( arr.Count() > 1 ) + { + if ( minInd == SYS_MAX_T ) minInd = 0; + if ( maxInd == SYS_MAX_T || maxInd > (size_t)arr.MaxIndex() ) maxInd = (size_t)arr.MaxIndex(); // \ru проверено count > 0 \en chеcked that count > 0 +//OV_x64 ===================== + size_t i = minInd, j = maxInd; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + size_t im = (i + j)/2; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + + Type * middle = arr[im]; + + do { + while( *arr[i] < *middle ) + i++; + while( *middle < *arr[j] ) + j--; + + if ( (ptrdiff_t)i <= (ptrdiff_t)j ) { + if ( i != j ) { + Type * wi = arr[i]; + arr[i] = arr[j]; + arr[j] = wi; + } + i++; + j--; + } + } while( !((ptrdiff_t)i > (ptrdiff_t)j) ); + + + if ( (ptrdiff_t)minInd < (ptrdiff_t)j ) + qp_sort_r( arr, minInd, j ); + if ( (ptrdiff_t)i < (ptrdiff_t)maxInd ) + qp_sort_r( arr, i, maxInd ); + } +} + +template +void qp_sort_r2( Type ** arr, size_t minIndex, size_t maxIndex ) +{ + ptrdiff_t rangeSize = (ptrdiff_t)maxIndex - (ptrdiff_t)minIndex; + if ( rangeSize == 1 ) { + if ( arr[maxIndex] < arr[minIndex] ) { + Type *wi = arr[maxIndex]; + arr[maxIndex] = arr[minIndex]; + arr[minIndex] = wi; + } + } + else if ( rangeSize > 1 ) { + c3d::NumbersPair iterStack[30]; + int stackCount = -1; + + ptrdiff_t minInd = minIndex, maxInd = maxIndex; + ptrdiff_t i = minInd, j = maxInd; + ptrdiff_t im = 0; + Type *middle = NULL; + + for ( ;; ) { + i = minInd, j = maxInd; + im = ( i + j ) / 2; + middle = arr[im]; + + do { + while ( *arr[i] < *middle ) i++; + while ( *middle < *arr[j] ) j--; + if ( i <= j ) { + if ( i != j ) { + Type * wi = arr[i]; + arr[i] = arr[j]; + arr[j] = wi; + } + i++; + j--; + } + } while ( !( i > j ) ); + + if ( j - minInd > maxInd - i ) { + if ( minInd < j ) { + iterStack[++stackCount].first = minInd; + iterStack[stackCount].second = j; + } + + if ( i < maxInd ) { + minInd = i; + continue; + } + } + else { + if ( i < maxInd ) { + iterStack[++stackCount].first = i; + iterStack[stackCount].second = maxInd; + } + + if ( minInd < j ) { + maxInd = j; + continue; + } + } + + if ( stackCount < 0 ) + break; // \ru Все подмассивы обработаны. \en All subarrays are done. + minInd = iterStack[stackCount].first; + maxInd = iterStack[stackCount--].second; + } + } +} + + +template +void qp_sort( CSPArray & arr ) +{ + if ( !arr.m_sort ) { + if ( arr.Count() > 1 ) { + // ptrdiff_t maxIndex = arr.MaxIndex(); // проверено count > 1 \en // verified that count > 1 + //OV_x64qp_sort_r( arr, 0, maxIndex ); + qp_sort_r2( arr.begin(), 0, arr.Count() - 1 ); // C3D-1211 + //qp_sort_r( arr ); + + // \ru удаление одинаковых \en deletion of similar objects + if ( !arr.m_keepEq ) { + for ( ptrdiff_t i = arr.MaxIndex(); i >= 1; i-- ) { // \ru OV_x64 проверено что maxIndex > 0 \en OV_x64 verified that maxIndex > 0 + if ( *arr[i] == *arr[i-1] ) + arr.RemoveInd( i ); + } + } + } + + arr.m_sort = true; + } +} + + +#endif // __TEMPL_CSP_ARRAY_H diff --git a/C3d/Include/templ_css_array.h b/C3d/Include/templ_css_array.h new file mode 100644 index 0000000..f51f89d --- /dev/null +++ b/C3d/Include/templ_css_array.h @@ -0,0 +1,358 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный одномерный массив объектов. + \en Ordered one-dimensional array of objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_CSS_ARRAY_H +#define __TEMPL_CSS_ARRAY_H + + +#include +#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class CSSArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void q_sort( CSSArray & arr, SArray * del ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, CSSArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const CSSArray & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Упорядоченный одномерный массив. + \en Ordered one-dimensional array. \~ + \details \ru Упорядоченный одномерный массив объектов. \n + У объектов массива должны быть операторы "==" и "<". + Имеется возможность добавлять несортированные данные через функцию AddNoSort, + но при первом обращении к функциям Add и Find произойдет сортировка + Одинаковые объекты не добавляются. + \en Ordered one-dimensional array of objects. \n + Elements of the array should have operators "==" and "<". + The unsorted data can be added by the function 'AddNoSort', + but the sorting starts after the first call of functions Add and Find. + The similar objects are not added. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class CSSArray : protected SSArray { + bool m_sort; ///< \ru Признак сортированности массива. \en Attribute of an array being sorted. + +public: + /// \ru Конструктор. \en Constructor. + CSSArray( size_t maxCnt = 0, uint16 delt = 1 ) + : SSArray( maxCnt, delt ) + , m_sort( true ) + {} + /// \ru Конструктор копирования. \en Copy constructor. + CSSArray( const CSSArray & other ) + : SSArray( other ) + , m_sort( other.m_sort ) + {} + /// \ru Конструктор копирования. \en Copy constructor. + CSSArray( const SArray & other, SArray * del = NULL ) + : SSArray( other ) + , m_sort( false ) + { + ::q_sort( *this, del ); + } + /// \ru Конструктор копирования. \en Copy constructor. + CSSArray( const SArray< std::pair > & other, bool addFirst, SArray * del = NULL ) + : SSArray( other.Count(), 1 ) + , m_sort( false ) + { + if ( addFirst ) { + for ( size_t k = 0, cnt = other.Count(); k < cnt; k++ ) + AddNoSort( other[k].first ); + } + else { + for ( size_t k = 0, cnt = other.Count(); k < cnt; k++ ) + AddNoSort( other[k].second ); + } + ::q_sort( *this, del ); + } + + using SSArray::Flush; + using SSArray::HardFlush; + using SSArray::Adjust; + using SSArray::operator[]; + using SSArray::Remove; + using SSArray::RemoveInd; + using SSArray::Count; + using SSArray::MaxIndex; + using SSArray::GetAddr; + using SSArray::GetEndAddr; + using SSArray::Reserve; + using SSArray::SetSize; + using SSArray::SetMaxDelta; + + using SSArray::empty; + using SSArray::size; + using SSArray::reserve; + using SSArray::clear; + + using SSArray::begin; + + void AddNoSort( const Type & ent ) { SSArray::AddSimple( ent ); m_sort = false; } ///< \ru Добавить элемент без сортировки. \en Add element without sorting. + Type * Add ( const Type & ); ///< \ru Добавить элемент с упорядочиванием по массиву. \en Add element with sorting. + Type * Add ( const Type &, size_t & indexEnt ); ///< \ru Добавить элемент с упорядочиванием по массиву, возвращает индекс. \en Add element with sorting by array, returns index of the element. + size_t Find( const Type & ); ///< \ru Найти элемент в упорядоченном массиве. \en Find an element in ordered array. + void Sort( SArray * del = NULL ); ///< \ru Выполнить сортировку элементов массива. \en Sort elements of array. + size_t RemoveObj( const Type & delObject ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + void SetNoSort() { m_sort = false; } ///< \ru Сбросить флаг сортированности. \en Reset the flag of being sorted. + + void AddArray( const CSSArray & arr, bool doSort ); ///< \ru Добавить массив. \en Add array + void AddArray( const SArray & arr, bool doSort ); ///< \ru Добавить массив. \en Add array + bool IsSorted() const {return m_sort; } ///< \ru Вернуть вризнак сортированности массива. \en Return an attribute of an array being sorted. + + TEMPLATE_FRIEND void q_sort TEMPLATE_SUFFIX ( CSSArray & arr, SArray * del ); + + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, CSSArray & ref ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const CSSArray & ref ); + // Intel Compiler 12 // KNOWN_OBJECTS_RW_REF_OPERATORS( CSSArray ) +}; + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type * CSSArray::Add( const Type & el ) { + ::q_sort( *this, (SArray *)NULL ); + return SSArray::Add( el ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type * CSSArray::Add( const Type & el, size_t & indexEl ) { + ::q_sort( *this, (SArray *)NULL ); + return SSArray::Add( el, indexEl ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление массива \en adding of an array +// --- +template +inline void CSSArray::AddArray( const CSSArray & arr, bool doSort ) +{ + if ( this != &arr ) { + m_sort = false; + (*this) += arr; + if ( doSort ) + ::q_sort( *this, (SArray *)NULL ); + } +} + + +//------------------------------------------------------------------------------- +// \ru добавление массива \en adding of an array +// --- +template +inline void CSSArray::AddArray( const SArray & arr, bool doSort ) +{ + if ( this != &arr ) { + m_sort = false; + (*this) += arr; + if ( doSort ) + ::q_sort( *this, (SArray *)NULL ); + } +} + + +//------------------------------------------------------------------------------- +// \ru поиск объека в массиве \en search of an element in array +// --- +template +inline size_t CSSArray::Find( const Type & el ) { + ::q_sort( *this, (SArray *)NULL ); + return SSArray::Find( el ); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void CSSArray::Sort( SArray * del ) { + ::q_sort( *this, del ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline size_t CSSArray::RemoveObj( const Type & delObject ) { + size_t ind = Find( delObject ); + if ( ind != SYS_MAX_T ) + RemoveInd( ind ); + return ind; +} + + +//----------------------------------------------------------------------------- +// \ru Н.Вирт "Алгоритмы и структуры данных" 2е издание, Санкт-Петербург, 2001г., стр.111 \en see N.Wirth "Algorithms and Data Structures" +// --- +template +void q_sort_r( CSSArray & arr, size_t minInd = SYS_MAX_T, size_t maxInd = SYS_MAX_T ) +{ + if ( arr.Count() > 1 ) { + if ( minInd == SYS_MAX_T ) minInd = 0; + if ( maxInd == SYS_MAX_T || maxInd > (size_t)arr.MaxIndex() ) + maxInd = (size_t)arr.MaxIndex(); // \ru проверено count > 0 \en chacked that count > 0 + + size_t i = minInd, j = maxInd; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + size_t im = (i + j)/2; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + + Type * middle = (Type *)new char[sizeof(Type)]; + ::memcpy( middle, &arr[im], sizeof( Type ) ); + + Type * buff = (Type *)new char[sizeof(Type)]; + do { + while( arr[i] < *middle ) i++; + while( *middle < arr[j] ) j--; + if ( (ptrdiff_t)i <= (ptrdiff_t)j ) { + if ( i != j ) { + Type * wi = &arr[i]; + Type * wj = &arr[j]; + ::memcpy( buff, wi, sizeof( Type ) ); + ::memcpy( wi, wj, sizeof( Type ) ); + ::memcpy( wj, buff, sizeof( Type ) ); + } + i++; + j--; + } + } while( !((ptrdiff_t)i > (ptrdiff_t)j) ); + + delete [] (char*)buff; + delete [] (char*)middle; + + if ( (ptrdiff_t)minInd < (ptrdiff_t)j ) + q_sort_r( arr, minInd, j ); + if ( (ptrdiff_t)i < (ptrdiff_t)maxInd ) + q_sort_r( arr, i, maxInd ); + } +} + +//----------------------------------------------------------------------------- +// \ru Аналог q_sort_r без рекурсии. Не требует выделения/освобождения памяти на каждой итерации. +// \en Analog of q_sort_r without recursion. Not require memory allocation/deallocation at each iteration. +// \param arr[out] - \ru Указатель на начало сортируемого участка массива. \en Pointer to the beginning of the array part being sorted. +// \param minIndex[in] - \ru Индекс первого элемента в сортируемом участке массива. \en Index of the first element in the array part being sorted. +// \param maxIndex[in] - \ru Индекс последнего элемента в сортируемом участке массива. \en Index of the last element in the array part being sorted. +// --- +template +void q_sort_r2( Type * arr, size_t minIndex, size_t maxIndex ) +{ + ptrdiff_t rangeSize = (ptrdiff_t)maxIndex - (ptrdiff_t)minIndex; + if ( rangeSize == 1 ) { + if ( arr[maxIndex] < arr[minIndex] ) { + Type * buff = ( Type * )new char[sizeof( Type )]; + Type * w0 = &arr[minIndex]; + Type * w1 = &arr[maxIndex]; + ::memcpy( buff, w1, sizeof( Type ) ); + ::memcpy( w1, w0, sizeof( Type ) ); + ::memcpy( w0, buff, sizeof( Type ) ); + delete[]( char* )buff; + } + } + else if ( rangeSize > 1 ) { + c3d::NumbersPair iterStack[30]; + int stackCount = -1; + + ptrdiff_t minInd = minIndex, maxInd = maxIndex; + ptrdiff_t i = minInd, j = maxInd; + ptrdiff_t im = 0; + + Type * middle = ( Type * )new char[sizeof( Type )]; + Type * buff = ( Type * )new char[sizeof( Type )]; + + for ( ;; ) { + i = minInd, j = maxInd; + im = ( i + j ) / 2; + ::memcpy( middle, &arr[im], sizeof( Type ) ); + + do { + while ( arr[i] < *middle ) i++; + while ( *middle < arr[j] ) j--; + if ( i <= j ) { + if ( i != j ) { + Type * wi = &arr[i]; + Type * wj = &arr[j]; + ::memcpy( buff, wi, sizeof( Type ) ); + ::memcpy( wi, wj, sizeof( Type ) ); + ::memcpy( wj, buff, sizeof( Type ) ); + } + i++; + j--; + } + } while ( !( i > j ) ); + + if ( j - minInd > maxInd - i ) { + if ( minInd < j ) { + iterStack[++stackCount].first = minInd; + iterStack[stackCount].second = j; + } + + if ( i < maxInd ) { + minInd = i; + continue; + } + } + else { + if ( i < maxInd ) { + iterStack[++stackCount].first = i; + iterStack[stackCount].second = maxInd; + } + + if ( minInd < j ) { + maxInd = j; + continue; + } + } + + if ( stackCount < 0 ) + break; // \ru Все подмассивы обработаны. \en All subarrays are done. + minInd = iterStack[stackCount].first; + maxInd = iterStack[stackCount--].second; + } + + delete[]( char* )buff; + delete[]( char* )middle; + } +} + +//----------------------------------------------------------------------------- +// +// --- +template +void q_sort( CSSArray & arr, SArray * del ) +{ + if ( !arr.m_sort ) { + if ( arr.Count() ) { + q_sort_r2( arr.begin(), 0, arr.Count() - 1 ); // C3D-1211 + //q_sort_r( arr ); + + // \ru удаление одинаковых \en deletion of similar objects + for ( ptrdiff_t i = arr.MaxIndex(); i >= 1; i-- ) { // OV_x64 maxIndex >= 0 + if ( arr[i] == arr[i-1] ) { + if ( del ) + del->Add( arr[i] ); + arr.RemoveInd( i ); + } + } + } + + arr.m_sort = true; + } +} + + +#endif // __TEMPL_CSS_ARRAY_H diff --git a/C3d/Include/templ_delete_define.h b/C3d/Include/templ_delete_define.h new file mode 100644 index 0000000..657786d --- /dev/null +++ b/C3d/Include/templ_delete_define.h @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Типы удаления элементов из массива. + \en Types of deletion of elements from array. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_DELETE_DEFINE_H +#define __TEMPL_DELETE_DEFINE_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы удаления элементов. + \en Types of elemets deletion. \~ + \details \ru Типы удаления элементов при удалении из массива. + \en Types of elements deletion while the deletion from an array. \~ + \ingroup Base_Tools +*/ +// --- +enum DelType { + defDelete, ///< \ru Удалять объект по умолчанию. \en Delete an object by default. + noDelete, ///< \ru Не удалять объект. \en Do not delete an object. + Delete ///< \ru Удалять объект. \en Delete an object. +}; + + +#endif // __TEMPL_DELETE_DEFINE_H diff --git a/C3d/Include/templ_dptr.h b/C3d/Include/templ_dptr.h new file mode 100644 index 0000000..94f46ad --- /dev/null +++ b/C3d/Include/templ_dptr.h @@ -0,0 +1,186 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Автоматический указатель на объекты, не имеющие счетчиков ссылок. + \en Smart pointer to objects without reference counters. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_DPTR_H +#define __TEMPL_DPTR_H + + +#ifndef NULL + #define NULL 0 +#endif + + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель. + \en Smart pointer. \~ + \details \ru Автоматический указатель на объекты, не имеющие счетчиков ссылок. \n + \en Smart pointer to objects without reference counters. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class DPtr { +public: + /// \ru Конструктор. \en Constructor. + DPtr(); + /// \ru Конструктор по указателю на объект. \en Constructor by pointer to an object. + DPtr( dtype * obj ); + /// \ru Конструктор по автоматическому указателю на объект. \en Constructor by smart pointer to an object. + DPtr( const DPtr & dptr ); + /// \ru Деструктор. \en Destructor. + ~DPtr(); + +public: + /// \ru Оператор доступа. \en An access operator. + operator dtype* ( void ) const { return m_Ptr; } + /// \ru Оператор доступа. \en An access operator. + dtype & operator * ( void ) const { return *m_Ptr; } + /// \ru Оператор доступа. \en An access operator. + dtype * operator -> ( void ) const { return m_Ptr; } + /// \ru Оператор присваивания. \en The assignment operator. + DPtr & operator = ( dtype * pObj ); + /// \ru Оператор присваивания. \en The assignment operator. + DPtr & operator = ( const DPtr & src ); + /// \ru Оператор равенства. \en The equality operator. + bool operator == ( const DPtr & src ) const { return ( m_Ptr == src.m_Ptr ); } + /// \ru Оператор равенства. \en The equality operator. + bool operator == ( dtype * pObj ) const { return ( m_Ptr == pObj ); } + /// \ru Оператор неравенства. \en The inequality operator. + bool operator != ( const DPtr & src ) const { return ( !(operator == (src )) ); } + /// \ru Оператор неравенства. \en The inequality operator. + bool operator != ( dtype * pObj ) const { return ( !(operator == (pObj)) ); } + +private: + /// \ru Счетчик ссылок на объект. \en A counter of references to an object. + template + struct Owner { + dtype1 * m_Ptr; + uint m_RefCounter; + + Owner( dtype1 * obj ) + : m_Ptr( obj ) + , m_RefCounter(0) + {} + ~Owner() + { + PRECONDITION( m_RefCounter == 0 ); + delete m_Ptr; + } + void Release() + { + if ( m_RefCounter-- == 1 ) + delete this; + } + }; + +private: + dtype * m_Ptr; ///< \ru Указатель на объект. \en A pointer to an object. + Owner * m_Owner; ///< \ru Счетчик ссылок на объект. \en A counter of references to an object. +}; + + +//------------------------------------------------------------------------------- +/// \ru Конструктор. \en Constructor. +// --- +template +DPtr::DPtr() + : m_Ptr ( NULL ) + , m_Owner( NULL ) +{ +} + + +//------------------------------------------------------------------------------- +// \ru Конструктор по указателю на объект. \en Constructor by pointer to an object. +// --- +template +DPtr::DPtr( dtype * obj ) + : m_Ptr ( obj ) + , m_Owner( NULL ) +{ + if ( obj != NULL ) { + m_Owner = new Owner( obj ); + m_Owner->m_RefCounter++; + } +} + + +//------------------------------------------------------------------------------- +// \ru Конструктор копирования. \en Copy constructor. +// --- +template +DPtr::DPtr( const DPtr & dptr ) + : m_Ptr( dptr.m_Ptr ) + , m_Owner( dptr.m_Owner ) +{ + if ( m_Owner != NULL ) + m_Owner->m_RefCounter++; +} + + +//------------------------------------------------------------------------------- +// \ru Оператор присваивания. \en Assignment operator. +// --- +template +DPtr & DPtr::operator = ( dtype * pObj ) +{ + if ( m_Ptr != pObj ) { + m_Ptr = pObj; + if ( m_Owner != NULL ) { + m_Owner->Release(); + m_Owner = NULL; + } + if ( pObj != NULL ) { + m_Owner = new Owner( pObj ); + m_Owner->m_RefCounter++; + } + } + + return *this; +} + + +//------------------------------------------------------------------------------- +// \ru Оператор присваивания. \en Assignment operator. +// --- +template +DPtr & DPtr::operator = ( const DPtr & dptr ) +{ + if ( m_Ptr != dptr.m_Ptr ) { + m_Ptr = dptr.m_Ptr; + if ( m_Owner != NULL ) { + m_Owner->Release(); + m_Owner = NULL; + } + if ( dptr.m_Ptr != NULL ) { + m_Owner = dptr.m_Owner; + m_Owner->m_RefCounter++; + } + } + + return *this; +} + + +//------------------------------------------------------------------------------- +// \ru Деструктор. \en Destructor. +// --- +template +DPtr::~DPtr() +{ + if ( m_Owner ) + m_Owner->Release(); +} + + +#endif // __TEMPL_DPTR_H diff --git a/C3d/Include/templ_fdp_array.h b/C3d/Include/templ_fdp_array.h new file mode 100644 index 0000000..089ed17 --- /dev/null +++ b/C3d/Include/templ_fdp_array.h @@ -0,0 +1,358 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Одномерный массив указателей. + \en One-dimensional array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_FDP_ARRAY_H +#define __TEMPL_FDP_ARRAY_H + + +#include +#include +#include +#include +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class FDPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void destroy_array ( FDPArray & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool set_Farray_size( FDPArray &, size_t newSize, bool clear ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, FDPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const FDPArray & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей. + \en One-dimensional array of pointers. \~ + \details \ru Одномерный массив указателей на объекты. \n + Можно использовать для классов с указателями. Удаление объектов производится через функцию удаления. \n + Внимание! Удаление объектов в больших массивах выполняется медленнее, чем в PArray. \n + Чтобы избежать потери времени, надо использовать Clear( TotalDestroyFunc ). + \en One-dimensional array of pointers to objects. \n + It may be used for the classes with pointers. Deletion of objects is performed by the function of deletion. \n + Attention! Destructing of large arrays is performed slower than in PArray. \n + In order to avoid of losing time Clear( TotalDestroyFunc ) should be used. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class FDPArray : public RPArray { +public : + typedef void (*TotalDestroyFunc)( const Type**, size_t ); // \ru функция удаления ВСЕГО массива, работает значительно быстрее \en the function of deletion of THE WHOLE array, it works significantly faster. + typedef bool (*DestroyFunc)( Type * ); // \ru функция удаления вместо флага fDestroy \en the function of deletion instead of the "tDestroy" flag + +protected : + DestroyFunc fDestroy; // \ru функция удаления вместо флага owns \en the function of deletion instead of the flag 'owns' + + Type * nowDeletedElem; // \ru Bременно \en Temporarily + +public : + /// \ru Конструктор. \en Constructor. + FDPArray() + : RPArray() + , fDestroy( NULL ) + , nowDeletedElem(0) + {} + /// \ru Конструктор. \en Constructor. + FDPArray( size_t i_upper, uint16 i_delta, DestroyFunc fd ) + : RPArray( i_upper, i_delta) + , fDestroy( fd ) + , nowDeletedElem(0) + {} + /// \ru Деструктор. \en Destructor. + virtual ~FDPArray(); + + /// \ru Установлена ли функция удаления элементов? \en Whether a function of deletion of elements is set? + bool OwnsElem() const { return !!fDestroy; } + /// \ru Установить функцию удаления элементов. \en Set a function of deletion of elements. + void OwnsElem( DestroyFunc fd ) { fDestroy = fd; } + + /// \ru Функции, выделяющие потенциально большие участки памяти, возвращают результат операции (успех/ошибка). + /// \en Functions that allocate potentially large memory, return an operation result (success/error). + bool SetSize ( size_t newSize, bool clear ); ///< \ru Указать новый размер массива. \en Set the new size of an array. + + void Flush( DelType = defDelete ); ///< \ru Удалить все элементы. \en Delete all elements. + void Clear( TotalDestroyFunc ); ///< \ru Удалить все элементы. \en Delete all elements. + + Type * RemoveObj( Type * delObject, DelType del = defDelete ); ///< \ru Удалить элемент из массива по указателю. \en Delete an element from array by the pointer. + virtual Type * RemoveInd( size_t delIndex, DelType del = defDelete ); ///< \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + + Type * DestroyInd( size_t delIndex, DestroyFunc ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + Type * DestroyObj( Type *delObject, DestroyFunc ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + +public: // \ru унификация с вектором STL \en unification with STL vector + virtual void clear() { Flush(); } ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + +private: + FDPArray( const FDPArray & ); // \ru запрещено !!! \en forbidden !!! + FDPArray & operator = ( const FDPArray & ); // \ru запрещено !!! \en forbidden !!! + + TEMPLATE_FRIEND void destroy_array TEMPLATE_SUFFIX ( FDPArray & ); + TEMPLATE_FRIEND bool set_Farray_size TEMPLATE_SUFFIX ( FDPArray &, size_t newSize, bool clear ); + + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, FDPArray & ref ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const FDPArray & ref ); + // Intel Compiler 12 // KNOWN_OBJECTS_RW_PTR_OPERATORS( FDPArray ) + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + FDPArray( FDPArray && ); ///< \ru Конструктор перемещения массива. \en Constructor of an array moving. + FDPArray & operator = ( FDPArray && ); ///< \ru Оператор перемещения массива. \en Operator of an array moving. +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * FDPArray::operator new( size_t size ) { + return ::Allocate( size, typeid(FDPArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void FDPArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(FDPArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +//------------------------------------------------------------------------------ +// \ru Конструктор перемещения массива. \en Constructor of an array moving. +// --- +template +FDPArray::FDPArray( FDPArray && _Right ) + : RPArray (std::move(_Right) ) + , fDestroy ( std::move(_Right.fDestroy) ) + , nowDeletedElem( std::move(_Right.nowDeletedElem) ) +{ + _Right.fDestroy = nullptr; + _Right.nowDeletedElem = nullptr; +} + +//------------------------------------------------------------------------------ +// \ru Оператор перемещения массива. \en Operator of an array moving. +// --- +template +FDPArray & FDPArray::operator = ( FDPArray && _Right ) +{ + if ( this != &_Right ) + { + destroy_array( *this ); + std::swap ( fDestroy, _Right.fDestroy ); + std::swap ( nowDeletedElem, _Right.nowDeletedElem ); + RPArray::operator = ( std::move(_Right) ); + } + return (*this); +} +#endif // STANDARD_CPP11_RVALUE_REFERENCES +//------------------------------------------------------------------------------ +// \ru деструктор массива \en destructor of array +// --- +template +inline FDPArray::~FDPArray() { + PRECONDITION( nowDeletedElem == 0 ); + + destroy_array( *this ); +} + + +//------------------------------------------------------------------------------ +// \ru обнулить количество элементов \en set the number of elements to null. +// --- +template +inline void FDPArray::Flush( DelType del ) { + PRECONDITION( nowDeletedElem == 0 ); + + if ( del==Delete || (del==defDelete && fDestroy) ) + destroy_array( *this ); + else + RPArray::count = 0; +} + + +//------------------------------------------------------------------------------ +// \ru обнулить количество элементов \en set the number of elements to null. +// --- +template +inline void FDPArray::Clear( typename FDPArray::TotalDestroyFunc fd ) { + PRECONDITION( nowDeletedElem == 0 ); + + size_t oldCount = RPArray::count; + RPArray::count = 0; // \ru сначала приведем в порядок массив ... \en put an array in order at first ... + + if ( fd ) + (*fd)( RPArray::GetAddr()/*parr*/, oldCount ); // \ru ...а потом будем удалять \en ... and then delete +} + + +//------------------------------------------------------------------------------ +// \ru указать новый размер массива \en set the new size of an array. +// \ru если clear = true, то массив очистится !!! \en if 'clear' is true than the array will be cleared !!! +// --- +template +inline bool FDPArray::SetSize( size_t newSize, bool clear ) { + return set_Farray_size( *this, newSize, clear ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type* FDPArray::RemoveInd( size_t delIndex, DelType del ) { + PRECONDITION( delIndex < RPArray::count ); + + const Type **d = RPArray::GetAddr() + delIndex; + + Type *r = (Type*) *d; + + // \ru сначала приведем в порядок массив ... \en put an array in order at first ... + memmove( d, d+1, (RPArray::count - delIndex - 1) * SIZE_OF_POINTER ); + RPArray::count--; + + // \ru ...а потом будем удалять \en ... and then delete + if ( fDestroy && (del==Delete || del==defDelete) ) { + PRECONDITION( !r || nowDeletedElem != r ); + nowDeletedElem = r; + + (*fDestroy)(r); + r = 0; + + nowDeletedElem = 0; + } + + return r; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type * FDPArray::RemoveObj( Type * delObject, DelType del ) +{ + PRECONDITION( nowDeletedElem == 0 ); + size_t i = find_in_array( *this, delObject ); + return (i != SYS_MAX_T) ? RemoveInd(i, del) : 0; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type* FDPArray::DestroyInd( size_t delIndex, typename FDPArray::DestroyFunc fd ) { + PRECONDITION( delIndex < RPArray::count ); + + const Type **d = RPArray::GetAddr() + delIndex; + + Type *r = (Type*) *d; + + // \ru сначала приведем в порядок массив ... \en put an array in order at first ... + memmove( d, d+1, (RPArray::count - delIndex - 1) * SIZE_OF_POINTER ); + RPArray::count--; + + // \ru ...а потом будем удалять \en ... and then delete + if ( fd ) { + PRECONDITION( !r || nowDeletedElem != r ); // \ru Bременно, для отладки \en Temporarily, for debugging. + nowDeletedElem = r; + + (*fd)(r); + r = 0; + + nowDeletedElem = 0; + } + + return r; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type * FDPArray::DestroyObj( Type * delObject, typename FDPArray::DestroyFunc fd ) +{ + PRECONDITION( nowDeletedElem == 0 ); + size_t i = find_in_array( *this, delObject ); + return ( i != SYS_MAX_T ) ? DestroyInd( i, fd ) : 0; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +void destroy_array( FDPArray & arr ) +{ + size_t oldCount = arr.count; + arr.count = 0; + + if ( arr.fDestroy ) { + size_t i = 0; + for ( const Type **parr = arr.GetAddr(); i < oldCount; i++, parr++ ) { + + Type *del = (Type*)*parr; + *parr = 0; // \ru сначала обнулить... \en set to null at first... + + PRECONDITION( !del || arr.nowDeletedElem != del ); // \ru Bременно, для отладки \en Temporarily, for debugging. + arr.nowDeletedElem = del; + + (*arr.fDestroy)( del ); // \ru ...потом удалить \en ... then delete + + arr.nowDeletedElem = 0; + } + } +} + + +//------------------------------------------------------------------------------ +// +// --- +template +bool set_Farray_size( FDPArray & arr, size_t newSize, bool clear ) +{ + PRECONDITION( arr.nowDeletedElem == 0 ); + + if ( clear && arr.count ) + arr.Flush(); // \ru будет arr.count = 0; \en arr.count will be equal 0; + + if ( newSize < arr.count ) { // \ru нужно удалить лишние элементы массива \en it is necessary to delete extra elements from the array + if ( arr.fDestroy ) { + if ( newSize == 0 ) { + if ( arr.count ) + arr.Flush(); // \ru будет arr.count = 0; \en arr.count will be equal 0; + } + else + while ( arr.count > newSize ) + arr.RemoveInd( arr.count - 1 ); // \ru удалить элемент из массива (по индексу), count-- \en delete an element from array (by the index), count-- + } + + arr.count = newSize; + } + + return set_Rarray_size( arr, newSize ); +} + + +#endif // __TEMPL_FDP_ARRAY_H diff --git a/C3d/Include/templ_fdp_array_.h b/C3d/Include/templ_fdp_array_.h new file mode 100644 index 0000000..905ae99 --- /dev/null +++ b/C3d/Include/templ_fdp_array_.h @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cтандартные реализации функций удаления элементов для FDPArray'а. + \en Standard implementations of FDPArray elements deletion functions. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_FDP_ARRAY__H +#define __TEMPL_FDP_ARRAY__H + +#include + + +//------------------------------------------------------------------------------ +// \ru функция удаления одного элемента \en function of one element deletion +// --- +template +inline bool FDPArray_Destroy( Type *el ) { + delete el; + return true; +} + + +//------------------------------------------------------------------------------ +// \ru функция удаления всех элементов \en function of all elements deletion +// --- +template +void FDPArray_TotalDestroy( const Type **arr, size_t count ) { + if ( arr ) { + size_t i = 0; + for( const Type** parr = arr; i < count; i++, parr++ ) { + Type *del = (Type*)*parr; + *parr = 0; // \ru Cначала обнулить ... \en Set to null at first... + delete del; // \ru ... потом удалить \en ... then delete + } + } +} + + +//------------------------------------------------------------------------------ +// \ru функция освобождения одного элемента (true означает, что el деструктурирован) \en function of one element release (returns true if 'el' has been destructured) +// --- +template +inline bool FDPArray_Release( Type *el ) { + if ( el ) + return (el->Release() == 0); + + return true; +} + + +//------------------------------------------------------------------------------ +// \ru функция освобождения всех элементов \en function of all elements release +// --- +template +void FDPArray_TotalRelease( const Type **arr, size_t count ) { + if ( arr ) { + for ( const Type** parr = arr, **last = arr + count; parr < last; ++parr ) + { + Type *del = (Type*)*parr; + *parr = 0; // \ru Cначала обнулить ... \en Set to null at first... + if ( del ) + del->Release(); // \ru ... потом удалить \en ... then delete + } + } +} + + +#endif // __TEMPL_FDP_ARRAY__H diff --git a/C3d/Include/templ_fdp_array_rw.h b/C3d/Include/templ_fdp_array_rw.h new file mode 100644 index 0000000..4587d92 --- /dev/null +++ b/C3d/Include/templ_fdp_array_rw.h @@ -0,0 +1,178 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация FDPArray. + \en Serialization of FDPArray. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_FDP_ARRAY_RW_H +#define __TEMPL_FDP_ARRAY_RW_H + + +#include +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru при записи FDPArray владение не записывается т.к. не умею записывать \en while writing FDPArray ownership is not written +// \ru адрес функции удаления элементов. \en addess of elements deletion function. +// \ru После чтения адрес функции удаления элементов придется выставлять вручную \en After reading the address of elements deletion function should be set manually +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в объект (на добавление объектов к существующему массиву не рассчитано) \en reading of array from a stream to an object (adding new objects to an existed array is not supported) +// --- +template +reader & operator >> ( reader & in, FDPArray & ref ) +{ + ref.Flush(); + + if ( in.good() ) { + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + + if ( in.good() ) + { + if ( count ) + { + // \ru половина адресного пространства для 32-разрядного приложения \en a half of address space for 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, count ) ) + { + ref.SetSize( count, true/*clear*/ ); + + const Type ** parr = ref.GetAddr(); + + if ( parr != NULL ) { + size_t i; + // \ru поочередное чтение объектов массива \en successive reading of objects from an array + for ( i = 0; i < count && in.good(); i++ ) { + Type * el = NULL; + in >> el; + parr[i] = el; + } + ref.count = i; // \ru сколько штук реально прочитано \en the number of read objects + } + else { + ref.SetSize( 0, true/*clear*/ ); + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); + } + } + else { + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не бывает столько памяти \en incorrect size of memory + } + } + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer & operator << ( writer & out, const FDPArray & ref ) +{ + WriteCOUNT( out, ref.count ); + + const Type **parr = ref.GetAddr(); + for ( size_t i = 0; i < ref.count && out.good(); i++ ) { + Type * el = (Type *)parr[i]; + out << el; + } + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в указатель \en reading of array from a stream to a pointer +// --- +template +reader & operator >> ( reader & in, FDPArray *& ptr ) +{ + ptr = NULL; + if ( in.good() ) { + if ( in.MathVersion() < 0x06000012L ) + ptr = new FDPArray; + else { + uint8 existPtr = 0; + in >> existPtr; + if ( existPtr ) + ptr = new FDPArray; + } + + if ( ptr ) + in >> *ptr; + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из указателя \en writing of array from a pointer to a stream +// --- +template +writer & operator << ( writer & out, const FDPArray * ptr ) +{ + // \ru при записи в старую версию оставляю без проверки указателя \en While writing to an old version the pointer is not checked + if ( out.MathVersion() < 0x06000012L ) { + C3D_ASSERT( ptr ); + out << *ptr; + } + else { + uint8 existPtr = !!ptr; + out << existPtr; + if ( existPtr ) + out << *ptr; // \ru запись телом \en writing by a solid + } + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru Т.к. наследование от базового класса сделано private, то делаю доступ к оператору базового класса. +// \en Since there is a private inheritance from the base class, I give an access to the operator of the base class. +// --- +template +reader & operator >> ( reader & in, SFDPArray & ref ) { + return in >> (FDPArray &)ref; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта. Т.к. наследование от базового класса сделано private, то делаю доступ к оператору базового класса. +// \en Writing of array from an object to a stream. Since there is a private inheritance from the base class, I give an access to the operator of the base class. +// --- +template +writer & operator << ( writer & out, const SFDPArray & ref ) { + return out << (const FDPArray &)ref; +} + + +// ----------------------------------------------------------------------------- +// \ru удаление всех габаритов - функция удаления массива указателей \en deletion of all bounding boxes - the function of deletion of pointers array +// --- +template +static void TotalDestroy( Type ** arr, size_t count ) { + if ( arr ) { + size_t i = 0; + for ( Type** parr = arr; i < count; i++, parr++ ) { + Type *del = *parr; + *parr = NULL; // \ru Cначала обнулить ... \en Set to null at first... + delete del; // \ru ... потом удалить \en ... then delete + } + } +} + + +#endif // __TEMPL_FDP_ARRAY_RW_H diff --git a/C3d/Include/templ_ifc_array.h b/C3d/Include/templ_ifc_array.h new file mode 100644 index 0000000..22618be --- /dev/null +++ b/C3d/Include/templ_ifc_array.h @@ -0,0 +1,310 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Одномерный массив указателей с подсчетом ссылок. + \en One-dimensional array of pointers with counting of references. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_IFC_ARRAY_H +#define __TEMPL_IFC_ARRAY_H + + +#include +#include +#include +//#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class IFC_Array ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, IFC_Array & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const IFC_Array & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей с подсчетом ссылок. + \en One-dimensional array of pointers with counting of references. \~ + \details \ru Одномерный массив указателей с подсчетом ссылок. \n + У объектов должны быть функции AddRef и Release. + \en One-dimensional array of pointers with counting of references. \n + Objects should have functions AddRef and Release. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class IFC_Array : private RPArray +{ +public: + typedef Type * stored_type; ///< \ru Имя для указателя на объект. \en A name of the pointer to the object. + typedef Type * & reference; + typedef Type * const & const_reference; + + /// \ru Константный итератор (новые функции можно добавлять по мере необходимости). \en A constant iterator (new functions can be added as necessary) + class iterator + { + public: + typedef std::forward_iterator_tag iterator_category; + typedef const Type* value_type; + typedef ptrdiff_t difference_type; + typedef const value_type * pointer; + + public: + iterator() { m_curr = NULL; } + iterator( const stored_type * ptr ) { m_curr = ptr; } + iterator( const iterator & iter ) { m_curr = iter.m_curr; } + stored_type operator*() const { return *m_curr; } + // \ru Префиксный инкремент \en A prefix increment + iterator & operator++() + { + ++m_curr; + return *this; + } + bool operator == ( const iterator & iter ) + { + return iter.m_curr == m_curr; + } + bool operator != ( const iterator & iter ) + { + return iter.m_curr != m_curr; + } + iterator & operator = ( const iterator& iter ) + { + m_curr = iter.m_curr; + return *this; + } + + private: + const stored_type * m_curr; ///< \ru Указатель на указатель на объект \en A pointer to the pointer to the object + }; + +public: + /// \ru Конструктор. \en Constructor. + IFC_Array() + : RPArray( 0, 1 ) + {} + /// \ru Конструктор копирования. \en Copy constructor. + IFC_Array( const IFC_Array & init ) + : RPArray( 0, 1 ) + { + RPArray::AddArray( init ); + for ( size_t idx = Count(); idx != 0; ) { + RPArray::operator[](--idx)->AddRef(); + } + } + /// \ru Конструктор. \en Constructor. + IFC_Array( size_t i_upper, uint16 i_delta ) + : RPArray( i_upper, i_delta ) + {} + /// \ru Деструктор. \en Destructor. + ~IFC_Array(); + +public: + /// \ru Добавить элемент с повышением счетчика ссылок. \en Add an element with increase of the reference counter. + void Add( stored_type ); + /// \ru Итератор начала. \en An iterator of the beginning. + iterator Begin() const { return iterator(RPArray::begin()); } + /// \ru Итератор конца. \en An iterator of the end. + iterator End() const { return iterator(RPArray::end()); } + /// \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + void AddAt( stored_type, size_t ); + /// \ru Вставить элемент после указанного. \en Insert an element after the specified one. + void AddAfter( stored_type, size_t ); + /// \ru Задать i-му элементу новое значение. \en Set a new value for the i-th element. + void SetAt( stored_type, size_t ); + /// \ru Поменять местами значения двух элементов массива. \en Swap values of two elements of an array. + void Exchange( size_t, size_t ); + /// \ru Удалить первый найденый элемент из массива. \en Remove a first founded element from an array. + stored_type RemoveObj ( stored_type ); + /// \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + stored_type RemoveInd ( size_t ); + /// \ru Очистить массив. \en Clear the array. + void Flush(); + /// \ru Индексированный доступ (принципиально выдается элемент массива, а не ссылка на него). \en indexed access (returns an element of an array but not the reference to it) + const_reference operator []( size_t idx ) const { return RPArray::at(idx); } + +public: // \ru Стандартные функции контейнерного типа. \en Standard functions of container type. + using RPArray::empty; + using RPArray::size; + using RPArray::capacity; + using RPArray::reserve; + /// \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const stored_type * begin () const { return RPArray::begin(); } + ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + const stored_type * end() const { return RPArray::end(); } + + +public: // \ru Доступные методы от RPArray \en Available methods from RPArray + using RPArray::Adjust; + using RPArray::Count; + using RPArray::Upper; + using RPArray::MaxIndex; + using RPArray::FindIt; + using RPArray::IsExist; + using RPArray::Reserve; + using RPArray::SetMaxDelta; + using RPArray::Sort; + using RPArray::GetLast; + +private: + IFC_Array & operator = ( const IFC_Array & ); // \ru Реализовать по необходимости \en Implement if necessary + + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, IFC_Array & ref ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const IFC_Array & ref ); + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + IFC_Array( IFC_Array && ); ///< \ru Конструктор перемещения массива. \en Constructor of an array moving. + IFC_Array & operator = ( IFC_Array && ); ///< \ru Оператор перемещения массива. \en Operator of an array moving. +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + +//------------------------------------------------------------------------------ +// \ru функция освобождения одного элемента (true означает, что el деструктурирован) \en function of one element release (returns true if 'el' has been destructured) +// --- +template +inline void IFCArray_Release( Type * & el ) +{ + if ( el != NULL && el->Release() == 0 ) + { + // AS K11 27.05.2008 Обнулять, только если объект действительно удален. + el = NULL; + } +} + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +//------------------------------------------------------------------------------ +// \ru Конструктор перемещения массива. \en Constructor of an array moving. +// --- +template +inline IFC_Array::IFC_Array(IFC_Array && _Right) + : RPArray( std::move(_Right) ) +{ +} + +//------------------------------------------------------------------------------ +// \ru Оператор перемещения массива. \en Operator of an array moving. +// --- +template +IFC_Array & IFC_Array::operator = ( IFC_Array && _Right ) +{ + if (this != &_Right) + { + std::for_each( RPArray::begin(), RPArray::end(), IFCArray_Release ); + RPArray::operator = ( std::move(_Right) ); + } + return (*this); +} +#endif // STANDARD_CPP11_RVALUE_REFERENCES + +//------------------------------------------------------------------------------ +// \ru Деструктор массива. \en Destructor of array +// --- +template +inline IFC_Array::~IFC_Array() +{ + std::for_each( RPArray::begin(), RPArray::end(), IFCArray_Release ); +} + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент в конец массива \en add 1 element at the end of array +// --- +template +inline void IFC_Array::Add( Type* ent ) { + if ( ent != NULL ) + ent->AddRef(); + RPArray::Add( ent ); +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент перед указанным \en insert element before the specified one +// --- +template +inline void IFC_Array::AddAt( stored_type ent, size_t ind ) { + if ( ent != NULL ) + ent->AddRef(); + RPArray::AddAt( ent, ind ); +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент после указанного \en insert element after the specified one +// --- +template +inline void IFC_Array::AddAfter( stored_type ent, size_t ind ) { + if ( ent != NULL ) + ent->AddRef(); + RPArray::AddAfter( ent, ind ); +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент перед указанным \en insert element before the specified one +// --- +template +inline void IFC_Array::SetAt( stored_type ent, size_t ind ) { + if ( ent != NULL ) + ent->AddRef(); + Type * & el = RPArray::operator[](ind); + if ( el != NULL ) + el->Release(); + el = ent; +} + + +//------------------------------------------------------------------------------ +// \ru Поменять значения двух элементов массива местами \en Swap values of two elements of an array. +//--- +template +inline void IFC_Array::Exchange( size_t ind1, size_t ind2 ) { + if ( ind1 != ind2 ) { + Type * value = RPArray::operator[](ind2); + RPArray::operator[](ind2) = RPArray::operator[](ind1); + RPArray::operator[](ind1) = value; + } +} + + +//------------------------------------------------------------------------------ +/// \ru Удалить элемент из массива по индексу \en Delete an element from array by the index +// --- +template +inline Type * IFC_Array::RemoveInd( size_t delIndex ) +{ + PRECONDITION( delIndex < RPArray::count ); + + stored_type * d = RPArray::begin() + delIndex; + + stored_type r = *d; + + memmove( d, d+1, (RPArray::count - delIndex - 1) * SIZE_OF_POINTER ); + RPArray::count--; + IFCArray_Release( r ); + return r; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива. \en delete an element from array. +// --- +template +inline Type * IFC_Array::RemoveObj( stored_type delObject ) +{ + size_t i = find_in_array( *(RPArray*)this, delObject ); + return (i != SYS_MAX_T) ? RemoveInd(i) : 0; +} + + +//------------------------------------------------------------------------------ +// \ru обнулить количество элементов \en set the number of elements to null. +// --- +template +inline void IFC_Array::Flush() +{ + std::for_each( RPArray::begin(), RPArray::end(), IFCArray_Release ); + RPArray::DetachAll(); +} + + +#endif // __TEMPL_IFC_ARRAY_H diff --git a/C3d/Include/templ_ifc_array_rw.h b/C3d/Include/templ_ifc_array_rw.h new file mode 100644 index 0000000..2e0b534 --- /dev/null +++ b/C3d/Include/templ_ifc_array_rw.h @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация IFC_Array. + \en Serialization of IFC_Array. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_IFC_ARRAY_RW_H +#define __TEMPL_IFC_ARRAY_RW_H + + +#include +#include + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в объект (на добавление объектов к существующему массиву) \en reading of array from a stream to an object (adding new objects to an existed array is not supported) +// --- +template +reader & operator >> ( reader& in, IFC_Array & ref ) +{ + ref.Flush(); + if ( in.good() ) { + const size_t count = ReadCOUNT( in, true/*uint_val*/ ); + + if ( in.good() ) + { + if ( count ) + { + // \ru половина адресного пространства для 32-разрядного приложения \en a half of address space for 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, count ) ) + { + ref.Reserve( count, false ); + C3D_ASSERT( ref.Count() == 0 && ref.Upper() == count ); + + for ( size_t i = 0; i < count && in.good(); ++i ) + { + Type * el = 0; + in >> el; + if ( in.good() ) + ref.Add( el ); + } + + if ( ref.Count() != count ) + { + ref.Flush(); + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); + } + } + else { + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не бывает столько памяти \en incorrect size of memory + } + } + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer & operator << ( writer& out, const IFC_Array & ref ) +{ + WriteCOUNT( out, ref.count ); + if ( out.good() ) + { + const Type **parr = ref.GetAddr(); + for ( size_t i = 0; i < ref.count && out.good(); i++ ) + { + out << parr[i]; + } + } + return out; +} + + +#endif // __TEMPL_IFC_ARRAY_RW_H diff --git a/C3d/Include/templ_im_array.h b/C3d/Include/templ_im_array.h new file mode 100644 index 0000000..12a79f6 --- /dev/null +++ b/C3d/Include/templ_im_array.h @@ -0,0 +1,653 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный массив индексов присланного PArray. + \en Ordered array of indices of the given PArray. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_IM_ARRAY_H +#define __TEMPL_IM_ARRAY_H + + +#include +#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class IMArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * add_to_array ( IMArray &, size_t ind, size_t * ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t add_to_array ( IMArray &, Type * el, size_t * ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_in_array ( const IMArray &, const void *, size_t * ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void array_remove_ind ( IMArray &, size_t delIndex, bool completely ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void array_remove_obj ( IMArray &, const size_t & delObj, bool completely ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_my_index ( const IMArray &, size_t ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * reindex_array_obj ( IMArray &, size_t ind, size_t * myIndex ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t reindex_array_obj ( IMArray &, Type * el, size_t * myIndex ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * reindex_array_ind ( IMArray &, size_t myIndex ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool exchange_to_array ( IMArray &, size_t ind1, size_t ind2 ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void reindexall_to_array ( IMArray & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void array_reduction_obj ( IMArray & arr, const size_t & delObject ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, IMArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const IMArray & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Упорядоченный массив индексов присланного PArray. + \en Ordered array of indices of the given PArray. \~ + \details \ru Упорядоченный массив индексов присланного PArray. \n + \en Ordered array of indices of the given PArray. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class IMArray : private SArray { +public : + typedef int (Type::*Compare_t)( const Type * ); + typedef int (Type::*Compare_v)( const void * ); + + PArray & array; + Compare_t compT; // \ru функция сортировки используется при добавлении объекта \en sorting function is used while adding an object + Compare_v compV; // \ru функция сортировки используется при поиске объекта \en sorting function is used while search an object + +public: + IMArray( PArray< Type > & arr, Compare_t c_t, Compare_v c_v, size_t maxCnt = 0, uint16 delt = 1 ); + + using SArray::Flush; + using SArray::Count; + using SArray::Sort; // \ru сортировать массив \en sort the array + using SArray::Reserve; + using SArray::SetSize; + + Type * Add( size_t ind, size_t * ); // \ru добавить элемент с упорядочиванием по массиву \en add element with sorting + size_t Add( Type * ent, size_t * ); // \ru добавить элемент с упорядочиванием по массиву \en add element with sorting + + Type * operator [] ( size_t ) const; + size_t & operator () ( size_t ) const; + IMArray & operator = ( const IMArray & ); + + size_t Find ( const void *, size_t * ) const; // \ru найти элемент в упорядоченном массиве \en find an element in ordered array + size_t GetIndex ( size_t myIndex ) const; + size_t GetMyIndex( size_t parentIndex ) const; + + void RemoveInd ( size_t delIndex, bool completely = true ); // \ru удалить элемент из массива \en delete an element from array + void RemoveObj ( const size_t & delObject, bool completely = true ); // \ru удалить элемент из массива \en delete an element from array + + Type * ReindexInd( size_t ind, size_t * = NULL ); // \ru заменить элемент с упорядочиванием по массиву \en replace element with sorting + size_t ReindexObj( Type * ent, size_t * = NULL ); // \ru заменить элемент с упорядочиванием по массиву \en replace element with sorting + + Type * ReindexMyInd( size_t ); // \ru заменить элемент с упорядочиванием по массиву \en replace element with sorting + + bool Exchange ( size_t ind1, size_t ind2 ); // \ru поменять местами по индексам в папином массиве \en swap by indices in the parent array + void ReindexAll (); // \ru перестроить индексный массив \en reconstruct the index array + + bool ReductionObj( const size_t & delObject ); // \ru понижение всех индексов > delObject \en decrease of all indices greater than 'delObject' + + TEMPLATE_FRIEND Type * add_to_array TEMPLATE_SUFFIX ( IMArray &, size_t ind, size_t * ); + TEMPLATE_FRIEND size_t add_to_array TEMPLATE_SUFFIX ( IMArray &, Type * el, size_t * ); + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const IMArray &, const void *, size_t * ); + TEMPLATE_FRIEND void array_remove_ind TEMPLATE_SUFFIX ( IMArray &, size_t delIndex, bool completely ); + TEMPLATE_FRIEND void array_remove_obj TEMPLATE_SUFFIX ( IMArray &, const size_t & delObj, bool completely ); + TEMPLATE_FRIEND size_t find_my_index TEMPLATE_SUFFIX ( const IMArray &, size_t ); + TEMPLATE_FRIEND Type * reindex_array_obj TEMPLATE_SUFFIX ( IMArray &, size_t ind, size_t * myIndex ); + TEMPLATE_FRIEND size_t reindex_array_obj TEMPLATE_SUFFIX ( IMArray &, Type* el, size_t * myIndex ); + TEMPLATE_FRIEND Type * reindex_array_ind TEMPLATE_SUFFIX ( IMArray &, size_t myIndex ); + TEMPLATE_FRIEND bool exchange_to_array TEMPLATE_SUFFIX ( IMArray &, size_t ind1, size_t ind2 ); + TEMPLATE_FRIEND void reindexall_to_array TEMPLATE_SUFFIX ( IMArray & ); + TEMPLATE_FRIEND void array_reduction_obj TEMPLATE_SUFFIX ( IMArray &arr, const size_t & delObject ); + +private: + IMArray( const IMArray & ); // \ru запрещено !!! \en forbidden !!! + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, IMArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const IMArray & ref ); + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * IMArray::operator new( size_t size ) { + return ::Allocate( size, typeid(IMArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void IMArray::operator delete ( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(IMArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------- +// \ru конструктор массива \en constructor of an array +// --- +template +inline IMArray::IMArray( PArray< Type > & arr, Compare_t c_t, Compare_v c_v, size_t maxCnt, uint16 delt ) + : SArray< size_t >( maxCnt, delt ), array(arr), compT(c_t), compV(c_v) {} + + +//------------------------------------------------------------------------------- +// \ru добавить объект по индексу в PAarray \en add an object by the index in PArray +// --- +template +inline Type* IMArray::Add( size_t ind, size_t * myIndex ) { + return add_to_array( *this, ind, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru добавить объект, объект в PArray должен быть \en add an object, the object in PArray should exist +// --- +template +inline size_t IMArray::Add( Type * el, size_t * myIndex ) { + return add_to_array( *this, el, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru удалить объект по индексу \en delete an object by index +// \ru completely = true - с понижением всех индексов > delIndex \en completely = true - with decrease of all indices greater than delIndex +// --- +template +inline void IMArray::RemoveInd( size_t delIndex, bool completely ) { + array_remove_ind( *this, delIndex, completely ); +} + + +//------------------------------------------------------------------------------- +// \ru удалить объект \en delete an object +// \ru completely = true - с понижением всех индексов > delIndex \en completely = true - with decrease of all indices greater than delIndex +// --- +template +inline void IMArray::RemoveObj( const size_t & delObject, bool completely ){ + array_remove_obj( *this, delObject, completely ); +} + + +//------------------------------------------------------------------------------- +// \ru понижение всех индексов > delObject \en decrease of all indices greater than 'delObject' +// --- +template +inline bool IMArray::ReductionObj( const size_t & delObject ) { +// \ru АВВ К12 Результат нужен только из этой функции \en АВВ К12 Only the result of this function is required +// \ru АВВ К12 array_reduction_obj сделал void-ной для ускорения \en АВВ К12 array_reduction_obj is void for acceleration +// \ru АВВ К12 return array_reduction_obj( *this, delObject ); \en АВВ К12 return array_reduction_obj( *this, delObject ); + bool res = false; + size_t * parr = (size_t *)GetAddr(); + size_t * end = parr + count; + + while ( parr < end ) + { + if ( *parr > delObject ) + { + --(*parr); + res = true; + } + parr++; + } + + return res; +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект по индексу в PArray \en reorder an object by the index in PArray +// \ru функция возвращает указатель на объект и индекс объекта в IMArray \en the function returns a pointer to the object and an index of the object in IMArray +// --- +template +inline Type* IMArray::ReindexInd( size_t ind, size_t * myIndex ) { + return reindex_array_obj( *this, ind, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект \en reorder an object +// \ru функция возвращает индекс объекта в PArray и индекс объекта в IMArray \en the function returns an index of the object in PArray and an index of the object in IMArray +// --- +template +inline size_t IMArray::ReindexObj( Type * ent, size_t * myIndex ) { + return reindex_array_obj( *this, ent, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект \en reorder an object +// \ru функция возвращает указатель на объект \en the function returns a pointer to the object +// --- +template +inline Type * IMArray::ReindexMyInd( size_t myIndex ) { + return reindex_array_ind( *this, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru поменять идексы в PArray местами \en swap indices in PArray +// --- +template +inline bool IMArray::Exchange ( size_t ind1, size_t ind2 ) { + return exchange_to_array( *this, ind1, ind2 ); +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить весь массив \en reorder the whole array +// --- +template +inline void IMArray::ReindexAll() { + reindexall_to_array( *this ); +} + + +//------------------------------------------------------------------------------- +// \ru оператор индексирования \en indexing operator +// --- +template +inline Type* IMArray::operator [] ( size_t ind ) const { + return array[ SArray < size_t >::operator []( ind ) ]; +} + + +//------------------------------------------------------------------------------- +// \ru оператор присвоения \en assignment operator +// --- +template +inline IMArray& IMArray::operator = ( const IMArray & o ) { + SArray< size_t >::operator = ( o ); + return *this; +} + + +//------------------------------------------------------------------------------- +// \ru найти объект удовлетворяющий условию \en find an object satisfying the condition +// --- +template +inline size_t IMArray::Find( const void * val, size_t * myIndex ) const { + return find_in_array( *this, val, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru получить индекс объекта в PArray по иедексу в IMArray \en get an index of object in PArray by the index in IMArray +// --- +template +inline size_t IMArray::GetIndex( size_t myIndex ) const { + return SArray< size_t >::operator[] (myIndex); +} + + +//------------------------------------------------------------------------------- +// \ru получить индекс объекта в IMArray по индексу в PArray (перебор) \en get an index of object in PArray by the index in IMArray (full search) +// --- +template +inline size_t IMArray::GetMyIndex( size_t parentIndex ) const { + return find_my_index( *this, parentIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru оператор приведения \en adduction operator +// --- +template +inline size_t & IMArray::operator ()( size_t myIndex ) const { + return SArray< size_t >::operator[] ( myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru добавить объект с упорядочиванием \en add an object with sorting +// --- +template +Type * add_to_array( IMArray & arr, size_t ind, size_t * myIndex ) { + PRECONDITION( ind < arr.array.Count() ); + + Type * el = arr.array[ind]; + size_t mcIArr = SYS_MAX_T; // \ru текущий индекс в IMArray \en the current index in IMArray + + if ( el ) { + + if ( !arr.count ) { + arr.SArray< size_t >::Add( ind ); + mcIArr = 0; + } + else { + size_t ml = 0; + mcIArr = ml; + size_t mcPArr = arr.GetIndex( mcIArr ); // \ru текущий индекс в PArray \en the current index in PArray + + // \ru проверяем первый эл. \en check the first element + int resL = (el->*arr.compT)( arr.array[mcPArr] ); + + // \ru если элемент меньше первого, вставляем перед первым \en if an element is less than the first element then place it before the first element + if ( resL < 0 ) + arr.InsertInd( mcIArr, ind ); + else { + size_t mr = arr.count - 1; + mcIArr = mr; + mcPArr = arr.GetIndex( mcIArr ); + + // \ru проверяем последний эл. \en check the last element + int resR = !mcIArr ? resL : (el->*arr.compT)( arr.array[mcPArr] ); + + // \ru если один объект в массиве или эл. больше или равен последнему, \en if one object in the array or an element is not less than the last element, + // \ru должны попасть сюда \en should be here + if ( !mcIArr || resR >= 0 ) { + arr.SArray< size_t >::Add( ind ); + mcIArr = mr + 1; + } + else { + if ( arr.count == 2 ) + arr.InsertInd( mcIArr, ind ); + else { + + // \ru сюда попадаем если resL >= 0 и resR < 0 \en this is the case when resL >= 0 and resR < 0 + while ( ml + 1 < mr ) { // \ru пока не нашли - ищем \en seek until do not find + + if ( !resL ) { + mcIArr = ml; + +// 68759 do { +// mcIArr++; +// mcPArr = arr.GetIndex( mcIArr ); +// } while ( (el->*arr.compT)( arr.array[mcPArr] ) == 0 ); + mcIArr++; + mcPArr = arr.GetIndex( mcIArr ); + + break; + } + else { + size_t md = ( ml + mr ) / 2; + mcPArr = arr.GetIndex( md ); + + int res = (el->*arr.compT)( arr.array[mcPArr] ); + + if ( res > 0 ) + ml = md; + else if ( res < 0 ) { + mr = md; + mcIArr = md; + } + else { + resL = res; //res = 0 + mcIArr = md + 1; // \ru если ml + 1 < mr не выполнится объект должен добавиться после md \en if ml + 1 is not less than mr then the object should be added after md + ml = md; + } + } + } + + arr.InsertInd( mcIArr, ind ); + } + } + } + } + } + + if ( myIndex ) + *myIndex = mcIArr; + + return el; +} + + +//------------------------------------------------------------------------------- +// \ru добавить объект с упорядочиванием \en add an object with sorting +// \ru получить индекс объекта в PArray \en get an index of the object in PArray +// --- +template +size_t add_to_array( IMArray & arr, Type * el, size_t * myIndex ) { + size_t ind = SYS_MAX_T; + ptrdiff_t mi = arr.array.MaxIndex(); + + if ( mi >= 0 ) { + + if ( arr.array[mi] == el ) + ind = mi; + else + ind = arr.array.FindIt(el); + } + + if ( ind == SYS_MAX_T ) { + + if ( myIndex ) + *myIndex = SYS_MAX_T; + } + else + add_to_array( arr, ind, myIndex ); + + return ind; +} + + +//------------------------------------------------------------------------------- +// \ru найти объект в массиве, удовлетворяющий условию \en find an object in array, satisfying the condition +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// --- +template +size_t find_in_array( const IMArray & arr, const void * val, size_t * myIndex ) { + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + int res = 1; + + size_t mcIArr; // \ru текущий индекс в IMArray \en the current index in IMArray + size_t mcPArr; // \ru текущий индекс в PArray \en the current index in PArray + + if ( arr.count > 3 ) { + size_t mr = arr.count - 1; + + size_t mxc = mr; + size_t ml = 0; + + while ( ml + 1 < mr ) { // \ru пока не нашли - ищем \en seek until do not find + mcIArr = ( ml + mr ) / 2; + mcPArr = arr.GetIndex( mcIArr ); + res = (arr.array[mcPArr]->*arr.compV)( val ); + + if ( res == 1 ) + mr = mcIArr; + else if ( res == - 1 ) + ml = mcIArr; + else + break; + } + + if ( res ) { + // \ru проверка по границам \en check by bounds + mcIArr = 0; + mcPArr = arr.GetIndex( mcIArr ); + res = (arr.array[mcPArr]->*arr.compV)( val ); + + if ( res ) { + mcIArr = mxc; + mcPArr = arr.GetIndex( mcIArr ); + res = (arr.array[mcPArr]->*arr.compV)( val ); + } + } + } + else { + + for( mcIArr = 0; mcIArr < arr.count; mcIArr++ ) { + mcPArr = arr.GetIndex( mcIArr ); + res = (arr.array[mcPArr]->*arr.compV)( val ); + + if ( res >= 0 ) + break; + } + } + + if ( res ) { + mcIArr = SYS_MAX_T; + mcPArr = SYS_MAX_T; + } + + if ( myIndex ) + *myIndex = mcIArr; + + return mcPArr; +} + + +//------------------------------------------------------------------------------- +// \ru удалить объект по индексу \en delete an object by index +// \ru completely = true - с понижением всех индексов > delIndex \en completely = true - with decrease of all indices greater than delIndex +// --- +template +void array_remove_ind( IMArray & arr, size_t delIndex, bool completely ){ + PRECONDITION( delIndex < arr.count ); + size_t arrayIndex = arr.GetIndex(delIndex); //arr.parr[ delIndex ]; + arr.SArray< size_t >::RemoveInd( delIndex ); + + if ( completely ) + array_reduction_obj( arr, arrayIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru удалить объект \en delete an object +// \ru completely = true - с понижением всех индексов > delIndex \en completely = true - with decrease of all indices greater than delIndex +// --- +template +void array_remove_obj( IMArray & arr, const size_t & delObject, bool completely ){ + arr.SArray< size_t >::RemoveObj( delObject ); + + if ( completely ) + array_reduction_obj( arr, delObject ); +} + +// \ru АВВ К12 //------------------------------------------------------------------------------- \en АВВ К12 //------------------------------------------------------------------------------- +// \ru АВВ К12 // понижение всех индексов > delObject \en АВВ К12 // decrease of all indices greater than delObject +// \ru АВВ К12 // --- \en АВВ К12 // --- +// \ru АВВ К12 template \en АВВ К12 template +// \ru АВВ К12 bool array_reduction_obj( IMArray & arr, const uint & delObject ){ \en АВВ К12 bool array_reduction_obj( IMArray & arr, const uint & delObject ){ +// \ru АВВ К12 bool res = false; \en АВВ К12 bool res = false; +// \ru АВВ К12 const uint *parr = arr.GetAddr(); \en АВВ К12 const uint *parr = arr.GetAddr(); +// \ru АВВ К12 \en АВВ К12 +// \ru АВВ К12 for( uint i = 0; i < arr.count; i++ ) { \en АВВ К12 for( uint i = 0; i < arr.count; i++ ) { +// \ru АВВ К12 uint *parrI = (uint *)(parr + i); \en АВВ К12 uint *parrI = (uint *)(parr + i); +// \ru АВВ К12 \en АВВ К12 +// \ru АВВ К12 if ( *parrI > delObject ){ \en АВВ К12 if ( *parrI > delObject ){ +// \ru АВВ К12 (*parrI)--; \en АВВ К12 (*parrI)--; +// \ru АВВ К12 res = true; \en АВВ К12 res = true; +// \ru АВВ К12 } \en АВВ К12 } +// \ru АВВ К12 } \en АВВ К12 } +// \ru АВВ К12 return res; \en АВВ К12 return res; +// \ru АВВ К12 } \en АВВ К12 } + + +//------------------------------------------------------------------------------- +// \ru понижение всех индексов > delObject \en decrease of all indices greater than 'delObject' +// --- +template +void array_reduction_obj( IMArray & arr, const size_t & delObject ){ + size_t *parr = (size_t *)arr.GetAddr(); + size_t *end = parr + arr.count; + + while ( parr < end ) + { + if ( *parr > delObject ) + --(*parr); + + parr++; + } +} + + +//------------------------------------------------------------------------------- +// \ru получить индекс объекта в IMArray по индексу в PArray \en get an index of object in PArray by the index in IMArray +// --- +template +size_t find_my_index( const IMArray & arr, size_t parentIndex ) { + + for ( size_t i = 0; i < arr.count; i++ ) + + if ( arr.GetIndex(i) == parentIndex ) + return i; + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект в массиве \en reorder an object in the array +// --- +template +size_t reindex_array_obj( IMArray & arr, Type * el, size_t * myIndex ) { + size_t ind = arr.array.FindIt(el); + + if ( ind == SYS_MAX_T ) { + + if ( myIndex ) + *myIndex = SYS_MAX_T; + return ind; + } + + reindex_array_obj( arr, ind, myIndex ); + + return ind; +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект в массиве \en reorder an object in the array +// --- +template +Type* reindex_array_obj( IMArray & arr, size_t ind, size_t * myIndex ) { + arr.SArray< size_t >::RemoveObj( ind ); + return add_to_array( arr, ind, myIndex ); +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить объект в массиве \en reorder an object in the array +// --- +template +Type* reindex_array_ind( IMArray & arr, size_t myIndex ) { + size_t ind = arr.GetIndex( myIndex ); //arr.parr[ myIndex ]; + arr.SArray< size_t >::RemoveInd( myIndex ); + return add_to_array( arr, ind, 0 ); +} + + +//------------------------------------------------------------------------------- +// \ru переупорядочить весь массив \en reorder the whole array +// --- +template +void reindexall_to_array( IMArray & arr ) { + + arr.SArray< size_t >::Flush(); + + for( size_t i = 0; i < arr.array.Count(); i++ ) + add_to_array( arr, i, 0 ); +} + + +//------------------------------------------------------------------------------- +// \ru поменять идексы в PArray местами \en swap indices in PArray +// --- +template +bool exchange_to_array( IMArray & arr, size_t ind1, size_t ind2 ) { + size_t myInd1 = arr.SArray< size_t >::FindIt( ind1 ); + + if ( !(myInd1 == SYS_MAX_T) ) { + size_t myInd2 = arr.SArray< size_t >::FindIt( ind2 ); + + if ( !(myInd2 == SYS_MAX_T) ) { + const size_t *parr = arr.GetAddr(); + *(size_t *)(parr + myInd1) = ind2; + *(size_t *)(parr + myInd2) = ind1; + return true; + } + } + return false; +} + + +#endif // __TEMPL_IM_ARRAY_H diff --git a/C3d/Include/templ_iterator.h b/C3d/Include/templ_iterator.h new file mode 100644 index 0000000..065b25a --- /dev/null +++ b/C3d/Include/templ_iterator.h @@ -0,0 +1,96 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Итератор массива. + \en Iterator of array. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_ITERATOR_H +#define __TEMPL_ITERATOR_H + +#include + +//------------------------------------------------------------------------------ +/** \brief \ru Интерфейс итератора. + \en Interface of iterator. \~ + \details \ru Итератор итератора. \n + \en Iterator of iterator. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class PointersIterator { +public: + /// \ru Деструктор. \en Destructor. + virtual ~PointersIterator() {}; + /// \ru Сброс итератора. \en Reset iterator. + virtual void Restart() = 0; + /// \ru Получить текущий элемент и сдвинуть итератор на следующий. \en Get the current element and move an iterator to the next. + virtual Type * operator ++(int) = 0; + /// \ru Получить текущий элемент \en Get the current element + virtual Type * operator() () const = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Итератор массива. + \en Iterator of array. \~ + \details \ru Итератор массива указателей. \n + \en Iterator of pointers array. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class PointersArrayIterator : public PointersIterator { +private: + const Array & items; ///< \ru Ссылка на массив. \en A reference to the array. + size_t index; ///< \ru Текущее положение итератора. \en The current position of iterator. + +public: + /// \ru Конструктор итератора. \en Constructor of iterator. + PointersArrayIterator( const Array & arr ) : items( arr ), index( 0 ) {} + /// \ru Сброс итератора. \en Reset iterator. + virtual void Restart() { index = 0; } + /// \ru Получить текущий элемент и сдвинуть итератор на следующий. \en Get the current element and move an iterator to the next. + virtual Type * operator ++(int) { return (index < items.Count()) ? items[index++] : NULL; } + /// \ru Получить текущий элемент \en Get the current element + virtual Type * operator() () const { return (index < items.Count()) ? items[index] : NULL; } + +private: // \ru не реализовано \en not implemented + PointersArrayIterator & operator = ( const PointersArrayIterator & ); + PointersArrayIterator ( const PointersArrayIterator & ); + PointersArrayIterator (); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Итератор списка. + \en Iterator of list. \~ + \details \ru Итератор списка указателей. \n + \en Iterator of pointers list. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +struct PointersListIterator : public LIterator, public PointersIterator +{ + /// \ru Конструктор итератора. \en Constructor of iterator. + PointersListIterator( const List & l ) : LIterator( l ) {} + /// \ru Конструктор итератора. \en Constructor of iterator. + PointersListIterator() : LIterator() {} + + /// \ru Сброс итератора. \en Reset iterator. + virtual void Restart() { LIterator::Restart(); } + /// \ru Получить текущий элемент и сдвинуть итератор на следующий. \en Get the current element and move an iterator to the next. + virtual Type * operator ++(int) { return LIterator::operator++(int()); } + /// \ru Получить текущий элемент \en Get the current element + virtual Type * operator() () const { return LIterator::operator()(); } + +private: // \ru не реализовано \en not implemented + PointersListIterator & operator = ( const PointersListIterator & ); + PointersListIterator ( const PointersListIterator & ); +}; + + +#endif //__TEMPL_ITERATOR_H diff --git a/C3d/Include/templ_kdtree.h b/C3d/Include/templ_kdtree.h new file mode 100644 index 0000000..cb97bf5 --- /dev/null +++ b/C3d/Include/templ_kdtree.h @@ -0,0 +1,506 @@ +////////////////////////////////////////////////////////////////////////////////// +/** +\file +\brief \ru К-мерное дерево. + \en K-d tree. \~ + +*/ +// \ru К-мерное дерево - это структура данных с разбиением пространства для упорядочивания точек из K-мерного пространства, +// используемая для поиска k ближайших соседей. +// \en K-d tree is a space-partitioning data structure for organizing points in a k-dimensional space, +// using for the k-nearest neighbors (kNN) search +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef __MB_KDTREE_H +#define __MB_KDTREE_H + +#include +#include +#include +#include +#include + + +//----------------------------------------------------------------------------- +/** \brief \ru Очередь с приоритетом с использованием кучи. + \en Priority queue using a heap. \~ + \details \ru Очередь с приоритетом с использованием кучи. Размер очереди фиксирован. + Производительность этой реализации выше чем у std::priority_queue. \n + \en Priority queue using a heap. Size of queue is fixed. + This implementation perfomance is better in comparsion with std::priority_queue. \n \~ + \ingroup Base_Tools +*/ +// --- +template +class PriorityQueue +{ +protected: + struct Element ///< \ru Элемент очереди. \en Element of queue. + { + Weight weight; ///< \ru Вес элемента. \en Weight of element. + Index index; ///< \ru Индекс элемента. \en Index of element. + }; + Element * elements; ///< \ru Элементы очереди. \en Elements of queue. + Element * offsetedElements; ///< \ru Смещенные элементы очереди. \en Shifted elements of queue. + size_t count; ///< \ru Актуальное число элементов в очереди. \en Actual count of elements in the queue. + size_t maxSize; ///< \ru Максимальное число элементов в очереди. \en Maximal count of elements in the queue. + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + PriorityQueue( const PriorityQueue & ); + +public: + /// \ru Конструктор. \en Constructor. + PriorityQueue( ); + /// \ru Деструктор. \en Destructor. + ~PriorityQueue(); + +public: + /** \ru \name Функции очереди с приоритетом. + \en \name Functions of priority queue. + \{ */ + /// \ru Инициализировать очередь максимальным количеством элементов в очереди. \en Initialize the queue by number of elements. + inline bool Initialize( size_t _maxSize ); + /// \ru Получить количество элементов в очереди. \en Get elements count in the queue. + inline size_t ElementsCount() const { return count; } + /// \ru Получить вес элемента очереди. \en Get weight of element in the queue. + inline Weight GetWeight( size_t i ) const { return elements[i].weight; } + /// \ru Получить индекс элемента очереди. \en Get index of element in the queue. + inline Index GetIndex( size_t i ) const { return elements[i].index; } + /// \ru Получить вес верхнего элемента очереди. \en Get weight of the top element in the queue. + inline Weight GetTopWeight() const { return elements[0].weight; } + /// \ru Вставить элемент с заданным индексом и весом в очередь. \en Insert element with given index and weight in the queue. + inline void Insert( Index index, Weight weight ); + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const PriorityQueue & ); +}; + + +//----------------------------------------------------------------------------- +/** \brief \ru К-d дерево. + \en K-d tree. \~ + \details \ru К-мерное бинарное дерево. \n + \en K-d binary tree. \n \~ + \ingroup Base_Tools +*/ +// --- +template +class KdTree { +public: + struct Node { ///< \ru Структура узла дерева. \en Structure of node of the tree. + union { + struct { ///< \ru Узел дерева. \en Node of tree. + Scalar splitValue; ///< \ru Разделяющее значение. \en Split value. + size_t firstChildId : 24; ///< \ru Индекс первого потомка. \en Index of first child. + size_t dim : 2; ///< \ru Измерение, вдоль которого происходит сравнение [0 = x, 1 = y, 2 = z]. \en The dimension along which node is splitted [0 = x, 1 = y, 2 = z]. + size_t type : 1; ///< \ru Тип узла дерева (0 - узел, 1 - лист). \en Type of node (0 - node, 1 - leaf). + }; + struct { ///< \ru Лист дерева. \en Leaf of tree. + unsigned int start; ///< \ru Индекс первого элемента листа. \en Index of first element of leaf. + unsigned short size; ///< \ru Количество элементов листа. \en Number of elements in the leaf. + }; + }; + }; + + typedef std::vector NodeList; + typedef std::vector PointList; + typedef std::vector IndexList; + typedef PriorityQueue ScalarPriorityQueue; + +protected: + MbCube box; ///< \ru Ограничивающий куб. \en Bounding box. + NodeList nodes; ///< \ru Узлы дерева. \en Nodes of tree. + PointList points; ///< \ru Множество точек. \en Set of points. + IndexList indices; ///< \ru Индексы точек. \en Indices of points. + size_t targetCellSize; ///< \ru Минимальное количество точек в листе дерева. \en Minimal number of point in a tree leaf. + size_t targetMaxDepth; ///< \ru Максимальная глубина дерева. \en Maximal tree depth. + size_t numLevel; ///< \ru Глубина дерева. \en Tree depth. + bool isBalanced; ///< \ru Cбалансированное дерево или нет. \en Three is balanced or unbalanced. + + struct QueryNode { ///< \ru Структура узла для запроса. \en Structure of query node. + QueryNode() {} + QueryNode( size_t id ) : nodeId( id ) {} + size_t nodeId; ///< \ru Id следующего узла. \en Id of next node. + Scalar sq; ///< \ru Квадрат расстояния до следующего узла. \en Squared distance to next node. + }; + +public: + /** + \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор k-мерного дерева. + \en Constructor of k-d tree. \~ + \param[in] points - \ru Множество точек. + \en Set of points. \~ + \param[in] minLeafSize - \ru Минимальное количество точек в листе дерева (по умолчанию 16). + \en Minimal number of point in a tree leaf (16 by default). \~ + \param[in] maxDepth - \ru Максимальная глубина дерева (по умолчанию 64). + \en Maximal tree depth (64 by default). \~ + \param[in] balanced - \ru Создать сбалансированное дерево или нет (по умолчанию несбалансированное). + \en Create three balanced or unbalanced (unbalanced by default). \~ + */ + KdTree( const PointList & points, size_t minLeafSize = 16, size_t maxDepth = 64, bool balanced = false ); + /// \ru Деструктор. \en Destructor. + ~KdTree(); + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + KdTree( const KdTree & ); + +public: + /** \ru \name Функции очереди с приоритетом. + \en \name Functions of priority queue. + \{ */ + /** + \brief \ru Найти k ближайших соседей для данной точки. + \en Performs the k-nearest neighbors (kNN) query. \~ + \details \ru Найти k ближайших соседей для данной точки. + \en Performs the k-nearest neighbors (kNN) query. \~ + \param[in] queryPoint - \ru Точка, для которой ищутся соседи. + \en The point for which the neighbors are being searched for . \~ + \param[in] neighborCount - \ru Запрашиваемое число соседей . + \en Number of neighbors requested. \~ + \param[in] neighborQueue - \ru Очередь с результатами поиска, в котором верхний элемент является наиболее удаленным от заданной точки + \en Queue with k-nearest neighbors (kNN) query results, where the topmost element [0] is NOT the nearest but the farthest \~ + */ + void GetKNearestNeighbors( const MbCartPoint3D & queryPoint, size_t neighborCount, ScalarPriorityQueue & neighborQueue ); + /// \ru Получить узлы дерева. \en Get tree nodes. + inline const NodeList & GetNodes() { return nodes; } + /// \ru Получить множество точек. \en Get points set. + inline const PointList & GetPoints() { return points; } + /// \ru Получить глубину дерева. \en Get depth of tree. + inline size_t GetNumLevel() { return numLevel; } + /// \ru Получить ограничивающий куб. \en Get axis aligned bounding box. + inline const MbCube & GetAxisAlignedBox() { return box; } + /** \} */ + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation, to prevent an assignment by default. + void operator = ( const KdTree & ); + // Используется для построения дерева: разделить множество subset [start..end] согласно dim и splitValue, + // и вернуть индекс первого элемента второго множества. + size_t split( size_t start, size_t end, size_t dim, double splitValue ); + // Построение дерева. + size_t createTree( size_t nodeId, size_t start, size_t end, size_t level ); + +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru PriorityQueue - очередь с приоритетом. \en PriorityQueue - priority queue. +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------- +// \ru Конструктор очереди с приоритетом. \en Constructor of priority queue. +// --- +template +PriorityQueue::PriorityQueue() + : elements( 0 ) + , maxSize ( 0 ) +{ +} + + +//------------------------------------------------------------------------------- +// \ru Деструктор очереди с приоритетом. \en Destructor of priority queue. +// --- +template +PriorityQueue::~PriorityQueue() +{ + if ( elements ) + delete[] elements; +} + + +//------------------------------------------------------------------------------- +// \ru Инициализировать очередь максимальным количеством элементов в очереди. \en Initialize the queue by number of elements. +// --- +template +inline bool PriorityQueue::Initialize( size_t _maxSize ) +{ + if ( maxSize != _maxSize ) { + maxSize = _maxSize; + delete[] elements; + try { + elements = new Element[maxSize]; + } + catch ( ... ) { + elements = NULL; + maxSize = count = 0; + C3D_CONTROLED_THROW; + return false; + } + offsetedElements = ( elements - 1 ); + } + count = 0; + return true; +} + + +//------------------------------------------------------------------------------- +// \ru Вставить элемент с заданным индексом и весом в очередь. \en Insert element with given index and weight in the queue. +// --- +template +inline void PriorityQueue::Insert( Index index, Weight weight ) +{ + if ( count == maxSize ) { + if ( weight < elements[0].weight ) { + size_t j, k; + j = 1; + k = 2; + while ( k <= maxSize ) { + Element* z = &( offsetedElements[k] ); + if ( (k < maxSize) && (z->weight < offsetedElements[k+1].weight) ) + z = &( offsetedElements[++k] ); + + if( weight >= z->weight ) + break; + offsetedElements[j] = *z; + j = k; + k = 2 * j; + } + offsetedElements[j].weight = weight; + offsetedElements[j].index = index; + } + } + else { + size_t i, j; + i = ++count; + while ( i >= 2 ) { + j = i >> 1; + Element& y = offsetedElements[j]; + if( weight <= y.weight ) + break; + offsetedElements[i] = y; + i = j; + } + offsetedElements[i].index = index; + offsetedElements[i].weight = weight; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru К-d дерево. \en PriorityQueue - priority queue. +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------- +// \ru Конструктор дерева. \en K-d tree. +// --- +template +KdTree::KdTree( const PointList & _points, size_t nofPointsPerCell, size_t maxDepth, bool balanced ) + : points ( _points.size() ) + , indices( _points.size() ) +{ + points[0] = _points[0]; + box.SetEmpty(); + for( size_t i = 1; i < points.size(); ++i ) { + points[i] = _points[i]; + indices[i] = i; + box |= ( points[i] ); + } + + targetMaxDepth = maxDepth; + targetCellSize = nofPointsPerCell; + isBalanced = balanced; + + // Добавление первого узла. Остальные добавляются при вызове createTree (рекурсия). + nodes.resize( 1 ); + nodes.back().type = 0; + numLevel = createTree( 0, 0, points.size(), 1 ); +} + + +//------------------------------------------------------------------------------- +// \ru Деструктор дерева. \en Destructor of tree. +// --- +template +KdTree::~KdTree() +{ +} + + +//------------------------------------------------------------------------------- +// \ru Найти k ближайших соседей для данной точки. Результат операции хранится +// в виде стека neighborQueue, в котором верхний элемент является наиболее +// удаленным от заданной точки. +// (его содержимое не сортировано, но упорядоченно расположено в куче) +// \en Performs the k-nearest neighbors (kNN) query. The result of the query, +// the k-nearest neighbors, are stored into the stack neighborQueue, where the +// topmost element [0] is NOT the nearest but the farthest! +// (they are not sorted but arranged into a heap) +// --- +template +void KdTree::GetKNearestNeighbors( const MbCartPoint3D & queryPoint, size_t k, ScalarPriorityQueue & neighborQueue ) +{ + if ( !neighborQueue.Initialize( k ) ) + return; + + std::vector nodeStack( numLevel + 1 ); + nodeStack[0].nodeId = 0; + nodeStack[0].sq = 0.0; + size_t count = 1; + + while( count ) { + QueryNode & qnode = nodeStack[count - 1]; // Последний вставленный в стек узел. + + // При проходе вниз по дереву qnode.nodeId является ближайшим поддеревом, т.е. + // qnode.nodeId является другим поддеревом, которое будет обрабатываться, + // если фактический ближайший узел будет больше, чем делящее расстояние (split distance). + Node & node = nodes[qnode.nodeId]; // + + // Если расстояние меньше чем верхний элемент neighborQueue, то это может быть один из k ближайших соседей. + if( neighborQueue.ElementsCount() < k || neighborQueue.GetTopWeight() ) { + if( node.type ) { // Достигли листа дерева. + --count; + + // Индекс последнего элемента листа в points. + size_t end = node.start + node.size; + // Добавление элемента листа в очередь. + for( size_t i = node.start; i < end; ++i ) + neighborQueue.Insert( indices[i], ( queryPoint - points[i] )*( queryPoint - points[i] ) ); + } + else { // Не лист дерева. + // Расстояние между найденной точкой и фактической координатой деления. + double new_off = queryPoint[node.dim] - node.splitValue; + + // Левое поддерево. + if( new_off < 0. ) { + nodeStack[count].nodeId = node.firstChildId; + // В родительском nodeId хранится индекс другого поддерева (для прохода в обратном направлении). + qnode.nodeId = node.firstChildId + 1; + } + // Правое поддерево. + else { + nodeStack[count].nodeId = node.firstChildId + 1; + qnode.nodeId = node.firstChildId; + } + // Расстояние наследуется от родителя(при спуске по дереву оно равно 0). + nodeStack[count].sq = qnode.sq; + // Расстояние от родителя - это квадрат расстояния от плоскости деления. + qnode.sq = new_off * new_off; + ++count; + } + } + else { + --count; + } + } +} + + +//------------------------------------------------------------------------------- +// \ru Разделить часть массива между индексами start и end на две части, одна из которых меньше +// чем splitValue, другое с элементами больше или равными чем splitValue. Сравнение элементов +// производится с помощью координаты dim [0 = x, 1 = y, 2 = z]. +// \en Split the array part between start and end in two part, one with the elements less than splitValue, +// the other with the elements greater or equal than splitValue. The elements are compared +// using the "dim" coordinate [0 = x, 1 = y, 2 = z]. +// --- +template +size_t KdTree::split( size_t start, size_t end, size_t dim, double splitValue ) +{ + size_t l( start ), r( end - 1 ); + for( ; l < r; ++l, --r ) { + while( l < end && points[l][dim] < splitValue ) + l++; + while( r >= start && points[r][dim] >= splitValue ) + r--; + if( l > r ) + break; + std::swap( points[l], points[r] ); + std::swap( indices[l], indices[r] ); + } + return ( points[l][dim] < splitValue ? l + 1 : l ); // Вернуть индекс первого элемента во второй части. +} + + +//------------------------------------------------------------------------------- +// \ru Построить k-мерное дерево (рекурсивно). Если количество точек узла меньше чем +// targetCellsize, то делаем этот узел листом, иначе рассчитываем ограничивающий +// куб для точек узла и делим его по среднему значению наибольшего габарита куба. +// \en Build the kdtree recursively. If the number of points in the node is lower than +// targetCellsize then mark this node as leaf, else compute the bounding box of the points +// of the node and split it at the middle of the largest bounding box dimension. +// --- +template +size_t KdTree::createTree( size_t nodeId, size_t start, size_t end, size_t level ) +{ + Node & node = nodes[nodeId]; // Первый узел + MbCube cube; + + for( size_t i = start + 1; i < end; ++i ) + cube |= points[i] ; + + + MbVector3D diag = cube.pmax - cube.pmin; // Диагональ габаритного куба. + + size_t dim; + if( diag.x > diag.y ) + dim = diag.x > diag.z ? 0 : 2; + else + dim = diag.y > diag.z ? 1 : 2; + + node.dim = dim; + if( isBalanced ) // Разделить точки используя среднее значение вдоль направления dim. + { + std::vector tempVector; + for( size_t i = start + 1; i < end; ++i ) + tempVector.push_back( (points[i])[dim] ); + std::sort( tempVector.begin(), tempVector.end() ); + node.splitValue = ( tempVector[int(tempVector.size() / 2.0)] + tempVector[int(tempVector.size() / 2.0) + 1] ) / 2.0; + } + else // Разделить ограничивающий куб на две части на основе среднего значение вдоль направления dim. + node.splitValue = Scalar( 0.5*( cube.pmax[dim] + cube.pmin[dim] ) ); + + size_t midId = split( start, end, dim, node.splitValue ); // Индекс первого элемента во второй части. + + node.firstChildId = nodes.size(); + nodes.resize( nodes.size() + 2 ); + bool flag = ( midId == start ) || ( midId == end ); + size_t leftLevel, rightLevel; + { + // Левый потомок. + size_t childId = nodes[nodeId].firstChildId; + Node & child = nodes[childId]; + if( flag || ( midId - start ) <= targetCellSize || level >= targetMaxDepth ) { + child.type = 1; + child.start = (unsigned int)start; + child.size = (unsigned short)(midId - start); + leftLevel = level; + } + else { + child.type = 0; + leftLevel = createTree( childId, start, midId, level + 1 ); + } + } + + { + // Правый потомок. + size_t childId = nodes[nodeId].firstChildId + 1; + Node & child = nodes[childId]; + if( flag || ( end - midId ) <= targetCellSize || level >= targetMaxDepth ) { + child.type = 1; + child.start = (unsigned int)midId; + child.size = (unsigned short)(end - midId); + rightLevel = level; + } + else { + child.type = 0; + rightLevel = createTree( childId, midId, end, level + 1 ); + } + } + if( leftLevel > rightLevel ) + return leftLevel; + return rightLevel; +} + + +#endif //__MB_KDTREE_H \ No newline at end of file diff --git a/C3d/Include/templ_lis_array.h b/C3d/Include/templ_lis_array.h new file mode 100644 index 0000000..0473359 --- /dev/null +++ b/C3d/Include/templ_lis_array.h @@ -0,0 +1,257 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Little SArray - укороченный SArray. + \en Little SArray - shortened SArray. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_LIS_ARRAY_H +#define __TEMPL_LIS_ARRAY_H + + +#include +#include + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ // \ru после sys_defs.h !!! \en after sys_defs.h !!! +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class LiSArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void set_array_size( LiSArray &, size_t newSize ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader& in, LiSArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer& out, const LiSArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader& in, LiSArray *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer& out, const LiSArray * ptr ) ); + + +//------------------------------------------------------------------------------ +// \ru Little SArray - укороченный SArray \en Little SArray - shortened SArray +// \ru одномерный массив объектов не содержащих указателей !!!!!!! \en one-dimensional array of objects without pointers !!! +// \ru В массиве нельзя хранить объекты содержащие указатели или \en An array should not contain objects with pointers or +// \ru классы с указателями, а также абстрактные классы с наследниками \en classes with pointers and abstract classes with inheritors +// --- +template +class LiSArray { +protected : + uint8 count; // \ru размерность массива \en a size of the array + Type * parr; + + // \ru Этот массив прирастает всегда по 2. \en This array always increase by 2. + enum { + li_delta = 2, + }; + +public : + LiSArray(); + LiSArray( const LiSArray & ); + virtual ~LiSArray() { set_array_size( *this, 0 ); } +public: + void Flush(); // \ru обнулить количество элементов \en set the number of elements to null. + Type * Add( const Type & ); // \ru добавить элемент в конец массива \en add element to the end of array + Type * InsertInd( size_t index, const Type & ); // \ru вставить элемент перед указанным \en insert element before the specified one + void RemoveInd( size_t delIndex ); // \ru удалить элемент из массива \en delete an element from array + size_t Count() const { return count; } // \ru дать количество элементов массива \en get the number of elements + + LiSArray & operator = ( const LiSArray & ); + LiSArray & operator += ( const LiSArray & ); + const Type & operator []( size_t loc ) const { C3D_ASSERT(loc < count); return parr[loc]; } // \ru ИР C3D_ASSERT нужен для оценки выхода за пределы массива. Я один раз вышел полдня потом искал!!! \en ИР C3D_ASSERT is necessary to detect out of bounds. - + Type & operator []( size_t loc ) { C3D_ASSERT(loc < count); return parr[loc]; } // \ru ИР C3D_ASSERT нужен для оценки выхода за пределы массива. Я один раз вышел полдня потом искал!!! \en ИР C3D_ASSERT is necessary to detect out of bounds. - + const Type * GetAddr() const { return parr; } // \ru выдать адрес начала массива \en get address of the beginning of an array + +protected : + void CatchMemory(); // \ru захватить память \en catch memory + + TEMPLATE_FRIEND void set_array_size TEMPLATE_SUFFIX ( LiSArray &, size_t newSize ); + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, LiSArray & ref ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const LiSArray & ref ); + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, LiSArray *& ptr ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const LiSArray * ptr ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * LiSArray::operator new( size_t size ) { + return ::Allocate( size, typeid(LiSArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void LiSArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(LiSArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +//------------------------------------------------------------------------------ +// \ru Конструктор массива \en Constructor of an array +// --- +template +inline LiSArray::LiSArray() + : count ( 0 ) + , parr ( 0 ) +{} + +//------------------------------------------------------------------------------ +// \ru Конструктор копирования массива \en Copy-constructor of an array +// --- +template +inline LiSArray::LiSArray( const LiSArray & o ) + : count ( 0 ) + , parr ( 0 ) +{ + *this = o; +} + +//------------------------------------------------------------------------------ +// \ru сбросить массив \en reset an array +// --- +template +inline void LiSArray::Flush() +{ + set_array_size( *this, 0 ); + count = 0; +} + +//------------------------------------------------------------------------------ +// \ru добавить элемент в конец массива \en add element to the end of array +// --- +template +inline Type* LiSArray::Add( const Type & ent ) +{ + CatchMemory(); + C3D_ASSERT( count < 253 ); + return (Type*)memcpy( parr+count++, &ent, sizeof(Type) ); +} + +//------------------------------------------------------------------------------ +// \ru вставить элемент перед указанным \en insert element before the specified one +// --- +template +inline Type * LiSArray::InsertInd( size_t index, const Type & ent ) +{ + C3D_ASSERT( index <= count ); + CatchMemory(); // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + + if ( index >= count ) + index = count; + else { + memmove( parr+index+1, parr+index, (count-index) * sizeof(Type) ); + } + count++; + C3D_ASSERT( count < 254 ); + // \ru передвинем вправо все элементы массива с последнего до указанного \en move to the right all elements of the array from the last to the specified one + return (Type*)memcpy( parr+index, &ent, sizeof(Type) ); // \ru записываем новый элемент \en writing new element +} + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline void LiSArray::RemoveInd( size_t delIndex ) +{ + C3D_ASSERT( delIndex < count ); + C3D_ASSERT( delIndex < 254 ); + C3D_ASSERT( count < 254 ); + if ( delIndex < count ) { + memcpy( parr+delIndex, parr+delIndex+1, (count - delIndex-1)*sizeof(Type) ); + count--; + C3D_ASSERT( count < 254 ); + } +} + +//------------------------------------------------------------------------------ +// \ru присвоение массива массиву \en assignment of an array to array +// --- +template +inline LiSArray & LiSArray::operator = ( const LiSArray & o ) +{ + set_array_size( *this, o.count ); // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + count = o.count; + C3D_ASSERT( count < 254 ); + if ( count > 0 && parr != NULL ) + memcpy( parr, o.parr, count * sizeof(Type) ); + + return *this; +} + +//------------------------------------------------------------------------------ +// \ru добавление массива к массиву \en add the array to the array +// --- +template +inline LiSArray & LiSArray::operator += ( const LiSArray & o ) +{ + if ( o.count ) { + set_array_size( *this, count + o.count ); // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + if ( parr != NULL ) + memcpy( parr+count, o.parr, o.count * sizeof(Type) ); + + count = (uint8)(count + o.count); + C3D_ASSERT( count < 254 ); + } + + return *this; +} + +//------------------------------------------------------------------------------ +// \ru захват большего куска памяти ( если нужно ) \en allocate the large piece of memory (if it is necessary) +// --- +template +inline void LiSArray::CatchMemory() +{ + C3D_ASSERT( count < 254 ); + set_array_size( *this, count + 1 ); + // \ru здесь count не увеличивается! \en 'count' is not increased! +} + +//------------------------------------------------------------------------------ +// \ru Если захвачен не такой размер памяти, то захватить новый \en If the size of caught memory is not appropriated then allocate memory again +// \ru если clear = true, то присвоить arr.count=0 и старое содержимое не копировать \en if clear = true then set arr.count=0 and do not copy the old content +// --- +template +void set_array_size( LiSArray & arr, size_t newSize ) +{ + C3D_ASSERT( newSize <= 0xff ); // \ru поскольку здесь uint8 count \en since uint8 count + C3D_ASSERT( arr.Count() < 254 ); + uint8 newUpper = (uint8)(newSize + newSize % (size_t)LiSArray::li_delta); + uint8 oldUpper = (uint8)(arr.Count() + arr.Count() % (size_t)LiSArray::li_delta); + + if ( newUpper != oldUpper ) { +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void *oldParr = arr.parr; +#endif // __REALLOC_ARRAYS_STATISTIC_ + +#ifdef USE_REALLOC_IN_ARRAYS + arr.parr = (Type*) ::realloc( arr.parr, newUpper * sizeof(Type) ); +#else + Type *p_tmp = newUpper ? (Type*)new TCHAR[ newUpper * sizeof(Type) ] : 0; + + if ( arr.parr && p_tmp ) + memcpy( p_tmp, arr.parr, std_min(oldUpper, (uint8)newUpper)* sizeof(Type) ); + + if ( arr.parr ) + delete [] (TCHAR *) arr.parr; + + arr.parr = p_tmp; +#endif // USE_REALLOC_IN_ARRAYS + +// \ru !!! здесь count не изменяется!!! \en !!! 'count' is not changed!! + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldUpper * sizeof(Type), arr.parr, newUpper * sizeof(Type), 3/*LiSArray*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ + } +} + +#endif // __TEMPL_LIS_ARRAY_H diff --git a/C3d/Include/templ_multimap.h b/C3d/Include/templ_multimap.h new file mode 100644 index 0000000..4dfad24 --- /dev/null +++ b/C3d/Include/templ_multimap.h @@ -0,0 +1,699 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Мультимножество, реализующее основной функционал std::multimap. + \en Multiset implementing the core functionality of std::multimap. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_MULTIMAP_H +#define __TEMPL_MULTIMAP_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Ассоциативное множество c дубликатами (мультимножество). + \en Associative set with duplicates (multiset). \~ + \details \ru Ассоциативное множество c дубликатами (мультимножество). \n + Реализует основные функциии std::multimap. Требования к типам данных KeyType и ValType такие же, как в SArray. + Мультимножество задает соответствие (ассоциации) объекта-ключа подмножеству объектов-значений. + Для некоторого объекта типа KeyType задается соответствие подмножеству объектов ValType. + \en Associative set with duplicates (multiset). \n + Implements the core functions of is std::multimap. Requirements to data types KeyType and ValType are the same as in SArray. + Multiset sets the mapping (associations) between a key-object and a subset of value-objects. + For some object of the "KeyType" type there is set a mapping to a subset of objects of the "ValType" type. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class MultiMap { +public: + + struct Pair + { + const KeyType m_key; + const ValType m_val; + Pair( const KeyType & key, const ValType & val ) : m_key( key ), m_val( val ) {} + bool operator < ( const Pair & p ) const { + return m_key < p.m_key; + } + bool operator == ( const Pair & p ) const { + return m_key == p.m_key && m_val == p.m_val; + } + Pair & operator = ( const Pair & ); // \ru Не реализовано. \en Not implemented. + }; + +public: + MultiMap(); + virtual ~MultiMap() {} + + class Iterator; + +public: + /// \ru Оператор доступа по ключу. \en Access by key operator. + Iterator operator[] ( const KeyType & key ) const; + /// \ru Получить итератор, указывающий на первый элемент. \en Get an iterator pointing to the first element. + Iterator First() const; + /// \ru Добавить элемент с заданным ключом и значением. \en Add an element with specified key and value. + void Associate( const KeyType & key, const ValType & val ); + /// \ru Удалить заданное значение с заданным ключом. \en Remove an element with specified key and value. + void Dissociate( const KeyType & key, const ValType & val ); + /// \ru Удалить элементы в диапазоне [it1, it2). \en Remove elements in the range [it1, it2). + void Dissociate( Iterator & it1, Iterator & it2 ); + /// \ru Удалить элемент, указанный итератором. \en Remove an element specified by an iterator. + Iterator Dissociate( Iterator & it ); + /// \ru Удалить все элементы из контейнера. \en Removes all elements from the container. + void Flush() { m_Pairs.Flush(); } + /// \ru Существует ли элемент с заданными ключом и значением. \en Is there an element with the specified key and value. + bool IsAssociated( const KeyType & key, const ValType & val ) const; + /// \ru Найти элемент с заданными ключом и значением. \en Find an element with the specified key and value. + Iterator Find( const KeyType & key ) const; + // \ru Итератор, указывающий на первый элемент со значением ключа, не меньшим, чем заданный. \en An iterator pointing to the first element not less than the given key. + Iterator LowerBound( const KeyType & key ) const; + // \ru Итератор, указывающий на первый элемент со значением ключа, большим, чем заданный. \en An iterator pointing to the first element greater than the given key. + Iterator UpperBound( const KeyType & key ) const; + // \ru Диапазон, содержащий все элементы с данным ключом в контейнере. \en A range containing all elements with the given key in the container. + std::pair EqualRange( const KeyType & key ) const; + // \ru Количество элементов в контейнере. \en The number of elements in the container. + size_t Count() const { return m_Pairs.Count(); } + + static size_t UpperBoundEx( const SArray & pairs, const KeyType & key ); + static size_t LowerBoundEx( const SArray & pairs, const KeyType & key ); + static std::pair EqualRangeEx( const SArray & pairs, const KeyType & key ); + +private: + SArray m_Pairs; + + private: // \ru Специфицируем нуль для разных типов. \en Specify null for different types. + template + struct Null { // \ru Нуль тривиальных типов (int, float, double и т.д.). \en Null of trivial types (int, float, double etc.). + static inline T val() { return 0; } + }; + template + struct Null { // \ru Нуль указателей. \en Null of pointers. + static inline T* val() { return NULL; } + }; +// \ru LF_Linux: 25.03.11 g++ выдает ошибку на этот код - не использованы KeyType, ValType в полной специализации шаблона. +// Однако непонятно, зачем нужна эта полная специализация - общая частичная специализация для тривиальных типов вполне подойдет. +// \en LF_Linux: 25.03.11 g++ returns an error in this code - types KeyType and ValType are not used in the full specialization of template. +// But it is not clear what for this specialization is required - the common partial specialization for the trivial types is sufficient. +// template<> +// \ru struct Null { // Нуль вещественных чисел \en struct Null { // Null of real numbers +// static inline double val() { return 0.0; } +// }; + +public: + // \ru Итератор по элементам контейнера. \en Iterator for the container elements. + class Iterator { + private: + Pair * m_Ptr; + Pair * m_MaxPtr; + + public: + Iterator() : m_Ptr( NULL ), m_MaxPtr( NULL ) {} + Iterator( const Iterator & iter ) : m_Ptr( iter.m_Ptr ), m_MaxPtr( iter.m_MaxPtr ) {} + Iterator( const SArray & m_Pairs, const Pair & pair ) : m_Ptr( NULL ), m_MaxPtr( NULL ) + { + const size_t count = m_Pairs.Count(); + if ( count > 0 ) { + size_t idx = MultiMap::LowerBoundEx( m_Pairs, pair.m_key ); + size_t temp = idx; + while ( temp < m_Pairs.Count() && m_Pairs[temp].m_key == pair.m_key ) { + if ( m_Pairs[temp] == pair ) { + idx = temp; + break; + } + temp++; + } + m_MaxPtr = &m_Pairs[count-1]; + if ( idx < count ) { + m_Ptr = &m_Pairs[idx]; + } + } + } + Iterator( const SArray & m_Pairs, const Iterator & iter1, const Iterator & iter2 ) // range + : m_Ptr( NULL ), m_MaxPtr( NULL ) + { + const size_t count = m_Pairs.Count(); + if ( count > 0 && iter1.m_Ptr != NULL ) { + size_t idx1 = MultiMap::LowerBoundEx( m_Pairs, iter1.m_Ptr->m_key ); + size_t temp = idx1; + while ( temp < m_Pairs.Count() && m_Pairs[temp].m_key == iter1.m_Ptr->m_key ) { + if ( m_Pairs[temp] == *iter1.m_Ptr ) { + idx1 = temp; + break; + } + temp++; + } + size_t idx2 = SYS_MAX_T; + if ( iter2.m_Ptr != NULL ) { + idx2 = MultiMap::UpperBoundEx( m_Pairs, iter2.m_Ptr->m_key ); + if ( idx2 < m_Pairs.Count() ) { + if ( idx2 > 0) + idx2--; + else + idx2 = SYS_MAX_T; + } + } + if ( idx2 == SYS_MAX_T ) + idx2 = count - 1; + if ( idx1 < count && idx2 < count ) { + m_Ptr = &m_Pairs[idx1]; + m_MaxPtr = &m_Pairs[idx2]; + } + } + } + + public: + /// \ru Получить текущий элемент и сдвинуть итератор на следующий. \en Get the current element and move the iterator to the next. + Iterator operator ++( int ) + { + Iterator iter(*this); + if ( m_Ptr && m_Ptr < m_MaxPtr ) + m_Ptr++; + else + m_Ptr = 0; + return iter; + } + /// \ru Оператор равенства. \en An equality operator. + bool operator == ( const Iterator & itr ) const + { + if ( Empty() && itr.Empty() ) + return true; + if ( ( Empty() && !itr.Empty() ) || ( !Empty() && itr.Empty() ) ) + return false; + return m_Ptr == itr.m_Ptr && m_MaxPtr == itr.m_MaxPtr; + } + /// \ru Оператор "!=". \en An "!=" operator. + bool operator != ( const Iterator & itr ) const + { + if ( Empty() && itr.Empty() ) + return false; + if ( ( Empty() && !itr.Empty() ) || ( !Empty() && itr.Empty() ) ) + return true; + return m_Ptr != itr.m_Ptr || m_MaxPtr != itr.m_MaxPtr; + } + /// \ru Оператор "меньше". \en Operator "less". + bool operator < ( const Iterator& itr ) const + { + return m_Ptr < itr.m_Ptr && m_MaxPtr <= itr.m_MaxPtr; + } + /// \ru Пустой ли итератор. \en Is the iterator empty. + bool Empty() const + { + return !( m_Ptr && m_Ptr <= m_MaxPtr ); + } + // \ru Получить текущий ключ элемента. \en Get the current key of the element. + KeyType Key() const + { + return !Empty() ? m_Ptr->m_key : (KeyType)0; + } + // \ru Получить текущее значение элемента. \en Get the current value of the element. + ValType Value() const + { + return !Empty() ? m_Ptr->m_val : (ValType)0; + } + // \ru Получить пару с текущим ключом и текущим кзначением элемента. \en Get the pair with the current key and the current value of the element. + Pair* GetPair() const + { + return m_Ptr; + } + }; +}; + + +//------------------------------------------------------------------------------ +// +// --- +template +size_t MultiMap::LowerBoundEx( const SArray::Pair> & pairs, const KeyType & key ) +{ + if ( pairs.Count() > 11 ) { + size_t end = pairs.Count() - 1; + size_t last = end; + size_t start = 0; + size_t firstNotLess = SYS_MAX_T; + + while ( start + 1 < end ) { // \ru Ищем, пока не нашли. \en Seek until find. + size_t middle = ( start + end ) / 2; + Pair& mdE = pairs[middle]; + if ( mdE.m_key < key ) { + start = middle; + } + else if ( key <= mdE.m_key ) { + if ( middle < firstNotLess ) + firstNotLess = middle; + end = middle; + } + // \ru Если попадаем сюда, значит некорректно написаны операторы "тождественно" и сравнения. + // \en If we are here, then operators of identity check and comparison are not correct. + else { + PRECONDITION( 0 ); + return SYS_MAX_T; + } + } + + // \ru Проверяем ключ между start и end. \en Check a key between start and end. + if ( start + 1 < pairs.Count() - 1 ) { + size_t middle = start + 1; + Pair& mdE = pairs[middle]; + if ( key <= mdE.m_key && middle < firstNotLess ) + firstNotLess = middle; + } + + if ( key <= pairs[0].m_key ) + return 0; + if ( firstNotLess <= last && firstNotLess >= 0 && key <= pairs[firstNotLess].m_key ) + return firstNotLess; + if ( key == pairs[last].m_key ) + return last; + } + else { + if ( pairs.Count() == 1 ) + return key <= pairs[0].m_key ? 0 : SYS_MAX_T; + else if ( pairs.Count() == 2 ) { + if ( key <= pairs[0].m_key ) + return 0; + if ( key <= pairs[1].m_key ) + return 1; + } + else { // 2 < count <= 11 + for( size_t i = 0; i < pairs.Count(); ++i ) + if ( key <= pairs[i].m_key ) + return i; + } + } + return SYS_MAX_T; +} + +//------------------------------------------------------------------------------ +// \ru Итератор, указывающий на первый элемент со значением ключа, не меньшим, чем заданный. +// \en An iterator pointing to the first element not less than the given key. +// --- +template +inline typename MultiMap::Iterator MultiMap::LowerBound( const KeyType & key ) const +{ + size_t idx = LowerBoundEx ( m_Pairs, key ); + return idx < m_Pairs.Count() ? Iterator ( m_Pairs, m_Pairs[idx] ) : Iterator(); +} + +template +size_t MultiMap::UpperBoundEx( const SArray::Pair> & pairs, const KeyType & key ) +{ + if ( pairs.Count() > 11 ) { + size_t end = pairs.Count() - 1; + size_t last = end; + size_t start = 0; + size_t firstGreater = SYS_MAX_T; + + while ( start + 1 < end ) { // \ru Ищем, пока не нашли. \en Seek until find. + size_t middle = ( start + end ) / 2; + Pair& mdE = pairs[middle]; + if ( mdE.m_key <= key ) { + start = middle; + } + else if ( key < mdE.m_key ) { + if ( middle < firstGreater ) + firstGreater = middle; + end = middle; + } + // \ru Если попадаем сюда, значит некорректно написаны операторы "тождественно" и сравнения. + // \en If we are here, then operators of identity check and comparison are not correct. + else { + PRECONDITION( 0 ); + return SYS_MAX_T; + } + } + + if ( key < pairs[0].m_key ) + return 0; + if ( firstGreater <= end && firstGreater >= 0 && key < pairs[firstGreater].m_key ) + return firstGreater; + if ( key < pairs[last].m_key ) + return last; + } + else { + if ( pairs.Count() == 1 ) + return key < pairs[0].m_key ? 0 :SYS_MAX_T; + else if ( pairs.Count() == 2 ) { + if ( key < pairs[0].m_key ) + return 0; + if ( key < pairs[1].m_key ) + return 1; + } + else { // 2 < count <= 11 + for( size_t i = 0; i < pairs.Count(); ++i ) + if ( key < pairs[i].m_key ) + return i; + } + } + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru Итератор, указывающий на первый элемент со значением ключа, большим, чем заданный. +// \en An iterator pointing to the first element greater than the given key. +// --- +template +inline typename MultiMap::Iterator MultiMap::UpperBound( const KeyType & key ) const +{ + size_t ind = UpperBoundEx ( m_Pairs, key ); + return ind != SYS_MAX_T ? Iterator ( m_Pairs, m_Pairs[ind] ) : Iterator(); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +std::pair MultiMap::EqualRangeEx( const SArray::Pair> & pairs, const KeyType & key ) +{ + if ( pairs.Count() > 11 ) { + size_t end = pairs.Count() - 1; + size_t lastRight = end; + size_t start = 0; + size_t firstNotLess = SYS_MAX_T; + size_t firstGreater = SYS_MAX_T; + + // \ru Проверяем последний элемент. \en Check the last element. + if ( key > pairs[pairs.Count() - 1].m_key ) + return std::pair (SYS_MAX_T, SYS_MAX_T); + + // \ru Проверяем первый элемент. \en Check the first element. + if ( key < pairs[0].m_key ) + return std::pair (0, 0); + + if ( key != pairs[0].m_key ) { + while ( start + 1 < end ) { // \ru Ищем, пока не нашли. \en Seek until find. + size_t middle = ( start + end ) / 2; + Pair& mdE = pairs[middle]; + if ( mdE.m_key < key ) { + start = middle; + } + else if ( key <= mdE.m_key ) { + if ( key < mdE.m_key && lastRight > middle ) + lastRight = middle; + if ( middle < firstNotLess ) + firstNotLess = middle; + end = middle; + } + // \ru Если попадаем сюда, значит некорректно написаны операторы "тождественно" и сравнения. + // \en If we are here, then operators of identity check and comparison are not correct. + else { + PRECONDITION( 0 ); + return std::pair (SYS_MAX_T, SYS_MAX_T); + } + } + } + else + firstNotLess = 0; // key == pairs[0].m_key + + // \ru Проверяем ключ между start и end. \en Check a key between start and end. + if ( start + 1 == end ) { + size_t middle = start + 1; + Pair& mdE = pairs[middle]; + if ( key <= mdE.m_key && middle < firstNotLess ) + firstNotLess = middle; + } + + // \ru Проверяем последний элемент. \en Check the last element. + if ( firstNotLess == SYS_MAX_T && key == pairs[pairs.Count() - 1].m_key ) + return std::pair (pairs.Count() - 1, SYS_MAX_T); + + if ( firstNotLess == SYS_MAX_T ) + return std::pair (SYS_MAX_T, SYS_MAX_T); + + // \ru Теперь начинаем правый поиск. \en Now start right search. + end = lastRight; + start = firstNotLess; + + if ( start == end && pairs[firstNotLess].m_key != key ) + return std::pair ( firstNotLess, firstNotLess ); + + while ( start + 1 < end ) { // \ru Ищем, пока не нашли. \en Seek until find. + size_t middle = ( start + end ) / 2; + Pair& mdE = pairs[middle]; + if ( mdE.m_key <= key ) { + start = middle; + } + else if ( key < mdE.m_key ) { + if ( middle < firstGreater ) + firstGreater = middle; + end = middle; + } + // \ru Если попадаем сюда, значит некорректно написаны операторы "тождественно" и сравнения. + // \en If we are here, then operators of identity check and comparison are not correct. + else { + PRECONDITION( 0 ); + return std::pair ( SYS_MAX_T, SYS_MAX_T ); + } + } + + if ( firstGreater == SYS_MAX_T ) + { + if ( pairs[firstNotLess].m_key != key ) + firstGreater = firstNotLess; + else if ( lastRight > 0 && pairs[lastRight - 1].m_key == key && pairs[lastRight].m_key != key ) + firstGreater = lastRight; + else if ( firstNotLess + 1 < pairs.Count() && pairs[firstNotLess + 1].m_key != key ) + firstGreater = firstNotLess + 1; + } + return std::pair ( firstNotLess, firstGreater ); + } + else { + if ( pairs.Count() == 0 ) + return std::pair ( SYS_MAX_T, SYS_MAX_T ); + if ( pairs.Count() == 1 ) + return key == pairs[0].m_key ? std::pair ( 0, SYS_MAX_T ) : + ( key < pairs[0].m_key ? std::pair ( 0, 0 ) : std::pair ( SYS_MAX_T, SYS_MAX_T ) ); + if ( pairs.Count() == 2 ) { + size_t first = SYS_MAX_T; + if ( key < pairs[0].m_key ) + return std::pair(0, 0); + if ( key > pairs[1].m_key ) + return std::pair(SYS_MAX_T, SYS_MAX_T); + if ( key == pairs[0].m_key ) + first = 0; + else if ( key == pairs[1].m_key ) + first = 1; + else // ( key > pairs[0].m_key && key < pairs[1].m_key ) + return std::pair ( 1, 1 ); + if ( key == pairs[1].m_key ) + return std::pair ( first, SYS_MAX_T ); + return std::pair (first, 1); + } + else { // 2 < count <= 11 + size_t first = SYS_MAX_T, second = SYS_MAX_T; + if ( key < pairs[0].m_key ) + return std::pair ( 0, 0 ); + if ( key > pairs[pairs.Count() - 1].m_key ) + return std::pair ( first, second ); + for( size_t i = 0; i < pairs.Count(); ++i ) { + if ( key == pairs[i].m_key ) { + if ( first == SYS_MAX_T ) + first = i; + } + else { + if ( key < pairs[i].m_key ) { + second = i; + break; + } + } + } + if ( first == SYS_MAX_T ) + first = second; + return std::pair ( first, second ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Диапазон, содержащий все элементы с данным ключом в контейнере. +// \en A range containing all elements with the given key in the container. +// --- +template +inline std::pair::Iterator,typename MultiMap::Iterator> + MultiMap::EqualRange ( const KeyType & key ) const +{ + std::pair idx = EqualRangeEx ( m_Pairs, key ); + Iterator first, second; + if ( idx.first < m_Pairs.Count() ) + first = Iterator ( m_Pairs, m_Pairs[idx.first]); + if ( idx.second < m_Pairs.Count() ) + second = Iterator ( m_Pairs, m_Pairs[idx.second]); + return std::pair ( first, second ); +} + + +//------------------------------------------------------------------------------ +/// \ru Найти элемент с заданными ключом и значением. +// \en Find an element with the specified key and value. +// --- +template +inline typename MultiMap::Iterator MultiMap::Find( const KeyType & key ) const +{ + if ( m_Pairs.Count() > 11 ) { + size_t mx = m_Pairs.Count() - 1; + size_t mxc = mx; + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru Ищем, пока не нашли. \en Seek until find. + size_t md = ( mn + mx ) / 2; + Pair& mdE = m_Pairs[md]; + if ( mdE.m_key < key ) { + mn = md; + } + else if ( key < mdE.m_key ) { + mx = md; + } + else if ( mdE.m_key == key ) + return Iterator ( m_Pairs, mdE ); + // \ru Если попадаем сюда, значит некорректно написаны операторы "тождественно" и сравнения. + // \en If we are here, then operators of identity check and comparison are not correct. + else { + PRECONDITION( 0 ); + return Iterator(); + } + } + + if ( key == m_Pairs[0].m_key ) + return Iterator ( m_Pairs, m_Pairs[0] ); + if ( key == m_Pairs[mxc].m_key ) + return Iterator ( m_Pairs, m_Pairs[mxc] ); + } + else { + if ( m_Pairs.Count() == 1 ) + return key == m_Pairs[0].m_key ? Iterator ( m_Pairs, m_Pairs[0] ) : Iterator(); + else if ( m_Pairs.Count() == 2 ) { + if ( key == m_Pairs[0].m_key ) + return Iterator ( m_Pairs, m_Pairs[0] ); + if ( key == m_Pairs[1].m_key ) + return Iterator ( m_Pairs, m_Pairs[1] ); + return Iterator(); + } + else { // 2 < count <= 11 + for( size_t i = 0; i < m_Pairs.Count(); ++i ) + if ( key == m_Pairs[i].m_key ) + return Iterator ( m_Pairs, m_Pairs[i] ); + } + } + return Iterator(); +} + + +//------------------------------------------------------------------------------- +// \ru Конструктор. \en Contructor. +// --- +template +MultiMap::MultiMap() + : m_Pairs( 0, 1 ) +{} + + +//------------------------------------------------------------------------------- +/// \ru Добавить элемент с заданным ключом и значением. +// \en Add an element with specified key and value. +// --- +template +inline void MultiMap::Associate( const KeyType & key, const ValType & val ) { + Pair pair( key, val ); + std::pair idx = EqualRangeEx ( m_Pairs, key ); + if ( idx.second < m_Pairs.Count() ) + m_Pairs.InsertInd ( idx.second, pair ); + else + m_Pairs.Add ( pair ); +} + + +//------------------------------------------------------------------------------- +// \ru Существует ли элемент с заданными ключом и значением. +// \en Is there an element with the specified key and value. +// --- +template +inline bool MultiMap::IsAssociated( const KeyType & key, const ValType & val ) const { + return m_Pairs.FindIt( Pair(key, val) ) < m_Pairs.Count(); +} + + +//------------------------------------------------------------------------------- +/// \ru Удалить заданное значение с заданным ключом. \en Remove an element with specified key and value. +// --- +template +inline void MultiMap::Dissociate( const KeyType & key, const ValType & val ) { + Pair pair( key, val ); + size_t idx = m_Pairs.FindIt( pair ); + if ( idx < m_Pairs.Count() ) { + m_Pairs.RemoveInd( idx ); + } +} + + +//------------------------------------------------------------------------------- +/// \ru Удалить элемент, указанный итератором. \en Remove an element specified by an iterator. +// --- +template +inline typename MultiMap::Iterator MultiMap::Dissociate( + typename MultiMap::Iterator & it ) +{ + size_t idx = m_Pairs.FindIt( *it.GetPair() ); + if ( idx < m_Pairs.Count() ) { + m_Pairs.RemoveInd( idx ); + if ( idx < m_Pairs.Count() ) + return Iterator ( m_Pairs, m_Pairs[idx]); + } + return Iterator(); +} + + +//------------------------------------------------------------------------------- +/// \ru Удалить элементы в диапазоне [it1, it2). \en Remove elements in the range [it1, it2). +// --- +template +inline void MultiMap::Dissociate( + typename MultiMap::Iterator & it1, + typename MultiMap::Iterator & it2 ) +{ + if ( m_Pairs.Count() == 0 || it1.Empty() ) + return; + if ( it2.Empty() ) { + // \ru Удаляем с it1 до конца. \en Remove from it1 up to the end. + it2 = Iterator ( m_Pairs, m_Pairs[m_Pairs.Count() - 1] ); + if ( it1 == it2 ) + Dissociate ( it1.Key(), it1.Value() ); // \ru Просто удаляем последний элемент. \en Just remove the last element. + else if ( it1 < it2 ) { + size_t idx = m_Pairs.FindIt( *it1.GetPair() ); + if ( idx != SYS_MAX_T ) + m_Pairs.RemoveInd ( idx, m_Pairs.Count () ); + } + } + else if ( it1 < it2 ) + m_Pairs.Remove ( it1.GetPair(), it2.GetPair() ); +} + + +//------------------------------------------------------------------------------- +/// \ru Оператор доступа по ключу. \en Access by key operator. +// --- +template +inline typename MultiMap::Iterator MultiMap::operator[] ( const KeyType & key ) const { + return Iterator( m_Pairs, Pair(key, Null::val()) ); +} + + +//------------------------------------------------------------------------------- +/// \ru Получить итератор, указывающий на первый элемент. \en Get an iterator pointing to the first element. +// --- +template +inline typename MultiMap::Iterator MultiMap::First() const { + if ( m_Pairs.Count() ) + return Iterator ( m_Pairs, m_Pairs[0] ); + return Iterator(); +} + + +#endif // __TEMPL_MULTIMAP_H diff --git a/C3d/Include/templ_p_array.h b/C3d/Include/templ_p_array.h new file mode 100644 index 0000000..0b9f935 --- /dev/null +++ b/C3d/Include/templ_p_array.h @@ -0,0 +1,482 @@ + +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Одномерный массив указателей. + \en One-dimensional array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_P_ARRAY_H +#define __TEMPL_P_ARRAY_H + + +#include +#include +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +// \ru Реализация методов для чтения/записи массива лежит в templ_p_array_rw.h \en Implementation of methods for reading/writing of array is located in templ_p_array_rw.h + + +FORVARD_DECL_TEMPLATE_TYPENAME( class PArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool set_Parray_size( PArray &, size_t newSize, bool clear ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void destroy_array ( PArray & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, PArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const PArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, PArray *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const PArray * ptr ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей. + \en One-dimensional array of pointers. \~ + \details \ru Одномерный массив указателей на объекты. + Может владеть(удалять) или не владеть указателями. \n + \en One-dimensional array of pointers to objects. + Can own (delete) or not own pointers. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class PArray : public RPArray +{ +protected : + bool owns; ///< \ru Флаг владения элементами массива (элементы можно удалять) \en A flag of ownership of elements of an array (elements can be deleted) + Type * nowDeletedElem; ///< \ru Удаляемый элемент \en Deleted element + +public : + /// \ru Конструктор. \en Constructor. + PArray() + : RPArray() + , owns( true ) + , nowDeletedElem(0) + {} + /// \ru Конструктор. \en Constructor. + PArray( size_t i_upper, uint16 i_delta = 1, bool shouldDelete = true )//, bool shouldNullSet = false ) + : RPArray( i_upper, i_delta )//, shouldNullSet ) + , owns( shouldDelete ) + , nowDeletedElem(0) + {} + /// \ru Деструктор. \en Destructor. + virtual ~PArray(); + /// \ru Владеем ли элементами? \en Are the elements owned? + bool OwnsElem() const { return owns; } + /// \ru Выставить состояние флага владения элементами. \en Set the flag of elements ownership + void OwnsElem( bool ownsEl ) { owns = ownsEl; } + + /// \ru Функции, выделяющие потенциально большие участки памяти, возвращают результат операции (успех/ошибка). + /// \en Functions that allocate potentially large memory, return an operation result (success/error). + bool SetSize ( size_t newSize, bool clear ); ///< \ru Установить новый размер массива. \en Set the new size of an array. + + void Flush ( DelType = defDelete ); ///< \ru Удалить все элементы. \en Delete all elements. + void HardFlush( DelType shdl = defDelete ) { Flush(shdl); RPArray::Adjust(); } ///< \ru Освободить всю память. \en Free the whole memory. + void RemoveAll( DelType shdl = defDelete ) { Flush(shdl); } ///< \ru Удалить все элементы обнулить количество элементов. \en Delete all elements and set the number of elements to null. + Type * RemoveObj( Type * delObject, DelType = defDelete ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + virtual Type * RemoveInd( size_t delIndex, DelType del = defDelete ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + +public: // \ru унификация с вектором STL \en unification with STL vector + virtual void clear() { Flush(); } ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + +private: + /// \ru Перераспределение памяти под новый размер массива. \en Reallocation of memory for the new size of array. + TEMPLATE_FRIEND bool set_Parray_size TEMPLATE_SUFFIX ( PArray &, size_t newSize, bool clear ); + // \ru Удаление всех указателей, собранных в массиве. \en Deletion of all pointers from array. + TEMPLATE_FRIEND void destroy_array TEMPLATE_SUFFIX ( PArray & ); + + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, PArray & ref ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const PArray & ref ); + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, PArray *& ptr ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const PArray * ptr ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +private: + PArray( const PArray & ); + PArray & operator = ( const PArray & ); +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * PArray::operator new( size_t size ) { + return ::Allocate( size, typeid(PArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void PArray::operator delete( void *ptr, size_t size ) { + ::Free( ptr, size, typeid(PArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class PIArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const PIArray &, typename PIArray::IteratorFunc func ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const PIArray &, typename PIArray::ParIteratorFunc func, void * pars ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t first_that_in_array( const PIArray &, typename PIArray::CompareFunc func, void * pars, size_t from ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей с итераторными функциями. + \en One-dimensional array of pointers with iterator functions. \~ + \details \ru Одномерный массив указателей с итераторными функциями. \n + \en One-dimensional array of pointers to objects with iterator functions. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class PIArray : virtual public PArray { +public : + /// \ru Конструктор. \en Constructor. + PIArray() + : PArray() + {} + /// \ru Конструктор. \en Constructor. + PIArray( size_t i_upper, uint16 i_delta = 1, uint8 shouldDelete = 1 ) + : PArray( i_upper, i_delta, !!shouldDelete ) + {} + + typedef void (*IteratorFunc) ( Type * ); + // void ForEachI( IteratorFunc func ) const; + + typedef void (*ParIteratorFunc) ( Type *, void * ); + void ForEachI( ParIteratorFunc func, void * ) const; + + typedef int (*CompareFunc) ( Type *, void * ); + size_t FirstThatI( CompareFunc func, void * pars, size_t from = 0 ) const; + + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const PIArray &, IteratorFunc func ); + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const PIArray &, ParIteratorFunc func, void * pars ); + TEMPLATE_FRIEND size_t first_that_in_array TEMPLATE_SUFFIX ( const PIArray &, CompareFunc func, void * pars, size_t from ); + +private: + PIArray( const PIArray & ); // \ru запрещено !!! \en forbidden !!! + void operator = ( const PIArray & ); // \ru запрещено !!! \en forbidden !!! +}; + + +FORVARD_DECL_TEMPLATE_TYPENAME( class PMIArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const PMIArray &, typename PMIArray::IteratorMemFunc func ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const PMIArray &, typename PMIArray::ParIteratorMemFunc func, void * pars ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t first_that_in_array( const PMIArray &, typename PMIArray::CompareMemFunc func, void * pars, size_t from ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей с итераторными функциями. + \en One-dimensional array of pointers with iterator functions. \~ + \details \ru Одномерный массив указателей с итераторными функциями - членами классов. \n + \en One-dimensional array of pointers to objects with iterator functions - class members. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class PMIArray : virtual public PArray { +public : + /// \ru Конструктор. \en Constructor. + PMIArray() + : PArray() + {} + /// \ru Конструктор. \en Constructor. + PMIArray( size_t i_upper, uint16 i_delta = 1, uint8 shouldDelete = 1 ) + : PArray( i_upper, i_delta, !!shouldDelete ) + {} + + typedef void (Type::*IteratorMemFunc) (void); + // void ForEach( IteratorMemFunc func ) const; + + typedef void (Type::*ParIteratorMemFunc) (void * pars); + void ForEach( ParIteratorMemFunc func, void * pars ) const; + + typedef bool (Type::*CompareMemFunc) (void * pars); + size_t FirstThat( CompareMemFunc func, void * pars, size_t from = 0 ) const; + + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const PMIArray &, IteratorMemFunc func ); + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const PMIArray &, ParIteratorMemFunc func, void * pars ); + TEMPLATE_FRIEND size_t first_that_in_array TEMPLATE_SUFFIX ( const PMIArray &, CompareMemFunc func, void * pars, size_t from ); + +private: + PMIArray( const PMIArray & ); // \ru запрещено !!! \en forbidden !!! + void operator =( const PMIArray & ); // \ru запрещено !!! \en forbidden !!! +}; + + +//------------------------------------------------------------------------------ +// \ru деструктор массива \en destructor of array +// --- +template +inline PArray::~PArray() { + PRECONDITION( nowDeletedElem == 0 ); + if ( owns ) + destroy_array( *this ); +} + + +//------------------------------------------------------------------------------ +// \ru обнулить количество элементов \en set the number of elements to null +// --- +template +inline void PArray::Flush( DelType del ) { + PRECONDITION( nowDeletedElem == 0 ); + + if ( del==Delete || (del==defDelete && owns) ) + destroy_array( *this ); + else + RPArray::count = 0; +} + + +//------------------------------------------------------------------------------ +// \ru Указать новый размер массива, если clear = true, то массив очистится !!! +// \en Set the new size of an array, if 'clear' is true than the array will be cleared !!! +// --- +template +inline bool PArray::SetSize( size_t newSize, bool clear ) { + return set_Parray_size( *this, newSize, clear ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива (по индексу) \en delete an element from array (by the index) +// --- +template +inline Type * PArray::RemoveInd( size_t delIndex, DelType del ) { + PRECONDITION( delIndex < RPArray::count ); + + const Type **d = RPArray::GetAddr() + delIndex; + Type *r = (Type*)*d; + + // \ru сначала приведем в порядок массив ... \en put an array in order at first ... + memmove( d, d+1, (RPArray::count - delIndex - 1) * SIZE_OF_POINTER ); + RPArray::count--; + + // \ru ... а теперь будем удалять \en ... and now we will delete + if ( del==Delete || (del==defDelete && owns) ) { + PRECONDITION( !r || nowDeletedElem != r ); + nowDeletedElem = r; + + delete r; + r = 0; + + nowDeletedElem = 0; + } + + return r; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива (по указателю) \en delete an element from array (by the pointer) +// --- +template +inline Type * PArray::RemoveObj( Type * delObject, DelType del ) { + PRECONDITION( nowDeletedElem == 0 ); // \ru временно, для отладки \en temporarily, for debugging + + size_t i = find_in_array( *this, delObject ); + return (i != SYS_MAX_T) ? RemoveInd(i, del) : 0; +} + + +//------------------------------------------------------------------------------- +// \ru удаление всех указателей, собранных в массиве \en deletion of all pointers from array +// --- +template +void destroy_array( PArray & arr ) { + size_t i = 0, oldCount = arr.count; + + arr.count = 0; // \ru сразу приведем в порядок массив ... \en put an array in order ... + + // \ru ... а теперь будем удалять \en ... and now we will delete + for( const Type **parr = arr.GetAddr(); i < oldCount; i++, parr++ ) { + + Type * del = (Type *)*parr; + *parr = 0; // \ru сначала обнулим указатель ... \en set pointer to null at first ... + + PRECONDITION( !del || arr.nowDeletedElem != del ); + arr.nowDeletedElem = del; // \ru временно \en temporarily + + delete del; // \ru ... а потом будем удалять \en ... and then delete + + arr.nowDeletedElem = 0; // \ru временно \en temporarily + } +} + + +//------------------------------------------------------------------------------ +// \ru Перераспределение памяти под новый размер массива. \en Reallocation of memory for the new size of array. +// --- +template +bool set_Parray_size( PArray & arr, size_t newSize, bool clear ) { + PRECONDITION( arr.nowDeletedElem == 0 ); // \ru временно \en temporarily + + if ( clear && arr.count ) + arr.Flush(); // \ru будет arr.count = 0; \en arr.count will be equal 0; + + if ( newSize < arr.count ) { + if ( arr.owns ) { + if ( newSize == 0 ) { + if ( arr.count ) + arr.Flush(); // \ru будет arr.count = 0; \en arr.count will be equal 0; + } + else + while ( arr.count > newSize ) + arr.RemoveInd( arr.count - 1 ); // \ru удалить элемент из массива (по индексу), count-- \en delete an element from array (by the index), count-- + } + + arr.count = newSize; + } + + return set_Rarray_size( arr, newSize ); +} + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию для каждого элемента \en perform the function for every element +// --- +//template +//inline void PIArray::ForEachI( IteratorFunc func ) const { +// \ru C3D_ASSERT( PArray::nowDeletedElem == 0 ); // временно \en C3D_ASSERT( PArray::nowDeletedElem == 0 ); // temporarily +//#if !defined ( __INTEL_COMPILER ) /// for Intel C++ Compiler +// for_each_in_array( *this, func ); +//#endif // __INTEL_COMPILER +//} + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию с параметрами для каждого элемента \en perform the function with parameters for every element +// --- +template +inline void PIArray::ForEachI( ParIteratorFunc func, void * pars ) const { + C3D_ASSERT( PArray::nowDeletedElem == 0 ); + for_each_in_array( *this, func, pars ); +} + + +//------------------------------------------------------------------------------ +// \ru найти элемент по условию \en find an element by condition +// --- +template +inline size_t PIArray::FirstThatI( CompareFunc func, void * pars, size_t from ) const { + C3D_ASSERT( PArray::nowDeletedElem == 0 ); + return first_that_in_array( *this, func, pars, from ); +} + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию для каждого элемента \en perform the function for every element +// --- +//template +//inline void PMIArray::ForEach( IteratorMemFunc func ) const { +// \ru C3D_ASSERT( PArray::nowDeletedElem == 0 ); +//#if !defined ( __INTEL_COMPILER ) /// for Intel C++ Compiler +// for_each_in_array( *this, func ); +//#endif // __INTEL_COMPILER +//} + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию с параметрами для каждого элемента \en perform the function with parameters for every element +// --- +template +inline void PMIArray::ForEach( ParIteratorMemFunc func, void * pars ) const { + C3D_ASSERT( PArray::nowDeletedElem == 0 ); + for_each_in_array( *this, func, pars ); +} + + +//------------------------------------------------------------------------------ +// \ru найти элемент по условию \en find an element by condition +// --- +template +inline size_t PMIArray::FirstThat( CompareMemFunc func, void * pars, size_t from ) const { + C3D_ASSERT( PArray::nowDeletedElem == 0 ); + return first_that_in_array( *this, func, pars, from ); +} + + +//------------------------------------------------------------------------------- +// \ru вызвать итераторную функцию для каждого объекта массива \en call iterator function for every object of an array +// --- +template +void for_each_in_array( const PIArray& arr, void ( *func ) ( Type * ) ) { + for( size_t i = 0; i < arr.Count(); i++ ) + func( arr[i] ); +} + + +//------------------------------------------------------------------------------- +// \ru вызвать итераторную функцию для каждого объекта массива \en call iterator function for every object of an array +// --- +template +void for_each_in_array( const PIArray & arr, void ( *func ) ( Type *, void * ), void * pars ) { + for( size_t i = 0; i < arr.Count(); i++ ) + func( arr[i], pars ); +} + + +//------------------------------------------------------------------------------- +// \ru найти объект, удовлетворяющий условию, которое проверяется в присланной функции \en find an object satisfying the condition which is verified in the given function +// --- +template +size_t first_that_in_array( const PIArray & arr, int ( *func ) ( Type *, void * ), void * pars, size_t from ) { + for( size_t i = from; i < arr.Count(); i++ ) + if ( func( arr[i], pars ) ) + return i; + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// \ru вызвать итераторную функцию-метод для каждого объекта массива \en call iterator function-method for every object of an array +// --- +template +void for_each_in_array( const PMIArray & arr, void ( Type::*func ) (void) ) { + for( size_t i = 0; i < arr.Count(); i++ ) + (arr[i]->*func)(); +} + + +//------------------------------------------------------------------------------- +// \ru вызвать итераторную функцию-метод для каждого объекта массива \en call iterator function-method for every object of an array +// --- +template +void for_each_in_array( const PMIArray & arr, void ( Type::*func ) (void *), void * pars ) { + for( size_t i = 0; i < arr.Count(); i++ ) + (arr[i]->*func)( pars ); +} + + +//------------------------------------------------------------------------------- +// \ru найти объект, удовлетворяющий условию, которое проверяется в присланной функции-методе \en find an object satisfying the condition which is verified in the sent function-method +// --- +template +size_t first_that_in_array( const PMIArray & arr, bool ( Type::*func ) (void *), void * pars, size_t from ) { + for( size_t i = from; i < arr.Count(); i++ ) + if ( (arr[i]->*func)(pars) ) + return i; + + return SYS_MAX_T; +} + + +#endif // __TEMPL_P_ARRAY_H diff --git a/C3d/Include/templ_p_array_rw.h b/C3d/Include/templ_p_array_rw.h new file mode 100644 index 0000000..4b42c85 --- /dev/null +++ b/C3d/Include/templ_p_array_rw.h @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация PArray. + \en Serialization of PArray. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_P_ARRAY_RW_H +#define __TEMPL_P_ARRAY_RW_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +// \ru Чтение массива из потока в объект (на добавление объектов к существующему массиву не рассчитано). \en Reading of array from a stream to an object (adding new objects to an existed array is not supported). +// --- +template +reader & operator >> ( reader & in, PArray & ref ) +{ + ref.Flush(); + + if ( in.good() ) + { + uint8 owns; + in >> owns; + + const size_t count = ReadCOUNT( in, true/*uint_val*/ ); + + if ( in.good() ) + { + ref.owns = !!owns; + + if ( count ) + { + // \ru половина адресного пространства для 32-разрядного приложения \en a half of address space for 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, count ) ) + { + ref.SetSize( count, true/*clear*/ ); + + const Type ** parr = ref.GetAddr(); + + if ( parr != NULL ) + { + ref.count = 0; // \ru Err #69421 сколько штук реально прочитано \en Err #69421 how many elements were actually counted + + size_t i; + // \ru поочередное чтение объектов массива \en successive reading of objects from an array + for ( i = 0; i < count && in.good(); i++ ) + { + Type * el = NULL; + in >> el; + parr[i] = el; + + ref.count++; // \ru Err #69421 сколько штук реально прочитано \en Err #69421 how many elements were actually counted + + // \ru были записаны не все данные (при условии что запись массива эмулировалась, \en not all data has been written (in condition that writing of array was emulated, + // \ru писалось не через operator << (writer& out, const PArray& ref) ) \en it was written without the operator << (writer& out, const PArray& ref) ) + if ( in.eof() ) // \ru вычитали-ли весь файл и ничего не осталось \en the whole file was read and nothing is left + break; // for + } + } + else + { + ref.SetSize( 0, true/*clear*/ ); + C3D_ASSERT_UNCONDITIONAL( false ); + } + + // \ru количество прочитанных должно совпадать с количеством записанных \en the number of read elemetns should be equal to the number of written elements + if ( ref.count != count ) + { + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не все эл-ты прочитаны \en not all elements was read + in.setState( io::fail ); // \ru есть ошибка \en there is an error + } + // \ru Err #69421 ref.count = i; // сколько штук реально прочитано \en Err #69421 ref.count = i; // how many elements were actually read + } + else { + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не бывает столько памяти \en incorrect size of memory + in.setState( io::fail ); // \ru ошибка чтения \en reading error + } + } + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer & operator << ( writer& out, const PArray & ref ) +{ + if ( out.good() ) { + out << uint8(ref.owns); + + WriteCOUNT( out, ref.count ); + + const Type **parr = ref.GetAddr(); + for ( size_t i = 0; i < ref.count && out.good(); i++ ) { + Type *el = (Type *)parr[i]; + out << el; + } + } + else + C3D_ASSERT_UNCONDITIONAL( false ); // \ru Ошибка Записи \en Writing Error + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в указатель \en reading of array from a stream to a pointer +// --- +template +reader & operator >> ( reader & in, PArray *& ptr ) +{ + ptr = NULL; + if ( in.good() ) { + if ( in.MathVersion() < 0x06000012L ) + ptr = new PArray; + else { + uint8 existPtr; + in >> existPtr; + if ( existPtr ) + ptr = new PArray; + } + + if ( ptr ) + in >> *ptr; + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из указателя \en writing of array from a pointer to a stream +// --- +template +writer & operator << ( writer & out, const PArray * ptr ) +{ + // \ru при записи в старую версию оставляю без проверки указателя \en While writing to an old version the pointer is not checked + if ( out.MathVersion() < 0x06000012L ) { + C3D_ASSERT( ptr ); + out << *ptr; + } + else { + uint8 existPtr = !!ptr; + out << existPtr; + if ( existPtr ) + out << *ptr; // \ru запись телом \en writing by a solid + } + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в объект \en reading of array from a stream to an object +// --- +template +reader & operator >> ( reader & in, SPArray & ref ) { + return in >> (PArray &)ref; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer & operator << ( writer & out, const SPArray & ref ) { + return out << (const PArray &)ref; +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в объект \en reading of array from a stream to an object +// +template +reader & operator >> ( reader & in, CSPArray & ref ) { + in >> (SPArray &)ref; + int b; in >> b; ref.m_sort = !!b; //OV_x64 in >> ref.sort; + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer& operator << ( writer & out, const CSPArray & ref ) { + out << (const SPArray &)ref; + int b = !!ref.m_sort; out << b; //OV_x64 out << ref.sort; + return out; +} + + +#endif // __TEMPL_P_ARRAY_RW_H diff --git a/C3d/Include/templ_parameter.h b/C3d/Include/templ_parameter.h new file mode 100644 index 0000000..5c9b2ea --- /dev/null +++ b/C3d/Include/templ_parameter.h @@ -0,0 +1,170 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Параметр с контролем измененности. + \en Paramenter with the control of being changed. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_PARAMETER_H +#define __TEMPL_PARAMETER_H + +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Предназначен для контроля измененности значения по отношении к настроенному \en Template is used for the control that the value has been changed in relation to configured value +// +//////////////////////////////////////////////////////////////////////////////// +template class Param +{ + T m_value; // \ru значение параметра \en a Parameter value + bool m_bHandChanged; // \ru параметр изменен вручную и значение не соответствует настройкам документа \en a parameter has been changed manually and the value does not match the document settings + +public : + Param( const T & ); + Param( const Param & ); + + /// \ru проверить параметр на измененность \en check whether parameter has been changed + bool IsHandChanged() const; + + /// \ru установить флаг, что парамерт изменен из API нужно сбрасывать флаг \en set the flag that parameter has been changed, the flag should be reset from API + void SetHandChanged( bool change = true ); + + /// \ru сопоставить значение с умолчательным и при различии взвести флаг m_bHandChanged \en compare the value with default value and set the flag m_bHandChanged = true if they are different + void CheckHandChanged ( const T & ); + + /// \ru проинициализировать новым значением, если не было изменено ранее вручную \en initialize by a new value if it was not changed by hand earlier + void InitIfNoHandChange( const T & ); + + /// \ru получить значение \en get the value + const T & GetValue() const; + + void operator = ( const Param & ); + void operator = ( const T & ); + /// \ru чтение/запись из потока \en reading/writing from stream + void Read ( reader & in ); + void Write( writer & ) const; +}; + + +//------------------------------------------------------------------------------- +// +// --- +template +Param::Param ( const T & val ) : + m_value ( val ), + m_bHandChanged( false ) +{ +} + + +//------------------------------------------------------------------------------- +// +// --- +template +Param::Param( const Param & other ) : + m_value ( other.m_value ), + m_bHandChanged( other.m_bHandChanged ) +{ +} + + +//------------------------------------------------------------------------------- +/// \ru проверить параметр на измененность \en check whether parameter has been changed +// --- +template +bool Param::IsHandChanged() const +{ + return m_bHandChanged; +} + + +//------------------------------------------------------------------------------- +/// \ru установить флаг, что парамерт изменен \en set the flag that parameter has been changed +// --- +template +void Param::SetHandChanged( bool change/* = true*/ ) +{ + m_bHandChanged = change; +} + + +//------------------------------------------------------------------------------- +/// \ru сопоставить значение с умолчательным и при различии взвести флаг m_bHandChanged \en compare the value with default value and set the flag m_bHandChanged = true if they are different +// --- +template +void Param::CheckHandChanged( const T & val ) +{ + if ( m_value != val ) + m_bHandChanged = true; +} + + +//------------------------------------------------------------------------------- +/// \ru проинициализировать новым значением, если не было изменено ранее вручную \en initialize by a new value if it was not changed by hand earlier +// --- +template +void Param::InitIfNoHandChange( const T & val ) +{ + if ( !m_bHandChanged ) + m_value = val; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +const T & Param::GetValue() const +{ + return m_value; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +void Param::operator = ( const Param & other ) +{ + m_value = other.m_value; + m_bHandChanged = other.m_bHandChanged; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +void Param::operator = ( const T & val ) +{ + m_value = val; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +void Param::Read ( reader & in ) +{ + in >> m_value; + in >> m_bHandChanged; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +void Param::Write( writer & out ) const +{ + out << m_value; + out << m_bHandChanged; +} + + +#endif // __TEMPL_PARAMETER_H diff --git a/C3d/Include/templ_pointer.h b/C3d/Include/templ_pointer.h new file mode 100644 index 0000000..01b7469 --- /dev/null +++ b/C3d/Include/templ_pointer.h @@ -0,0 +1,295 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Автоматический указатель. + \en Smart pointer. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_POINTER_H +#define __TEMPL_POINTER_H + + +#ifndef NULL +#define NULL 0 +#endif + + +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// A pair of smart pointer template classes. Provides basic conversion +// operator to T*, as well as dereferencing (*), and 0-checking (!). +// These classes assume that they alone are responsible for deleting the +// object or array unless Relinquish() is called. +// +//////////////////////////////////////////////////////////////////////////////// + + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый класс автоматического указателя. + \en Base class of smart pointer. \~ + \details \ru Базовый класс автоматического указателя. \n + \en Base class of smart pointer. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class TPointerBase { +public: + T & operator * () const { return *P; } + operator T* () const { return P; } + + int operator ! () const { return (P == NULL);} + T * Relinquish() {T * p = P; P = NULL; return p;} + + T * Get() { return P; } + const T * Get() const { return P; } + +protected: + TPointerBase( T * pointer ) : P(pointer) {} + TPointerBase() : P( NULL ) {} +protected: + T * P; +private: + void * operator new( size_t ); // prohibit use of new + void operator delete( void * p ) { ((TPointerBase*)p)->P = NULL; } + +// СМВ К15 MVS 2012 +private: + TPointerBase( const TPointerBase & other ); +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + TPointerBase( TPointerBase && _Right ): P( _Right.P ) { _Right.P = nullptr; } + TPointerBase & operator = ( TPointerBase && _Right ) + { + if ( this != &_Right ) + { P = _Right.P; _Right.P = nullptr; } + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель на объект. + \en A smart pointer to an object. \~ + \details \ru Автоматический указатель на объект. + Обеспечивает доступ через оператор "->". \n + \en A smart pointer to an object. + Provides an access by the operator "->". \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class TPointer : public TPointerBase { +public: + TPointer() : TPointerBase() {} + TPointer( T * pointer ) : TPointerBase( pointer ) {} + ~TPointer() + { + delete TPointerBase::P; + } +public: + TPointer & operator = ( T * src ) + { + if ( src != TPointerBase::P ) + { + delete TPointerBase::P; + TPointerBase::P = src; + } + return *this; + } + T * operator ->() { return TPointerBase::P; } // Could throw exception if P==0 + const T * operator ->() const { return TPointerBase::P; } // Could throw exception if P==0 + +// СМВ К15 MVS 2012 +#ifndef __MOBILE_VERSION__ +private: +#endif // __MOBILE_VERSION__ + TPointer( const TPointer & other ); + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + TPointer( TPointer && _Right ) + : TPointerBase( std::move(_Right) ) + { } + TPointer & operator = ( TPointer && _Right ) + { + if ( this != &_Right ) + { + delete TPointerBase::P; + TPointerBase::P = _Right.P; + _Right.P = nullptr; + } + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель на объект. + \en A smart pointer to an object. \~ + \details \ru Автоматический указатель на объект. + Обеспечивает доступ через оператор "->". + Есть флаг владения объектом. \n + \en A smart pointer to an object. + Provides an access by the operator "->". + There is a flag of ownership of object. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class TOwnPointer : public TPointerBase { + bool own; // own = false - no delete +public: + TOwnPointer() : TPointerBase(), own(true) {} + TOwnPointer( T * pointer ) : TPointerBase(pointer), own(true) {} + ~TOwnPointer() + { + if ( own ) + delete TPointerBase::P; + } +public: + TOwnPointer & operator = ( T * src ) + { + if ( src != TPointerBase::P ) + { + if ( own ) + delete TPointerBase::P; + TPointerBase::P = src; + } + return *this; + } + T * operator ->() { return TPointerBase::P; } // Could throw exception if P==0 + bool GetOwn() const { return own; } + void SetOwn( bool val ) { own = val; } + +// СМВ К15 MVS 2012 +private: + TOwnPointer( const TOwnPointer & other ); + TOwnPointer & operator = ( const TOwnPointer & _Right ); +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + TOwnPointer( TOwnPointer && _Right ) + : TPointerBase( std::move(_Right) ) + , own ( std::move(_Right.own) ) + { } + TOwnPointer & operator = ( TOwnPointer && _Right ) + { + if ( this != &_Right ) + { + if ( own ) + delete TPointerBase::P; + TPointerBase::P = _Right.P; + own = _Right.own; + _Right.P = nullptr; + } + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель на массив объектов. + \en A smart pointer to an array of objects. \~ + \details \ru Автоматический указатель на массив объектов. + Обеспечивает доступ к элементам массива по индексу. + Удаляет массив через delete[]. \n + \en A smart pointer to an array of objects. + Provides an access to elements of array by index. + Deletes an array by the operator delete[]. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class TAPointer : public TPointerBase { +public: + TAPointer() : TPointerBase() {} + TAPointer( T* array ) : TPointerBase( array ) {} + ~TAPointer() + { + delete[] TPointerBase::P; + } +public: + TAPointer & operator = ( T * src ) + { + if ( src != TPointerBase::P ) + { + delete[] TPointerBase::P; + TPointerBase::P = src; + } + return *this; + } + T & operator []( size_t i ) { return TPointerBase::P[i]; } // Could throw exception if P==0 + +// СМВ К15 MVS 2012 +//private: // g++4.7 KUbuntu + TAPointer( const TAPointer & other ); +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + TAPointer(TAPointer && _Right) + : TPointerBase( std::move(_Right) ) + { } + TAPointer & operator = (TAPointer && _Right) + { + if (this != &_Right) + { + delete[] TPointerBase::P; + TPointerBase::P = _Right.P; + _Right.P = nullptr; + } + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +//------------------------------------------------------------------------------ +// Obsolete, should use TAPointer for char[]'s +//--- +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель на массив символов. + \en A smart pointer to an array of symbols. \~ + \details \ru Автоматический указатель на массив символов. \n + \en A smart pointer to an array of symbols. \n \~ + \warning \ru Устаревший класс, пользуйтесь TAPointer + \en This class is out-of-date, use TAPointer \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template <> +class TPointer : public TPointerBase { +public: + TPointer() : TPointerBase() {} + TPointer( char pointer[] ) : TPointerBase( pointer ) {} + ~TPointer() { delete[] P; } +public: + char * operator = ( char src[] ) { delete[] P; return P = src; } + char * operator = ( const TPointer & src ) { delete[] P; return P = src.P; } + char & operator []( size_t i ) { return P[i]; } +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + TPointer( TPointer && _Right ) + : TPointerBase( std::move(_Right) ) + { } + TPointer & operator = ( TPointer && _Right ) + { + if ( this != &_Right ) + { + delete[] P; + P = _Right.P; + _Right.P = nullptr; + } + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +#endif // __TEMPL_POINTER_H diff --git a/C3d/Include/templ_psrt_array.h b/C3d/Include/templ_psrt_array.h new file mode 100644 index 0000000..0828801 --- /dev/null +++ b/C3d/Include/templ_psrt_array.h @@ -0,0 +1,729 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru parray c возможность сортировки по любому признаку + \en Array of pointers (of parray type) with ability of sorting by any criteria. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_PSRT_ARRAY_H +#define __TEMPL_PSRT_ARRAY_H + + +#include + + +#ifdef __FreeBSD__ +#include +#endif + + +//------------------------------------------------------------------------------ +// \ru константы для поиска \en constants for search +// --- +enum PArraySortFind { + // \ru граница выравнивания трудоемкости простого перебора с делением пополам \en balancing boundary of complexity of simple search with bisection + // \ru (а) для int ключа \en (a) for integer (int) key + // \ru ((4(*) + 4(/)) + 2(== >1) + 2(смещ2)) / (1(== >1) + 1(смещ2)) = 5 трудоемкость одной итерации поиска, \en ((4(*) + 4(/)) + 2(== >1) + 2(смещ2)) / (1(== >1) + 1(смещ2)) = 5 complexity of one iteration of search, + // \ru выравнивание при ~ 25 (5 делений(32) - 25 сравнений) \en balancing for ~ 25 (5 bisections (32) - 25 comparisons) + // \ru (b) для double ключа \en (b) for double key + // \ru ((4(*) + 4(/)) + 2(== >2) + 2(смещ2)) / (1(== >2) + 1(смещ2)) = 4 трудоемкость одной итерации поиска, \en ((4(*) + 4(/)) + 2(== >2) + 2(смещ2)) / (1(== >2) + 1(смещ2)) = 4 complexity of one iteration of search, + // \ru выравнивание при ~ 20 (5 делений(32) - 20 сравнений) \en balancing for ~ 20 (5 bisections (32) - 20 comparisons) + paf_Flat = 20, // \ru для double если меньше 20 элементов простой перебор выгодней \en simple search is more advantageous for double values if the number of elements is less than 20 + paf_Bytwo = 4096, + paf_Byline = 2048, +}; + + +//------------------------------------------------------------------------------ +// +// --- +enum PArraySortDivide { + pad_Two = 2, + pad_Line = 10, +}; + + +//------------------------------------------------------------------------------ +// +// --- +enum PArraySortMemory { + pam_1 = 100, + pam_1Delta = 10, + pam_2 = 1000, + pam_2Delta = 200, + pam_3 = 10000, + pam_3Delta = 2300, + pam_4 = 100000, + pam_4Delta = 27182, +}; + + +//------------------------------------------------------------------------------ +// +// --- +enum PResSO { + pso_More, + pso_Less, + pso_Equal, +}; + + +//------------------------------------------------------------------------------ +// +// --- +class PArrayReg { +public: + size_t armin; + size_t armax; +public: + PArrayReg( size_t oMin, size_t oMax = SYS_MAX_T ) + : armin( oMin ) + , armax( oMax ) + {} +}; + + +//------------------------------------------------------------------------------ +// \ru массив указателей с быстрой сортировкой и поиском \en array of pointers with quick sorting and searching +// --- +template +class PArraySort : public PArray { +private: + typedef size_t (*PArSortAddress )( const Type * ); + typedef size_t (*PArSortObj )( const void *, const Type * ); + typedef bool (*PArSortRangeCompFunc)( const void *, const Type *, const Type * ); + +public: + PArraySort( size_t i_upper = 5, uint16 i_delta = 5, bool shouldDelete = true ); // \ru конструктор \en constructor + + void Add ( Type * ent ); // \ru добавить элемент в конец массива \en add element to the end of array + void AddAt ( Type * ent, size_t k ) { Insert( k, ent ); } + void AddAfter ( Type * ent, size_t k ); // \ru добавить элемент после указанного \en add element after specified one + void Add ( PArray & ); // \ru добавить массив \en add array + void Add ( PArray &, size_t k ); // \ru добавить массив в позицию \en add array to the position + void Insert ( size_t k, Type * ent ); // \ru вставить элемент перед указанным \en insert element before the specified one + + void RemoveRng ( size_t, size_t, DelType del = defDelete ); // \ru удалить диапазон указателей из массива \en delete a range of pointers from array + void DetachRng ( size_t, size_t ); // \ru отцепить из массива диапазон указателей \en detach a range of pointers from array + + typedef int (*PArSortCompFunc)( const Type **, const Type ** ); + void Sort ( PArSortCompFunc, PArrayReg * = NULL ); // \ru быстрая сортировка в любом диапазоне \en quick sorting in any range + void Sort ( const void *, PArSortRangeCompFunc, size_t armin = 0, size_t armax = SYS_MAX_T ); // \ru быстрая сортировка в заданном диапазоне \en quick sorting in a given range + bool Find ( const Type *, PArSortAddress, size_t &, size_t armin = 0, size_t armax = SYS_MAX_T ); // \ru найти адрес в любом поле объекта \en find address in any field of object + bool Find ( const size_t, PArSortAddress, size_t &, size_t armin = 0, size_t armax = SYS_MAX_T ); // \ru найти адрес в любом поле объекта \en find address in any field of object + bool Find ( const void *, PArSortObj, size_t &, size_t armin = 0, size_t armax = SYS_MAX_T ); // \ru найти данный объект в сортированном массиве \en find a given object in sorted array + + int FindObj ( const Type *, PArSortCompFunc, size_t &, PArrayReg * = NULL ) const; // \ru найти данный объект в сортированном массиве \en find a given object in sorted array + Type * AddSort ( Type *, PArSortCompFunc, size_t & ); // \ru добавить элемент в сортированном порядке \en add element in sorted order + + void Inverse (); // \ru инверсия массива \en inversion of array + + void Reserve ( size_t n ); // \ru зарезервировать место под n элементов \en reserve memory for n elements + +private: + bool FindObject ( const void *, PArSortObj, size_t &, size_t, size_t ); // \ru найти данный объект в сортированном массиве \en find a given object in sorted array + bool FindAddress ( const size_t, PArSortAddress, size_t &, size_t, size_t ); // \ru найти адрес в любом поле объекта \en find address in any field of object + void SortRange ( const void *, PArSortRangeCompFunc, size_t, size_t ); // \ru быстрая сортировка в заданном диапазоне \en quick sorting in a given range + void CatchMemory (); // \ru захват памяти \en capture of memory + size_t CalculateDelta(); + +private: + PArraySort( const PArraySort & ); // \ru не реализовано \en not implemented + void operator = ( const PArraySort & ); // \ru не реализовано \en not implemented +}; + + +//----------------------------------------------------------------------------- +// \ru конструктор \en constructor +// --- +template +inline PArraySort::PArraySort( size_t i_upper, uint16 i_delta, bool shouldDelete ) + : PArray( i_upper, i_delta, shouldDelete ) { +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// --- +template +inline void PArraySort::Add( PArray & o ) +{ + PArray::AddArray( o ); + if ( PArray::owns ) + o.OwnsElem( false ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// --- +template +inline void PArraySort::Add( PArray & o, size_t index ) +{ + PArray::InsertArray( o, index ); + if ( PArray::owns ) + o.OwnsElem( false ); +} + + +//----------------------------------------------------------------------------- +// \ru добавить элемент \en add element +// --- +template +inline void PArraySort::Add( Type * ent ) +{ + CatchMemory(); + this->operator[]( PArray::count++ ) = ent; +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// --- +template +inline void PArraySort::AddAfter( Type * ent, size_t index ) +{ + if ( ! PArray::count ) + Add( ent ); + else { + CatchMemory(); // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + PArray::AddAfter( ent, index ); + } +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент \en insert element +// --- +template +inline void PArraySort::Insert( size_t index, Type * ent ) +{ + CatchMemory(); // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + PArray::Insert( index, ent ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить диапазон из массива \en delete a range from array +// --- +template +void PArraySort::RemoveRng( size_t startIndex, size_t countRng, DelType del ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + // \ru если диапазон не пуст и индекс принадлежит массиву \en if range is not empty and index belongs to array + if ( countRng && startIndex < PArray::count ) { + + // \ru корректируем размер удаляемого региона \en correct the deleted region size + if ( startIndex + countRng > PArray::count ) + countRng = PArray::count - startIndex; + + // \ru вычислить флаг необходимости удаления объектов \en calculate a flag of necessity to delete objects + if ( del == Delete || ( del == defDelete && PArray::owns ) ) { + + // \ru будем удалять \en to delete + size_t i = 0; + for( const Type ** parr = PArray::GetAddr() + startIndex; i < countRng; i++, parr++ ) { + Type * d = (Type*)*parr; + *parr = 0; // \ru сначала обнулим указатель ... \en set pointer to null ... + + C3D_ASSERT( !d || PArray::nowDeletedElem != d ); // \ru ЯТ - временно \en ЯТ - temporarily + PArray::nowDeletedElem = d; + + delete d; + + PArray::nowDeletedElem = 0; + } + } + + // \ru вычислить новую позицию \en calculate a new position + size_t newPos = startIndex + countRng; + + // \ru передвинуть элементы в конце на стартовую позицию \en move elements at the end to the start position + const Type **parr = PArray::GetAddr(); + + memcpy( (void*)(parr + startIndex), (void*)(parr + newPos), (PArray::count - newPos) * SIZE_OF_POINTER ); + + PArray::count -= countRng; // \ru установить новое количество элементов в массиве \en set a new number of elements in array + } +} + + +//------------------------------------------------------------------------------ +// \ru Отсоединить от массива диапазон указателей без удаления \en Detach from array a range of pointers without deletion +// --- +template +inline void PArraySort::DetachRng( size_t startIndex, size_t countRng ) { + RemoveRng( startIndex, countRng, noDelete ); +} + + +//------------------------------------------------------------------------------ +// \ru Определить величину приращения \en Determine a value of increment +// --- +template +inline size_t PArraySort::CalculateDelta() +{ + if ( PArray::count > pam_1/*100*/ ) { + if ( PArray::count < pam_2/*1000*/ ) { + if ( PArray::delta < (uint16)pam_1Delta/*10*/ ) + PArray::delta = (uint16)pam_1Delta; + } + else if ( PArray::count < pam_3/*10000*/ ) { + if ( PArray::delta < (uint16)pam_2Delta/*200*/ ) + PArray::delta = (uint16)pam_2Delta; + } + else if ( PArray::count < pam_4/*100000*/ ) { + if ( PArray::delta < (uint16)pam_3Delta/*2300*/ ) + PArray::delta = (uint16)pam_3Delta; + } + else { // >= 100000 + if ( PArray::delta < (uint16)pam_4Delta/*27182*/ ) + PArray::delta = (uint16)pam_4Delta; + } + } + return PArray::delta; +} + + +//----------------------------------------------------------------------------- +// \ru захват большего куска памяти ( если нужно ) \en allocate the larger piece of memory (if it is necessary) +// --- +template +inline void PArraySort::CatchMemory() +{ + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + if ( PArray::upper == PArray::count ) + set_Parray_size( *this, PArray::upper + CalculateDelta(), false/*clear*/ ); +} + + +//------------------------------------------------------------------------------ +// \ru зарезервировать место под n элементов \en reserve memory for n elements +// --- +template +inline void PArraySort::Reserve( size_t n ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + // \ru если требуется памяти больше, чем есть сейчас, и больше, чем оказалось бы \en if there is required more memory that exists at the moment and more than it would become + // \ru при следующем захвате, то захватить ее \en on the next allocation then allocate it + size_t space = PArray::upper - PArray::count; + if ( space < n && (space + CalculateDelta() < n) ) + set_Parray_size( *this, PArray::count + n, false/*clear*/ ); +} + + +//----------------------------------------------------------------------------- +// \ru быстрая сортировка всего массива по признаку заданному функцией fcmp \en quick sort of the whole array with the specified by the function 'fcmp' criteria +// --- +template +inline void PArraySort::Sort( PArSortCompFunc fcmp, PArrayReg * arReg ) +{ + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + if ( PArray::count > 1 ) { // \ru если хотя бы два элемента в массиве \en if there are at least two elements in array + typedef int (*QCompFunc)( const void*, const void* ); + if ( !arReg ) { + ::qsort( (void *) PArray::GetAddr(), PArray::count, sizeof(size_t), (QCompFunc)fcmp ); + } + else if ( arReg->armin < arReg->armax ) { // \ru если сортируемый диапазон правильный \en if the sorted range is correct + size_t maxInd = PArray::count - 1; + // \ru если минимальная граница меньше максимального элемента в массиве \en if the minimum bound is less than the maximum element in array + if ( arReg->armin < maxInd ) { + if ( arReg->armax > maxInd ) + arReg->armax = maxInd; + ::qsort( (void *)( PArray::GetAddr() + arReg->armin), (arReg->armax - arReg->armin + 1), sizeof(size_t), (QCompFunc)fcmp ); + } + } + } +} + + +//----------------------------------------------------------------------------- +// \ru быстрая сортировка в заданном диапазоне по признаку заданному функцией fcmp \en quick sort of the given range with the specified by the function 'fcmp' criteria +// --- +template +inline void PArraySort::Sort( const void * obj, PArSortRangeCompFunc fcmp, size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + if ( PArray::count > 1 ) { // \ru если хотя бы два элемента в массиве \en if there are at least two elements in array + if ( armax > armin ) { // \ru если диапазон сортировки правильный \en if the sorting range is correct + if ( armin < PArray::count - 1 ) { // \ru если минимальная граница меньше максимального элемента в массиве \en if the minimum bound is less than the maximum element in array + if ( armax >= PArray::count ) // \ru если максимальная граница больше или равна максимальному индексу плюс один \en if the maximum boundis not less than maximum index plus one + armax = PArray::count - 1; // \ru установить armax равным максимальному индексу в массиве \en set 'armax' to be equal to the maximum index in array + SortRange( obj, fcmp, armin, armax ); // \ru функция быстрой сортировки \en the quick sort function + } + } + } +} + + +//----------------------------------------------------------------------------- +// \ru быстрая сортировка в заданном диапазоне по признаку заданному функцией fcmp \en quick sort of the given range with the specified by the function 'fcmp' criteria +// --- +template +void PArraySort::SortRange( const void * obj, PArSortRangeCompFunc fcmp, size_t ilo, size_t ihi ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + size_t lo = ilo; // \ru нижняя граница \en lower bound + size_t hi = ihi; // \ru верхняя граница \en upper bound + + const Type * mid = (const Type*)(*this)/*parr*/[(lo + hi) / 2]; // \ru найти значение в середине диапазона \en find the value in the middle of the range + + do { // \ru до тех пор пока верхняя граница больше или равна нижней \en until the upper bound is not less than the lower bound + while ( !fcmp(obj, (const Type*)(*this)/*parr*/[lo], mid ) ) + lo++; // \ru если нет необходимости переставлять нижний индекс \en if there is no reason to change position of the lower index + + while ( !fcmp(obj, mid, (const Type*)(*this)/*parr*/[hi]) ) + hi--; // \ru если нет необходимости переставлять верхний индекс \en if there is no reason to change position of the upper index + + if ( lo <= hi ) { // \ru если нижняя граница меньше или равна верхней то \en if the lower bound is not greater than the upper bound then + Type *t = (*this)/*parr*/[lo]; // \ru переставить объекты в массиве \en exchange positions of objects in array + (*this)/*parr*/[lo] = (*this)/*parr*/[hi]; + (*this)/*parr*/[hi] = t; + lo++; // \ru сдвинуть границу \en move the bound + hi--; + } + else + break; + + } while ( true ); + + if ( hi > ilo ) // \ru рекурсия для верхней и нижней границы \en recursion for upper and lower bounds + SortRange( obj, fcmp, ilo, hi ); + + if ( lo < ihi ) + SortRange( obj, fcmp, lo, ihi ); +} + + +//----------------------------------------------------------------------------- +// \ru найти адрес в любом поле объекта \en find address in any field of object +// --- +template +inline bool PArraySort::Find( const size_t address, PArSortAddress fadr, size_t & findedAddress, + size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + bool res = false; + + findedAddress = SYS_MAX_T/*OV_x64 -1*/; + + if ( PArray::count && armin < PArray::count && armax >= armin ) { + + if ( armax >= PArray::count ) { + armax = PArray::count; + armax--; + } + + findedAddress = armax; + findedAddress++; + + res = FindAddress( address, fadr, findedAddress, armin, armax ); + } + + return res; +} + + +//----------------------------------------------------------------------------- +// \ru найти адрес в любом поле объекта \en find address in any field of object +// --- +template +inline bool PArraySort::Find( const Type * member, PArSortAddress fadr, size_t & findedAddress, size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + return Find( fadr(member), fadr, findedAddress, armin, armax ); +} + + +//------------------------------------------------------------------------------ +// \ru найти данный объект в сортированном массиве \en find a given object in sorted array +// --- +template +inline bool PArraySort::Find( const void * obj, PArSortObj fobj, size_t & findedId, size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + bool res = false; + + findedId = SYS_MAX_T; + + if ( PArray::count && armin < PArray::count && armax >= armin ) { + + if ( armax >= PArray::count ) { + armax = PArray::count; + armax--; + } + + findedId = armax; + findedId++; + + res = FindObject( obj, fobj, findedId, armin, armax ); + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru найти данный объект в сортированном массиве \en find a given object in sorted array +// --- +template +bool PArraySort::FindObject( const void * obj, PArSortObj fobj, size_t & findedId, size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + bool res = false; // \ru флаг, который указывает существует ли искомый объект в массиве \en flag which specifies whether the required object is in array + + size_t id = armax - armin; // \ru количество элементов в диапазоне \en the number of elements in range + + if ( id < paf_Flat ) { // \ru если количество элементов в диапазоне небольшое, то просматриваем сначала \en if the number of elements in range is not too large then start search from the beginning + + for ( size_t i = armin; i <= armax; i++ ) { // \ru (т.к. одно умножение в 4 раза дольше сравнения) \en (because one multiplying takes in 4 times more time than a comparison) + size_t pso = fobj( obj, (*this)/*parr*/[i] ); + + if ( !(pso == pso_More) ) { // \ru возвращаем номер вершины \en return a number of vertex + res = pso == pso_Equal; + findedId = i; + break; + } + } + } + else { + // \ru находим вершину находящуюся в середине диапазона (целочисленное деление) \en find a vertex in the middle of range (integer division) + size_t half = id / pad_Two + armin; + size_t pso = fobj( obj, (*this)/*parr*/[half] ); + + if ( pso == pso_More ) + armin = half; + else + armax = half; + + res = FindObject( obj, fobj, findedId, armin, armax ); // \ru рекурсивно вызываем функцию с новым диапазоном \en recursively call the function with new range + } + + return res; +} + + +//----------------------------------------------------------------------------- +// \ru найти адрес в любом поле объекта \en find address in any field of object +// --- +template +bool PArraySort::FindAddress( const size_t address, PArSortAddress fadr, size_t & findedAddress, size_t armin, size_t armax ) +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + bool res = false; // \ru флаг, который указывает существует ли искомый адресс в массиве \en flag which specifies whether the required address is in array + size_t id = armax - armin; // \ru количество элементов в диапазоне \en the number of elements in range + + if ( id < paf_Flat ) { // \ru если количество элементов в диапазоне не большое, то просматривем сначала \en if the number of elements in range is not too large then start search from the beginning + + for ( size_t i = armin; i <= armax; i++ ) { // \ru (т.к. одно умножение в 4 раза дольше сравнения) \en (because one multiplying takes in 4 times more time than a comparison) + size_t currentAddress = fadr( (*this)/*parr*/[i] ); + + if ( !(currentAddress < address) ) { // \ru возвращаем номер вершины, \en return a number of vertex, + res = currentAddress == address; + findedAddress = i; + break; + } + } + } + else { + // \ru если количество элементов в массиве достаточное, то деление пополам \en if the number of elements in array is enough then perform a bisection + if ( id < paf_Bytwo ) { + // \ru находим вершину находящуюся в середине диапазона (целочисленное деление) \en find a vertex in the middle of range (integer division) + size_t half = id / pad_Two + armin; + size_t addressHalf = fadr( (*this)/*parr*/[half] ); + + if ( addressHalf < address ) + armin = half; + else + armax = half; + + res = FindAddress( address, fadr, findedAddress, armin, armax ); // \ru рекурсивно вызываем функцию с новым диапазоном \en recursively call the function with new range + } + else { // \ru если вершин очень много в массиве, то используем линейную аппроксимацию \en if there are too many vertices in array then use a linear approximation + size_t minAddress = fadr( (*this)/*parr*/[armin] ); // \ru минимальный адрес \en minimal address + + if ( minAddress != address ) { // \ru если не равен искомому адресу \en if it is not equal to the required address + size_t maxAddress = fadr( (*this)/*parr*/[armax] ); // \ru максимальный адрес в массиве \en maximal address in array + + size_t d = maxAddress - minAddress; // \ru диапазон адресов в массиве \en range of addresses in array + size_t i = ( address - minAddress ) * id / d + armin; // \ru предполагаемый индекс искомого адреса \en the expected index of the required address + + if ( i < armin ) // \ru выровнять диапазон \en justify the range + i = armin; + else if ( i > armax ) + i = armax; + + size_t middleAddress = fadr( (*this)/*parr*/[i] ); // \ru найти адрес вершины по данному индексу \en find the address of vertex by the given index + + if ( middleAddress < address ) { // \ru если искомый адрес больше \en if the required address is greater + + armin = i; // \ru установить нижнюю границу \en set the lower bound + id = armax - armin; // \ru вычислить новый диапазон индексов \en calculate the new range of indices + + if ( id > paf_Byline ) { // \ru если он достаточно большой оценить верхнюю границу \en if it is rather large then estimate the upper bound + size_t h = id / pad_Line + armin; + size_t haddress = fadr( (*this)/*parr*/[h] ); + + if ( haddress < address ) + armin = h; + else + armax = h; + } + + res = FindAddress( address, fadr, findedAddress, armin, armax ); + } + else { // \ru если искомый адрес меньше \en if the required address is less + + armax = i; // \ru установить верхнюю границу \en set the upper bound + id = armax - armin; // \ru вычислить новый диапазон индексов \en calculate the new range of indices + + if ( id > paf_Byline ) { // \ru если он достаточно большой оценить нижнюю границу \en if it is rather large then estimate the lower bound + size_t h = armax - id / pad_Line; + size_t haddress = fadr( (*this)/*parr*/[h] ); + + if ( haddress < address ) + armin = h; + else + armax = h; + } + + res = FindAddress( address, fadr, findedAddress, armin, armax ); + } + } + else { // \ru иначе искомая вершина находится в начале массива \en otherwise the required value is situated in the begin of array + res = true; + findedAddress = armin; + } + } + } + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru найти данный объект в сортированном массиве (!!!obj - обязан быть первым в fcmp!!!) \en find the given object in sorted array (!!! 'obj' sould be the first in 'fcmp' !!!) +// --- +template +int PArraySort::FindObj( const Type * obj, PArSortCompFunc fcmp, size_t & iFnd, PArrayReg * arReg ) const +{ + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + if ( (PArray::count) > 0 ) { + size_t id = PArray::count; // \ru количество элементов в диапазоне \en the number of elements in range + id--; + size_t armin, armax, half; + if ( !arReg ) { + if ( fcmp((const Type **)&obj, (const Type **)&((*this)[id])) > 0 ) { + iFnd = id; + return 2; + } + armin = 0; + armax = id; + } + else { + if ( arReg->armax < id ) { + if ( fcmp((const Type **)&obj, (const Type **)&((*this)[arReg->armax])) > 0 ) { + iFnd = arReg->armax; + return 1; + } + armax = arReg->armax; + } + else { + if ( fcmp((const Type **)&obj, (const Type **)&((*this)[id])) > 0 ) { + iFnd = id; + return 2; + } + armax = id; + } + armin = ( (arReg->armin < armax) ? arReg->armin : armax ); + id = ( armax - armin ); + } + int ires = fcmp( (const Type **)&obj, (const Type **)&((*this)[armin]) ); + if ( ires <= 0 ) { // \ru возвращаем номер вершины, \en return a number of vertex, + iFnd = armin; + return ires; + } + while ( id > paf_Flat ) { + id /= 2; + half = id + armin; + ires = fcmp( (const Type **)&obj, (const Type **)&((*this)[half]) ); + if ( ires > 0 ) { + armin = half; + } + else if ( ires < 0 ) { + armax = half; + } + else { + iFnd = half; + while ( (half > 0) && !fcmp((const Type **)&obj, (const Type **)&((*this)[--half])) ) + iFnd = half; + return 0; + } + } + // \ru если количество элементов в диапазоне не большое, то просматриваем сначала \en if the number of elements in range is not too large then start search from the beginning + for ( size_t i = armin; i <= armax; i++ ) { // \ru (т.к. одно умножение в 4 раза дольше сравнения) \en (because one multiplying takes in 4 times more time than a comparison) + ires = fcmp( (const Type **)&obj, (const Type **)&((*this)[i]) ); + if ( ires <= 0 ) { // \ru возвращаем номер вершины, \en return a number of vertex, + iFnd = i; + return ires; + } + } + iFnd = armax; + return 1; + } + return -2; +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент в сортированном порядке \en add element in sorted order +// --- +template +inline Type * PArraySort::AddSort( Type * obj, PArSortCompFunc fcmp, size_t & iFnd ) +{ + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + int ires = FindObj( obj, fcmp, iFnd ); + if ( (ires == -2) || (ires == 2) ) { + iFnd = ( (ires == -2) ? 0 : PArray::count ); + Add( obj ); + } + else + if ( ires == -1 ) + AddAt( obj, iFnd ); + + return ires ? (*this)/*parr*/[iFnd] : NULL; +} + + +//------------------------------------------------------------------------------ +// \ru инверсия массива \en inversion of array +// --- +template +void PArraySort::Inverse() +{ + C3D_ASSERT( PArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + if ( PArray::count ) { + size_t endI = PArray::count - 1; // \ru проверено count > 0 \en count > 0 validated + size_t fstI = 0; + + while ( (ptrdiff_t)fstI < (ptrdiff_t)endI ) { + + Type * fstObj = (*this)/*parr*/[fstI]; // \ru запомнить указатель на объект (это копия указателя!!!) \en remember the pointer to the object (this is the copy of the pointer!!!) + + (*this)/*parr*/[fstI] = (*this)/*parr*/[endI]; + (*this)/*parr*/[endI] = fstObj; + + fstI++; + endI--; + } + } +} + + +#endif // __TEMPL_PSRT_ARRAY_H diff --git a/C3d/Include/templ_rp_array.h b/C3d/Include/templ_rp_array.h new file mode 100644 index 0000000..730c59c --- /dev/null +++ b/C3d/Include/templ_rp_array.h @@ -0,0 +1,688 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Одномерный массив указателей. + \en One-dimensional array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_RP_ARRAY_H +#define __TEMPL_RP_ARRAY_H + +#include +#include +#include +#include +#include +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class RPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool set_Rarray_size( RPArray &, size_t newSize ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_in_array ( const RPArray & arr, const Type * el ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, RPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const RPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, RPArray *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const RPArray * ptr ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Одномерный массив указателей на объекты. + \en One-dimensional array of pointers to objects. \~ + \details \ru Шаблонный массив, работающий с указателями на объекты. \n + \en A template array working with pointers to objects. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class RPArray { +public: + /// \ru Имя указателя на объект. \en A name of the pointer to the object. + typedef Type * TPtr; + typedef Type * value_type; + typedef Type * const & const_reference; + typedef Type * & reference; + +protected: + size_t count; ///< \ru Количество элементов в массиве. \en The number of elements in array. + size_t upper; ///< \ru Под какое количество элементов выделена память. \en The number of elements the memory is allocated for. + uint16 delta; ///< \ru Приращение по количеству элементов при выделении дополнительной памяти. \en Increment by the number of elements while the allocation of additional memory. +private: + TPtr * parr; ///< \ru Указатель на первый элемент массива. \en A pointer to the first array element. + +public : + /// \ru Конструктор. \en Constructor. + RPArray(); + /// \ru Конструктор. \en Constructor. + RPArray ( size_t i_upper, uint16 i_delta = 1 );//, bool shouldNullSet = false ); + /// \ru Деструктор. \en Destructor. + virtual ~RPArray(); + +public: + + /// \ru Получить приращение по количеству элементов при выделении дополнительной памяти. \en Get the increment by the number of elements while the allocation of additional memory. + uint16 Delta() const { return delta; } + /// \ru Количество элементов, для которых выделена память? \en The number of elements the memory is allocated for. + size_t Upper() const { return upper; } + /// \ru Установить приращение по количеству элементов при выделении дополнительной памяти (1 - автоприращение). \en Set the increment by the number of elements while the allocation of additional memory (1 - autoincrement). + void Delta( uint16 newDelta ) { delta = newDelta; } + /// \ru Установить максимальное из приращений. \en Set the maximum increment. + void SetMaxDelta( uint16 newDelta ) { if ( delta < newDelta ) delta = newDelta; } + + /// \ru Функции, выделяющие потенциально большие участки памяти, возвращают результат операции (успех/ошибка). + /// \en Functions that allocate potentially large memory, return an operation result (success/error). + bool SetSize ( size_t newSize ); ///< \ru Установить новый размер массива. \en Set the new size of an array. + bool Reserve ( size_t n, bool addAdditionalSpace = true ); ///< \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + + bool Add ( Type * ); ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + bool AddAt ( Type * e, size_t index ) { return Insert( index, e ); } ///< \ru Вставить элемент в указанную позицию. \en Insert an element to the given position. + bool AddAfter( Type * e, size_t index ); ///< \ru Добавить элемент после указанного. \en Add an element after the specified one. + bool Insert ( size_t index, Type * ); ///< \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + + bool AddArray ( const RPArray & ); ///< \ru Добавить массив. \en Add array. + bool AddCArray ( const Type **, size_t count ); ///< \ru Добавить C-массив. \en Add C-array. + bool InsertArray( const RPArray &, size_t index ); ///< \ru Добавить массив в позицию. \en Add an array to the position. + + void DetachAll(); ///< \ru Удалить все элементы обнулить количество элементов. \en Delete all elements and set the number of elements to null. + void Adjust(); ///< \ru Удалить лишнюю память. \en Free the unnecessary memory. + Type * DetachInd( size_t delIndex ); ///< \ru Отсоединить элемент от массива. \en Detach an element from the array. + bool DetachObj( const Type * delObject ); ///< \ru Отсоединить элемент от массива. \en Detach an element from the array. + + virtual Type * RemoveInd( size_t delIndex, DelType /*del*/ = defDelete ) { return DetachInd( delIndex); } ///< \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + + void Swap( RPArray & arr ); ///< \ru Обменять местами данные массивов. \en Swap data of arrays. + + size_t FindIt ( const Type * ) const; ///< \ru Найти элемент по указателю. \en Find an element by a pointer. + bool IsExist( const Type * ) const; ///< \ru Есть ли элемент в массиве. \en Whether an element belongs the array. + size_t Count() const { return count; } ///< \ru Получить количество элементов массива. \en Get the number of array elements. + ptrdiff_t MaxIndex() const { return ((ptrdiff_t)count - 1); } ///< \ru Получить индекс последнего объект в массиве. \en Get the index of the last element in the array. + + typedef int (*CompFunc)( const Type **, const Type ** ); ///< \ru Шаблон функции сортировки. \en A template of sorting function. + void Sort ( CompFunc comp ); ///< \ru Сортировать массив. \en Sort the array. + + /// \ru Оператор доступа по индексу. \en Access by index operator. + Type *& operator []( size_t loc ) const { PRECONDITION( loc < count ); return parr[loc]; } + /// \ru Получить адрес последнего элемента в массиве. \en Get the address of the last element in the array. + Type * GetLast() const { return ((count > 0) ? parr[count-1] : (Type*)NULL); } + +public: // \ru унификация с вектором STL \en unification with STL vector + bool empty() const { return count == 0; } + size_t size() const { return count; } ///< \ru Дать количество элементов массива. \en Get the number of elements in array. + bool reserve( size_t n ) { return Reserve( n, false ); } ///< \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + size_t capacity() const { return Upper(); } ///< \ru Под какое количество элементов выделена память? \en What is the number of elements the memory is allocated for? + void push_back( const Type * e ) { Add( const_cast(e) ); } ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + template + void insert( Iterator pos, const Type * e ); ///< \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + // \ru прописывать поведение у всех классов-наследников! \en define the behavior for all classes-inheritors! + template + void erase( Iterator pos ); ///< \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + template + void erase( Iterator first, Iterator last ); ///< \ru Удалить элементы из массива начиная с индекса first до last-1 включительно. \en Delete elements from the array from first to last-1 inclusively. + virtual void clear() { DetachAll(); } ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + void shrink_to_fit() { Adjust(); } ///< \ru Удалить лишнюю память. \en Free the unnecessary memory (Reduce capacity). + + const TPtr * begin() const { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + TPtr * begin() { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const TPtr * end() const { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + TPtr * end() { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + const TPtr * cbegin() const { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const TPtr * cend() const { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + const value_type front() const { PRECONDITION(!empty()); return *parr; } + value_type & front() { PRECONDITION(!empty()); return *parr; } + const value_type back() const { PRECONDITION(!empty()); return *(parr + count - 1); } + value_type & back() { PRECONDITION(!empty()); return *(parr + count - 1); } + const_reference at( size_t idx ) const { PRECONDITION( idx < count ); return parr[idx]; } + reference at( size_t idx ) { PRECONDITION( idx < count ); return parr[idx]; } + +protected: + const Type ** GetAddr() const { return (const Type **)parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const TPtr * _Begin() const { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + TPtr * _Begin() { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const TPtr * _End() const { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + + bool CatchMemory(); ///< \ru Захватить память. \en Catch memory. + bool AddMemory( size_t n ); ///< \ru Обеспечить место в памяти под n элементов, независимо от AutoDelta \en Provide memory for n elements, independently from AutoDelta + size_t AutoDelta() const { return ::KsAutoDelta( count, delta ); } ///< \ru Вычислить автоприращение. \en Calculate autoincrement. + +private: + RPArray( const RPArray & ); // \ru запрещено !!! \en forbidden !!! + RPArray & operator =( const RPArray & ); // \ru запрещено !!! \en forbidden !!! + + TEMPLATE_FRIEND bool set_Rarray_size TEMPLATE_SUFFIX ( RPArray &, size_t newSize ); + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const RPArray & arr, const Type * el ); +#ifdef _MSC_VER + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const RPArray & arr, const Type * el ); +#endif // _MSC_VER + + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, RPArray & ref ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const RPArray & ref ); + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, RPArray *& ptr ); + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const RPArray * ptr ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + RPArray( RPArray && ); ///< \ru Конструктор перемещения массива. \en Constructor of an array moving. + RPArray & operator = ( RPArray && ); ///< \ru Оператор перемещения массива. \en Operator of an array moving. +#endif // STANDARD_CPP11_RVALUE_REFERENCES + +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * RPArray::operator new( size_t size ) { + return ::Allocate( size, typeid(RPArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void RPArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(RPArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------ +// \ru конструктор массива \en constructor of an array +// --- +template +inline RPArray::RPArray() + : count( 0 ) + , upper( 0 ) + , delta( 1 ) + , parr ( 0 ) +{} + + +//------------------------------------------------------------------------------ +// \ru конструктор массива \en constructor of an array +// --- +template +inline RPArray::RPArray( size_t i_upper, uint16 i_delta )//, bool shouldNullSet ) + : count( 0 ) + , upper( 0 ) + , delta( i_delta ) + , parr ( 0 ) //i_upper ? new TPtr[i_upper] : 0 ) +{ + if ( !set_Rarray_size(*this, i_upper) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + + //if ( shouldNullSet && upper > 0 ) { + // count = upper; + // memset( parr, 0, count * SIZE_OF_POINTER ); + //} +} + + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +//------------------------------------------------------------------------------ +// \ru Конструктор перемещения массива. \en Constructor of an array moving. +// --- +template +inline RPArray::RPArray( RPArray && _Right ) + : count(_Right.count) + , upper(_Right.upper) + , delta(_Right.delta) + , parr (_Right.parr) +{ + _Right.count = 0; + _Right.upper = 0; + _Right.delta = 1; + _Right.parr = nullptr; +} + +//------------------------------------------------------------------------------ +// \ru Оператор перемещения массива. \en Operator of an array moving. +// --- +template +RPArray & RPArray::operator = ( RPArray && _Right ) +{ + if ( this != &_Right ) + { + set_Rarray_size( *this, 0 ); + _Right.Swap( *this ); + } + return (*this); +} +#endif // STANDARD_CPP11_RVALUE_REFERENCES + + +//------------------------------------------------------------------------------ +// \ru деструктор массива \en destructor of array +// --- +template +inline RPArray::~RPArray() { + set_Rarray_size( *this, 0 ); //delete [] parr; +} + + +//------------------------------------------------------------------------------- +// \ru обнулить количество элементов \en set the number of elements to null +// --- +template +inline void RPArray::DetachAll() { + count = 0; +} + + +//------------------------------------------------------------------------------ +// \ru Указать новый размер массива. \en Set the new size of an array. +// --- +template +inline bool RPArray::SetSize( size_t newSize ) { + return set_Rarray_size( *this, newSize ); +} + + +//------------------------------------------------------------------------------ +// \ru Зарезервировать место под n элементов. \en Reserve memory for n elements. +// --- +template +inline bool RPArray::Reserve( size_t n, bool addAdditionalSpace ) { + if ( addAdditionalSpace ) + n += count; + // \ru Захватить память, если требуется памяти больше, чем есть сейчас. \en if there is required more memory that exists at the moment catch it. + if ( upper < n ) { + return set_Rarray_size( *this, n ); + } + else { + // C3D_ASSERT( upper <= n ); // Use SetSize!!! + } + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Обеспечить место под n элементов, независимо от AutoDelta \en Provide memory for n elements, independently from AutoDelta +// --- +template +inline bool RPArray::AddMemory( size_t n ) { + if ( upper - count < n ) { + return set_Rarray_size( *this, count + n ); + } + return true; +} + + +//------------------------------------------------------------------------------ +// \ru освободить лишнюю память \en free unnecessary memory +// --- +template +inline void RPArray::Adjust() { + if ( count < upper ) + set_Rarray_size( *this, count ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент в конец массива \en add 1 element to the end of array +// --- +template +inline bool RPArray::Add( Type * ent ) { + if ( CatchMemory() ) { + parr[count++] = ent; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент после заданного \en add 1 element after the given one +// --- +template +inline bool RPArray::AddAfter( Type * ent, size_t index ) { + if ( !count ) + return Add( ent ); + else { + if ( CatchMemory() ) { // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + if ( index > count - 1 ) + index = count - 1; + // \ru передвинем вправо все элементы массива с index+1 до последнего \en move to the right all elements of the array from index+1 to the last + memmove( parr + index + 2, parr + index + 1, (count - index - 1) * SIZE_OF_POINTER ); + parr[index + 1] = ent; // \ru записываем новый элемент \en writing new element + count++; + return true; + } + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru добавить массив \en add array +// \ru эти функции раньше обнуляли признак владения у второго массива, \en These functions set to null the attribute of second element ownership earlier, +// \ru Теперь об этом нужно заботиться самостоятельно ! \en Now you should take care of it ! +// --- +template +inline bool RPArray::AddArray( const RPArray & from ) { + return AddCArray( from.GetAddr(), from.count ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить C-массив \en add C-array +// --- +template +inline bool RPArray::AddCArray( const Type ** from, size_t fromCount ) { + if ( fromCount ) { + if ( AddMemory( fromCount ) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + memcpy( parr + count, from, fromCount * SIZE_OF_POINTER ); + count += fromCount; + return true; + } + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru добавить массив в позицию index \en Add an array to the position index +// \ru (если index>count, то в конец) \en (if 'index' > 'count' then add to the end) +// \ru эти функции раньше обнуляли признак владения у второго массива, \en These functions set to null the attribute of second element ownership earlier, +// \ru теперь об этом нужно заботиться самостоятельно ! \en Now you should take care of it ! +// --- +template +inline bool RPArray::InsertArray( const RPArray & from, size_t index ) { + if ( from.count ) { + if ( index > count ) + index = count; + if ( AddMemory( from.count ) ) { + if ( count > index ) // \ru переместить хвост подальше \en move a tale farther + memmove( parr + index + from.count, parr + index, (count - index) * SIZE_OF_POINTER ); + memcpy( parr + index, from.parr, from.count * SIZE_OF_POINTER ); + count += from.count; + return true; + } + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru вставить 1 элемент перед указанным \en insert 1 element before the specified one +// --- +template +inline bool RPArray::Insert( size_t index, Type * ent ) { + if ( CatchMemory() ) { // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + if ( index >= count ) + index = count; + else { + // \ru передвинем вправо все элементы массива с последнего до указанного \en move to the right all elements of the array from the last to the specified one + memmove( parr + index + 1, parr + index, (count - index) * SIZE_OF_POINTER ); + } + parr[index] = ent; // \ru записываем новый элемент \en writing new element + count++; + return true; + } + return false; +} + + +//------------------------------------------------------------------------------ +// \ru вернуть индекс элемента в массиве \en return an index of the element in the array +// --- +template +inline size_t RPArray::FindIt( const Type * el ) const +{ + // \ru MA Linux return find_in_array( *this, el ); // ошибка при сопоставлении шаблонов для RPArray \en MA Linux return find_in_array( *this, el ); // an error in matching of templates for RPArray + if ( parr ) + { + TPtr * iterLast = parr+count; + TPtr * iter = std::find( parr, iterLast, el ); + if ( iter != iterLast ) + { + return std::distance( parr, iter ); + } + } + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru Есть ли в массиве такой указатель \en Whether such pointer exists in the array +// --- +template +inline bool RPArray::IsExist( const Type * el ) const { + return (FindIt( el ) != SYS_MAX_T); +} + + +//------------------------------------------------------------------------------ +// \ru отсоединить элемент от массива (по индексу) \en detach an element from the array (by the index) +// --- +template +inline Type * RPArray::DetachInd( size_t delIndex ) +{ + Type * r = 0; + + if ( parr ) { + PRECONDITION( delIndex < count ); + r = parr[delIndex]; + memmove( parr+delIndex, parr+delIndex+1, (count-- - delIndex - 1)*SIZE_OF_POINTER ); + } + + return r; +} + + +//------------------------------------------------------------------------------ +// \ru Вставить элемент перед указанным. \en Insert an element before the specified one. +// --- +template +template +void RPArray::insert( Iterator pos, const Type * e ) +{ + if ( !begin() ) { + reserve( 1 ); + pos = begin(); + } + if ( begin() ) { + const ptrdiff_t k = std::distance( (Iterator)begin(), pos ); + if ( k >= 0 && k <= count ) + Insert( k, const_cast(e) ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. +// --- +template +template +void RPArray::erase( Iterator pos ) +{ + if ( begin() ) { + const ptrdiff_t k = std::distance( (Iterator)begin(), pos ); + if ( k >= 0 && k < count ) + RemoveInd( k ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Удалить элементы из массива начиная с индекса first до last-1 включительно. \en Delete elements from the array from first to last-1 inclusively. +// --- +template +template +void RPArray::erase( Iterator first, Iterator last ) +{ + if ( begin() ) { + const ptrdiff_t k1 = std::distance( (Iterator)begin(), first ); + const ptrdiff_t k2 = std::distance( (Iterator)begin(), last ); + + if ( k1 >= 0 && k1 < k2 && k2 <= count ) { + for ( ptrdiff_t k = k2-1; k >= k1; k-- ) { + RemoveInd( k ); + } + } + } +} + + +//------------------------------------------------------------------------------ +// \ru отсоединить элемент от массива (по указателю) \en detach an element from the array (by the pointer) +// --- +template +inline bool RPArray::DetachObj( const Type * delObject ) +{ + size_t i = FindIt( delObject ); + if ( i != SYS_MAX_T ) + { + DetachInd( i ); + return true; + } + return false; +} + + +//------------------------------------------------------------------------------- +// \ru обменять местами данные массивов \en swap data of arrays +// --- +template +void RPArray::Swap( RPArray & arr ) { + std::swap( count, arr.count ); + std::swap( upper, arr.upper ); + std::swap( delta, arr.delta ); + std::swap( parr, arr.parr ); +} + + +//------------------------------------------------------------------------------ +// \ru захват большего куска памяти ( если нужно ) \en allocate the large piece of memory (if it is necessary) +// --- +template +inline bool RPArray::CatchMemory() { + if ( upper == count ) + return set_Rarray_size( *this, upper + AutoDelta() ); + return true; +} + + +//------------------------------------------------------------------------------ +// \ru сортировать массив \en sort the array +// --- !!!!!!!!!! +template +inline void RPArray::Sort( CompFunc fcmp ) { + ::KsQSort( (void *)parr, count, SIZE_OF_POINTER, (KsQSortCompFunc)fcmp ); +} + + +//------------------------------------------------------------------------------ +// \ru Установить присланный размер массива. Если он меньше имеющегося count, то \en Set the given size of an array. If it is less than existed 'count' then +// \ru лишние элементы массива будут удалены \en extra elements of the array will be deleted +// --- +template +bool set_Rarray_size( RPArray & arr, size_t newSize ) +{ + if ( newSize != arr.upper ) { + // \ru половина адресного пространства для 64- и 32-разрядного приложения \en a half of address space for 64- and 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, newSize ) ) { + try { +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void * oldParr = arr.parr; + size_t oldSize = arr.upper; +#endif // __REALLOC_ARRAYS_STATISTIC_ + +#ifdef USE_REALLOC_IN_ARRAYS + arr.parr = (typename RPArray::TPtr *)REALLOC_ARRAY_SIZE( arr.parr, newSize * SIZE_OF_POINTER, false/*clear*/ ); +#else + typename RPArray::TPtr *p_tmp = newSize ? new typename RPArray::TPtr[newSize] : 0; + + if ( arr.parr && p_tmp ) + memcpy( p_tmp, arr.parr, (arr.upper < newSize ? arr.upper : newSize) * SIZE_OF_POINTER ); + + if ( arr.parr ) + delete[] arr.parr; + + arr.parr = p_tmp; +#endif // USE_REALLOC_IN_ARRAYS + + arr.upper = newSize; + arr.count = newSize < arr.count ? newSize : arr.count; + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldSize * SIZE_OF_POINTER, arr.parr, newSize * SIZE_OF_POINTER, 1/*RParray*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ + } + catch ( const std::bad_alloc & ) { + C3D_CONTROLED_THROW; + return false; + } + catch ( ... ) { + if ( newSize == 0 )// \ru Не смогли корректно удалить arr.parr. \en Failed to delete arr.parr correctly. + arr.parr = NULL; + C3D_CONTROLED_THROW; + return false; + } + } + else { + PRECONDITION( false ); // \ru не бывает столько памяти \en incorrect size of memory + C3D_CONTROLED_THROW_EX( std::bad_alloc() ); + return false; + } + } + return true; +} + + +//------------------------------------------------------------------------------- +// \ru найти объект в массиве \en find an object in the array +// --- +template +size_t find_in_array( const RPArray & arr, const Type * el ) { + typename RPArray::TPtr * parr = arr.parr; + for ( size_t i = 0, c = arr.count; i < c; i++, parr++ ) + if ( *parr == el ) + return i; + + return SYS_MAX_T; +} + + +#ifdef _MSC_VER // LF-Linux: ambiguous template specialization +//------------------------------------------------------------------------------- +// \ru найти объект в массиве \en find an object in the array +// --- +template +size_t find_in_array( const RPArray & arr, const Type * el ) { + typename RPArray::TPtr * parr = arr.parr; + for ( size_t i = 0, c = arr.count; i < c; i++, parr++ ) + if ( *parr == el ) + return i; + return SYS_MAX_T; +} +#endif // _MSC_VER + + +//------------------------------------------------------------------------------ +// \ru Вычислить приращение для массива в зависимости от количества предполагаемых \en Calculate an increment for the array according to the number of assumed +// \ru объектов в этом массив (делаю так, чтобы захватов памяти было не более 100) - \en objects in this array (so the number of memory captures will not exceed 100) - +// \ru иначе при количестве объектов 75000 операции с захватом памяти занимают \en otherwise if the number of objects is 75000 then operations with memory captures take +// \ru бесконечное время \en infinite time +// --- +inline uint16 CalcArrayDelta( size_t objsCount ) { + size_t delta = objsCount / 100; + delta = delta > 65000 ? 50000 : delta > 0 ? delta : 1; + return (uint16)delta; +} + + +#endif // __TEMPL_RP_ARRAY_H diff --git a/C3d/Include/templ_rp_array_rw.h b/C3d/Include/templ_rp_array_rw.h new file mode 100644 index 0000000..fe85cc2 --- /dev/null +++ b/C3d/Include/templ_rp_array_rw.h @@ -0,0 +1,120 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация RPArray. + \en Serialization of RPArray. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_RP_ARRAY_RW_H +#define __TEMPL_RP_ARRAY_RW_H + + +#include +#include + + +//------------------------------------------------------------------------------ +// \ru Чтение массива из потока в объект (на добавление объектов к существующему массиву не рассчитано). \en reading of array from a stream to an object (adding new objects to an existed array is not supported). +// --- +template +reader & operator >> ( reader & in, RPArray & ref ) +{ + ref.DetachAll(); + + if ( in.good() ) + { + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + + if ( in.good() ) + { + if ( count ) + { + // \ru половина адресного пространства для 32-разрядного приложения \en a half of address space for 32-bit application + if ( ::TestNewSize( SIZE_OF_POINTER, count ) ) + { + ref.Reserve( count ); + + const Type ** parr = ref.GetAddr(); + + if ( parr != NULL ) { + size_t i; + // \ru поочередное чтение объектов массива \en successive reading of objects from an array + for ( i = 0; i < count && in.good(); i++ ) { + Type *el; + in >> el; + parr[i] = el; + } + ref.count = i; // \ru сколько штук реально прочитано \en the number of read objects + } + else { + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); + } + } + else { + in.setState( io::fail ); // \ru ошибка чтения \en reading error + C3D_ASSERT_UNCONDITIONAL( false ); // \ru не бывает столько памяти \en incorrect size of memory + } + } + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из объекта \en writing of array from an object to a stream +// --- +template +writer& operator << ( writer& out, const RPArray& ref ) { +//OV_x64 out << ref.count; + WriteCOUNT( out, ref.count ); + + const Type **parr = ref.GetAddr(); + for ( size_t i = 0; i < ref.count && out.good(); i++ ) { + Type *el = (Type *)parr[i]; + out << el; + } + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru чтение массива из потока в указатель \en reading of array from a stream to a pointer +// --- +template +reader& operator >> ( reader& in, RPArray*& ptr ) { + ptr = NULL; + if ( in.good() ) { + uint8 existPtr; + in >> existPtr; + if ( existPtr ) { + ptr = new RPArray; + in >> *ptr; + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись массива в поток из указателя \en writing of array from a pointer to a stream +// --- +template +writer& operator << ( writer& out, const RPArray* ptr ) { + + uint8 existPtr = !!ptr; + out << existPtr; + if ( existPtr ) + out << *ptr; // \ru запись телом \en writing by a solid + + return out; +} + + +#endif // __TEMPL_RP_ARRAY_RW_H diff --git a/C3d/Include/templ_rp_stack.h b/C3d/Include/templ_rp_stack.h new file mode 100644 index 0000000..7507e9f --- /dev/null +++ b/C3d/Include/templ_rp_stack.h @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Не владеющий стек указателей. + \en Not owning stack of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_RP_STACK_H +#define __TEMPL_RP_STACK_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Стек указателей. + \en Stack of pointers. \~ + \details \ru Стек указателей без владения. \n + Для организации стека используем в качестве базы RPArray, и отсекаем лишнее с помощью приватного наследования. + \en Stack of pointers without ownership. \n + For the organization of the stack use RPArray as the base and cut all unnecessary by the private inheritance. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class RPStack: private RPArray { +public: + RPStack( size_t i_upper, uint16 i_delta = 1 ): RPArray( i_upper, i_delta ) {} + +public: + void Push( Type & obj ); ///< \ru Добавить элемент в стек. \en Add an element to the stack. + Type * Pop(); ///< \ru Извлечь один элемент стека, если возвращаетя NULL, значит достигнуто дно стека. \en Retrieve one element from the stack, if NULL is returned then the bottom of stack is reached. + Type * Top() const; ///< \ru Верхний элемент стека. \en The top element of the stack. + + // \ru Оставить доступными следующие методы: \en Leave an access to the next methods: + using RPArray::DetachAll; ///< \ru Отцепить все элементы (очистить стек). \en Detach all elements (clear the stack). + using RPArray::Count; + using RPArray::IsExist; + using RPArray::operator[]; ///< \ru Оператор доступа по индексу; \en Access by index operator; + +private: + RPStack( const RPStack & ); // \ru запрещено !!! \en forbidden !!! + void operator =( const RPStack & ); // \ru запрещено !!! \en forbidden !!! +}; + + +//------------------------------------------------------------------------------ +// \ru Добавить элемент в стек \en Add an element to the stack. +//--- +template +void RPStack::Push( Type & obj ) { + RPArray::Add( &obj ); +} + + +//------------------------------------------------------------------------------ +// \ru Извлечь один элемент стека \en Retrieve one element from the stack +//--- +template +Type * RPStack::Pop() { + if ( RPArray::count > 0 ) { + Type * ret = (*this)[RPArray::count-1]; + RPArray::count--; + return ret; + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru Верхний элемент стека; \en The top element of the stack; +//--- +template +Type * RPStack::Top() const { + if ( RPArray::count > 0 ) { + return (*this)[RPArray::count-1]; + } + return NULL; +} + + +#endif // __TEMPL_RP_STACK_H diff --git a/C3d/Include/templ_rw_operator.h b/C3d/Include/templ_rw_operator.h new file mode 100644 index 0000000..7647336 --- /dev/null +++ b/C3d/Include/templ_rw_operator.h @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функции сериализации. + \en Functions of serialization. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_RW_OPERATOR_H +#define __TEMPL_RW_OPERATOR_H + + +#include + + +//------------------------------------------------------------------------------ +// \ru Функция чтения указателя на основе оператора чтения ссылки \en Function of pointer reading on the basis of reference reading operator. +// \ru для объектов имеющих конструктор по умолчанию \en for objects which have constructor by default +//--- +template +inline reader & ReadPtrByRefDCtor ( reader & in, Type *& ptr ) +{ + ptr = NULL; + + char exist; + in >> exist; + + if ( exist ) { + ptr = new Type; // \ru не прислали объект - сделаем новый \en if the object has not been sent then make the new one + in >> (*ptr); + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru Функция чтения указателя на основе оператора чтения ссылки \en Function of pointer reading on the basis of reference reading operator +// \ru для объектов имеющих конструктор для чтения/записи \en for objects which have constructor for reading/writing +//--- +template +inline reader & ReadPtrByRefRWCtor ( reader & in, Type *& ptr ) +{ + ptr = NULL; + + char exist; + in >> exist; + + if ( exist ) { + ptr = new Type( tapeInit ); // \ru не прислали объект - сделаем новый \en if the object has not been sent then make the new one + in >> (*ptr); + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru Функция записи указателя на основе оператора записи ссылки \en Function of pointer writing on the basis of reference writing operator +//--- +template +inline writer & WritePtrByRef ( writer & out, const Type * ptr ) +{ + char exist = (ptr != NULL); + out << exist; + + if ( exist ) + out <<(*ptr); + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru Реализация чтения/записи указателей в поток \en Implementation of reading/writing of pointers to stream +// \ru на основе оператора записи ссылки \en on the basis of reference writing operator. +// \ru для объектов имеющих конструктор для чтения/записи \en for objects which have constructor for reading/writing +//--- +#define KNOWN_OBJECTS_RW_PTR_OPERATORS_IMP_BY_REF(Class) \ + reader & operator >> ( reader & in, Class *& ptr ) \ + { return ReadPtrByRefRWCtor(in, ptr); } \ + writer & operator << ( writer & out, const Class * ptr ) \ + { return WritePtrByRef(out, ptr); } + + +//------------------------------------------------------------------------------ +// \ru Реализация чтения/записи указателей в поток \en Implementation of reading/writing of pointers to stream +// \ru на основе оператора записи ссылки \en on the basis of reference writing operator +// \ru для объектов имеющих конструктор по умолчанию \en for objects which have constructor by default +//--- +#define KNOWN_OBJECTS_DEF_CTOR_RW_PTR_OPERATORS_IMP_BY_REF(Class) \ + reader & operator >> ( reader & in, Class *& ptr ) \ + { return ReadPtrByRefDCtor(in, ptr); } \ + writer & operator << ( writer & out, const Class * ptr ) \ + { return WritePtrByRef(out, ptr); } + + +#endif // __TEMPL_RW_OPERATOR_H diff --git a/C3d/Include/templ_s_array.h b/C3d/Include/templ_s_array.h new file mode 100644 index 0000000..c173f1b --- /dev/null +++ b/C3d/Include/templ_s_array.h @@ -0,0 +1,1143 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Одномерный массив объектов. + \en One-dimensional array of objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_S_ARRAY_H +#define __TEMPL_S_ARRAY_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined( __BORLANDC__ ) +#include +#endif + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +FORVARD_DECL_TEMPLATE_TYPENAME( class SArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool set_array_size ( SArray &, size_t newSize, bool clear ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * add_n_to_array ( SArray &, size_t n ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_in_array ( const SArray &, const Type & object ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool fill_array ( SArray &, size_t fillCount, const Type & fillData ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool fill_array_zero( SArray &, size_t fillCount, size_t startIndex ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, SArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const SArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, SArray *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const SArray * ptr ) ); + + +//------------------------------------------------------------------------------ +// \ru Функция сравнения для сортировки упорядочивает элементы по возрастанию (элементы должны иметь функции > и <). +// \en The comparison function for sorting orders elements in ascending (elements should have functions > and <). \~ +// --- +template +inline int CompareSArrayItems( const Type * f1, const Type * f2 ) { + return (*f1 > *f2) ? 1 : ((*f1 < *f2) ? -1 : 0); +} + + +//----------------------------------------------------------------------------- +/** \brief \ru Массив простых структур данных. + \en Array of plain old data structures (POD). \~ + \details \ru Шаблонный массив, работающий только с простыми (POD) данными, которые + могут копироваться или перемещаться в памяти методом memcpy без нарушения целостности объекта. + Например, в массиве нельзя хранить объекты, динамически выделяющие память или + классы с указателями, а также классы с виртуальными функциями. \n + \en A template array working with POD-only data that can be copied or moved in + memory by 'memcpy' maintaining the validity of the object. For sample, the array should + not contain objects which dynamically allocate memory, or classes with virtual functions. + \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SArray { +public: + typedef Type value_type; + typedef Type const & const_reference; + typedef Type & reference; +protected : + size_t count; ///< \ru Количество элементов в массиве. \en The number of elements in array. + size_t upper; ///< \ru Под какое количество элементов выделена память. \en The number of elements the memory is allocated for. + uint16 delta; ///< \ru Приращение по количеству элементов при выделении дополнительной памяти. \en Increment by the number of elements while the allocation of additional memory. +private : + Type * parr; ///< \ru Указатель на первый элемент массива. \en A pointer to the first array element. + +public : + /// \ru Конструктор. \en Constructor. + explicit SArray( size_t i_max = 0, uint16 i_delta = 1 ); + /// \ru Конструктор копирования. \en Copy constructor. + SArray( const SArray & ); + /// \ru Конструктор копирования. \en Copy constructor. + explicit SArray( const std::vector & ); + /// \ru Деструктор. \en Destructor. + virtual ~SArray() { set_array_size( *this, 0, true/*clear*/ ); } + +public: + /// \ru Количество элементов, под которое зарезервирована память. \en The number of elements the memory is allocated for. + size_t Upper() const { return upper; } + /// \ru Получить приращение по количеству элементов при выделении дополнительной памяти. \en Get the increment by the number of elements while the allocation of additional memory. + uint16 Delta() const { return delta; } + /// \ru Установить приращение по количеству элементов при выделении дополнительной памяти (1 - автоприращение). \en Set the increment by the number of elements while the allocation of additional memory (1 - autoincrement). + void Delta( uint16 newDelta ) { delta = newDelta; } + /// \ru Установить максимальное из приращений. \en Set the maximum increment. + void SetMaxDelta( uint16 newDelta ) { if ( delta < newDelta ) delta = newDelta; } + + /// \ru Функции, выделяющие потенциально большие участки памяти, возвращают результат операции (успех/ошибка). + /// \en Functions that allocate potentially large memory, return an operation result (success/error). + bool SetSize( size_t newSize, bool clear/*=true*/ ); ///< \ru Установить новый размер массива. \en Set the new size of an array. + bool Reserve( size_t n, bool addAdditionalSpace = true ); ///< \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + + void Flush () { count = 0; } ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + void HardFlush() { Flush(); Adjust(); } ///< \ru Освободить всю память. \en Free the whole memory. + void Adjust(); ///< \ru Удалить лишнюю память. \en Free the unnecessary memory. + Type * Add(); ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + Type * AddItems ( size_t n ); ///< \ru Добавить n элементов в конец массива. \en Add n elements to the end of the array. + Type * Add ( const Type & ); ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + Type * AddAt ( const Type & ent, size_t index ) { return InsertInd( index, ent ); } ///< \ru Вставить элемент по индексу. \en Insert an element by the index. + Type * AddAfter ( const Type &, size_t index ); ///< \ru Добавить элемент после указанного. \en Add an element after the specified one. + Type * InsertObj( const Type & index, const Type & ent ); ///< \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + Type * InsertInd( size_t index, const Type & ); ///< \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + Type * InsertInd( size_t index ); ///< \ru Вставить пустой элемент перед указанным. \en Insert the empty element before the specified one. + void Remove( Type * firstItr, Type * lastItr ); ///< \ru Удалить элементы из массива начиная с позиции firstItr до lastItr-1 включительно. \en Delete elements from the array from firstItr to lastItr-1 inclusively. + void RemoveInd( size_t firstIdx, size_t lastIdx ); ///< \ru Удалить элементы из массива начиная с индекса firstIdx до lastIdx-1 включительно. \en Delete elements from the array from firstIdx to lastIdx-1 inclusively. + void RemoveInd( size_t idx ); ///< \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + size_t RemoveObj( const Type & delObject ); ///< \ru Удалить элемент из массива. \en Delete an element from array. + bool Fill( size_t fillCount, const Type & fillData ); ///< \ru Заполнить массив значениями. \en Fill an array. + bool FillZero( size_t fillCount, size_t startIndex = 0 ); ///< \ru Заполнить массив байтами содержащими 0. \en Fill an array by bites consisting of 0. + size_t FindIt ( const Type & ) const; ///< \ru Вернуть индекс элемента в массиве. \en Return an index of the element in the array. + bool IsExist ( const Type & ) const; ///< \ru true если элемент найден. \en true if the element is found. + size_t Count() const { return count; } ///< \ru Дать количество элементов массива. \en Get the number of elements in array. + ptrdiff_t MaxIndex() const { return ((ptrdiff_t)count - 1); } ///< \ru Дать количество элементов массива. \en Get the number of elements in array. + + bool SetCArray( const Type * o, size_t count ); ///< \ru Присвоить значения из c-массива. \en Assign the value from the c-array. + + void Swap ( SArray & arr ); ///< \ru Обменять местами данные массивов. \en Swap data of arrays. + + SArray & operator = ( const SArray & ); ///< \ru Оператор присваивания. \en Assignment operator. + SArray & operator = ( const std::vector & ); ///< \ru Оператор присваивания. \en Assignment operator. + SArray & operator += ( const SArray & ); ///< \ru Оператор слияния. \en Merging operator. + SArray & operator += ( const std::vector & ); ///< \ru Оператор слияния. \en Merging operator. + bool operator == ( const SArray& w ) const; ///< \ru Оператор равенства. \en Equality operator. + + /// \ru Оператор доступа по индексу. \en Access by index operator. + Type & operator []( size_t loc ) const { PRECONDITION( loc < upper ); return parr[loc]; } + + typedef int (*CompFunc)( const Type *, const Type * ); ///< \ru Шаблон функции сортировки. \en A template of sorting function. + void Sort ( CompFunc comp = CompareSArrayItems ); ///< \ru Сортировать массив. По умолчанию сортирует в порядке возрастания. \en Sort the array. Sort in ascending order by default. + + const Type * GetAddr() const { return parr; } ///< \ru Выдать адрес начала массива. \en Get the address of the beginning of the array. + const Type * GetEndAddr() const { return parr + count; } ///< \ru Выдать указатель конца (следующим за крайним). \en Get a pointer of the end (which follows the last element). + + /** + \name \ru Унификация с контейнерами STL. + \en Unification with STL-compatible containers. \~ + \{ + */ + +public: + bool empty() const { return 0 == count; } ///< \ru Проверить не пустой ли массив (т.е. не равен ли его размер 0). \en Test whether vector is empty (i.e. whether its size is 0). + size_t size() const { return count; } ///< \ru Дать количество элементов массива. \en Get the number of elements in array. + void reserve( size_t n ) { Reserve( n, false ); } ///< \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + void resize( size_t n, Type val = Type() ); ///< \ru Изменить размер массива. \en Resizes the container so that it contains n elements. + size_t capacity() const { return Upper(); } ///< \ru Под какое количество элементов выделена память? \en What is the number of elements the memory is allocated for? + void push_back( const Type & e ) { Add( e ); } ///< \ru Добавить элемент в конец массива. \en Add an element to the end of the array. + void pop_back() { RemoveInd( MaxIndex() ); } ///< \ru Удалить элемент из конца массива. \en Removes the last element in the array, reducing the array size by one. + template + void insert( Iterator pos, const Type & e ); ///< \ru Вставить элемент перед указанным. \en Insert an element before the specified one. + template + void erase( Iterator pos ); ///< \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. + template + void erase( Iterator first, Iterator last ); ///< \ru Удалить элементы из массива начиная с индекса first до last-1 включительно. \en Delete elements from the array from first to last-1 inclusively. + void clear() { Flush(); } ///< \ru Обнулить количество элементов. \en Set the number of elements to null. + void shrink_to_fit() { Adjust(); } ///< \ru Удалить лишнюю память. \en Free the unnecessary memory (Reduce capacity). + + template + void assign ( Iterator first, Iterator last ); ///< \ru Присвоить массиву новое содержимое, заменив его текущее содержимое. \en Assign new contents to the array, replacing its current contents. + void assign ( size_t n, const Type & val ) { resize( n, val ); } ///< \ru Присвоить массиву новое содержимое, заменив его текущее содержимое. \en Assign new contents to the array, replacing its current contents. + const Type * begin() const { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + Type * begin() { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const Type * end() const { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + Type * end() { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + const Type * cbegin() const { return parr; } ///< \ru Получить указатель на первый элемент массива. \en Get the pointer to the first array element. + const Type * cend() const { return parr + count; } ///< \ru Получить указатель на участок памяти после массива. \en Get the pointer to the piece of memory after the array. + const Type & front() const { PRECONDITION(!empty()); return *parr; } + Type & front() { PRECONDITION(!empty()); return *parr; } + const Type & back() const { PRECONDITION(!empty()); return *(parr+count-1); } + Type & back() { PRECONDITION(!empty()); return *(parr+count-1); } + + /** + \} + */ + +protected : + bool CatchMemory(); ///< \ru Захватить память. \en Catch memory. + bool AddMemory( size_t n ); ///< \ru Обеспечить место под n элементов, независимо от AutoDelta. \en Provide memory for n elements, independently from AutoDelta. + size_t AutoDelta() const { return ::KsAutoDelta( count, delta ); } ///< \ru Вычислить автоприращение. \en Calculate autoincrement. + + /// \ru Перезахватить память. \en Reallocate memory. + TEMPLATE_FRIEND bool set_array_size TEMPLATE_SUFFIX ( SArray &, size_t newSize, bool clear ); + /// \ru Добавить памяти под n элментов массива и вернуть указатель на начало выделеного участка памяти. \en Add memory for n elements of the array and return a pointer to the beginning of the selected piece of memory. + TEMPLATE_FRIEND Type * add_n_to_array TEMPLATE_SUFFIX ( SArray &, size_t n ); + /// \ru Найти элемент в массиве. \en Find an element in the array. + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const SArray &, const Type &object ); + /// \ru Заполнить fillCount элементов массива копиями объекта fillData. \en Fill fillCount elements of the array by copies of the object fillData. + TEMPLATE_FRIEND bool fill_array TEMPLATE_SUFFIX ( SArray &, size_t fillCount, const Type & fillData ); + /// \ru Заполнить fillCount элементов массива нулями. \en Fill fillCount elements of the array by nulls. + TEMPLATE_FRIEND bool fill_array_zero TEMPLATE_SUFFIX ( SArray &, size_t fillCount, size_t startIndex ); + + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, SArray & ref ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const SArray & ref ); + /// \ru Оператор чтения. \en Read operator. + TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, SArray *& ptr ); + /// \ru Оператор записи. \en Write operator. + TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const SArray * ptr ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * SArray::operator new( size_t size ) { + return ::Allocate( size, typeid(SArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void SArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(SArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------ +// \ru Конструктор массива \en Constructor of an array +// --- +template +inline SArray::SArray( size_t i_max, uint16 i_delta ) + : count( 0 ) + , upper( 0 ) + , delta( i_delta ) + , parr ( 0 ) // i_max ? (Type*)new char[ i_max * sizeof(Type) ] : 0 ) +{ + if ( !set_array_size( *this, i_max, true/*\ru clear - здесь неважно \en clear - it is not necessary here */ ) && !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор копирования массива \en Copy-constructor of an array +// --- +template +inline SArray::SArray( const SArray & o ) + : count( 0 ) + , upper( 0 ) + , delta( o.delta ) + , parr ( 0 ) +{ + if ( o.upper ) { + // \ru operator = копирует только o.count элементов, а нужно все до o.upper \en the operator = copies only o.count elements, but there must be copied all elements to o.upper + if ( set_array_size( *this, o.upper, true/*\ru clear - здесь неважно \en clear - it is not necessary here */ ) ) { + memcpy( static_cast(parr), static_cast(o.parr), o.upper * sizeof(Type) ); + count = o.count; + } + else if ( !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + } +} + + +//------------------------------------------------------------------------------ +// \ru Конструктор копирования массива \en Copy-constructor of an array +// --- +template +inline SArray::SArray( const std::vector & o ) + : count( 0 ) + , upper( 0 ) + , delta( 1 ) + , parr ( 0 ) +{ + const size_t oCount = o.size(); + if ( oCount ) { + // \ru operator = копирует только o.count элементов, а нужно все до o.upper \en the operator = copies only o.count elements, but there must be copied all elements to o.upper + if ( set_array_size(*this, oCount, true/*\ru clear - здесь неважно \en clear - it is not necessary here */) ) { + memcpy( parr, &o[0], oCount * sizeof(Type) ); + count = oCount; + } + else if ( !ExceptionMode::IsEnabled() ) + throw std::bad_alloc(); // \ru Бросить исключение при любом режиме. \en Throw exception in case of any mode. + } +} + + +//------------------------------------------------------------------------------ +// \ru Указать новый размер массива. \en Set the new size of an array. +// \ru если clear = true, то массив очистится !!! \en if 'clear' is true than the array will be cleared !!! +// \ru если clear = true, то присвоить count=0 и старое содержимое не копировать \en if clear = true then set count=0 and do not copy the old content +// --- +template +inline bool SArray::SetSize( size_t newSize, bool clear ) { + return set_array_size( *this, newSize, clear ); +} + + +//------------------------------------------------------------------------------ +// \ru Зарезервировать место под n элементов. \en Reserve memory for n elements. +// --- +template +inline bool SArray::Reserve( size_t n, bool addAdditionalSpace ) { + if ( addAdditionalSpace ) { + size_t nn = count + n; + if ( upper < nn ) + return set_array_size( *this, nn, false/*clear*/ ); + } + else { + // \ru Захватить память, если требуется памяти больше, чем есть сейчас. \en if there is required more memory that exists at the moment catch it. + if ( upper < n ) + return set_array_size( *this, n, false/*clear*/ ); + else { + // C3D_ASSERT( upper <= n ); // Use SetSize!!! + } + } + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Добавить память под n элементов. \en Add memory for n elements. +// --- +template +inline bool SArray::AddMemory( size_t n ) { + if ( upper - count < n ) + return set_array_size( *this, count + n, false/*clear*/ ); + return true; +} + + +//------------------------------------------------------------------------------ +// \ru Изменить размер массива. \en Resizes the container so that it contains n elements. +// --- +template +inline void SArray::resize( size_t n, Type val ) +{ + size_t n0 = count; + if ( AddItems(n) != 0 ) { + if ( parr != NULL ) { + for ( size_t k = n0; k < count; k++ ) + parr[k] = val; + } + } +} + + +//------------------------------------------------------------------------------ +// \ru отсечь неиспользуемую часть \en cut the useless part +// --- +template +inline void SArray::Adjust() { + if ( count < upper ) + set_array_size( *this, count, false/*clear*/ ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент в конец массива и вернуть указатель на него \en add 1 element to the end of the array and return a pointer to it +// --- +template +inline Type * SArray::Add() { + if ( CatchMemory() ) + return &parr[ count++ ]; + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru добавить n элементов в конец массива и вернуть указатель на первый добавленный \en add n elements to the end of the array and return a pointer to the first of added elements +// --- +template +inline Type * SArray::AddItems( size_t n ) { + return add_n_to_array( *this, n ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент в конец массива \en add 1 element to the end of array +// --- +template +inline Type * SArray::Add( const Type & ent ) +{ + if ( CatchMemory() ) + return static_cast( memcpy(static_cast(parr+count++), static_cast(&ent), sizeof(Type)) ); + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru добавить 1 элемент после заданного \en add 1 element after the given one +// --- +template +inline Type * SArray::AddAfter( const Type & ent, size_t index ) { + PRECONDITION( index < count ); + if ( CatchMemory() ) { + + memmove( parr + index + 2, parr + index + 1, sizeof(Type)*(count - index - 1) ); + count++; + + return (Type*)memcpy( parr + index + 1, &ent, sizeof(Type) ); + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru вставить 1 элемент перед указанным \en insert 1 element before the specified one +// --- +template +inline Type * SArray::InsertInd( size_t index, const Type & ent ) { + PRECONDITION( index <= count ); + if ( CatchMemory() ) { // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + + if ( index >= count ) + index = count; + else { + // \ru передвинем вправо все элементы массива с последнего до указанного \en move to the right all elements of the array from the last to the specified one + memmove( parr + index + 1, parr + index, (count - index) * sizeof(Type) ); + } + count++; + + return (Type*)memcpy( parr + index, &ent, sizeof(Type) ); // \ru записываем новый элемент \en writing new element + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru вставить пустой элемент перед указанным \en insert the empty element before the specified one. +// --- +template +inline Type * SArray::InsertInd( size_t index ) { + PRECONDITION( index <= count ); + if ( CatchMemory() ) { // \ru добавить памяти, если все использовано \en add memory if whole allocated memory is used + + // \ru передвинем вправо все элементы массива с последнего до указанного \en move to the right all elements of the array from the last to the specified one + memmove( parr + index + 1, parr + index, (count - index) * sizeof(Type) ); + count++; + + return (Type*)( parr + index ); // \ru записываем новый элемент \en writing new element + } + return NULL; +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент перед указанным \en insert element before the specified one +// --- +template +inline Type * SArray::InsertObj( const Type & ind, const Type & ent ) { + size_t index = FindIt(ind); + return ( index != SYS_MAX_T) ? InsertInd( index, ent ) : 0; +} + + +//------------------------------------------------------------------------------ +// \ru вернуть индекс элемента в массиве \en return an index of the element in the array +// --- +template +inline size_t SArray::FindIt( const Type & object ) const { + return find_in_array( *this, object ); +} + + +//------------------------------------------------------------------------------ +// \ru true если элемент найден \en true if the element was found +// --- +template +inline bool SArray::IsExist( const Type & object ) const { + return find_in_array( *this, object ) != SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline size_t SArray::RemoveObj( const Type & delObject ) +{ + size_t ind = FindIt( delObject ); + if ( ind != SYS_MAX_T ) + RemoveInd( ind ); + return ind; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline void SArray::RemoveInd( size_t idx ) +{ + // RemoveInd( idx, idx+1 ); + if ( parr ) { + Type * ptr = parr + idx; + Remove( ptr, ptr+1 ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Вставить элемент перед указанным. \en Insert an element before the specified one. +// --- +template +template +void SArray::insert( Iterator pos, const Type & e ) +{ + if ( !begin() ) { + reserve( 1 ); + pos = begin(); + } + if ( begin() ) { + const ptrdiff_t k = std::distance( (Iterator)begin(), pos ); + if ( k >= 0 && k <= count ) + InsertInd( k, e ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Удалить элемент из массива по индексу. \en Delete an element from array by the index. +// --- +template +template +void SArray::erase( Iterator pos ) +{ + if ( begin() ) { + const ptrdiff_t k = std::distance( (Iterator)begin(), pos ); + if ( k >= 0 && k < count ) + RemoveInd( k ); + } +} + +//------------------------------------------------------------------------------ +// \ru Удалить элементы из массива начиная с индекса first до last-1 включительно. \en Delete elements from the array from first to last-1 inclusively. +// --- +template +template +void SArray::erase( Iterator first, Iterator last ) +{ + if ( begin() ) { + const ptrdiff_t k1 = std::distance( (Iterator)begin(), first ); + const ptrdiff_t k2 = std::distance( (Iterator)begin(), last ); + + if ( k1 >= 0 && k1 < k2 && k2 <= count ) { + RemoveInd( k1, k2 ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Удалить группу элементов начиная с firstIdx до lastIdx-1 включительно \en Delete the group of elements from firstIdx to lastIdx-1 inclusively +// --- +template +inline void SArray::RemoveInd( size_t firstIdx, size_t lastIdx ) { + if ( parr ) + Remove( parr+firstIdx, parr+lastIdx ); +} + + +//------------------------------------------------------------------------------ +// \ru Удалить элементы из массива начиная с позиции firstItr до lastItr-1 включительно \en Delete elements from the array from firstItr to lastItr-1 inclusively +// --- +template +inline void SArray::Remove( Type * firstItr, Type * lastItr ) +{ + PRECONDITION( firstItr >= parr && firstItr < lastItr && (lastItr - parr) <= (ptrdiff_t)count ); + ptrdiff_t cpyCount = (parr + count) - lastItr; + if ( cpyCount > 0 ) { + memmove( static_cast(firstItr), static_cast(lastItr), cpyCount*sizeof(Type) ); + } + if ( lastItr - firstItr > 0 ) + count -= (lastItr-firstItr); +} + + +//------------------------------------------------------------------------------ +// \ru заполнить массив значениями \en fill an array +// --- +template +inline bool SArray::Fill( size_t fillCount, const Type & fillData ) { + return fill_array( *this, fillCount, fillData ); +} + + +//------------------------------------------------------------------------------ +// \ru заполнить массив байтами содержащими 0 \en fill an array by bites consisting of 0 +// \ru размер полученного массива устанавливается в fillCount + startIndex \en a size of the obtained array is set to fillCount + startIndex. +// --- +template +inline bool SArray::FillZero( size_t fillCount, size_t startIndex ) { + return fill_array_zero( *this, fillCount, startIndex ); +} + + +//------------------------------------------------------------------------------ +// \ru присвоение массива массиву \en assignment of an array to array +// --- +template +inline SArray & SArray::operator = ( const SArray & o ) { + if ( this != &o ) { // \ru при присваивании самому себе delete делать нельзя \en when it is assigned to itself operato delete should not be used + Flush(); + if ( AddMemory(o.count) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + count = o.count; + if ( count && parr ) + memcpy( static_cast(parr), static_cast(o.parr), count * sizeof(Type) ); + } + } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru присвоение массива массиву \en assignment of an array to array +// --- +template +inline SArray & SArray::operator = ( const std::vector & o ) { + Flush(); + if ( AddMemory(o.size()) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + count = o.size(); + if ( count && parr ) + memcpy( static_cast(parr), static_cast(&o[0]), count * sizeof(Type) ); + } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru присвоение массива массиву \en assignment of an array to array +// --- +template +inline bool SArray::SetCArray( const Type * o, size_t countC ) +{ + Flush(); + bool bRes = AddMemory( countC ); + if ( bRes ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + count = countC; + if ( count && parr ) + memcpy( parr, o, count * sizeof(Type) ); + } + return bRes; +} + + +//------------------------------------------------------------------------------- +// \ru обменять местами данные массивов \en swap data of arrays +// --- +template +void SArray::Swap( SArray & arr ) { + std::swap( count, arr.count ); + std::swap( upper, arr.upper ); + std::swap( delta, arr.delta ); + std::swap( parr, arr.parr ); +} + + +//------------------------------------------------------------------------------ +// \ru добавление массива к массиву \en add the array to the array +// --- +template +inline SArray & SArray::operator += ( const SArray & o ) { + if ( o.size() ) { + size_t addSize = o.size(); + if ( AddMemory(addSize) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + if ( parr ) + memcpy( static_cast(parr + count), static_cast(o.parr), addSize * sizeof(Type) ); + count += addSize; + } + } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru добавление массива к массиву \en add the array to the array +// --- +template +inline SArray & SArray::operator += ( const std::vector & o ) { + if ( o.size() ) { + size_t addSize = o.size(); + if ( AddMemory(addSize) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + if ( parr ) + memcpy( static_cast(parr + count), static_cast(&o[0]), addSize * sizeof(Type) ); + count += addSize; + } + } + return *this; +} + + +//------------------------------------------------------------------------------ +// \ru Если вся память использована - захватить по больше \en If the whole memory is used then catch more memory +// \ru (применяется перед добавлением в массив одного элемента) \en (it is used before adding one element in the array) +// --- +template +inline bool SArray::CatchMemory() { + if ( upper == count ) + return set_array_size( *this, upper + AutoDelta(), false/*clear*/ ); + return true; +} + + +//------------------------------------------------------------------------------ +// \ru сортировать массив \en sort the array +// --- +template +inline void SArray::Sort( CompFunc fcmp ) { + ::KsQSort( (void *)parr, count, sizeof(Type), (KsQSortCompFunc)fcmp ); +} + + +//---------------------------------------------------------------------------------------- +// \ru Присвоить массиву новое содержимое, заменив его текущее содержимое. +// \en Assign new contents to the array, replacing its current contents. +//--- +template +template +void SArray::assign( Iterator first, Iterator last ) +{ + const ptrdiff_t newCount = std::distance( first, last ); + if ( set_array_size(*this, newCount, true) ) { + PRECONDITION( newCount <= upper && count == 0 ); + for ( ; first != last; ++first, ++count ) { + parr[count] = *first; + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Если захвачен не такой размер памяти, то захватить новый если clear = true, то присвоить arr.count=0 и старое содержимое не копировать. +// \en If the size of caught memory is not appropriated then allocate memory again if clear = true then set arr.count=0 and do not copy the old content. +// --- +template +bool set_array_size( SArray & arr, size_t newSize, bool clear ) +{ + bool res = true; + if ( newSize != arr.upper ) { + size_t sizeOfType = sizeof(Type); + + // \ru половина адресного пространства для 64- и 32-разрядного приложения \en a half of address space for 64- and 32-bit application + // if ( double(newSize) * sizeOfType < /*OV_x64 0x7FFFFFFF*/(double)SYS_MAX_ST ) { //-V113 + if ( ::TestNewSize( sizeOfType, newSize ) ) { + try { +#ifdef __REALLOC_ARRAYS_STATISTIC_ + void * oldParr = arr.parr; + size_t oldSize = arr.upper; +#endif // __REALLOC_ARRAYS_STATISTIC_ + +#ifdef USE_REALLOC_IN_ARRAYS + //YYK V15 #77319 Некорректная отрисовка на видеокартах семейства NVIDIA Quadro, + //YYK V15 требуется 16-байтовое выравнивание массивов вершин и нормалей. + //YYK V15 Исправлять приходится глобально для всех экземпляров SArray + //YYK V15 arr.parr = (Type*) REALLOC_ARRAY_SIZE( arr.parr, newSize * sizeOfType, clear ); +#ifdef C3D_WINDOWS //_MSC_VER // win + arr.parr = (Type *)_aligned_realloc( arr.parr, newSize * sizeOfType, 16 ); +#else + arr.parr = (Type *)REALLOC_ARRAY_SIZE( arr.parr, newSize * sizeOfType, clear ); +#endif // win +#else + //YYK V15 #77319 Type * p_tmp = newSize ? (Type*)new char[ newSize * sizeOfType ] : 0; +#ifdef C3D_WINDOWS //_MSC_VER // win + Type * p_tmp = newSize ? (Type*)_aligned_malloc( newSize * sizeOfType, 16 ) : NULL; +#else + Type * p_tmp = newSize ? (Type*)new char[newSize * sizeOfType] : 0; +#endif // win + + if ( !clear && arr.parr && p_tmp ) + memcpy( static_cast(p_tmp), static_cast(arr.parr), std_min(arr.upper, newSize) * sizeOfType ); + + if ( arr.parr ) + //YYK V15 #77319 delete [] (char *) arr.parr; +#ifdef C3D_WINDOWS //_MSC_VER // win + _aligned_free( arr.parr ); +#else + delete[](char *) arr.parr; +#endif // win + + arr.parr = p_tmp; +#endif //USE_REALLOC_IN_ARRAYS + + arr.upper = newSize; + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + ::ReallocArrayStatistic( oldParr, oldSize * sizeOfType, arr.parr, newSize * sizeOfType, 0/*SArray*/ ); +#endif // __REALLOC_ARRAYS_STATISTIC_ + } + catch ( const std::bad_alloc & ) { + newSize = 0; // \ru т.к. ниже есть код с применением newSize \en because there is a code with using of newSize below + C3D_CONTROLED_THROW; + res = false; + } + catch ( ... ) { + if ( newSize == 0 ) { // \ru Не смогли корректно удалить arr.parr. \en Failed to delete arr.parr correctly. + arr.parr = NULL; + arr.upper = newSize; + } + newSize = 0; // \ru т.к. ниже есть код с применением newSize \en because there is a code with using of newSize below + C3D_CONTROLED_THROW; + res = false; + } + } + else { + PRECONDITION( false ); // \ru не бывает столько памяти \en incorrect size of memory + newSize = 0; // \ru т.к. ниже есть код с применением newSize \en because there is a code with using of newSize below + C3D_CONTROLED_THROW_EX( std::bad_alloc() ); + res = false; + } + } + + if ( clear ) + arr.count = 0; + else + if ( newSize < arr.count ) + arr.count = newSize; + + return res; +} + + +//------------------------------------------------------------------------------ +// \ru добавить n элементов в конец массива и вернуть указатель на первый добавленный \en add n elements to the end of the array and return a pointer to the first of added elements +// --- +template +Type * add_n_to_array( SArray & to, size_t n ) { + if ( n ) { + if ( to.AddMemory(n) ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + size_t oldCount = to.count; + to.count += n; + return &to[oldCount]; + } + } + return 0; +} + + +//------------------------------------------------------------------------------ +// \ru Внеклассные функции для сравнения содержимого объектов в методах SArray. У объектов должен быть реализован оператор сравнения на равенство. +// \en Out-of-class functions for the comparison of objects contents in the methods of SArray. There should be implemented an operator of comparison for equality in objects. +// --- +template +bool IsEqualSArrayItems( const Type & item1, const Type & item2 ) { + return item1 == item2; +} + +template +inline bool IsEqualSArrayItems( const std::pair & item1, const std::pair & item2 ) { + return ((item1.first == item2.first) && (item1.second == item2.second)); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +size_t find_in_array( const SArray & arr, const Type & object ) { + for ( size_t i = 0; i < arr.count; i++ ) + // \ru OV K6 Использование функции memcmp дает неверные результаты, если для участка кода, \en OV K6 Using of the function memcmp causes incorrect results if for a part of the code + // \ru где она вызывается, поставлено выравнивание 8, а размер сравниваемых данные не кратен 8. \en where it is called set the alignment 8 but the size of compared date is not a multiple of 8. + // \ru Пусть каждый объект сам решает как ему сравниваться с себе подобным \en Let every object define the way of comparison to the similar object + //OV K6 if ( !memcmp( &arr[i], &object, sizeof(Type) ) ) + if ( ::IsEqualSArrayItems( arr[i], object ) ) + return i; + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// \ru оператор сравнения двух массивов \en an operator of two arrays comparison +// --- +template +inline bool SArray::operator == ( const SArray & w ) const { + if ( count != w.count ) + return false; + + // \ru OV K6 При размещении в памяти с выравниванием не равным 1, между элементами массива \en OV K6 While the memory allocation with alignment which is not equal 1 between elements of the array + // \ru возможно появление "дырок" заполненного случайным мусором, т.к. сравнивать этот мусор \en may appear "holes" filled by random trash, since there is not reason to compare this trash + // \ru нам незачем, будем сравнивать содержимое массивов поэлементно (через оператор == объекта) \en we will compare the content of arrays element by element (using the operator == of an object) + for ( size_t i = 0; i < count; i++ ) { + if ( !::IsEqualSArrayItems( (*this)[i], w[i] ) ) + return false; + } + + return true; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +bool fill_array( SArray & arr, size_t fillCount, const Type & fillData ) +{ + arr.Flush(); + bool res = arr.AddMemory( fillCount ); + if ( res ) { // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + arr.count = fillCount; + for ( size_t i = 0; i < arr.count; i++ ) { + arr[i] = fillData; // Потребуем наличия оператора присвоения + } + } + return res; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +bool fill_array_zero( SArray & arr, size_t fillCount, size_t startIndex ) +{ + bool res = arr.AddMemory( fillCount + startIndex ); // \ru обеспечить память на такое кол-во элементов \en allocate memory for the given number of elements + if ( res ) { + arr.count = fillCount + startIndex; // \ru установить размер массива \en set the size of the array + memset( (void*)&arr[startIndex], 0, fillCount * sizeof(Type) ); + } + return res; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Mассив с итераторными функциями \en An Array with Iterator Functions +// +//////////////////////////////////////////////////////////////////////////////// + + +FORVARD_DECL_TEMPLATE_TYPENAME( class SIArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const SIArray &, typename SIArray::IteratorFunc ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void for_each_in_array ( const SIArray &, typename SIArray::ParIteratorFunc, void * pars ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t first_that_in_array( const SIArray &, typename SIArray::CompareFunc, void * pars, size_t from ) ); + + +//----------------------------------------------------------------------------- +/** \brief \ru Одномерный массив обьектов с итераторными функциями. + \en One-dimensional array of objects with iterator functions. \~ + \details \ru Одномерный массив обьектов, не содержащих указателей (вернее, не имеющих деструкторов). + В массиве нельзя хранить объекты, содержащие указатели или классы с указателями, + а также абстрактные классы с наследниками. \n + \en One-dimensional array of objects without pointers (i.e. without destructors). + The array should not contain objects with pointers or classes with pointers, + or abstract classes with inheritors. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SIArray : public SArray { +public : + SIArray( size_t i_max=0, uint16 i_delta=1 ) : SArray( i_max, i_delta ) {} + SIArray( const SArray & other ) : SArray( other ) {} + + typedef void (*IteratorFunc) ( Type & obj ); + void ForEach( IteratorFunc func ) const; + typedef void (*ParIteratorFunc) ( Type & obj, void * pars ); + void ForEach( ParIteratorFunc func, void * pars ) const; + typedef bool (*CompareFunc) ( Type & obj, void * pars ); + size_t FirstThat( CompareFunc func, void * pars, size_t from = 0 ) const; + +private: + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const SIArray &, IteratorFunc ); + TEMPLATE_FRIEND void for_each_in_array TEMPLATE_SUFFIX ( const SIArray &, ParIteratorFunc, void * pars ); + TEMPLATE_FRIEND size_t first_that_in_array TEMPLATE_SUFFIX ( const SIArray &, CompareFunc, void * pars, size_t from ); +}; + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию для каждого элемента \en perform the function for every element +// --- +template +inline void SIArray::ForEach( IteratorFunc func ) const { + for_each_in_array( *this, func ); +} + + +//------------------------------------------------------------------------------ +// \ru выполнить функцию с параметрами для каждого элемента \en perform the function with parameters for every element +// --- +template +inline void SIArray::ForEach( ParIteratorFunc func, void * pars ) const { + for_each_in_array( *this, func, pars ); +} + + +//------------------------------------------------------------------------------ +// \ru найти элемент по условию \en find an element by condition +// --- +template +inline size_t SIArray::FirstThat( CompareFunc func, void* pars, size_t from ) const { + return first_that_in_array( *this, func, pars, from ); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +void for_each_in_array( const SIArray & arr, typename SIArray::IteratorFunc func ) { + for( size_t i = 0; i < arr.Count(); i++ ) + func( arr[i] ); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +void for_each_in_array( const SIArray& arr, typename SIArray::ParIteratorFunc func, void* pars ) { + for( size_t i = 0; i < arr.Count(); i++ ) + func( arr[i], pars ); +} + + +//------------------------------------------------------------------------------ +// +// --- +template +size_t first_that_in_array( const SIArray & arr, typename SIArray::CompareFunc func, void * pars, size_t from ) { + for( size_t i = from; i < arr.Count(); i++ ) { + if ( func(arr[i],pars) ) + return i; + } + return SYS_MAX_T; +} + + +//----------------------------------------------------------------------------- +/** \brief \ru Инициализация массива списком значений. + \en Initialization of an array by the list of values. \~ + \details \ru Инициализация массива списком значений. \n + Пример использования: \n + SArray_assign arr; \n + arr = val1, val2, val3; \n + \en Initialization of an array by the list of values. \n + example of using: \n + SArray_assign arr; \n + arr = val1, val2, val3; \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SArray_assign { +protected: + SArray m_arr; ///< \ru Массив объектов. \en An array of objects. +public: + /// \ru Конструктор. \en Constructor. + SArray_assign() : m_arr() {} + /// \ru Конструктор. \en Constructor. + explicit SArray_assign( size_t k ) : m_arr( k, 1 ) {} + /// \ru Конструктор копирования. \en Copy constructor. + SArray_assign( const SArray_assign & other ) : m_arr( other.m_arr ) {} + /// \ru Оператор добавления "через запятую". \en Operator of adding "separated by commas". + SArray_assign & operator , (const T & t) { Set().Add( t ); return *this; } + /// \ru Оператор присваивания. \en The assignment operator. + SArray_assign & operator = (const T & t) { Set().Flush(); Set().Add( t ); return *this; } + + operator SArray () const { return m_arr; } ///< \ru Оператор копирования данных. \en An operator of data copying. + operator SArray & () { return Set(); } ///< \ru Оператор доступа. \en An access operator. + const SArray & Get() const { return m_arr; } ///< \ru Оператор доступа. \en An access operator. + SArray & Set() { return m_arr; } ///< \ru Оператор доступа. \en An access operator. +}; + + +//------------------------------------------------------------------------------- +// \ru функции сравнения двух массивов \en functions of two arrays comparison +// --- +template +inline bool Eq( const SArray & ar1, const SArray & ar2 ) { + return ( ar1 == ar2 ); +} + + +//------------------------------------------------------------------------------ +// \ru Внеклассные ф-ии для сравнения содержимого объектов в методах SArray \en Out-of-class functions for the comparison of objects contents in the methods of SArray +// \ru должны выполнять действия, аналогичные ::memcmp( &obj1, obj2, sizeof(obj1) ) \en they should perform similar to ::memcmp( &obj1, obj2, sizeof(obj1) ) operations +// --- +template +bool IsLessThanSArrayItems( const Type& obj1, const Type& obj2 ); + +inline bool IsLessThanSArrayItems( const float &obj1, const float &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const double &obj1, const double &obj2 ) { return obj1 < obj2; } + +inline bool IsLessThanSArrayItems( const int8 &obj1, const int8 &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const uint8 &obj1, const uint8 &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const int16 &obj1, const int16 &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const uint16 &obj1, const uint16 &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const int &obj1, const int &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const uint &obj1, const uint &obj2 ) { return obj1 < obj2; } +#ifdef C3D_WINDOWS //_MSC_VER // Linux identical int/uint and int32/uint32 +inline bool IsLessThanSArrayItems( const int32 &obj1, const int32 &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const uint32 &obj1, const uint32 &obj2 ) { return obj1 < obj2; } +#endif // C3D_WINDOWS + +#if defined(PLATFORM_64) // \ru x32 совпадение типов ptrdiff_t и int \en x32 coincidence of ptrdiff_t and int types +inline bool IsLessThanSArrayItems( const size_t &obj1, const size_t &obj2 ) { return obj1 < obj2; } +inline bool IsLessThanSArrayItems( const ptrdiff_t &obj1, const ptrdiff_t &obj2 ) { return obj1 < obj2; } +#endif // PLATFORM_64 + + +//------------------------------------------------------------------------------- +// \ru функции сравнения двух массивов \en functions of two arrays comparison +// --- +template +inline bool Less( const SArray & ar1, const SArray & ar2 ) { + ptrdiff_t count1 = ar1.Count(); + ptrdiff_t count2 = ar2.Count(); + + // \ru OV K6 При размещении в памяти с выравниванием не равным 1, между элементами массива \en OV K6 While the memory allocation with alignment which is not equal 1 between elements of the array + // \ru возможно появление "дырок" заполненного случайным мусором, т.к. сравнивать этот мусор \en may appear "holes" filled by random trash, since there is not reason to compare this trash + // \ru нам ни к чему, будем сравнивать содержимое массивов поэлементно \en we will compare contents of arrays element by element + //OV K6 return ::memcmp( ar1.GetAddr(), ar2.GetAddr(), sizeof(Type) * count1 ) < 0; + for ( ptrdiff_t i = 0, c = std_min(count1, count2); i < c; i++ ) { + const Type & obj1 = ar1[i]; + const Type & obj2 = ar2[i]; + if ( !::IsEqualSArrayItems( obj1, obj2 ) ) + // \ru встретили различающиеся элементы \en there are different elements + return ::IsLessThanSArrayItems( obj1, obj2 ); + } + + if ( count1 < count2 ) + return true; + + return false; // \ru массивы полностью идентичны \en arrays are fully identical +} + + +#endif // __TEMPL_S_ARRAY_H diff --git a/C3d/Include/templ_s_array_rw.h b/C3d/Include/templ_s_array_rw.h new file mode 100644 index 0000000..75d9eaf --- /dev/null +++ b/C3d/Include/templ_s_array_rw.h @@ -0,0 +1,233 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация SArray. + \en Serialization of SArray. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_S_ARRAY_RW_H +#define __TEMPL_S_ARRAY_RW_H + + +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/**\ru Чтение массива из потока в объект. + \en Reading of array from a stream to an object \~ + \ingroup Base_Tools_Containers +*/ +// +template +reader & operator >> ( reader & in, SArray & ref ) +{ + ref.Flush(); + if ( in.good() ) + { + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + + if ( in.good() && count ) + { + size_t sizeOfType = sizeof(Type); + // \ru половина адресного пространства для 32-разрядного приложения \en a half of address space for 32-bit application + if ( ::TestNewSize( sizeOfType, count ) ) + { + ref.SetSize( count, true/*clear*/ ); + C3D_ASSERT( ref.upper >= count ); + + if ( ref.GetAddr() != NULL ) { + size_t i; + for ( i = 0; i < count && in.good(); i++ ) + { + in >> ref.parr[i]; + + ref.count++; + + // \ru были записаны не все данные (при условии что запись массива эмулировалась, \en not all data has been written (in condition that writing of array was emulated, + // \ru писалось не через operator << (writer& out, const PArray& ref) ) \en it was written without the operator << (writer& out, const PArray& ref) ) + if ( in.eof() ) // \ru вычитали-ли весь файл и ничего не осталось \en the whole file was read and nothing is left + break; // for + } + } + else { + ref.SetSize( 0, true/*clear*/ ); + C3D_ASSERT_UNCONDITIONAL( false ); + in.setState( io::fail ); // \ru ошибка чтения \en reading error + } + } + else + in.setState( io::fail ); // \ru ошибка чтения \en reading error + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +/**\ru Запись массива в поток из объекта. + \en Writing of array from an object to a stream. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +writer& operator << ( writer& out, const SArray& ref ) { + //OV_x64 out << ref.count; + WriteCOUNT( out, ref.count ); + + for( size_t i = 0; i < ref.count && out.good(); i++ ) + out << ref.parr[i]; + return out; +} + + +//------------------------------------------------------------------------------ +/**\ru Чтение массива из потока в указатель. + \en Reading of array from a stream to a pointer. \~ + \ingroup Base_Tools_Containers +*/ +// +template +reader& operator >> ( reader& in, SArray*& ptr ) { + ptr = NULL; + if ( in.good() ) { + if ( in.MathVersion() < 0x06000012L ) + ptr = new SArray; + else { + uint8 existPtr; + in >> existPtr; + if ( existPtr ) + ptr = new SArray; + } + + if ( ptr ) + in >> *ptr; // \ru чтение тела \en reading of a solid + } + + return in; +} + + +//------------------------------------------------------------------------------ +/**\ru Запись массива в поток из указателя. + \en Writing of array from a pointer to a stream. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +writer& operator << ( writer& out, const SArray* ptr ) { + // \ru ЯТ К6 при записи в старую версию оставляю без проверки указателя \en ЯТ К6 while writing to an old version the pointer is not checked + if ( out.MathVersion() < 0x06000012L ) { + C3D_ASSERT( ptr ); + out << *ptr; + } + else { + uint8 existPtr = !!ptr; + out << existPtr; + if ( existPtr ) + out << *ptr; // \ru запись телом \en writing by a solid + } + + return out; +} + + +//------------------------------------------------------------------------------ +/**\ru Чтение массива из потока в объект. + \en Reading of array from a stream to an object. \~ + \ingroup Base_Tools_Containers +*/ +// +template +reader & operator >> ( reader& in, SSArray& ref ) { + return in >> (SArray &)ref; +} + + +//------------------------------------------------------------------------------ +/**\ru Запись массива в поток из объекта. + \en Writing of array from an object to a stream. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +writer& operator << ( writer& out, const SSArray& ref ) { + return out << (const SArray &)ref; +} + + +//------------------------------------------------------------------------------ +/**\ru Чтение массива из потока в объект. + \en Reading of array from a stream to an object. \~ + \ingroup Base_Tools_Containers +*/ +// +template +reader & operator >> ( reader& in, CSSArray& ref ) { + in >> (SSArray &)ref; + int b; in >> b; ref.m_sort = !!b; //OV_x64 in >> ref.sort; + return in; +} + + +//------------------------------------------------------------------------------ +/**\ru Запись массива в поток из объекта. + \en Writing of array from an object to a stream. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +writer& operator << ( writer& out, const CSSArray& ref ) { + out << (const SSArray &)ref; + int b = !!ref.m_sort; out << b; //OV_x64 out << ref.sort; + return out; +} + + +//------------------------------------------------------------------------------ +/**\ru Чтение массива из потока в объект. + \en Reading of array from a stream to an object. \~ + \ingroup Base_Tools_Containers +*/ +// +template +reader & operator >> ( reader& in, IMArray& ref ) { + // \ru OV x64 return in >> (SArray &)ref; // ЯТ К6 не Type, а uint !!! \en OV x64 return in >> (SArray &)ref; // ЯТ К6 not Type, but uint !!! + if ( in.good() ) { + size_t count = ReadCOUNT( in, true/*uint_val*/ ); + if ( in.good() && count ) { + ref.SetSize( count, true/*clear*/ ); + for ( size_t i = 0; i < count && in.good(); i++ ) { + size_t item = ReadCOUNT( in ); //OV_x64 in >> ref.parr[i]; + ((SArray &)ref).Add( item ); + } + } + } + return in; + +} + + +//------------------------------------------------------------------------------ +/**\ru Запись массива в поток из объекта. + \en Writing of array from an object to a stream. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +writer& operator << ( writer& out, const IMArray& ref ) { +// \ru OV x64 return out << (const SArray &)ref; // ЯТ К6 не Type, а uint !!! \en OV x64 return out << (const SArray &)ref; // ЯТ К6 not Type, but uint !!! + WriteCOUNT( out, ref.count ); + for( size_t i = 0; i < ref.count && out.good(); i++ ) + WriteCOUNT( out, (size_t)ref(i) ); + return out; +} + + +#endif // __TEMPL_S_ARRAY_RW_H diff --git a/C3d/Include/templ_s_list.h b/C3d/Include/templ_s_list.h new file mode 100644 index 0000000..f8d56ec --- /dev/null +++ b/C3d/Include/templ_s_list.h @@ -0,0 +1,934 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Список. + \en List. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_S_LIST_H +#define __TEMPL_S_LIST_H + + +#include +#include +#include + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +#include +#endif //__DEBUG_MEMORY_ALLOCATE_FREE_ + + +//----------------------------------------------------------------------------- +/** \brief \ru Элемент списка. + \en The list element. \~ + \details \ru Элемент списка. \n + \en The list element. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class ListItem { +public: + ListItem * next; ///< \ru Указатель на следующий элемент. \en A pointer to the next element. + Type * data; ///< \ru Указатель на поле данных. \en A pointer to field of data. + +public: + ListItem() : next( 0 ), data( 0 ) {} + ListItem( Type *d ) : next( 0 ), data( d ) {} + ListItem( Type *d, ListItem &prev ); // \ru добавить себя после заданного элемента \en add self after the given element + +private: + ListItem ( const ListItem& ); // \ru запрещено \en forbidden + void operator = ( const ListItem& ); // \ru запрещено \en forbidden +}; + + +//------------------------------------------------------------------------------ +// \ru вставляет себя после item \en inserts itself after 'item' +//--- +template +inline ListItem::ListItem( Type *d, ListItem &prev ) { + next = prev.next; + prev.next = this; + data = d; +} + + +//------------------------------------------------------------------------------ +// +// --- +FORVARD_DECL_TEMPLATE_TYPENAME( class LIterator ); +FORVARD_DECL_TEMPLATE_TYPENAME( class List ); +FORVARD_DECL_TEMPLATE_TYPENAME( void add_to_list ( List &, List & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void add_to_list ( List &, Type* data, const Type* after ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void insert_to_list ( List &, List & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void remove_from_list ( List &, DelType shdl ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void remove_from_list_release ( List & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t remove_from_list ( List &, List &, DelType shdl ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool detach_from_list ( List &, const Type * ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t recalc_list ( List & ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( bool is_exist_in_list ( const List &, const Type * ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( ListItem * find_prev_in_list ( const List &, ListItem* now ) ); + +class reader; +class writer; +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, List & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const List & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, List *& ptr ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const List * ptr ) ); + + +//----------------------------------------------------------------------------- +/** \brief \ru Cписок указателей на элементы. + \en List of pointers to elements. \~ + \details \ru Cписок указателей на элементы. \n + \en List of pointers to elements. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class List { +protected: + bool owns; ///< \ru Признак владения элементами. \en Attribute of ownership of elements. + size_t count; ///< \ru Кол-во эл-тов в списке. \en The number of elements in the list. + ListItem * first; ///< \ru Указатель на первый элемент в списке. \en A pointer to the first list element. + ListItem * last; ///< \ru Указатель на последний элемент в списке. \en A pointer to the last list element. + + ListItem * nowDelItem; // \ru Bременно, для отладки \en Temporarily, for debugging + Type * nowDelElem; // \ru Bременно, для отладки \en Temporarily, for debugging + +public: + explicit List( bool ownsEl = true ) + : owns( ownsEl ) + , count( 0 ) + , first( 0 ) + , last( 0 ) + , nowDelItem( 0 ) + , nowDelElem( 0 ) + {} + virtual ~List(); + + bool OwnsElem() const { return owns; } + void OwnsElem( bool ownsEl ) { owns = ownsEl; } + + void Add( Type * ); // \ru добавить элемент в конец списка \en add an element to the end of the list + void Add( Type *, const Type *after ); // \ru добавить элемент после заданного элемента \en add an element after the given element + void Add( Type *, bool check ); // \ru добавить элемент в конец списка с проверкой на существование \en add an element in the end of the list with existence validation. + void Add ( ListItem & ); // \ru добавить элемент в конец списка \en add an element to the end of the list + void Add ( List &l ) { add_to_list(*this, l); } // \ru добавить список list в конец данного списка \en add a list to the end of the given list + void AddAndEat( List & ); // \ru съесть список list в конец данного списка \en destroy a list and add it to the end of the given list + + void Insert ( Type * ); // \ru вставить элемент в начало списка \en insert an element to the beginning of the list + void Insert ( ListItem & ); // \ru вставить элемент в начало списка \en insert an element to the beginning of the list + void Insert ( List &l ) { insert_to_list(*this, l); } // \ru вставить список в начало данного списка \en insert a list to the beginning of the given list + void InsertAndEat( List & ); // \ru съесть список в начало данного списка \en destroy and add a list to the beginning of the given list + + void Flush ( DelType shdl=defDelete ) { Remove( shdl ); } // \ru удалить все элементы списка \en delete all elements of the list + void Remove( DelType shdl=defDelete ) { remove_from_list(*this, shdl); } // \ru удалить все элементы списка \en delete all elements of the list + + void FlushRelease() { RemoveRelease(); } // \ru удалить все элементы списка \en delete all elements of the list + void RemoveRelease() { remove_from_list_release(*this); } // \ru удалить все элементы списка \en delete all elements of the list + + bool Remove( Type *, DelType=defDelete ); // \ru удалить один элемент списка \en delete one element of the list + size_t Remove( List &l, DelType shdl=defDelete ) { return remove_from_list(*this, l, shdl ); } // \ru удалить все элементы принадлежащие списку l \en delete all elements from the list l + bool Detach( const Type *d ) { return detach_from_list(*this, d); } // \ru отсоединить один элемент списка \en detach one element from the list + size_t Detach( List &l ) { return Remove(l, noDelete); } // \ru отсоединить от списка другой список элементов \en detach other list from the list + + void Close(); // \ru замкнуть список \en close the list + void Split(); // \ru разомкнуть список \en split the list + + size_t Count() const { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + return count; } // \ru дать количество элементов в списке \en get the number of elements in the list + + size_t ReCalc() { return recalc_list(*this); }// \ru пересчитать количество элементов в списке \en count the number of elements in the list + bool IsEmpty () const { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + return first == 0; } // \ru проверить, пустой ли список \en check whether the list is empty + + bool IsExist( const Type *d ) const { return is_exist_in_list(*this, d);} // \ru найти элемент по равенству указателей \en find an element by the equality of pointers + + Type * GetFirstData() const { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + PRECONDITION( first ); return first->data; } // \ru получить данные первого элемента списка \en get the data of the first element of the list + Type * GetLastData() const { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + PRECONDITION( last ); return last->data; } // \ru получить данные последнего элемента списка \en get the data of the last element of the list + +protected: + TEMPLATE_FRIEND class LIterator TEMPLATE_SUFFIX; + +private: + ListItem * findPrev( ListItem *now ) { return find_prev_in_list(*this, now); } // \ru найти предыдущий \en find the previous + + List ( const List& ); // \ru запрещено \en forbidden + void operator = ( const List& ); // \ru запрещено \en forbidden + + TEMPLATE_FRIEND void add_to_list TEMPLATE_SUFFIX ( List &, List & ); + TEMPLATE_FRIEND void add_to_list TEMPLATE_SUFFIX ( List &, Type* data, const Type* after ); + TEMPLATE_FRIEND void insert_to_list TEMPLATE_SUFFIX ( List &, List & ); + TEMPLATE_FRIEND void remove_from_list TEMPLATE_SUFFIX ( List &, DelType shdl ); + TEMPLATE_FRIEND void remove_from_list_release TEMPLATE_SUFFIX ( List & ); + TEMPLATE_FRIEND size_t remove_from_list TEMPLATE_SUFFIX ( List &, List &, DelType shdl ); + TEMPLATE_FRIEND bool detach_from_list TEMPLATE_SUFFIX ( List &, const Type * ); + TEMPLATE_FRIEND size_t recalc_list TEMPLATE_SUFFIX ( List & ); + TEMPLATE_FRIEND bool is_exist_in_list TEMPLATE_SUFFIX ( const List &, const Type * ); + TEMPLATE_FRIEND ListItem * find_prev_in_list TEMPLATE_SUFFIX ( const List &, ListItem* now ); + + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, List & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const List & ref ); + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, List *& ptr ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const List * ptr ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * List::operator new( size_t size ) { + return ::Allocate( size, typeid(List).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void List::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(List).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//----------------------------------------------------------------------------- +/** \brief \ru Итератор списка. + \en Iterator of list. \~ + \details \ru Итератор списка. \n + \en Iterator of list. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class LIterator { +protected: + List * list; + ListItem * curr; + ListItem * prev; + +public: + LIterator() : list( 0 ), curr( 0 ), prev( 0 ) {} + LIterator( const List & l ) : list( 0 ), curr( 0 ), prev( 0 ) { Set(l); } + LIterator( const LIterator &i ) : list( i.list ), curr( i.curr ), prev( i.prev ) {} + virtual ~LIterator() {} + + void Set( const List& l ) { list = (List*)&l; Restart(); } + void Restart() { PRECONDITION(list); curr = list->first; prev = 0; } + Type * GetData() const { return curr ? curr->data : 0; } + Type * GetDataAndGo(); // \ru взять данные и продвинуть итератор \en take the data and move the iterator + List * GetList() const { return list; } + + Type& operator* () const { PRECONDITION(curr && curr->data ); return *curr->data; } + Type* operator () () const { return curr ? curr->data : 0; } + operator ListItem* () const { return curr; } + operator ListItem& () const { PRECONDITION(curr); return *curr; } + Type* operator ++() { prev = curr; if (curr) {curr=curr->next; return curr ? curr->data : 0;} else return 0; } + Type* operator ++(int) { prev = curr; if (curr) {Type* ret=curr->data; curr=curr->next; return ret;} else return 0; } + Type* operator --() { PRECONDITION(list); curr=prev; prev=list->findPrev(prev); return curr ? curr->data : 0; } + Type* operator --(int) { PRECONDITION(list); if (curr) {Type* ret=curr->data; curr=prev; prev=list->findPrev(prev); return ret;} else return 0; } + Type* operator ->() { return curr ? curr->data : 0; } + + bool operator == ( const LIterator &o ) const { return list==o.list && curr==o.curr; } + bool operator != ( const LIterator &o ) const { return ! operator == (o); } + LIterator & operator = ( const List &l ) { Set(l); return* this; } + LIterator & operator = ( const LIterator &o ) { list=o.list; curr = o.curr; prev = o.prev; return *this; } + + void Add ( Type * ); // \ru добавить элемент после заданного элемента \en add an element after the given element + void AddAndEat( List & ); // \ru съесть list после текущего элемента \en destroy the list and add it after the current element + + void Insert ( Type * ); // \ru вставить элемент перед заданным элементом \en insert an element before the given element + void InsertAndEat( List & ); // \ru съесть list перед заданным элементом \en destroy the list and add it before the given element + + void Remove( DelType = defDelete ); // \ru удалить элемент списка и продвинуть вперед \en delete an element from the list and move forward + void Detach(); // \ru отсоединить элемент списка \en detach an element from the list + + bool IsOK() const { return curr != 0; } + ListItem * Next() const { PRECONDITION(curr); return curr->next; } + void Go() { prev = curr; if ( curr ) curr = curr->next; } + void GoLast() { PRECONDITION(list); curr = list->last; prev = list->findPrev(curr); } + + bool IsFirst() const { PRECONDITION(list); return curr == list->first; } + bool IsLast() const { PRECONDITION(list); return curr == list->last; } +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru список указателей на элементы \en a list of pointers to the elements +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// +//--- +template +inline List::~List() { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + Remove(); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент в конец списка \en add an element to the end of the list +//--- +template +inline void List::Add( Type* data ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + if ( last ) + last = new ListItem( data, *last ); + else + first = last = new ListItem( data ); + + count++; +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент после заданного элемента \en add an element after the given element +//--- +template +inline void List::Add( Type* data, const Type* after ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + add_to_list( *this, data, after ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент в конец списка с проверкой на существование \en add an element in the end of the list with existence validation +//--- +template +inline void List::Add( Type* data, bool /*check*/ ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + if ( !IsExist(data) ) + Add( data ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент в конец списка \en add an element to the end of the list +//--- +template +inline void List::Add( ListItem &item ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + item.next = 0; + + if ( last ) + last->next = &item; + else + first = &item; + + last = &item; + count++; +} + + +//------------------------------------------------------------------------------ +// \ru добавить список list в конец данного списка \en add a list to the end of the given list +// \ru list после добавления становится пустым! \en a list becomes empty after the adding of it! +//--- +template +inline void List::AddAndEat( List &list ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + if ( list.first ) { + + if ( last ) { + last->next = list.first; + last = list.last; + } + else { + first = list.first; + last = list.last; + } + + count += list.count; + list.count = 0; + list.first = list.last = 0; + } +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент в начало списка \en insert an element to the beginning of the list +//--- +template +inline void List::Insert( Type* data ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + Insert( *new ListItem(data) ); +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент в начало списка \en insert an element to the beginning of the list +//--- +template +inline void List::Insert( ListItem &item ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + ListItem* old = first; + + first = &item; + first->next = old; + + if ( !last ) + last = first; + + count++; +} + + +//------------------------------------------------------------------------------ +// \ru съесть список list в начало данного списка \en destroy and add a list to the beginning of the given list +//--- +template +inline void List::InsertAndEat( List &list ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + if ( list.first ) { + + if ( first ) { + PRECONDITION( list.last ); + list.last->next = first; + first = list.first; + } + else { + first = list.first; + last = list.last; + } + + count += list.count; + list.count = 0; + list.first = list.last = 0; + } +} + + +//------------------------------------------------------------------------------ +// \ru удалить один элемент списка \en delete one element of the list +//--- +template +inline bool List::Remove( Type *del, DelType shdl ) { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + if ( Detach(del) ) { + + if ( shdl==Delete || (shdl==defDelete && owns) ) { + nowDelElem = del; + delete del; + nowDelElem = NULL; + } + + return true; + } + + return false; +} + + +//------------------------------------------------------------------------------ +// \ru замкнуть список \en close the list +//--- +template +inline void List::Close() { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + if ( last ) + last->next = first; +} + + +//------------------------------------------------------------------------------ +// \ru разомкнуть список \en split the list +//--- +template +inline void List::Split() { + PRECONDITION( nowDelItem == 0 && nowDelElem == 0 ); + + if ( last ) + last->next = 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru итератор списка \en Iterator of list +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// \ru взять данные и продвинуть итератор \en take the data and move the iterator. +//--- +template +inline Type* LIterator::GetDataAndGo() { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( curr ) { + Type* ret = curr->data; + prev = curr; + curr = curr->next; + return ret; + } + + return 0; +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент после текущего элемента \en add an element after the current element +//--- +template +inline void LIterator::Add( Type *data ) { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( curr ) { + ListItem *newItem = new ListItem( data, *curr ); // \ru поставит себя после curr \en inserts itself after 'curr' + if ( list->last == curr ) + list->last = newItem; + list->count++; + } + else + list->Add( data ); +} + + +//------------------------------------------------------------------------------ +// \ru съесть list после текущего элемента \en destroy a list and add it after the current element +//--- +template +inline void LIterator::AddAndEat( List& l ) { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( l.first ) { + + if ( curr ) { + PRECONDITION( l.last ); + l.last->next = curr->next; + curr->next = l.first; + + if ( list->last == curr ) + list->last = l.last; + list->count += l.count; + + l.count = 0; + l.first = l.last = 0; + } + else + list->AddAndEat( l ); // \ru съесть список l в конец данного списка \en destroy a list l and add it to the end of the given list + } +} + + +//------------------------------------------------------------------------------ +// \ru вставить элемент перед текущим \en insert an element before the specified one +//--- +template +inline void LIterator::Insert( Type *data ) { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( prev ) { + ListItem *newItem = new ListItem( data, *prev ); // \ru ставит себя после prev \en inserts itself after 'prev' + + if ( list->last == prev ) + list->last = newItem; + + prev = newItem; + list->count++; + } + else + list->Insert( data ); // \ru вставить элемент в начало списка \en insert an element to the beginning of the list +} + + +//------------------------------------------------------------------------------ +// \ru съесть list перед моим текущим элементом \en destroy a list and add it before mine current element +//--- +template +inline void LIterator::InsertAndEat( List& l ) { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( l.first ) { + + if ( prev ) { + PRECONDITION( l.last ); + prev->next = l.first; + l.last->next = curr; + prev = l.last; + + list->count += l.count; + + l.count = 0; + l.first = l.last = 0; + } + else + list->InsertAndEat( l ); // \ru съесть список l в конец данного списка \en destroy a list l and add it to the end of the given list + } +} + + +//------------------------------------------------------------------------------ +// \ru удалить текущий элемент итератора \en delete the current element of the iterator +//--- +template +inline void LIterator::Remove( DelType shdl ) { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( curr ) { + if ( shdl==Delete || (shdl==defDelete && list->owns) ) { + list->nowDelElem = curr->data; + delete curr->data; + list->nowDelElem = 0; + } + + Detach(); + } +} + + +//------------------------------------------------------------------------------ +// \ru отсоединить элемент списка \en detach an element from the list +//--- +template +inline void LIterator::Detach() { + PRECONDITION( list && list->nowDelItem == 0 && list->nowDelElem == 0 ); + + if ( curr ) { + ListItem* next = curr->next; + + if ( prev ) + prev->next = next; + else + list->first = next; + + if ( !next ) + list->last = prev; + + list->nowDelItem = curr; + delete curr; + list->nowDelItem = 0; + curr = next; + + prev = list->findPrev( curr ); + list->count--; + } +} + + +//------------------------------------------------------------------------------ +template +void add_to_list( List &list, Type *data, const Type *after ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + if ( after ) { + ListItem *c = list.first; + + while ( c ) { + if ( c->data == after ) { + ListItem *newItem = new ListItem( data, *c ); // \ru поставит себя после c \en inserts itself after 'c' + if ( list.last == c ) + list.last = newItem; + list.count++; + return; + } + else + c = c->next; + } + } + + list.Add( data ); +} + + +//------------------------------------------------------------------------------ +template +void add_to_list( List &to, List &from ) { + PRECONDITION( to.nowDelItem == 0 && to.nowDelElem == 0 ); + PRECONDITION( from.nowDelItem == 0 && from.nowDelElem == 0 ); + + ListItem *curr = from.first; + while ( curr ) { + to.Add( curr->data ); + curr = curr->next; + } + + if ( to.owns ) + from.owns = false; +} + + +//------------------------------------------------------------------------------ +template +void insert_to_list( List &to, List &from ) { + PRECONDITION( to.nowDelItem == 0 && to.nowDelElem == 0 ); + PRECONDITION( from.nowDelItem == 0 && from.nowDelElem == 0 ); + + ListItem *curr = from.first; + while ( curr ) { + to.Insert( curr->data ); + curr = curr->next; + } + + if ( to.owns ) + from.owns = false; +} + + +//------------------------------------------------------------------------------ +// \ru Очистить лист с возможным удаленим данных \en Clear the list with data deletion +// --- +template +void remove_from_list( List &list, DelType shdl ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + bool del = shdl==Delete || (shdl==defDelete && list.owns); + + ListItem *first = list.first; + list.first = 0; + list.last = 0; + list.count = 0; + while ( first ) { + ListItem *temp = first; + first = first->next; + + if ( del ) { + list.nowDelElem = temp->data; + delete temp->data; + list.nowDelElem = 0; + } + + list.nowDelItem = temp; + delete temp; + list.nowDelItem = 0; + } +} + + +//------------------------------------------------------------------------------ +// \ru Очистить лист с возможным удаленим данных \en Clear the list with data deletion +// --- +template +void remove_from_list_release( List &list ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + ListItem *first = list.first; + list.first = 0; + list.last = 0; + list.count = 0; + while ( first ) { + ListItem *temp = first; + first = first->next; + + list.nowDelElem = temp->data; + if ( temp->data ) + temp->data->Release(); + list.nowDelElem = 0; + + list.nowDelItem = temp; + delete temp; + list.nowDelItem = 0; + } +} + + +//------------------------------------------------------------------------------ +// \ru Отцепить один список от другого с возможным удалением данных \en Detach one list from another with data deletion +// --- +template +size_t remove_from_list( List &list, List &deList, DelType shdl ) { + PRECONDITION( &list != &deList ); + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + PRECONDITION( deList.nowDelItem == 0 && deList.nowDelElem == 0 ); + + if ( !list.first || !deList.first ) // \ru какой-то из списков пуст ! \en one of the lists is empty ! + return 0; + + bool willDel = shdl==Delete || (shdl==defDelete && list.owns); + + list.last->next = list.first; // \ru закольцуем список \en close the list + ListItem *curr = list.first; // \ru начнем сначала \en start from the beginning + ListItem *prev = list.last; + ListItem *del = deList.first; // \ru текущий удаляемый \en the current deleted + ListItem *pdel = NULL; // \ru предыдущий удаляемый \en the previous deleted + size_t deleted = 0; // \ru отцепленных 0 \en there are 0 detached + + while( del && list.first ) { // \ru есть еще пока чего удалять и откуда \en there are elements to delete + ListItem *from = curr; // \ru начинаем с текущего \en start from the current one + bool found = false; + do { + if ( curr->data == del->data ) { // \ru поймался !! \en found !! + ListItem *condemned = curr; // \ru его будем удалять \en it will be deleted + found = true; + + if ( list.first == list.last ) { // \ru если всего один элемент, то ничего не останется \en if there is only one element then nothing will be left + list.count = 0; + list.first = NULL; + list.last = NULL; + // \ru curr продвигать не нужно - все равно заканчиваем \en 'curr' should not be moved + } + else { + list.count--; // \ru скорректируем счетчик \en correct the counter + if ( list.first == curr ) // \ru если вдруг в начале списка - \en if it is in the beginning of the list + list.first = curr->next; // \ru начало сдвинуть \en then move the beginning + + if ( list.last == curr ) // \ru если вдруг в конце списка - \en if it is in the end of the list + list.last = prev; // \ru конец сдвинуть \en then move the end + + prev->next = curr->next; // \ru отцепим найденный \en detach the found one + curr = curr->next; // \ru продвинемся \en move + } + + if ( willDel ) { // \ru если надо - удалим данные \en delete the data if it is necessary + list.nowDelElem = condemned->data; + delete condemned->data; + list.nowDelElem = 0; + } + + list.nowDelItem = condemned; + delete condemned; // \ru удалим квартиру \en delete condemned + list.nowDelItem = 0; + + deleted++; // \ru еще один удалили \en another one has been deleted + break; + } + else { // \ru если не нашли - продвинемся на следующий \en if nothing is found then move to the next + prev = curr; + curr = curr->next; + } + } while( curr != from ); // \ru есть где поискать \en there is something to find + + + ListItem *next = del->next; + if ( found && willDel ) { // \ru удаляем квартиру в list'е задающем список удаляемых \en delete a condemned from the list which sets the list of deleted elements + if ( pdel ) + pdel->next = next; + else + deList.first = next; + + if ( !next ) + deList.last = pdel; + + deList.nowDelItem = del; + delete del; // \ru помним, что данные мы уже удалили \en remember that the data has already been deleted + deList.nowDelItem = 0; + + deList.count--; + } + else + pdel = del; + + del = next; + } + + if ( list.last ) + list.last->next = 0; // \ru разорвать список \en split the list + + return deleted; +} + + +//------------------------------------------------------------------------------ +template +bool detach_from_list( List& from, const Type* del ) { + PRECONDITION( from.nowDelItem == 0 && from.nowDelElem == 0 ); + + ListItem* curr = from.first; + ListItem* prev = 0; + + while( curr ) { + if ( curr->data == del ) { // \ru нашли \en found + ListItem *next = curr->next; + if ( prev ) + prev->next = next; + else + from.first = next; + + if ( !next ) + from.last = prev; + + from.nowDelItem = curr; + delete curr; + from.nowDelItem = 0; + + from.count--; + return true; + } + else { + prev = curr; + curr = curr->next; + } + } + + return false; +} + + +//------------------------------------------------------------------------------ +template +size_t recalc_list( List &list ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + list.count = 0; + ListItem *curr = list.first; + while ( curr ) { + list.count++; + curr = curr->next; + } + return list.count; +} + + +//------------------------------------------------------------------------------ +template +bool is_exist_in_list( const List& list, const Type* what ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + bool exist = false; + + ListItem *curr = list.first; + while ( curr && !exist ) { + exist = ( curr->data == what ); + curr = curr->next; + } + + return exist; +} + + +//------------------------------------------------------------------------------ +template +ListItem* find_prev_in_list( const List& list, ListItem* now ) { + PRECONDITION( list.nowDelItem == 0 && list.nowDelElem == 0 ); + + if ( now ) { + ListItem *tmp = list.first; + while( tmp && tmp->next != now ) + tmp = tmp->next; + return tmp; + } + + return 0; +} + + +#endif // __TEMPL_S_LIST_H diff --git a/C3d/Include/templ_s_queue.h b/C3d/Include/templ_s_queue.h new file mode 100644 index 0000000..895f737 --- /dev/null +++ b/C3d/Include/templ_s_queue.h @@ -0,0 +1,355 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Очередь объектов, которые не имеют деструкторов. + \en Queue of objects without destructors. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __TEMPL_S_QUEUE_H +#define __TEMPL_S_QUEUE_H + + +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Очередь объектов, которые не имеют деструкторов. + \en Queue of objects without destructors. \~ + \details \ru Очередь объектов, которые не имеют деструкторов. \n + + Требования к объектам очереди такие же, как в SArray. + \en Queue of objects without destructors. \n + + Requirement for the objects are the same as in SArray. \~ + \attention \ru В целях эффективности контейнера проверки обращения к запредельной + памяти реализованы только под откладкой + \en In order to efficiency of the container validation - the usage of prohibitive + memory are implemented only for debug version \~ + \par \ru Рекомендации по использованию + Если предполагается фиксированный (известный) наибольший размер очереди, то + рекомендуется использовать функцию SQueue::Push() для добавления + объекта. Если предельный размер очереди не известен, то следует применять метод + SQueue::PushAlloc(), который при добавлении "наращивает" память + по мере необходимости. + \en Usage recommendations + If the fixed (known) maximum size of queue is assumed then + it is recommended to use the function SQueue::Push() to add + an object. If the limit size of queue is unknown then there should be applied the method + SQueue::PushAlloc() which builds up the memory + as necessary. \~ + + \par \ru Правило выделения памяти + Если размера буфера для хранения объектов очереди не достаточно, то выделяется + новый участок кучи с размеров на SQueue::delta больше. Если SQueue::delta = 1, + то размер выделенной памяти уведичивается на 12,5% при каждом достижении предела. + \en The rule of memory allocation + If the size of the buffer for storage of queue objects is not enough then allocated + a new part of the heap which has size greater on SQueue::delta. If SQueue::delta = 1, + then the size of allocated memory is increased by 12,5% each time the limit is reached. \~ + + \ingroup Base_Tools_Containers +*/ +// --- +template +class SQueue +{ + Type * data; ///< \ru Адрес начала выделенной памяти. \en An address of the beginning of the allocated memory. + Type * qlast; ///< \ru Адрес конца выделенной памяти (последний элемент массива выделенной памяти). \en An address of the end of the allocated memory (the last element of the allocated memory's array) + Type * qp1; ///< \ru Самый первый извлекаемый (queue pointer 1). \en The first extracted one (queue pointer 1). + Type * qp2; ///< \ru Следующий элемент от последнего вошедшего (queue pointer 2). \en The next element from the last entering (queue pointer 2). + +public: + /// \ru Конструктор. \en Constructor. + SQueue( size_t capacity = 0 ); + /// \ru Деструктор. \en Destructor. + virtual ~SQueue(); +public: + /// \ru Выдать размер выделенной памяти. \en Get the size of the allocated memory. + size_t Capacity() const { return qlast+1-data; } + /// \ru Последний элемент очереди. \en The last element of the queue. + Type & Back(); + /// \ru Последний элемент очереди. \en The last element of the queue. + const Type & Back() const; + /// \ru Первый элемент очереди. \en The first element of the queue. + Type & Front() { PRECONDITION(Capacity() > 0 && !Empty() ); return *qp1; } + /// \ru Первый элемент очереди. \en The first element of the queue. + const Type & Front() const { PRECONDITION(Capacity() > 0 && !Empty() ); return *qp1; } + /// \ru Свойство пустого множества. \en A property of the empty set. + bool Empty() const { return qp1 == qp2; } + /// \ru Свойство исчерпанной памяти. \en An expended memory property. + bool IsFull() const; + /// \ru Самый первый, выходящий из очереди (корректно работает только для непустой очереди). \en The very first one outgoing from the queue (it works correctly only for nonempty queue). + Type & First() const { PRECONDITION( qp1 <= qlast && qp1 >= data && qp1 != qp2 ); return *qp1; } + /// \ru Добавить в очередь и нарастить буфер выделенной памяти при необходимости. \en Add to the queue and increase the buffer of the allocated memory if it is necessary. + void Push( const Type & obj ); + /// \ru Вывести из очереди. \en Move out from queue. + void Pop(); + /// \ru Вывести из очереди. \en Move out from queue. + void Pop( Type & obj ); + /// \ru Зарезервировать дополнительную память. \en Reserve an additional memory. + bool Reserve( size_t ); + /// \ru Очистить очередь. \en Clear the queue. + void SetEmpty() { qp1 = qp2 = data; } + /// \ru Выдать размер очереди. \en Get the queue size. + size_t Size() const; + +private: + /// \ru Инкремент указателя с учётом зацикленности памяти. \en An increment of the pointer considering a looped memory. + Type * _IncPtr( Type * ptr ) const; + /// \ru Добавить в очередь без проверки израсходованной памяти. \en Add to the queue without check of consumed memory. + void _Push( const Type & u ); + /// \ru Задать наибольший размер очереди. \en Set the maximum size of the queue. + bool _NewCapacity( size_t max_len, bool clear ); +}; + +//------------------------------------------------------------------------------- +// +// --- +template +SQueue::SQueue( size_t capacity ) + : data( NULL ) + , qlast( NULL ) + , qp1( NULL ) + , qp2( NULL ) +{ + if ( capacity > 0 ) { + try { + data = new Type[capacity]; + } + catch ( const std::bad_alloc & ) { + data = NULL; + throw; + } + } + + qlast = data+capacity-1; + qp1 = qp2 = data; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +SQueue::~SQueue() +{ + delete [] data; + +#ifdef C3D_DEBUG + ::memset( &qp1, 0xFE, sizeof(Type *) ); + ::memset( &qp2, 0xFE, sizeof(Type *) ); + ::memset( &qlast, 0xFE, sizeof(Type *) ); + ::memset( &data, 0xFE, sizeof(Type *) ); +#endif // C3D_DEBUG +} + + +//------------------------------------------------------------------------------- +/// \ru Кто крайний? (корректно работает только для непустой очереди); \en Which is the last? (it works correctly only for nonempty queue); +// --- +template +inline const Type & SQueue::Back() const +{ + PRECONDITION( !Empty() && Capacity() > 0 ); + return qp2 == data ? *qlast : *(qp2-1); +} + + +//------------------------------------------------------------------------------- +/// \ru Кто крайний? (корректно работает только для непустой очереди) \en Which is the last? (it works correctly only for nonempty queue) +// --- +template +inline Type & SQueue::Back() +{ + PRECONDITION( !Empty() && Capacity() > 0 ); + return qp2 == data ? *qlast : *(qp2-1); +} + + +//------------------------------------------------------------------------------- +/// \ru Свойство полностью исчерпанного буфера \en A expended buffer property. +/**\ru Фактически свойство отвечает возможно ли добавить в очередь элемент без + передислокации буфера. + \en In fact this property answeres whether it is possible to add in a queue an element without + redeployment of the buffer. \~ +*/ +// --- +template +inline bool SQueue::IsFull() const +{ + return _IncPtr( qp2 ) == qp1 || data == NULL; +} + + +//------------------------------------------------------------------------------- +/// \ru Инкремент указателя с учётом зацикленности памяти \en An increment of the pointer considering a looped memory +//--- +template +inline Type * SQueue::_IncPtr( Type * ptr ) const +{ + PRECONDITION( ptr >= data && ptr <= qlast ); + if ( ++ptr > qlast ) + ptr = data; + return ptr; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +inline void SQueue::_Push( const Type & obj ) +{ + PRECONDITION( !IsFull() && Size() < Capacity() ); + memcpy( qp2, &obj, sizeof(Type) ); + qp2 = _IncPtr( qp2 ); + PRECONDITION( !Empty() ); // \ru после добавления очередь не может быть пустой \en the queue may bacome empty after the adding + PRECONDITION( qp2 >= data && qp2 <= qlast ); +} + + +//------------------------------------------------------------------------------- +/// \ru Добавить в очередь и нарастить буфер выделенной памяти при необходимости \en Add to the queue and increase the buffer of the llocated memory if it is necessary +/**\ru Тоже, что и #SQueue::Push, но с перезахватом памяти при исчерпании буфера + \en The same as #SQueue::Push, but with memory reallocation in a case when the buffer is full \~ +*/ +// --- +template +void SQueue::Push( const Type & obj ) +{ + if ( IsFull() ) // \ru Требуется перезахват памяти \en A memory reallocation is required + { + size_t cap = Capacity(); + cap += ::KsAutoDelta( cap ); + if ( !_NewCapacity(cap, false/*clear*/) ) + return; + } + _Push( obj ); + + PRECONDITION( qp2 >= data && qp2 <= qlast ); +} + + +//------------------------------------------------------------------------------- +// +// --- +template +inline void SQueue::Pop( Type & obj ) +{ + PRECONDITION( qp2 != qp1 ); // \ru перед извлечением очередь не может быть пустой \en the queue may bacome empty before the extraction + memcpy( &obj, qp1, sizeof(Type) ); + qp1 = _IncPtr( qp1 ); + PRECONDITION( qp1 <= qlast && qp1 >= data ); +} + + +//------------------------------------------------------------------------------- +// +// --- +template +inline void SQueue::Pop() +{ + PRECONDITION( qp2 != qp1 ); // \ru перед извлечением очередь не может быть пустой \en the queue may bacome empty before the extraction + qp1 = _IncPtr( qp1 ); + PRECONDITION( qp1 <= qlast && qp1 >= data ); +} + + +//------------------------------------------------------------------------------- +/// \ru Зарезервировать дополнительную память \en Reserve an additional memory +// --- +template +bool SQueue::Reserve( size_t addCapacity ) +{ + PRECONDITION( addCapacity > 0 ); + const size_t futureSize = Size() + addCapacity; // \ru Предполагаемый размер, растущей очереди \en An assumed size of increasing queue + if ( Capacity() < futureSize ) + { + return _NewCapacity( futureSize, false ); + } + return true; +} + + +//------------------------------------------------------------------------------- +/// \ru Выдать размер очереди \en Get the queue size +//--- +template +inline size_t SQueue::Size() const +{ + if ( qp2 >= qp1 ) + { + return qp2 - qp1; // \ru Нефрагментированная очередь \en Not fragmented queue + } + return ( qlast + 1 - qp1 ) + ( qp2 - data ); // \ru Сумма длин двух фрагментов очереди \en The lengths sum of two fragments of queue +} + + +//------------------------------------------------------------------------------- +/// \ru Задать наибольший размер очереди \en Set the maximum size of the queue +// --- +template +bool SQueue::_NewCapacity( size_t max_len, bool clear ) +{ + if ( clear || Empty() || max_len == 0 ) + { + try { + delete [] data; + data = qlast = qp1 = qp2 = NULL; + if ( max_len > 0 ) { + data = new Type[max_len]; + qlast = data + max_len - 1; + qp1 = qp2 = data; + } + } + catch ( ... ) { + data = qlast = qp1 = qp2 = NULL; + C3D_CONTROLED_THROW; + return false; + } + } + else + { + PRECONDITION( qp1 != qp2 && max_len>0 && clear == false ); // \ru Выражение обязано быть истинным \en The expression should be true + Type * n_data = NULL; + try { + n_data = new Type[max_len]; + if ( qp1 < qp2 ) // \ru Вариант без фрагментации \en A variant without fragmentation + { + size_t len = std_min( (size_t)/*OV_x64 (uint)*/( qp2 - qp1 ), max_len ); // \ru Количество ячеек с полезной информацией (не байты) \en The number of cells with useful information (not bites) + PRECONDITION( len <= max_len ); + ::memcpy( n_data, qp1, len * sizeof( Type ) ); + delete[] data; + data = qp1 = qp2 = n_data; + qp2 += len; + } + else if ( qp1 > qp2 ) // \ru Вариант с фрагментированным массивом полезной информации \en A variant with the fragmented array of useful information + { + size_t len1 = std_min( (size_t)( qlast - qp1 + 1 ), max_len ); // \ru Количество ячеек первого фрагмента \en The number of cells of the first fragment + size_t len2 = std_min( (size_t)( qp2 - data ), (size_t)( max_len - len1 ) ); // \ru Количество ячеек второго фрагмента \en The number of cells of the second fragment + PRECONDITION( len1 + len2 <= max_len ); + ::memcpy( n_data, qp1, len1 * sizeof( Type ) ); + ::memcpy( n_data + len1, data, len2 * sizeof( Type ) ); + delete[] data; + data = qp1 = qp2 = n_data; + qp2 += len1; + qp2 += len2; + } + qlast = data + max_len - 1; + } + catch ( ... ) { + C3D_CONTROLED_THROW; + return false; + } + } + return true; +} + + +#endif // __TEMPL_S_QUEUE_H diff --git a/C3d/Include/templ_sfdp_array.h b/C3d/Include/templ_sfdp_array.h new file mode 100644 index 0000000..8a8ea3c --- /dev/null +++ b/C3d/Include/templ_sfdp_array.h @@ -0,0 +1,617 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Cортированный одномерный массив указателей на обьекты. + \en Sorted one-dimensional array of pointers to objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_SFDP_ARRAY_H +#define __TEMPL_SFDP_ARRAY_H + + +#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class SFDPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t add_to_array ( SFDPArray & arr, Type& el, Type *& found, bool & added ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_in_array( const SFDPArray&, const Type&, Type *&found ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader& in, SFDPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer& out, const SFDPArray & ref ) ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Cортированный одномерный массив указателей на обьекты. + \en Sorted one-dimensional array of pointers to objects. \~ + \details \ru Cортированный одномерный массив указателей на обьекты. \n + Нет повторного добавления. Без функции сравнения массив бесполезен. + \en Sorted one-dimensional array of pointers to objects. \n + There is no repeat adding. The array is useless without comparison function. \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SFDPArray : private FDPArray { + +protected : + typedef int (*CompareFunc)( const Type &d1, const Type &d2 ); // \ru Функция сравнения для поиска и наполнения. \en A comparison function for search and filling. + typedef int (*SearchFunc) ( const Type &d1, size_t d ); // \ru Функция сравнения для поиска. \en A comparison function for search. + + CompareFunc fCompare; // \ru Функция сравнения. \en A comparison function. + +public : + SFDPArray( size_t i_upper, uint16 i_delta, CompareFunc fc, typename FDPArray::DestroyFunc fd ); + virtual ~SFDPArray(); + +using FDPArray::AddCArray; +using FDPArray::OwnsElem; +using FDPArray::Delta; +using FDPArray::Upper; +using FDPArray::SetMaxDelta; +using FDPArray::Flush; +using FDPArray::Clear; +using FDPArray::Adjust; +using FDPArray::Reserve; +using FDPArray::RemoveInd; +using FDPArray::DetachInd; +using FDPArray::DestroyInd; +using FDPArray::DestroyObj; +using FDPArray::Count; +using FDPArray::MaxIndex; +using FDPArray::operator[]; +using FDPArray::clear; + +using RPArray::empty; +using RPArray::size; +using RPArray::begin; +using RPArray::end; +using RPArray::cbegin; +using RPArray::cend; +using RPArray::front; +using RPArray::back; + + + /** \brief \ru Сбросить себя и скопировать other. \en Reset itself and copy 'other'. + */ + bool Init ( const SFDPArray & other ); + + /** + \brief \ru Попробовать добавить элемент с сортировкой. + \en Try to add an element with sorting. \~ + \details \ru Попробовать добавить элемент с сортировкой. Если объект уже существует, то не добавлять. + \en Try to add an element with sorting. If an object already exists, it is not added. \~ + \param[in] ent - \ru Элемент для добавления. + \en An element to add. \~ + \param[out] found - \ru Добавленный или найденный элемент. + \en Added or found element. \~ + \return \ru Если элемент добавлен, то возвращает индекс добавленного объекта, в противном случае возвращает индекс найденного объекта. + \en If the element has been added, then returns the index of added element, otherwise, returns the index of the found element.\~ + */ + size_t AddTry ( Type &ent, Type *&found ); + + /** + \brief \ru Добавить элемент с сортировкой. + \en Add an element with sorting. \~ + \details \ru Добавить элемент с сортировкой. Нельзя повторно добавить существующий объект. + \en Add an element with sorting. An existed object cannot be added repeatedly. \~ + \return \ru Возвращает true, если элемент добавлен. + Если элемент не добавлен: + - если он эквивалентен найденному в соответствии с функцией сравнения, + но не тот же самый (указатели данного элемента и существующего не равны), то возвращается false. + - если элемент тот же самый (указатели данного элемента и существующего равны), то возвращается true. + \en Returns true, if the element has been added. + If the element was not added: + - if the element is equivalent to the existing element according to the comparison function, + but not the same (the pointers of the given element and the existing element are not equal), false is returned. + - if the element is the same (the pointers of the given element and the existing element are equal), true is returned. \~ + */ + bool AddExact( Type & ); + + /** + \brief \ru Добавить элемент с сортировкой. + \en Add an element with sorting. + \details \ru Добавить элемент с сортировкой. Нельзя добавить повторно существующий объект. + \en Add an element with sorting. An existed object cannot be added repeatedly. + \return \ru Возвращает true, если элемент добавлен, или false, если не добавлен. + \en Returns true, if the element has been added, false - otherwise. + */ + bool AddIfNotExist( Type & ); + + /** + \brief \ru Доступ к функции базового класса - добавить элемент в конец массива. + \en An access to the function of the base class - add an element to the end of the array. + \details \ru Доступ к функции базового класса - добавить элемент в конец массива. + \en An access to the function of the base class - add an element to the end of the array. + */ + void AddSimple ( Type &ent ) { FDPArray::Add( &ent ); } + + /** + \brief \ru Найти индекс элемента, используя функцию сравнения. + \en Find the index of the element using the comparison function. + \details \ru Найти индекс элемента, используя функцию сравнения. + \en Find the index of the element using the comparison function. + \param[in] el - \ru элемент, который ищется. + \en An element to find. \~ + \param[out] found - \ru В 'found' будет лежать найденный элемент, или ближайший к искомому. + \en The 'found' will contain the found element or the nearest to the required element.\~ + \return \ru Вернет -1, если ближайший элемент, или индекс найденного элемента. + \en Returns -1, if this is the nearest element, or the index of the same element.\~ + */ + size_t FindNearest( const Type &el, Type *&found ) const; + + /** + \brief \ru Найти индекс элемента, используя функцию сравнения. + \en Find the index of the element using the comparison function. + \details \ru Найти индекс элемента, используя функцию сравнения. + \en Find the index of the element using the comparison function. + \return \ru Вернет точно найденный элемент или NULL, если элемент не найден. + \en Returns the found element or NULL, if element not found. + */ + Type * FindExact ( const Type &el ) const; + + /** + \brief \ru Вернет true, если элемент найден, или false в противном случае. + \en Returns true, if the element was found, or false otherwise. + \details \ru Вернет true, если элемент найден, или false в противном случае. + \en Returns true, if the element was found, or false otherwise. + */ + bool IsExist ( const Type &el ) const; + Type* RemoveObj( Type *delObject, DelType=defDelete ); + bool DetachObj( const Type *delObject ); + + /** + \brief \ru Найти индекс элемента, используя функцию поиска. + \en Find the index of the element using the search function. + \details \ru Найти индекс элемента, используя функцию поиска. + \en Find the index of the element using the search function. + \param[out] found - \ru В 'found' будет лежать найденный элемент, или ближайший к искомому. + \en The 'found' will contain the found element or the nearest to the required element. + \return \ru Вернет -1, если ближайший элемент, или индекс найденного элемента. + \en Returns -1, if this is the nearest, or the index of the same element. + */ + size_t SearchIt( size_t , SearchFunc, Type *&found ) const; + + /** + \brief \ru Сортировать массив, используя функцию сравнения. + \en Sort an array using the comparison function. + */ + void Sort( size_t /*OV_x64 int*/ minInd = SYS_MAX_T/*OV_x64 -1*/, size_t /*OV_x64 int*/ maxInd = SYS_MAX_T/*OV_x64 -1*/ ); + +private: + SFDPArray( const SFDPArray & ); // \ru запрещено !!! \en forbidden !!! + SFDPArray& operator = ( const SFDPArray & ); // \ru запрещено !!! \en forbidden !!! + + TEMPLATE_FRIEND size_t add_to_array TEMPLATE_SUFFIX ( SFDPArray& arr, Type& el, Type *&found, bool & added ); + // \ru в found будет лежать найденный, или ближайший к искомому \en in the 'found' object the found element or the nearest to the required element will be stored + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const SFDPArray&, const Type&, Type *&found ); + + // \ru Т.к. наследование от базового класса сделано private, то делаю доступ к операторам базового класса. + // \en Since there is a private inheritance from the base class, I give an access to the operators of the base class. + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, SFDPArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const SFDPArray & ref ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * SFDPArray::operator new( size_t size ) { + return ::Allocate( size, typeid(SFDPArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void SFDPArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(SFDPArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------ +// \ru конструктор массива \en constructor of an array +// --- +template +inline SFDPArray::SFDPArray( size_t i_upper, uint16 i_delta, CompareFunc fc, typename FDPArray::DestroyFunc fd ) + : FDPArray( i_upper, i_delta, fd ), + fCompare ( fc ) // \ru функция сравнения \en a comparison function +{} + + +//------------------------------------------------------------------------------ +// \ru деструктор массива \en destructor of array +// --- +template +inline SFDPArray::~SFDPArray() {} + + +//------------------------------------------------------------------------------ +// \ru сбросить себя и скопировать other \en reset itself and copy 'other' +// --- +template +bool SFDPArray::Init( const SFDPArray & other ) { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + + Flush(); // \ru сбросить себя \en reset itself + + return AddCArray( other.GetAddr(), other.count ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// --- +template +inline size_t SFDPArray::AddTry( Type& ent, Type *&found ) { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily +// \ru CatchMemory(); ЯТ \en CatchMemory(); ЯТ + + bool added = true; + return add_to_array( *this, ent, found, added ); +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// \ru вернет true - добавлен, false - не добавлен \en if returns true then the element has been added, it has not been added otherwise +// --- +template +inline bool SFDPArray::AddExact( Type& ent ) { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily +// \ru CatchMemory(); ЯТ \en CatchMemory(); ЯТ + + Type * found = NULL; + bool added = true; + add_to_array( *this, ent, found, added ); + return ( &ent == found ); // \ru вернет true - добавлен, false - не добавлен \en if returns true then the element has been added, it has not been added otherwise +} + + +//------------------------------------------------------------------------------ +// \ru добавить элемент \en add element +// \ru вернет true - добавлен, false - не добавлен \en if returns true then the element has been added, it has not been added otherwise +// --- +template +inline bool SFDPArray::AddIfNotExist( Type& ent ) { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily +// \ru CatchMemory(); ЯТ \en CatchMemory(); ЯТ + + Type * found = NULL; + bool added = true; + add_to_array( *this, ent, found, added ); + return ( added ); // \ru вернет true - добавлен, false - не добавлен \en if returns true then the element has been added, it has not been added otherwise +} + + +//------------------------------------------------------------------------------ +// \ru вернуть индекс элемента в массиве \en return an index of the element in the array +// --- +template +inline size_t SFDPArray::FindNearest( const Type &el, Type *&found ) const { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + return find_in_array( *this, el, found ); +} + + +//------------------------------------------------------------------------------ +// \ru найти индекс элемента, используя функцию сравнения \en find the index of the element using the comparison function +// \ru вернет точно найденный \en returns the found one +// --- +template +inline Type * SFDPArray::FindExact( const Type &el ) const { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + Type * found = NULL; + size_t foundInd = find_in_array( *this, el, found ); + return ( foundInd != SYS_MAX_T ) ? found : NULL; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type* SFDPArray::RemoveObj( Type *delObject, DelType del ) { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + if ( !delObject ) + return NULL; + + Type * found = NULL; + size_t i = find_in_array( *this, *delObject, found ); + return ( i != SYS_MAX_T ) ? RemoveInd(i, del) : 0; +} + + +//------------------------------------------------------------------------------ +// \ru отсоединить элемент от массива (по указателю) \en detach an element from the array (by the pointer) +// --- +template +inline bool SFDPArray::DetachObj( const Type *delObject ) { + if ( !delObject ) + return false; + Type * found = NULL; + size_t i = find_in_array( *this, *delObject, found ); + + if ( i != SYS_MAX_T ) { + DetachInd( i ); + return true; + } + + return false; +} + + +//------------------------------------------------------------------------------ +// \ru вернуть индекс элемента в массиве \en return an index of the element in the array +// --- +template +inline bool SFDPArray::IsExist( const Type &el ) const { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + Type * found = NULL; + return find_in_array( *this, el, found ) != SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru повторно добавить нельзя!!! \en it cannot be added repeatedly!!! +// \ru снаружи отвести памяти \en allocate memory from the outside +// --- +template +size_t add_to_array ( SFDPArray& arr, Type& el, Type *&found, bool & added ) { + PRECONDITION( arr.fCompare ); // \ru без функции сравнения массив бессмысленен \en the array is useless without comparison function + + added = true; + if ( !arr.count ) { + found = ⪙ +//arr.parr[arr.count++] = ⪙ // \ru count вырос на 1 \en 'count' increased by 1 + arr.Insert( 0, &el ); + return 0; + } + + found = arr/*.parr*/[0]; + int res = (*arr.fCompare)( *found, el ); + if ( res > 0 ) { // \ru нулевой БОЛЬШЕ пришедшего - вставим ПЕРЕД нулевым \en the first element is GREATER than the sent one - set it BEFORE the first element + found = ⪙ + arr.Insert( 0, &el ); + return 0; + } + else if ( res == 0 ) { + added = false; + return 0; // \ru повторно добавить нельзя!!! \en it cannot be added repeatedly!!! + } + + if ( arr.count == 1 ) { // \ru есть всего один \en only one exists + if ( res < 0 ) { // \ru нулевой МЕНЬШЕ пришедшего - вставим ПОСЛЕ нулевого \en the first element is LESS than the sent one - set it AFTER the first element + found = ⪙ + arr.Insert( 1, &el ); + return 1; + } + } + + // \ru к этому моменту пришедший БОЛЬШЕ нулевого \en by this time the sent element is GREATER than the first element + size_t mx = arr.count - 1; + + found = arr/*.parr*/[mx]; + res = (*arr.fCompare)( *found, el ); + if ( res < 0 ) { // \ru последний МЕНЬШЕ пришедшего - вставим ПОСЛЕ последнего \en the last element is LESS than the sent one - set it AFTER the last element + found = ⪙ + arr.Insert( mx+1, &el ); + return mx+1; + } + else if ( res == 0 ) { + added = false; + return mx; // \ru повторно добавить нельзя!!! \en it cannot be added repeatedly!!! + } + + if ( arr.count == 2 ) { // \ru значит между 0 и 1 \en between 0 and 1 + if ( res > 0 ) { // \ru последний БОЛЬШЕ пришедшего - вставим ПЕРЕД последним \en the last element is GREATER than the sent one - set it BEFORE the last element + found = ⪙ + arr.Insert( 1, &el ); + return 1; + } + } + + // \ru к этому моменту пришедший БОЛЬШЕ нулевого, но МЕНЬШЕ последнего \en by the moment the sent element is GREATER than the first element and LESS than the last element + // \ru вставим где-то между \en put it somewhere between + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + + found = arr/*.parr*/[md]; + res = (*arr.fCompare)( *found, el ); + if ( res > 0 ) { // \ru md БОЛЬШЕ пришедшего, но mn МЕНЬШЕ пришедшего - поиск слева \en 'md' is GREATER than the sent one and 'mn' is LESS than the sent one - search on the left + mx = md; + } + else if ( res < 0 ) { // \ru md МЕНЬШЕ пришедшего - поиск справа \en 'md' is LESS than the sent one - search on the right + mn = md; + } + else { + added = false; + return md; // \ru повторно добавить нельзя!!! \en it can not be added repeatedly!!! + } + + } // end while + + found = ⪙ + arr.Insert( mx, &el ); + return mx; +} + +//------------------------------------------------------------------------------ +// \ru бинарный поиск \en binary search +// --- +template +size_t find_in_array( const SFDPArray& arr, const Type& el, Type *&found ) { + PRECONDITION( arr.fCompare ); // \ru без функции сравнения массив бессмысленен \en the array is useless without comparison function + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + int res = 0; + if ( arr.count > 11 ) { + size_t mx = arr.count - 1; + + size_t mxc = mx; + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + found = arr[md]; + res = (*arr.fCompare)( *found, el ); + switch ( res ) { + case 1 : mx = md; break; + case -1 : mn = md; break; + case 0 : return md; + default : PRECONDITION( false ); + } + } + + // \ru проверка по границам \en check by bounds + found = arr[0]; + res = (*arr.fCompare)( *found, el ); + switch ( res ) { + case 0 : return 0; + case 1 : return SYS_MAX_T; + case -1 : break; + } + + found = arr[mxc]; + res = (*arr.fCompare)( *found, el ); + switch ( res ) { + case 0 : return mxc; + default : return SYS_MAX_T; + } + } + else { + // \ru специальные случаи count == >0 & < 11 \en special cases count == >0 & < 11 + for ( size_t i = 0, count = arr.count; i < count; i++ ) { + found = arr[i]; + switch ( (*arr.fCompare)( *found, el ) ) { + case 0 : return i; + case 1 : return SYS_MAX_T; + case -1 : break; + } + } + } + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru бинарный поиск \en binary search +// \ru найти индекс элемента, используя функцию поиска \en find the index of the element using the search function +// \ru вернуть индекс элемента в массиве \en return an index of the element in the array +// \ru в found будет лежать найденный, или ближайший к искомому \en in the 'found' object the found element or the nearest to the required element will be stored +// --- +template +size_t SFDPArray::SearchIt ( size_t data, typename SFDPArray::SearchFunc fSearch, Type *&found ) const { + PRECONDITION( FDPArray::nowDeletedElem == 0 ); // \ru ЯТ - временно \en ЯТ - temporarily + PRECONDITION( fSearch ); // \ru без функции сравнения массив бессмысленен \en the array is useless without comparison function + + if ( !FDPArray::count ) + return SYS_MAX_T; + + found = (*this)/*parr*/[0]; // \ru или найденный, или ближайший к искомому \en either found or the nearest to the required one + int res = (*fSearch)( *found, data ); + if ( res == 0 ) + return 0; + + if ( FDPArray::count == 1 ) + return SYS_MAX_T; + + if ( res > 0 ) // \ru пришедший МЕНЬШЕ нулевого \en the sent element is LESS than the first element + return SYS_MAX_T; + + // \ru к этому моменту пришедший БОЛЬШЕ нулевого \en by this time the sent element is GREATER than the first element + size_t mx = FDPArray::count - 1; + + found = (*this)/*parr*/[mx]; // \ru или найденный, или ближайший к искомому \en either found or the nearest to the required one + res = (*fSearch)( *found, data ); + if ( res < 0 ) { // \ru последний МЕНЬШЕ пришедшего \en the last element is LESS than the sent element + return SYS_MAX_T; + } + else if ( res == 0 ) { + return mx; // \ru повторно добавить нельзя!!! \en it can not be added repeatedly!!! + } + + if ( FDPArray::count == 2 ) { // \ru значит между 0 и 1 \en between 0 and 1 + return SYS_MAX_T; + } + + // \ru к этому моменту пришедший БОЛЬШЕ нулевого, но МЕНЬШЕ последнего \en by the moment the sent element is GREATER than the first element and LESS than the last element + // \ru вставим где-то между \en put it somewhere between + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + + found = (*this)/*parr*/[md]; // \ru или найденный, или ближайший к искомому \en either found or the nearest to the required one + res = (*fSearch)( *found, data ); + if ( res > 0 ) { // \ru md БОЛЬШЕ пришедшего, но mn МЕНЬШЕ пришедшего - поиск слева \en 'md' is GREATER than the sent one and 'mn' is LESS than the sent one - search on the left + mx = md; + } + else if ( res < 0 ) { // \ru md МЕНЬШЕ пришедшего - поиск справа \en 'md' is LESS than the sent one - search on the right + mn = md; + } + else { + return md; // \ru повторно добавить нельзя!!! \en it can not be added repeatedly!!! + } + + } // end while + + return SYS_MAX_T; +} + + +//----------------------------------------------------------------------------- +// \ru Сортировка массива \en Array sorting +// \ru Н.Вирт "Алгоритмы и структуры данных" 2е издание, Санкт-Петербург, 2001г., стр.111 \en see N.Wirth "Algorithms and Data Structures" +// --- +template +inline void SFDPArray::Sort( size_t /*OV_x64 int*/ minInd /*= -1*/, size_t /*OV_x64 int*/ maxInd /*= -1*/ ) +{ + // K10 SP2 33872 + if ( Count() == 0 ) + return; + + if ( minInd == SYS_MAX_T ) + minInd = 0; + if ( maxInd == SYS_MAX_T ) + maxInd = MaxIndex(); // \ru OV_x64 проверено - count > 0 \en OV_x64 validated - count > 0 + + size_t i = minInd, j = maxInd; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + size_t im = (i + j)/2; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and < + + Type * middle = (*this)[im]; + + do { + while( (*fCompare)(*((*this)[i]), *middle ) == -1 ) i++; + while( (*fCompare)( *middle, *(*this)[j]) == -1 ) j--; + if ( (ptrdiff_t)i <= (ptrdiff_t)j ) { + if ( i != j ) { + Type * wi = (*this)[i]; + (*this)[i] = (*this)[j]; + (*this)[j] = wi; + } + i++; + j--; + } + } while( !((ptrdiff_t)i > (ptrdiff_t)j) ); + + + if ( (ptrdiff_t)minInd < (ptrdiff_t)j ) + Sort( minInd, j ); + if ( (ptrdiff_t)i < (ptrdiff_t)maxInd ) + Sort( i, maxInd ); +} + + +#endif // __TEMPL_SFDP_ARRAY_H diff --git a/C3d/Include/templ_sfp_array.h b/C3d/Include/templ_sfp_array.h new file mode 100644 index 0000000..160ad1f --- /dev/null +++ b/C3d/Include/templ_sfp_array.h @@ -0,0 +1,522 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный массив указателей. + \en Ordered array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_SFP_ARRAY_H +#define __TEMPL_SFP_ARRAY_H + + +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru упорядоченный массив указателей \en ordered array of pointers +// \ru одинаковые объекты не добавляются \en the similar objects are not added +// +//////////////////////////////////////////////////////////////////////////////// +FORVARD_DECL_TEMPLATE_TYPENAME( class SFPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * add_to_array ( SFPArray &, Type * ent, size_t & indexEnt ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_from_array ( SFPArray &, const Type * ent ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * find_from_array_by_key( SFPArray &, void * key, size_t & index ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( void qp_sort ( SFPArray &, bool always ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, SFPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const SFPArray & ref ) ); + + +template +class SFPArray : private PArray { +public: +typedef int (*CompareFunc)( const Type * left, const Type * right ); // \ru функция сравнения для поиска и наполнения \en a comparison function for search and filling +typedef int (*SearchFunc) ( const Type * d1, void * key ); // \ru функция сравнения для поиска \en a comparison function for search +typedef void (*AssignFunc) ( Type *& oldObj, const Type * newObj ); // \ru функция присвоения \en an assignment function + + CompareFunc fCompare_m; // \ru функция сравнения \en a comparison function + SearchFunc fSearch_m; // \ru функция поиска \en a search function + +protected: + // \ru признак сортированности массива \en attribute of an array being sorted + bool m_sort; + // \ru при сортировке выкидывать одинаковые \en throw out the same elements while sorting + bool m_keepEq; + + +public : + SFPArray( size_t maxCnt + , uint16 delt + , CompareFunc fc + , SearchFunc fs + , bool shouldDelete + , bool keepEq + ) + : PArray( maxCnt, delt, shouldDelete ) + , fCompare_m ( fc ) // \ru функция сравнения \en a comparison function + , fSearch_m ( fs ) // \ru функция поиска \en a search function + , m_sort ( true ) + , m_keepEq ( keepEq ) + {} + + using PArray::OwnsElem; + using PArray::Delta; + using PArray::Flush; + using PArray::HardFlush; + using PArray::Adjust; + using PArray::RemoveInd; + using PArray::Count; + using PArray::MaxIndex; + using PArray::operator[]; + using PArray::Reserve; + using PArray::SetSize; + using PArray::GetLast; + + Type * Add( Type * ); // \ru добавить элемент с упорядочиванием по массиву \en add element with sorting + Type * Add( Type *, size_t & indexEnt );// \ru добавить элемент с упорядочиванием по массиву, возвращает индекс \en add element with sorting, returns index of the element. + void AddSimple( Type * ent ) { m_sort = false; PArray::Add( ent ); } // \ru Доступ к функции базового класса - добавить элемент в конец массива \en An access to the function of the base class - add an element to the end of the array + // \ru найти элемент в упорядоченном массиве \en find an element in ordered array + size_t /*OV_x64 int*/ Find( const Type * ); + // \ru найти элемент по ключевым полям \en find an element by the key fields + Type * FindByKey( void * key, size_t & index ); + // \ru удалить элемент из массива \en delete an element from array + Type * RemoveObj( Type * delObject, DelType=defDelete ); + // \ru true если элемент найден \en true if the element was found + bool IsExist( const Type * ); + // \ru сортировать массив, если не сортирован \en sort array if it is not sorted + void Sort(); + // \ru проверить на соответствие сортировке элемент массива \en check that an element of the array corresponds to the sorting + // \ru если меняли значение полей Type - условие сортировки может быть не выполнено \en if the values of fields Type have been changed then the comparison condition may be not performed + // \ru если это так - флаг сортировки у массива снимается \en if it is so then the flag of sorting is switched off + void SortCheckByIndex( size_t /*OV_x64 int*/ index ); + + TEMPLATE_FRIEND Type * add_to_array TEMPLATE_SUFFIX ( SFPArray &, Type * ent, size_t & indexEnt ); + TEMPLATE_FRIEND size_t find_from_array TEMPLATE_SUFFIX ( SFPArray &, const Type * ent ); + TEMPLATE_FRIEND Type * find_from_array_by_key TEMPLATE_SUFFIX ( SFPArray &, void * key, size_t & index ); + TEMPLATE_FRIEND void qp_sort TEMPLATE_SUFFIX ( SFPArray &, bool always ); + +private: + OBVIOUS_PRIVATE_COPY( SFPArray ) + + // \ru Т.к. наследование private, то сделаем здесь операторы чтения-записи \en Since there is a private inheritance, then make here operators of reading/writing +//ID K8 KNOWN_OBJECTS_RW_REF_OPERATORS( SFPArray ) + // \ru OV_x64 но коду не нашел реализации операторров чтения/записи \en OV_x64 implementation of reading/witing operators was not found + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, SFPArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const SFPArray & ref ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * SFPArray::operator new( size_t size ) { + return ::Allocate( size, typeid(SFPArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void SFPArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(SFPArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------- +// \ru добавить элемент с упорядочиванием по массиву \en add element with sorting +// --- +template +inline Type* SFPArray::Add( Type* el ) { + size_t index; + ::qp_sort( *this, false ); + return add_to_array( *this, el, index ); +} + + +//------------------------------------------------------------------------------- +// \ru добавить элемент с упорядочиванием по массиву, возвращает индекс \en add element with sorting, returns index of the element +// --- +template +inline Type* SFPArray::Add( Type* el, size_t & indexEl ) { + ::qp_sort( *this, false ); + return add_to_array( *this, el, indexEl ); +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// --- +template +inline size_t SFPArray::Find( const Type * el ) { + ::qp_sort( *this, false ); + return find_from_array( *this, el ); +} + + +//------------------------------------------------------------------------------- +// \ru найти элемент по ключевым полям \en find an element by the key fields +// --- +template +inline Type * SFPArray::FindByKey( void * key, size_t & index ) { + ::qp_sort( *this, false ); + return find_from_array_by_key( *this, key, index ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline Type * SFPArray::RemoveObj( Type *delObject, DelType del ) { + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru Bременно, для отладки \en Temporarily, for debugging + ::qp_sort( *this, false ); + size_t i = find_in_array( *this, delObject ); + return ( i != SYS_MAX_T ) ? RemoveInd(i, del) : 0; +} + + +//------------------------------------------------------------------------------ +// \ru true если элемент найден \en true if the element was found +// --- +template +inline bool SFPArray::IsExist( const Type * el ) { + ::qp_sort( *this, false ); + return find_in_array( *this, el ) != SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// \ru сортировать массив, если не сортирован \en sort array if it is not sorted +// --- +template +inline void SFPArray::Sort() { + ::qp_sort( *this, true ); +} + + +//------------------------------------------------------------------------------ +// \ru проверить на соответствие сортировке элемент массива \en check that an element of the array corresponds to the sorting +// \ru если меняли значение полей Type - условие сортировки может быть не выполнено \en if the values of fields Type have been changed then the comparison condition may be not performed +// \ru если это так - флаг сортировки у массива снимается \en if it is so then the flag of sorting is switched off +// --- +template +inline void SFPArray::SortCheckByIndex( size_t /*OV_x64 int*/ index ) { + if ( Count() ) + { + size_t /*OV_x64 int*/ maxIndex = Count() - 1; // \ru проверено count > 0 \en chacked that count > 0 + //if ( 0 <= index && index <= maxIndex ) OV - Expression '0 <= index' is always true. Unsigned type value is always >= 0. + if ( index <= maxIndex ) + { + Type * el = (*this)[index]; + // \ru проверяем середину интервала \en check the middle of the interval + if ( 0 < index && index < maxIndex ) { + if ( (*fCompare_m)( (*this)[index-1], el ) >= 0 + || + (*fCompare_m)( el, (*this)[index+1] ) >= 0 + ) + m_sort = false; + } + else + // \ru левая граница \en the left boundary + if ( index == 0 ) { + if ( (*fCompare_m)( el, (*this)[1] ) >= 0 ) + m_sort = false; + + } + else //index == maxIndex + // \ru правая граница \en the right boundary + if ( (*fCompare_m)( (*this)[index-1], el ) >= 0 ) + m_sort = false; + } + } +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив с упорядочиванием \en adding an object to the array with ordering +// --- +template +Type * add_to_array( SFPArray & arr, Type * el, size_t & indexEl ) { + size_t mr = arr.count - 1; + size_t mxc = mr; // \ru правое \en right + size_t ml = 0; // \ru левое \en left + int resCmp = 0; + size_t mc = 0; + + // \ru специальные случаи \en special cases + // \ru массив пустой - просто добавляем \en the array is empty - simply add + // \ru проверку на пустоту массива нельзя переносить за проверку границ - \en a check for array emptyness should not be moved outside a boundary check - + // \ru можно вылететь (из-за mxc = -1) \en the error may occur (because of mxc = -1) + if ( !arr.count ) { + arr.PArray::Add( el ); + indexEl = 0; + return arr[0]; //arr.parr; + } + + // \ru SA K6 элемент за границами массива - добавляем \en SA K6 an element is out of bounds - add it + resCmp = (*arr.fCompare_m)( el, arr[0] ); + if ( resCmp < 0 ) { + arr.Insert( 0, el ); + indexEl = 0; + return arr[0]; //arr.parr; + } + else + if ( 0 == resCmp ) { + indexEl = 0; + return 0; + } + + // \ru есть всего один \en only one exists + if ( arr.count == 1 ) { + arr.PArray::Add( el ); + indexEl = 0; + return arr[1]; + } + + // \ru проверка правой границы \en a check of the right bound + resCmp = (*arr.fCompare_m)( arr[mxc], el ); + if ( resCmp < 0 ) { + arr.PArray::Add( el ); + indexEl = mxc + 1; + return arr[indexEl]; //arr.parr + indexEl; + } + else + if ( 0 == resCmp ) { + indexEl = mxc; + return 0; + } + + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + if ( arr.count > 2 ) { + // \ru результаты сравнения элементов с левой и правой границей \en the results of comparison between the elements and bounds + // \ru сделаны для минимизации вызовов функций сравнений - они могут \en it is done in order to minimize the number of comparison functions calls - they may + // \ru быть дорогими по времени выполнения \en be too time-consuming + // \ru пока не нашли - ищем \en seek until do not find + while ( ml + 1 < mr ) { + // \ru ищем СРЕДНИЙ индекс \en seek for the MIDDLE index + mc = ( ml + mr ) / 2; + // \ru сравниваем СРЕДНЕЕ с присланным \en compare the MIDDLE element and the sent element + resCmp = (*arr.fCompare_m)( arr[mc], el ); + if ( resCmp > 0 ) { // \ru mc БОЛЬШЕ пришедшего, но mn МЕНЬШЕ пришедшего - поиск слева \en 'mc' is GREATER than the sent one and 'mn' is LESS than the sent one - search on the left + mr = mc; + } + else if ( resCmp < 0 ) { // \ru mc МЕНЬШЕ пришедшего - поиск справа \en 'mc' is LESS than the sent one - search on the right + ml = mc; + } + else { + // \ru такой элемент уже есть - добавления не происходит \en such element already exists - nothing to add + indexEl = mc; + return 0; + } + + } // end while + + arr.Insert( mr, el ); + indexEl = mr; + return arr[mr];//arr.parr + mr; + } + + // \ru SA K6 элемент не за границами массива и массив содержит 2 элемента \en SA K6 an element is not outside the array's bounds and the array consists of 2 elements + if ( arr.count == 2 ) { + arr.Insert( 1, el ); + indexEl = 1; + return arr[1]; // arr.parr + 1; + } + + indexEl = 0; + return 0; +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// --- +template +size_t find_from_array( SFPArray &arr, const Type* el ) +{ + C3D_ASSERT( arr.fCompare_m ); // \ru без функции сравнения массив бессмысленнен \en the array is useless without comparison function + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + int res = 0; + + if ( arr.count > 11 ) + { + size_t mr = arr.count - 1; // \ru проверено count >= 1 \en count >= 1 validated + size_t mxc = mr; + size_t ml = 0; + + while ( ml + 1 < mr ) { // \ru пока не нашли - ищем \en seek until do not find + size_t mc = ( ml + mr ) / 2; + res = (*arr.fCompare_m)( arr[mc], el ); + switch ( res ) { + case 1 : mr = mc; break; + case -1 : ml = mc; break; + case 0 : return mc; + } + } + + // \ru проверка по границам \en check by bounds + res = (*arr.fCompare_m)( arr[0], el ); + switch ( res ) { + case 0 : return 0; + case 1 : return SYS_MAX_T; + case -1 : break; + } + + res = (*arr.fCompare_m)( arr[mxc], el ); + switch ( res ) { + case 0 : return mxc; + default : return SYS_MAX_T; + } + } + else { + // \ru специальные случаи count == >0 & < 11 \en special cases count == >0 & < 11 + for( size_t i = 0, count = (size_t)arr.count; i < count; i++ ) { + switch ( (*arr.fCompare_m)( arr[i], el ) ) { + case 0 : return i; + case 1 : return SYS_MAX_T; + case -1 : break; + } + } + } + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// +// --- +template +Type * find_from_array_by_key( SFPArray & arr, void * key, size_t & index ) { + PRECONDITION( arr.fSearch_m && key ); // \ru без функции сравнения массив бессмысленнен \en the array is useless without comparison function + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + int res = 0; + if ( arr.count > 11 ) { + size_t mr = arr.count - 1; // \ru проверено count >= 1 \en count >= 1 validated + + size_t mxc = mr; + size_t ml = 0; + + while ( ml + 1 < mr ) { // \ru пока не нашли - ищем \en seek until do not find + size_t mc = ( ml + mr ) / 2; + res = (*arr.fSearch_m)( arr[mc], key ); + switch ( res ) { + case 1 : mr = mc; break; + case -1 : ml = mc; break; + case 0 : index = mc; return arr[mc]; + } + } + + // \ru проверка по границам \en check by bounds + res = (*arr.fSearch_m)( arr[0], key ); + switch ( res ) { + case 0 : index = 0; return arr[0]; + case 1 : index = SYS_MAX_T; return NULL; + case -1 : break; + } + + res = (*arr.fSearch_m)( arr[mxc], key ); + switch ( res ) { + case 0 : index = mxc; return arr[mxc]; + default : index = SYS_MAX_T; return NULL; + } + } + else { + // \ru специальные случаи count == >0 & < 11 \en special cases count == >0 & < 11 + for( size_t i = 0, count = (size_t)arr.count; i < count; i++ ) { + switch ( (*arr.fSearch_m)( arr[i], key ) ) { + case 0 : index = i; return arr[i]; + case 1 : index = SYS_MAX_T; return NULL; + case -1 : break; + } + } + } + + index = SYS_MAX_T; + return NULL; +} + + +//----------------------------------------------------------------------------- +// \ru Н.Вирт "Алгоритмы и структуры данных" 2е издание, Санкт-Петербург, 2001г., стр.111 \en see N.Wirth "Algorithms and Data Structures" +// --- +template +void qp_sort_r( SFPArray & arr, ptrdiff_t minInd, ptrdiff_t maxInd ) { +//OV_x64 ===================== + if ( arr.Count() > 1 ) + { + if ( minInd == -1 ) minInd = 0; + if ( maxInd == -1 || maxInd > arr.MaxIndex() ) maxInd = arr.MaxIndex(); // \ru проверено count > 0 \en chacked that count > 0 +//OV_x64 ===================== + + ptrdiff_t i = minInd, j = maxInd; + ptrdiff_t im = (i + j)/2; + + Type * middle = arr[im]; + + do { + while( (*arr.fCompare_m)( arr[i], middle ) < 0 ) i++; + while( (*arr.fCompare_m)( middle, arr[j] ) < 0 ) j--; + if ( i <= j ) { + if ( i != j ) { + Type * wi = arr[i]; + arr[i] = arr[j]; + arr[j] = wi; + } + i++; + j--; + } + } while( !(i > j) ); + + + if ( minInd < j ) + qp_sort_r( arr, minInd, j ); + if ( i < maxInd ) + qp_sort_r( arr, i, maxInd ); + } +} + + +//------------------------------------------------------------------------------- +// +// --- +template +void qp_sort( SFPArray & arr, bool always ) { + if ( !arr.m_sort || always ) { +//OV_x64 ===================== + if ( arr.Count() > 1 ) + { +//OV_x64 ===================== + size_t maxIndex = arr.MaxIndex(); // \ru проверено count > 1 \en chacked that count > 1 + qp_sort_r( arr, 0, maxIndex ); + // \ru удаление одинаковых \en deletion of similar objects + if ( !arr.m_keepEq ) + for ( size_t /*OV_x64 int*/ i = maxIndex; i >= 1; i-- ) { // maxIndex > 0 + int resCmp = (*arr.fCompare_m)( arr[i], arr[i-1] ); + switch ( resCmp ) { + case 1 : break; + case 0 : arr.RemoveInd( i ); break; + case -1 : PRECONDITION( false ); break; + } + } + } + + arr.m_sort = true; + } +} + + +#endif // __TEMPL_SFP_ARRAY_H diff --git a/C3d/Include/templ_sp_array.h b/C3d/Include/templ_sp_array.h new file mode 100644 index 0000000..f12a6a2 --- /dev/null +++ b/C3d/Include/templ_sp_array.h @@ -0,0 +1,420 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный массив указателей. + \en Ordered array of pointers. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_SP_ARRAY_H +#define __TEMPL_SP_ARRAY_H + + +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru упорядоченный массив указателей \en ordered array of pointers +// \ru у объектов массива должны быть операторы "==" и "<" \en objects of the array should have operators "==" and "<" +// \ru одинаковые объекты не добавляются \en the similar objects are not added +// +//////////////////////////////////////////////////////////////////////////////// + +FORVARD_DECL_TEMPLATE_TYPENAME( class SPArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * add_to_array( SPArray&, Type* ent, size_t & indexEnt ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_from_array( SPArray&, const Type* ent ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_from_array_spec( SPArray&, const Type* ent, bool& isPresent ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, SPArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const SPArray & ref ) ); + +template +class SPArray : protected PArray { +public : + SPArray( size_t maxCnt = 0, uint16 delt = 1, bool shouldDelete = true ) + : PArray( maxCnt, delt, shouldDelete ) {} + + using PArray::OwnsElem; + using PArray::Delta; + using PArray::Upper; + using PArray::Flush; + using PArray::HardFlush; + using PArray::Adjust; + using PArray::RemoveInd; + using PArray::Count; + using PArray::MaxIndex; + using PArray::operator[]; + using PArray::Reserve; + using PArray::SetSize; + using PArray::GetLast; + using PArray::FindIt; + + Type * Add( Type * ); // \ru добавить элемент с упорядочиванием по массиву \en add element with sorting + Type * Add( Type *, size_t & indexEnt );// \ru добавить элемент с упорядочиванием по массиву, возвращает индекс \en add element with sorting, returns index of the element + + // \ru После "простого" добавления нет возможности восстановить сортированность массива \en After a "simple" adding there is no possibility to recover the sorting of the array + void AddSimple ( Type * ent ) { PArray::Add( ent ); } // \ru Доступ к функции базового класса - добавить элемент в конец массива \en An access to the function of the base class - add an element to the end of the array + // \ru Доступ к функции базового класса - добавить массив в конец массива \en An access to the function of the base class - add an array to the end of the array + bool AddArraySimple( const RPArray & arr ) { return PArray::AddArray( arr ); } + Type * RemoveObj( Type *delObject, DelType = defDelete ); // \ru удалить элемент из массива \en delete an element from array + // \ru Доступ к функции базового класса - удалить элемент из массива \en An access to the function of the base class - delete an element from the array + Type * RemoveObjSimple( Type *delObject, DelType delType = defDelete ) { return PArray::RemoveObj( delObject, delType ); } ; // \ru удалить элемент из массива \en delete an element from array + size_t /*OV_x64 int*/ Find( const Type * ); // \ru найти элемент в упорядоченном массиве \en find an element in ordered array + size_t /*OV_x64 int*/ PossibleIndex( const Type *, bool& isPresent ); // \ru найти место в массиве, куда будет добавлен элемент ( без добавления ) \en find a place in the array for adding ann element (adding is not performed) + // \ru на выходе : isPresent == true - элемент уже в массиве \en in output : isPresent == true - the element is already in the array + bool IsExist( const Type * ); // \ru true если элемент найден \en true if the element was found + + TEMPLATE_FRIEND Type * add_to_array TEMPLATE_SUFFIX ( SPArray&, Type* ent, size_t & indexEnt ); + TEMPLATE_FRIEND size_t /*OV_x64 int*/ find_from_array TEMPLATE_SUFFIX ( SPArray&, const Type* ent ); + TEMPLATE_FRIEND size_t /*OV_x64 int*/ find_from_array_spec TEMPLATE_SUFFIX ( SPArray&, const Type* ent, bool& isPresent ); + +private: + SPArray( const SPArray & ); // \ru запрещено !!! \en forbidden !!! + void operator = ( const SPArray & ); // \ru запрещено !!! \en forbidden !!! + + // \ru Т.к. наследование private, то сделаем здесь операторы чтения-записи \en Since there is a private inheritance, then make here operators of reading/writing +//ID K8 KNOWN_OBJECTS_RW_REF_OPERATORS( SPArray ) + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, SPArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const SPArray & ref ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * SPArray::operator new( size_t size ) { + return ::Allocate( size, typeid(SPArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void SPArray::operator delete( void * ptr, size_t size ) { + ::Free( ptr, size, typeid(SPArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------- +// \ru добавить элемент с упорядочиванием по массиву \en add element with sorting +// --- +template +inline Type* SPArray::Add( Type* el ) { + size_t index; + return add_to_array( *this, el, index ); +} + + +//------------------------------------------------------------------------------- +// \ru добавить элемент с упорядочиванием по массиву, возвращает индекс \en add element with sorting, returns index of the element +// --- +template +inline Type* SPArray::Add( Type* el, size_t & indexEl ) +{ + return add_to_array( *this, el, indexEl ); +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// --- +template +inline size_t /*OV_x64 int*/ SPArray::Find( const Type * el ) +{ + return find_from_array( *this, el ); +} + + +//------------------------------------------------------------------------------ +// \ru Есть ли в массиве такой указатель \en Whether such pointer exists in the array +// --- +template +inline bool SPArray::IsExist( const Type *el ) { + return find_from_array( *this, el ) != SYS_MAX_T; +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива (по указателю) \en delete an element from array (by the pointer) +// --- +template +inline Type * SPArray::RemoveObj( Type * delObject, DelType del ) +{ + PRECONDITION( PArray::nowDeletedElem == 0 ); // \ru Bременно, для отладки \en Temporarily, for debugging + size_t i = find_from_array( *this, delObject ); + return ( i != SYS_MAX_T ) ? RemoveInd( i, del ) : 0; +} + + +//------------------------------------------------------------------------------- +// \ru найти место в массиве, куда будет добавлен элемент ( без добавления ) \en find a place in the array for adding ann element (adding is not performed) +// \ru на выходе : isPresent == true - элемент уже в массиве \en in output : isPresent == true - the element is already in the array +// --- +template +inline size_t SPArray::PossibleIndex( const Type* el, bool& isPresent ) { + return find_from_array_spec( *this, el, isPresent ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив с упорядочиванием \en adding an object to the array with ordering +// --- +template +Type * add_to_array( SPArray & arr, Type * el, size_t & indexEl ) +{ + if ( el == NULL ) // \ru LF_Linux: добавил проверку на NULL \en LF_Linux: added a check for NULL + return NULL; + size_t mx = arr.count - 1; + size_t mxc = mx; + size_t mn = 0; + + // \ru общий случай - элементов больше двух \en the common case - the number of elements is more than two + if ( arr.count > 2 ) { + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + if ( *arr[md] < *el ) { + if ( *el == *arr[mx] ) { + indexEl = mx; + return 0; + } + mn = md; + } + // \ru по логике правильнее было бы проверять сначала меньше, потом тождественно, а затем, уже \en it would be better to check at first whether it is less, then whether it is equal and only after this + // \ru без сравнения - делать вывод что больше. \en conclude which is greater without comparison. + // \ru НО! оператор сравнения, как правило более быстрый, чем оператор тождественности, \en BUT! the comparison operator is generally faster than identity operator, + // \ru и заведомо более часто используется( тождественно - финишная опреация в поиске ) \en and it is used more often (identity check is the last operation in search) + // \ru и если поставить проверку тождественности впереди "больше" - можно получить торможение \en and if the identity check will be placed before the "greater" check then there may occur an inhibition + // \ru на тяжелых операторах \en on heavy operators + // \ru Кроме того, все три проверки делаются, дабы не отказывать программистам в их праве делать \en - + // \ru ошибки при написании операторов сравнения и тождественности и потом их с комфортом исправлять. \en - + else if ( *el < *arr[md] ) { + if ( *el == *arr[mn] ) { + indexEl = mn; + return 0; + } + mx = md; + } + else if ( *arr[md] == (Type&)*el ) { + indexEl = md; + return 0; + } + // \ru если попадаем сюда - значит некорректно написаны операторы "тождественно" и сравнения \en if we are here then operators of identity check and comparison are not correct + else { + PRECONDITION( 0 ); + indexEl = SYS_MAX_T; + return 0; + } + } + + if ( *el < *arr[0] ) { + arr.Insert( 0, el ); + indexEl = 0; + return arr[0]; //arr.parr; + } + if ( *arr[mxc] < *el ) { + arr.PArray::Add( el ); + indexEl = mxc + 1; + return arr[indexEl]; //arr.parr + indexEl; + } + + arr.Insert( mx, el ); + indexEl = mx; + return arr[mx];//arr.parr + mx; + } + + // \ru специальные случаи \en special cases + // \ru массив пустой - просто добавляем \en the array is empty - simply add + // \ru проверку на пустоту массива нельзя переносить за проверку границ - \en a check for array emptyness should not be moved outside a boundary check - + // \ru можно вылететь (из-за mxc = -1) \en the error may occur (because of mxc = -1) + if ( !arr.count ) { + arr.PArray::Add( el ); + indexEl = 0; + return arr[0]; //arr.parr; + } + + // \ru SA K6 элемент за границами массива - добавляем \en SA K6 an element is out of bounds - add it + if ( *el < *arr[0] ) { + arr.Insert( 0, el ); + indexEl = 0; + return arr[0]; //arr.parr; + } + if ( *arr[mxc] < *el ) { + arr.PArray::Add( el ); + indexEl = mxc + 1; + return arr[indexEl]; //arr.parr + indexEl; + } + + // \ru SA K6 элемент не за границами массива и массив содержит 2 элемента \en SA K6 an element is not outside the array's bounds and the array consists of 2 elements + if ( arr.count == 2 ) { + if ( *el == *arr[0]/*arr.parr*/ ) { + indexEl = 0; + return 0; + } + else + if ( *el == *arr[1]/*arr.parr[1]*/ ) { + indexEl = 1; + return 0; + } + else { + arr.Insert( 1, el ); + indexEl = 1; + return arr[1]; // arr.parr + 1; + } + } + + indexEl = 0; + return 0; +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// --- +template +size_t find_from_array_spec( SPArray & arr, const Type * el, bool & isPresent ) +{ + isPresent = false; + + if ( el == NULL ) // \ru LF_Linux: добавил проверку на NULL \en LF_Linux: added a check for NULL + return SYS_MAX_T; + + if ( !arr.count || *el < *arr/*.parr*/[0] ) + return 0; + + size_t mx = arr.count - 1; + + if ( *arr/*.parr*/[mx] < *el ) + return mx + 1; + + if ( arr.count == 1 ) { // \ru значит *el == *parr[0] \en it means *el == *parr[0] + isPresent = true; + return 0; + } + + if ( arr.count == 2 ) { // \ru значит между 0 и 1 \en between 0 and 1 + if (*el == *arr/*.parr*/[0]) { + isPresent = true; + return 0; + } + else { + if (*el == *arr/*.parr*/[1]) isPresent = true; + return 1; + } + } + + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + if (*el == *arr/*.parr*/[mn]) { + isPresent = true; + return mn; + } + else + if (*el == *arr/*.parr*/[mx]) { + isPresent = true; + return mx; + } + else { + size_t md = ( mn + mx ) / 2; + if ( *arr/*.parr*/[md] < *el ) + mn = md; + else if ( *el < *arr/*.parr*/[md] ) + mx = md; + else if ( *arr/*.parr*/[md] == (Type&)*el ) { + isPresent = true; + return md; + } + } + } + + return mx; +} + + +//------------------------------------------------------------------------------- +// \ru поиск объекта в массиве \en search of an element in array +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// \ru Входные параметры: \en Input parameters: +// \ru arr - массив элементов \en arr - the array of elements +// \ru el - объект для поиска \en el - the object for the search +// \ru Возвращаемое значение: \en The returned value: +// \ru Индекс объекта в массиве. Если объект не был найден, то возращается SYS_MAX_T. \en index of an object in array If the object was not found then SYS_MAX_T is returned. +// --- +template +size_t find_from_array( SPArray & arr, const Type * el ) +{ + if ( el == NULL ) // \ru LF_Linux: добавил проверку на NULL \en LF_Linux: added a check for NULL + return SYS_MAX_T; + // \ru общий случай - элементов больше 11 //LF_Linux: откуда 11??? \en the common case - the number of elements is more than 11 //LF_Linux: why 11?? + if ( arr.count > 11 ) { + size_t mx = arr.count - 1; + size_t mxc = mx; + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + if ( *arr[md] < *el ) { + if ( *el == *arr[mx] ) + return mx; + mn = md; + } + // \ru по логике правильнее было бы проверять сначала меньше, потом тождественно, а затем, уже \en it would be better to check at first whether it is less, then whether it is equal and only after this + // \ru без сравнения - делать вывод что больше. \en conclude which is greater without comparison. + // \ru НО! оператор сравнения, как правило более быстрый, чем оператор тождественности, \en BUT! the comparison operator is generally faster than identity operator, + // \ru и заведомо более часто используется( тождественно - финишная опреация в поиске ) \en and it is used more often (identity check is the last operation in search) + // \ru и если поставить проверку тождественности впереди "больше" - можно получить торможение \en and if the identity check will be placed before the "greater" check then there may occur an inhibition + // \ru на тяжелых операторах \en on heavy operators + // \ru Кроме того, все три проверки делаются, дабы не отказывать программистам в их праве делать \en - + // \ru ошибки при написании операторов сравнения и тождественности и потом их с комфортом исправлять. \en - + else if ( *el < *arr[md] ) { + if ( *el == *arr[mn] ) + return mn; + mx = md; + } + else if ( *arr[md] == *el ) + return md; + // \ru если попадаем сюда - значит некорректно написаны операторы "тождественно" и сравнения \en if we are here then operators of identity check and comparison are not correct + else { + PRECONDITION( 0 ); + return SYS_MAX_T; + } + } + + // \ru проверка по границам \en check by bounds + if ( *el < *arr[0] ) + return SYS_MAX_T; + if ( *arr[mxc] < *el ) + return SYS_MAX_T/*-1*/; + } + else { + // \ru специальные случаи \en special cases + if ( arr.count == 1 ) + return *el == *arr[0] ? 0 : SYS_MAX_T; + else { + if ( arr.count == 2 ) + return *el == *arr[0] ? 0 : ((*el == *arr[1]) ? 1 : SYS_MAX_T); + else { + // 2 < count <= 11 + for( size_t i = 0, count = arr.count; i < count; i++ ) + if ( *el == *arr[i] ) + return i; + } + } + } + + return SYS_MAX_T; +} + + +#endif // __TEMPL_SP_ARRAY_H diff --git a/C3d/Include/templ_specify_facet.h b/C3d/Include/templ_specify_facet.h new file mode 100644 index 0000000..49e245e --- /dev/null +++ b/C3d/Include/templ_specify_facet.h @@ -0,0 +1,81 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Фасет. + \en Facet. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// specify_facet.h +// +// \ru Реализация класса specify_facet для поддержки идиомы RAII (Resource \en Implementation of the class specify_facet for the support of the idiom RAII (Resource +// \ru Acquisition Is Initialization) при задании фасетов потоку. \en Acquisition Is Initialization) when defining the facets for a stream. +// \ru В конструкторе задаём фасет, в деструкторе восстанавливаем локаль \en Set the facet in constructor, restore the locale in destructor +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef __TEMPL_SPECIFY_FACET_H +#define __TEMPL_SPECIFY_FACET_H + + +#include + + +namespace c3d // namespace C3D +{ + +/////////////////////////////////////////////////////////////////////////////// +// +// specify_facet +// \ru Поддержка RAII (Resource Acquisition Is Initialization) для задания \en Support of RAII (Resource Acquisition Is Initialization) for the setting of +// \ru фасетов потоку. В конструкторе задаём новый фасет, в деструкторе \en facets for a stream. Set a new facet in constructor, in destructor +// \ru восстанавливаем поведение \en restore the behaviour +// +// \ru Использование: \en The usage: +// std::wofstream file; +// +// sys_io::specify_facet sp_facet( file ); +// file.open( "file_name", std::ios_base::out | std::ios_base::binary +// | std::ios_base::trunc ); +// +// \ru Параметры шаблона: \en Template parameters: +// \ru StreamType - тип потока, FacetType - тип фасета \en StreamType - a stream type, FacetType - a facet type +// +/////////////////////////////////////////////////////////////////////////////// +template +class specify_facet +{ +private: + typedef StreamType _StType; // \ru Тип потока \en A stream type + typedef FacetType _FcType; // \ru Тип фасета \en A facet type + + _StType & _stream; // \ru Ссылка на поток, которым управляем \en A reference to the controlled stream + std::locale _locale; // \ru Старая локаль, которую надо будет восстанавливать \en An old locale to be restored + +public: + specify_facet( _StType & stream ) + : _stream( stream ) + { + // \ru Код разный в зависимости от компилятора. С переходом на VS2005 убрать \en The code is different, according to the compiler. Remove it after the moving to VS2005 +//OV_x64 #if defined(_MSC_VER) && _MSC_VER < 1400 +//OV_x64 _locale = _stream.imbue( _stream.getloc()._Addfac(new _FcType, _FcType::id, _FcType::_Getcat()) ); +//OV_x64 #else + _locale = _stream.imbue( std::locale(_stream.getloc(), new _FcType) ); +//OV_x64 #endif + } + + ~specify_facet() + { + // \ru Восстанавливаем старую локаль \en Restore the old locale + _stream.imbue( _locale ); + } +}; + +} // namespace C3D + + +#endif // __TEMPL_SPECIFY_FACET_H diff --git a/C3d/Include/templ_sptr.h b/C3d/Include/templ_sptr.h new file mode 100644 index 0000000..9bd40ce --- /dev/null +++ b/C3d/Include/templ_sptr.h @@ -0,0 +1,238 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Автоматические указатель и ссылка на объекты с подсчетом ссылок. + \en Smart pointer and reference to objects with reference counter. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_SPTR_H +#define __TEMPL_SPTR_H + +#include +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Отладочная проверка на NULL. + \en Debug check for NULL. \~ + \details \ru Отладочная проверка на NULL. \n + \en Debug check for NULL. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +#define NULL_CHECK PRECONDITION( m_pI != NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматический указатель на объекты с подсчетом ссылок. + \en Smart pointer to objects with reference counter. \~ + \details \ru Автоматический указатель (smart pointer) на объекты с подсчетом ссылок. + Требует от параметра шаблона реализации функций AddRef() и Release(). \n + \en Smart pointer to objects with reference counter. + It requires Implementation of functions AddRef() and Release() from the template parameter. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class SPtr +{ + T * m_pI; // \ru Указатель на объект. \en A pointer to an object. + +public: + /// \ru Конструктор. \en Constructor. + SPtr () : m_pI( NULL ) {} + /// \ru Конструктор по указателю. \en Constructor by pointer. + explicit SPtr ( T * elem ) + { + if ( (m_pI = elem) != NULL ) + m_pI->AddRef(); + } + /// \ru Конструктор копирования. \en Copy constructor. + SPtr( const SPtr & ptr ) : m_pI( NULL ) { assign(ptr.m_pI); } + /// \ru Конструктор по совместимому указателю \en Constructor by compatible pointer + template + SPtr( const SPtr<_T> & ptr ) : m_pI( ptr.get() ) { if ( m_pI != NULL ) { m_pI->AddRef();} } + /// \ru Деструктор. \en Destructor. + ~SPtr() { if( m_pI != NULL ) m_pI->Release(); } + +public: // \ru Перегрузка операторов \en Operators overloading + /// \ru Оператор преобразования к типу T* . \en An operator for conversion to the type T*. + operator T* ( void ) const { return m_pI; } + /// \ru Оператор преобразования к совместимому указателю. \en An operator for conversion to a compatible pointer. + /* + template + operator SPtr<_T> () const { return SPtr<_T>( m_pI ); } + */ + /// \ru Оператор доступа. \en An access operator. + T & operator * () const { NULL_CHECK return *m_pI; } + /// \ru Оператор доступа. \en An access operator. + T * operator -> () const { NULL_CHECK return m_pI; } + /// \ru Оператор присваивания. \en The assignment operator. + SPtr & operator = ( T * elem ) { return assign( elem ); } + /// \ru Оператор присваивания. \en The assignment operator. + SPtr & operator = ( const SPtr & ptr ) { return assign( ptr.get() ); } + /// \ru Оператор присваивания для совместимого указателя. \en An assignment operator for a compatible pointer. + template + SPtr & operator = ( const SPtr<_T> & ptr ) { return assign( ptr.get() ); } + /// \ru Оператор проверки на равенство. \en An operator for equality check. + template + bool operator == ( const SPtr<_T> & ptr ) const { return ( m_pI == ptr.get() ); } + /// \ru Оператор проверки на равенство. \en An operator for equality check. + template + bool operator == ( const _T * elem ) const { return ( m_pI == elem ); } + /// \ru Оператор проверки на равенство. \en An operator for equality check. + bool operator == ( T * elem ) const { return ( m_pI == elem ); } + /// \ru Оператор проверки на неравенство. \en An operator for inequality check. + template + bool operator != ( const SPtr<_T> & ptr ) const { return ( !(operator == (ptr)) ); } + /// \ru Оператор проверки на неравенство. \en An operator for inequality check. + template + bool operator != ( const _T * elem ) const { return ( !(operator == (elem)) ); } + /// \ru Оператор проверки на неравенство. \en An operator for inequality check. + bool operator != ( T * elem ) const { return ( !(operator == (elem)) ); } + /// \ru Отношение порядка. \en Order relation. + template + bool operator < ( const _T * elem ) const { return ( m_pI < elem ); } + /// \ru Отношение порядка. \en Order relation. + template + bool operator < ( const SPtr<_T> & elem ) const { return ( m_pI < elem.get() ); } + +public: + /// \ru Функция присваивания указателем. \en A function of assignment by pointer. + SPtr & assign( T * elem ); + /// \ru Фунция освобождения объекта. \en A function of release an object. + SPtr & reset( void ) { if( m_pI != NULL ) { m_pI->Release(); m_pI = NULL; } return *this; } + /// \ru Функция доступа к элементу данных. \en A function of access to data element. + T * get() const { return m_pI; } + /// \ru Функция отсоединяет объект. \en A function detaches an object. + T * detach() { T * obj = m_pI; m_pI = NULL; if ( obj != NULL ) obj->DecRef(); return obj; } + /// \ru Нулевой указатель? \en Is null pointer? + bool is_null() const { return (( NULL == m_pI ) ? true : false ); } + +#ifdef STANDARD_CPP11_RVALUE_REFERENCES +public: + /// \ru Конструктор перемещения. \en Moving constructor. + SPtr( SPtr && src ) : m_pI ( src.m_pI ) + { + src.m_pI = 0; + } + /// \ru Оператор перемещения. \en Moving operator. + SPtr & operator = ( SPtr && src ) + { + T * tmp = m_pI; + m_pI = src.m_pI; + src.m_pI = tmp; + return *this; + } +#endif // STANDARD_CPP11_RVALUE_REFERENCES +}; + + +//------------------------------------------------------------------------------ +// \ru Функция присваивания указателем \en A function of assignment by pointer. +// --- +template +inline SPtr & SPtr::assign( T * elem ) +{ + if ( m_pI != elem ) + { + if ( elem != NULL ) { elem->AddRef(); } + if ( m_pI != NULL ) { m_pI->Release(); } + m_pI = elem; + } + return *this; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Автоматическая ссылка на объекты с подсчетом ссылок. + \en Smart reference to objects with reference counter. \~ + \details \ru Автоматическая ссылка (smart reference) на объекты с подсчетом ссылок. + Фактически тоже самое, что и SPtr, но без возможности равенства NULL.\n + Требует от параметра шаблона реализации функций AddRef() и Release(). \n + \en Smart reference to objects with reference counter. + Actually it is the same as SPtr but without the possibility of equality to NULL \n + It requires Implementation of functions AddRef() and Release() from the template parameter. \n \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +class SRef +{ + T * m_pI; ///< \ru Указатель на значение \en A pointer to the value + +public: + /// \ru Конструктор по ссылке. \en Constructor by reference. + SRef ( T & ref ) : m_pI( & ref ) + { + m_pI->AddRef(); + } + /// \ru Конструктор копирования. \en Copy constructor. + SRef( const SRef & src ): m_pI( src.m_pI ) + { + m_pI->AddRef(); + } + /// \ru Деструктор. \en Destructor. + ~SRef( void ) + { + m_pI->Release(); + } +public: + /// \ru Функция доступа. \en An access function. + T & get() const { return *m_pI; } + /// \ru Оператор доступа. \en An access operator. + operator T & ( void ) const { return *m_pI; } + /// \ru Оператор доступа. \en An access operator. + T & operator()() const { return *m_pI; } + /// \ru Оператор проверки на равенство. \en An operator for equality check. + bool operator == ( const SRef & src ) const { return ( m_pI == src.m_pI ); } + /// \ru Оператор проверки на равенство. \en An operator for equality check. + bool operator == ( T & pObj ) const { return ( m_pI == &pObj ); } + /// \ru Оператор проверки на неравенство. \en An operator for inequality check. + bool operator != ( const SRef & src ) const { return ( !(operator == (src)) ); } + /// \ru Оператор проверки на неравенство. \en An operator for inequality check. + bool operator != ( T & pObj ) const { return ( !(operator == (pObj)) ); } + /// \ru Оператор присваивания. \en The assignment operator. + SRef & operator = ( const SRef & ref ) { return operator =( *ref.m_pI ); } + /// \ru Оператор присваивания. \en The assignment operator. + SRef & operator = ( T & obj ) + { + obj.AddRef(); + m_pI->Release(); + m_pI = &obj; + return *this; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Пара автоматических указателей. + \en A pair of smart pointers. \~ + \details \ru Пара автоматических указателей. \n + Удобно применять там, где требуется передавать в качестве аргумента + функции или результата пару указателей на объекты со счетчиком ссылок. + Все данные и методы класса намеренно сделаны открытыми. + \en A pair of smart pointers. \n + It is comfortable to use this when it is required to pass as an argument + of a function or a result, a pair of smart pointers to objects with reference counters. + All data and methods of the class are purposely made public. \~ + \ingroup Base_Tools_SmartPointers +*/ +// --- +template +struct SPtrPair +{ + SPtr first; ///< \ru Автоматический указатель на первый объект. \en A smart pointer to the first object. + SPtr second; ///< \ru Автоматический указатель на второй объект. \en A smart pointer to the second object. + /// \ru Конструктор. \en Constructor. + SPtrPair(): first(), second() {} + /// \ru Конструктор копирования. \en Copy constructor. + SPtrPair( const SPtrPair & sPair ) : first(sPair.first), second(sPair.second) {} + /// \ru Оператор присваивания. \en The assignment operator. + SPtrPair & operator = ( const SPtrPair & sPair ) { first = sPair.first; second = sPair.second; } +}; + + +#endif // __TEMPL_SPTR_H diff --git a/C3d/Include/templ_ss_array.h b/C3d/Include/templ_ss_array.h new file mode 100644 index 0000000..11eb29d --- /dev/null +++ b/C3d/Include/templ_ss_array.h @@ -0,0 +1,454 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Упорядоченный массив объектов. + \en Ordered array of objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_SSARRAY_H +#define __TEMPL_SSARRAY_H + + +#include + + +FORVARD_DECL_TEMPLATE_TYPENAME( class SSArray ); +FORVARD_DECL_TEMPLATE_TYPENAME( Type * add_to_array ( SSArray & arr, const Type & el, size_t & indexEl ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_in_array ( const SSArray &, const Type & el ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( size_t find_from_array_spec ( const SSArray &, const Type & el, bool & isPresent ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, SSArray & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const SSArray & ref ) ); + +//------------------------------------------------------------------------------ +/** \brief \ru Упорядоченный массив. + \en Ordered array. \~ + \details \ru Упорядоченный массив объектов. \n + У объектов массива должны быть операторы "==" и "<". + Одинаковые объекты не добавляются. \n + \en Ordered array of objects. \n + Elements of the array should have operators "==" and "<". + The similar objects are not added. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SSArray : protected SArray { +public : + SSArray( size_t maxCnt = 0, uint16 delt = 1 ) : SArray( maxCnt, delt ) {} + SSArray( const SSArray & other ) : SArray( other ) {} +protected: + SSArray( const SArray & other ) : SArray( other ) {} +public: + using SArray::operator[]; + + using SArray::Flush; + using SArray::HardFlush; + using SArray::Adjust; + using SArray::Remove; + using SArray::RemoveInd; + using SArray::Count; + using SArray::MaxIndex; + using SArray::GetAddr; + using SArray::GetEndAddr; + using SArray::Reserve; + using SArray::SetSize; + using SArray::SetMaxDelta; + + using SArray::size; + using SArray::reserve; + using SArray::front; + using SArray::back; + using SArray::begin; + using SArray::end; + using SArray::erase; + using SArray::clear; + + Type * Add ( const Type & ); // \ru добавить элемент с упорядочиванием по массиву \en add element with sorting + Type * Add ( const Type &, size_t & indexEnt ); // \ru добавить элемент с упорядочиванием по массиву, возвращает индекс \en add element with sorting, returns index of the element + // \ru используя эту функцию, пользователь несет всю ответственность за дальнейшую работу сортировки \en When using this function the user is fully responsible for the further work of the sorting process + // \ru - сортировка может работать неправильно. \en - sorting may work incorrectly. + void AddSimple( const Type &ent ) { SArray::Add( ent ); } // \ru Доступ к функции базового класса - добавить элемент в конец массива \en An access to the function of the base class - add an element to the end of the array + + size_t Find( const Type & ) const; // \ru найти элемент в упорядоченном массиве \en find an element in ordered array + size_t RemoveObj( const Type& delObject ); + + bool operator == ( const SSArray & ) const; // \ru сравнить два массива \en compare two arrays + bool operator != ( const SSArray & ) const; // \ru сравнить два массива \en compare two arrays + bool operator < ( const SSArray & ) const; // \ru сравнить два массива \en compare two arrays + void operator = ( const SSArray & arr ) { SArray::operator = ( arr ); } + + // \ru преобразование к базовому классу \en Convert to the base class + const SArray & BaseClass() const { return *this; } + + size_t PossibleIndex( const Type& ent, bool& isPresent ) const; // \ru найти место в массиве, куда будет добавлен элемент ( без добавления ) \en find a place in the array for adding ann element (adding is not performed) + // \ru на выходе : isPresent == true - элемент уже в массиве \en in output : isPresent == true - the element is already in the array + + TEMPLATE_FRIEND Type * add_to_array TEMPLATE_SUFFIX ( SSArray & arr, const Type & el, size_t & indexEl ); + TEMPLATE_FRIEND size_t find_in_array TEMPLATE_SUFFIX ( const SSArray &, const Type & el ); + TEMPLATE_FRIEND size_t find_from_array_spec TEMPLATE_SUFFIX ( const SSArray &, const Type & el, bool & isPresent ); + + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, SSArray & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const SSArray & ref ); + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +public: + void * operator new ( size_t ); + void operator delete ( void *, size_t ); +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ +}; + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора new. \en Overloading of the "new" operator. +// --- +template +inline void * SSArray::operator new( size_t size ) { + return ::Allocate( size, typeid(SSArray).name() ); +} + +//------------------------------------------------------------------------------ +// \ru Перегрузка оператора delete. \en Overloading of the "delete" operator. +// --- +template +inline void SSArray::operator delete ( void * ptr, size_t size) { + ::Free( ptr, size, typeid(SSArray).name() ); +} +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +//------------------------------------------------------------------------------- +// \ru оператор сравнения двух массивов \en an operator of two arrays comparison +// --- +template +inline bool SSArray::operator == ( const SSArray & w ) const { + if ( SArray::count != w.count ) + return false; + + // \ru OV K6 При размещении в памяти с выравниванием не равным 1, между элементами массива \en OV K6 While the memory allocation with alignment which is not equal 1 between elements of the array + // \ru возможно появление "дырок" заполненного случайным мусором, т.к. сравнивать этот мусор \en may appear "holes" filled by random trash, since there is not reason to compare this trash + // \ru нам никчему, будем сравнивать содержимое массивов поэлементно (через оператор == объекта) \en we will compare the content of arrays element by element (using the operator == of an object) + for ( size_t i = 0; i < SArray::count; ++i ) { + if ( !((*this)[i] == w[i]) ) + return false; + } + return true; +} + + +//------------------------------------------------------------------------------- +// \ru оператор сравнения двух массивов \en an operator of two arrays comparison +// --- +template +inline bool SSArray::operator < ( const SSArray & w ) const { + // \ru OV K6 При размещении в памяти с выравниванием не равным 1, между элементами массива \en OV K6 While the memory allocation with alignment which is not equal 1 between elements of the array + // \ru возможно появление "дырок" заполненного случайным мусором, т.к. сравнивать этот мусор \en may appear "holes" filled by random trash, since there is not reason to compare this trash + // \ru нам никчему, будем сравнивать содержимое массивов поэлементно (через оператор < объекта) \en we will compare the content of arrays element by element (using the operator < of an object) + for ( size_t i = 0, c = std_min(SArray::count, w.count); i < c; i++ ) { + if ( !((*this)[i] == w[i]) ) + return (bool)((*this)[i] < w[i]); + } + + if ( SArray::count != w.count ) + return SArray::count < w.count; + + return true; +} + + +//------------------------------------------------------------------------------- +// \ru оператор сравнения двух массивов \en an operator of two arrays comparison +// --- +template +inline bool SSArray::operator != ( const SSArray & w ) const { + return ! ( *this == w ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type * SSArray::Add( const Type & el ) { + size_t indexEl = SYS_MAX_T; + return add_to_array( *this, el, indexEl ); +} + + +//------------------------------------------------------------------------------- +// \ru добавление объекта в массив \en adding an object to array +// --- +template +inline Type * SSArray::Add( const Type & el, size_t & indexEl ) { + return add_to_array( *this, el, indexEl ); +} + + +//------------------------------------------------------------------------------ +// \ru удалить элемент из массива \en delete an element from array +// --- +template +inline size_t SSArray::RemoveObj( const Type & delObject ) { + size_t ind = Find( delObject ); + if ( ind != SYS_MAX_T ) + RemoveInd( ind ); + return ind; +} + + +//------------------------------------------------------------------------------- +// \ru поиск объека в массиве \en search of an element in array +// --- +template +inline size_t SSArray::Find( const Type & el ) const { + return find_in_array( *this, el ); +} + + +//------------------------------------------------------------------------------- +// \ru найти место в массиве, куда будет добавлен элемент ( без добавления ) \en find a place in the array for adding ann element (adding is not performed) +// --- +template +inline size_t SSArray::PossibleIndex( const Type & el, bool & isPresent ) const { + return find_from_array_spec( *this, el, isPresent ); +} + + +//------------------------------------------------------------------------------- +// \ru добавить объект в массив с упорядочиванием \en add an object to the array with ordering +// --- +template +Type * add_to_array( SSArray & arr, const Type & el, size_t & indexEl ) +{ + size_t mx = arr.count - 1; + size_t mxc = mx; + size_t mn = 0; + + if ( arr.count > 2 ) { + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + Type & mdE = arr[md]; + if ( mdE < el ) { + if ( el == arr[mx] ) { + indexEl = mx; + return 0; + } + mn = md; + } + // \ru по логике правильно было бы проверять сначала меньше, потом тождественно, а затем, уже \en it would be better to check at first whether it is less, then whether it is equal and only after this + // \ru без сравнения - делать вывод что больше. \en conclude which is greater without comparison. + // \ru НО! оператор сравнения, как правило более быстрый, чем оператор тождественности, \en BUT! the comparison operator is generally faster than identity operator, + // \ru и заведомо более часто используется( тождественно - финишная операция в поиске ) \en and it is used more often (identity check is the last operation in search) + // \ru и если поставить проверку тождественности впереди "больше" - можно получить торможение \en and if the identity check will be placed before the "greater" check then there may occur an inhibition + // \ru на тяжелых операторах \en on heavy operators + // \ru Кроме того, все три проверки делаются, дабы не отказывать программистам в их праве делать \en - + // \ru ошибки при написании операторов сравнения и тождественности и потом их с комфортом исправлять. \en - + else if ( el < mdE ) { + if ( el == arr[mn] ) { + indexEl = mn; + return 0; + } + mx = md; + } + else if ( mdE == (Type&)el ) { + indexEl = md; + return 0; + } + // \ru если попадаем сюда - значит некорректно написаны операторы "тождественно" и сравнения \en if we are here then operators of identity check and comparison are not correct + else { + PRECONDITION( 0 ); + return 0; // \ru но это не повод устраивать зависание. \en we have to exit to avoid hang. + } + } + + // \ru здесь дублирование кода проверки границ \en here the code of boundaries check is duplicated + // \ru объем кода принесен в жертву скорости \en the code is huge but optimized + if ( el < arr[0] ) { + Type * res = arr.InsertInd( 0, el ); + indexEl = 0; + return res; //arr.parr; + } + if ( arr[mxc] < el ) { + Type * res = arr.SArray::Add( el ); + indexEl = mxc + 1; + return res; + } + + Type * res = arr.InsertInd( mx, el ); + indexEl = mx; + return res; + } + + // \ru проверку на пустоту массива нельзя переносить за проверку границ - \en a check for array emptyness should not be moved outside a boundary check - + // \ru можно вылететь (из-за mxc = -1) \en the error may occur (because of mxc = -1) + if ( !arr.count ) { + Type * res = arr.SArray::Add( el ); + indexEl = 0; + return res; //arr.parr; + } + + // \ru здесь дублирование кода проверки границ \en here the code of boundaries check is duplicated + // \ru объем кода принесен в жертву скорости \en the code is huge but optimized + if ( el < arr[0] ) { + Type * res = arr.InsertInd( 0, el ); + indexEl = 0; + return res; + } + if ( arr[mxc] < el ) { + Type * res = arr.SArray::Add( el ); + indexEl = mxc + 1; + return res; + } + + if ( arr.count == 2 ) { + if ( el == arr[0] ) { + indexEl = 0; + return 0; + } + else + if ( el == arr[1] ) { + indexEl = 1; + return 0; + } + else { + Type * res = arr.InsertInd( 1, el ); + indexEl = 1; + return res; + } + } + + indexEl = 0; + return 0; +} + + +//------------------------------------------------------------------------------- +// \ru найти объект в массиве \en find an object in the array +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// --- +template +size_t find_in_array( const SSArray & arr, const Type & el ) +{ + if ( arr.count > 11 ) { + size_t mx = arr.count - 1; + size_t mxc = mx; + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + size_t md = ( mn + mx ) / 2; + Type & mdE = arr[md]; + if ( mdE < el ) { + if ( el == arr[mx] ) + return mx; + mn = md; + } + // \ru по логике правильнее было бы проверять сначала меньше, потом тождественно, а затем, уже \en it would be better to check at first whether it is less, then whether it is equal and only after this + // \ru без сравнения - делать вывод что больше. \en conclude which is greater without comparison. + // \ru НО! оператор сравнения, как правило более быстрый, чем оператор тождественности, \en BUT! the comparison operator is generally faster than identity operator, + // \ru и заведомо более часто используется( тождественно - финишная опреация в поиске ) \en and it is used more often (identity check is the last operation in search) + // \ru и если поставить проверку тождественности впереди "больше" - можно получить торможение \en and if the identity check will be placed before the "greater" check then there may occur an inhibition + // \ru на тяжелых операторах \en on heavy operators + // \ru Кроме того, все три проверки делаются, дабы не отказывать программистам в их праве делать \en - + // \ru ошибки при написании операторов сравнения и тождественности и потом их с комфортом исправлять. \en - + else if ( el < mdE ) { + if ( el == arr[mn] ) + return mn; + mx = md; + } + else if ( mdE == el ) + return md; + // \ru если попадаем сюда - значит некорректно написаны операторы "тождественно" и сравнения \en if we are here then operators of identity check and comparison are not correct + else { + PRECONDITION( 0 ); + return SYS_MAX_T; + } + } + + if ( el < arr[0] ) + return SYS_MAX_T; + if ( arr[mxc] < el ) + return SYS_MAX_T; + } + else { + if ( arr.count == 1 ) + return el == arr[0] ? 0 : SYS_MAX_T; + else { + if ( arr.count == 2 ) + return el == arr[0] ? 0 : ((el == arr[1]) ? 1 : SYS_MAX_T); + else { + // 2 < count <= 11 + for( size_t i = 0; i < arr.count; i++ ) + if ( el == arr[i] ) + return i; + } + } + } + + return SYS_MAX_T; +} + + +//------------------------------------------------------------------------------- +// \ru найти объект в массиве \en find an object in the array +// \ru поиск ведется методом половинных делений \en a search is performed by the bisection method +// --- +template +size_t find_from_array_spec( const SSArray & arr, const Type & el, bool & isPresent ) { + isPresent = false; + + if ( !arr.count || el < arr/*.parr*/[0] ) + return 0; + + size_t mx = arr.count - 1; + + if ( arr/*.parr*/[mx] < el ) + return mx + 1; + + if ( arr.count == 1 ) { // \ru значит *el == *parr[0] \en it means *el == *parr[0] + isPresent = true; + return 0; + } + + if ( arr.count == 2 ) { // \ru значит между 0 и 1 \en between 0 and 1 + if ( el == arr/*.parr*/[0] ) { + isPresent = true; + return 0; + } + else { + if (el == arr/*.parr*/[1]) isPresent = true; + return 1; + } + } + + size_t mn = 0; + + while ( mn + 1 < mx ) { // \ru пока не нашли - ищем \en seek until do not find + if ( el == arr/*.parr*/[mn] ) { + isPresent = true; + return mn; + } + else + if (el == arr/*.parr*/[mx]) { + isPresent = true; + return mx; + } + else { + size_t md = ( mn + mx ) / 2; + if ( arr/*.parr*/[md] < el ) + mn = md; + else if ( el < arr/*.parr*/[md] ) + mx = md; + else if ( arr/*.parr*/[md] == (Type&)el ) { + isPresent = true; + return md; + } + } + } + + return mx; +} + + +#endif // __TEMPL_SSARRAY_H diff --git a/C3d/Include/templ_stack.h b/C3d/Include/templ_stack.h new file mode 100644 index 0000000..3822185 --- /dev/null +++ b/C3d/Include/templ_stack.h @@ -0,0 +1,86 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Стек объектов. + \en A stack of objects. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __TEMPL_SSTACK_H +#define __TEMPL_SSTACK_H + + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Стек объектов. + \en A stack of objects. \~ + \details \ru Стек объектов. \n + Для организации стека используем в качестве строителя SArray, + и отсекаем лишнее с помощью приватного наследования. \n + \en A stack of objects. \n + To organize stack SArray is used as the builder, + and all redundant is cut by using a private inheritance. \n \~ + \ingroup Base_Tools_Containers +*/ +// --- +template +class SStack: private SArray { +public: + /// \ru Конструктор. \en Constructor. + SStack( size_t i_upper = 0, uint16 i_delta = 1 ) + : SArray( i_upper, i_delta ) + {} +public: + void Push( const Type & obj ); ///< \ru Добавить элемент в стек. \en Add an element to the stack. + Type & Pop(); ///< \ru Извлечь один элемент стека, если возвращаетя NULL, значит достигнуто дно стека. \en Retrieve one element from the stack, if NULL is returned then the bottom of stack is reached. + Type & Top() const; ///< \ru Верхний элемент стека (последний внесенный). \en The top element of the stack (the last added). + + // \ru Оставить доступными следующие методы: \en Leave an access to the next methods: + using SArray::Flush; ///< \ru Очистить стек. \en Clear the stack. + using SArray::Count; ///< \ru Количество элементов, содержащихся в стеке. \en The number of elements in stack. + using SArray::IsExist; ///< \ru Существует ли элемент. \en Whether an element exists. + using SArray::operator[]; ///< \ru Оператор прямого доступа - работает, как для массива. \en An operator of a direct access - it works as for an array. + +private: + SStack( const SStack & ); ///< \ru (!) Без реализации \en (!) There is no implementation + void operator =( const SStack & ); ///< \ru (!) Без реализации \en (!) There is no implementation +}; + + +//------------------------------------------------------------------------------ +/// \ru Добавить элемент в стек \en Add an element to the stack +//--- +template +void SStack::Push( const Type & obj ) { + SArray::Add( obj ); +} + + +//------------------------------------------------------------------------------ +/// \ru Извлечь один элемент стека \en Retrieve one element from the stack +//--- +template +Type & SStack::Pop() { + if ( SArray::count > 0 ) { + Type & ret = (*this)[SArray::count-1]; + SArray::count--; + return ret; + } + return (*this)[0]; +} + + +//------------------------------------------------------------------------------ +/// \ru Верхний элемент стека \en The top element of the stack +//--- +template +Type & SStack::Top() const { + return (*this)[SArray::count-1]; +} + + +#endif // __TEMPL_SSTACK_H diff --git a/C3d/Include/templ_t_list.h b/C3d/Include/templ_t_list.h new file mode 100644 index 0000000..ce51fb3 --- /dev/null +++ b/C3d/Include/templ_t_list.h @@ -0,0 +1,130 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сериализация списка List. + \en Serialization of list. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_T_LIST_H +#define __TEMPL_T_LIST_H + + +#include +#include +#include + + +//------------------------------------------------------------------------------ +// \ru чтение списка из потока в объект \en reading of list from a stream to an object +// +template +reader & operator >> ( reader& in, List& ref ) { + ref.Flush(); + + if ( in.good() ) { + uint8 val = 0; + in >> val; + + size_t count = ReadCOUNT( in, false/*uint_val*/ ); + + if ( in.good() ) { + ref.owns = !!val; + + if ( count ) { + Type* el; + for ( size_t i = 0; i < count; i++ ) + { + in >> el; + if ( in.good() ) + ref.Add( el ); + else { + if ( ref.owns ) // \ru ЯТ 03.01.01 \en ЯТ 03.01.01 + delete el; // \ru ЯТ 03.01.01 \en ЯТ 03.01.01 + break; + } + } + } + } + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись списка в поток из объекта \en writing of list from an object to a stream +// --- +template +writer& operator << ( writer& out, const List& ref ) { + out << uint8(ref.owns); + + ///////////////////////////////// + size_t refCount = ref.Count(); + + WriteCOUNT( out, refCount ); + + size_t count = 0; // \ru ЯТ защита от возможной рассогласованности списка \en ЯТ protection from the possible mismatch of the list + LIterator iter( ref ); + while( iter && out.good() && count < refCount ) { + out << iter++; + count++; + } + + // \ru ЯТ проверка на возможную рассогласованность списка \en ЯТ a check for the possible mismatch of the list + if ( out.good() ) { + C3D_ASSERT( count == refCount ); + } + + return out; +} + + +//------------------------------------------------------------------------------ +// \ru чтение списка из потока в указатель \en reading of list from a stream to a pointer +// +template +reader& operator >> ( reader& in, List*& ptr ) { + ptr = NULL; + + if ( in.good() ) { + if ( in.MathVersion() < 0x06000012L ) + ptr = new List; + else { + uint8 existPtr = 0; + in >> existPtr; + if ( existPtr ) + ptr = new List; + } + + if ( ptr ) + in >> *ptr; // \ru чтение тела \en reading of a solid + } + + return in; +} + + +//------------------------------------------------------------------------------ +// \ru запись списка в поток из указателя \en writing of list from a pointer to a stream +// --- +template +writer& operator << ( writer& out, const List* ptr ) { + // \ru ЯТ К6 при записи в старую версию оставляю без проверки указателя \en ЯТ К6 while writing to an old version the pointer is not checked + if ( out.MathVersion() < 0x06000012L ) { + C3D_ASSERT( ptr ); + out << *ptr; + } + else { + uint8 existPtr = !!ptr; + out << existPtr; + if ( existPtr ) + out << *ptr; // \ru запись телом \en writing by a solid + } + + return out; +} + + +#endif // __TEMPL_T_LIST_H diff --git a/C3d/Include/templ_three_states.h b/C3d/Include/templ_three_states.h new file mode 100644 index 0000000..81a0d70 --- /dev/null +++ b/C3d/Include/templ_three_states.h @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Трехпозиционный флаг. + \en Tree-position flag. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_THREE_STATES_H +#define __TEMPL_THREE_STATES_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Трехпозиционный флаг. + \en Tree-position flag. \~ + \details \ru Флаг из трех состояний. \n + \en A flag of three states. \n \~ + \ingroup Base_Tools +*/ +// --- +enum ThreeStates { + ts_negative = -1, ///< \ru Состояние НЕТ. \en The state NO. + ts_neutral = 0, ///< \ru Состояние НЕ ИЗВЕСТНО. \en The state UNKNOWN. + ts_positive = 1 ///< \ru Состояние ДА. \en The state YES. +}; + + +#endif // __TEMPL_THREE_STATES_H diff --git a/C3d/Include/templ_type_modified.h b/C3d/Include/templ_type_modified.h new file mode 100644 index 0000000..302b5e4 --- /dev/null +++ b/C3d/Include/templ_type_modified.h @@ -0,0 +1,186 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Объект с флагом модификации. + \en An object with the modifications flag. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_TYPE_MODIFIED_H +#define __TEMPL_TYPE_MODIFIED_H + + +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Класс рассчитан на Type только bool,bool,int,uint,int16,uint16,float,double, теперь работает и с более сложными объектами, но осторожно с деструкторами Type! +// \en The class is intended only for types bool,bool,int,uint,int16,uint16,float,double now it works with more complex objects too, but be careful with the destructors of the class 'Type'! +// +//////////////////////////////////////////////////////////////////////////////// + +FORVARD_DECL_TEMPLATE_TYPENAME( class TypeModified ); +FORVARD_DECL_TEMPLATE_TYPENAME( reader& CALL_DECLARATION operator >> ( reader& in, TypeModified & ref ) ); +FORVARD_DECL_TEMPLATE_TYPENAME( writer& CALL_DECLARATION operator << ( writer& out, const TypeModified & ref ) ); + + +template +class TypeModified { +private: + bool modified_m; + Type value_m; + + enum ValInit { valInit = 0 }; + +public : + TypeModified( ValInit val = valInit, bool modified = false ); // \ru ИР K7 для TRect тут компилятор сгенерирует ошибку \en ИР K7 here the compiler will generate an error for TRect + TypeModified( const Type & val, bool modified = false ); + TypeModified( const TypeModified & ); + virtual ~TypeModified(); + + void SetValue ( Type val, bool modified = true ); + void SetValueRef( const Type & val, bool modified = true ); + const Type & GetValue () const; + operator const Type & () const { return value_m; } + + void Assign ( const TypeModified & ); + + bool IsModified () const; + void SetModified( bool modified ); + +private: + void operator = ( const TypeModified & ); // \ru запрещено \en forbidden + +// ID K8 KNOWN_OBJECTS_RW_REF_OPERATORS(TypeModified ) + TEMPLATE_FRIEND reader& CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader& in, TypeModified & ref ); + TEMPLATE_FRIEND writer& CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer& out, const TypeModified & ref ); +}; + + +//------------------------------------------------------------------------------ +// +// --- +template +inline TypeModified::TypeModified( /*TypeModified::*/ValInit val, bool modified ) + : modified_m( modified ) + , value_m( val ) +{ +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline TypeModified::TypeModified( const Type & val, bool modified ) + : modified_m( modified ) + , value_m( val ) +{ +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline TypeModified::TypeModified( const TypeModified & other ) + : modified_m( other.modified_m ) + , value_m( other.value_m ) +{ +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline TypeModified::~TypeModified() { +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void TypeModified::SetValue( Type val, bool modified ) { + value_m = val; +//MA K9 modified_m = modified_m ? true : modified; + modified_m |= modified; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void TypeModified::SetValueRef( const Type & val, bool modified ) { + value_m = val; +//MA K9 modified_m = modified_m ? true : modified; + modified_m |= modified; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void TypeModified::Assign( const TypeModified & other ) { + value_m = other.value_m; + modified_m = other.modified_m; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline const Type & TypeModified::GetValue() const { + return value_m; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline bool TypeModified::IsModified() const { + return modified_m; +} + + +//------------------------------------------------------------------------------ +// +// --- +template +inline void TypeModified::SetModified( bool modified ) { + modified_m = modified; +} + + +#ifdef C3D_WINDOWS //_MSC_VER // LF_Linux +//------------------------------------------------------------------------------ +// +// --- +template +reader& operator >> ( reader& in, TypeModified& ref ) { + in >> ref.value_m; // \ru ИР K7 >> ref.modified_m; \en ИР K7 >> ref.modified_m; + int m; + in >> m; + ref.modified_m = !!m; + return in; +} + + +//------------------------------------------------------------------------------ +// +//--- +template +writer& operator << ( writer& out, const TypeModified& ref ) { + return out << ref.value_m << (int)ref.modified_m; +} +#endif // C3D_WINDOWS + + +#endif // __TEMPL_TYPE_MODIFIED_H diff --git a/C3d/Include/templ_visitor.h b/C3d/Include/templ_visitor.h new file mode 100644 index 0000000..a812ed2 --- /dev/null +++ b/C3d/Include/templ_visitor.h @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Посетитель классов. + \en Visitor of classes. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TEMPL_VISITOR_H +#define __TEMPL_VISITOR_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Абстрактный базовый класс посетителя. + \en Abstract base class of the visitor. \~ + \details \ru Абстрактный базовый класс паттерна Visitor. \n + Служит для ссылки на конкретного посетителя (ConcreteVisitor). \n + \en Abstract base class of the pattern 'Visitor'. \n + It serves for the reference of a concrete visitor. \n \~ + \ingroup Base_Tools +*/ +// --- +class Visitor +{ +public: + virtual ~Visitor(){}; ///< \ru Деструктор. \en Destructor. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Обобщенное объявление поддержки посещения объекта конкретным посетителем. + \en A generallized declaration of support of the object visit by a concrete visitor. \~ + \details \ru Обобщенное объявление поддержки посещения объекта конкретным посетителем. \n + Конкретный посетитель обязан наследовать от этой обобщенной реализации + для каждого типа посещаемых объектов. \n + \en A generalized declaration of support of the object visit by a concrete visitor. \n + A concrete visitor should inherit from this generalized implementation + for each type of visited objects. \n \~ + \ingroup Base_Tools +*/ +// --- +template class VisitorImpl +{ +public: + virtual void Visit( T & ) = 0; ///< \ru Функция, обрабатывающая посещение объекта. \en A function processing a visit of an object. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Реализация функции, инициирующей посещение объекта. + \en Implementation of a function initializing a visit of an object. \~ + \details \ru Реализация функции, инициирующей посещение объекта. \n + Сделана через динамическое приведение типов ради реализации асимметричного посетителя + (см. Александреску "Modern C++ Design"). + Необходимо объявлять в любом классе, поддерживающем посещение. + \en Implementation of a function initializing a visit of an object. \n + It is made by the dynamic cast in order to implement an asymmetric visitor + (see Alexandrescu "Modern C++ Design"). + There is necessary to declare this in every class which supports a visitor. \~ + \ingroup Base_Tools +*/ +// --- +#define VISITING_CLASS( Class ) \ + public: \ + virtual void Accept( Visitor & visitor ) \ + { \ + VisitorImpl * impl = dynamic_cast *>(&visitor); \ + if( impl ) \ + impl->Visit( *this ); \ + } + + +#endif // __TEMPL_VISITOR_H diff --git a/C3d/Include/tool_cstring.h b/C3d/Include/tool_cstring.h new file mode 100644 index 0000000..b201ab8 --- /dev/null +++ b/C3d/Include/tool_cstring.h @@ -0,0 +1,576 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Строка. + \en String. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_CSTRING_H +#define __TOOL_CSTRING_H + +#include +#include +#include +#include +#include +#include +#include + +#ifndef C3D_WINDOWS //_MSC_VER + #include + #include + #include +#else // C3D_WINDOWS + #include + #include + #include +#endif // C3D_WINDOWS + +#ifndef C3D_WINDOWS //_MSC_VER + #ifndef _UNICODE + typedef char TCHAR; + #define _T(x) x + #define _tcsstr strstr + #define _tcscpy strcpy + #define _tcsncpy strncpy + #define _tcslen strlen + #define _tcscmp strcmp + #define _tcsnccmp strncmp + #define _tcsftime strftime + #else // _UNICODE + typedef wchar_t TCHAR; + #define _T(x) L ## x + #define _tcsstr wcsstr + #define _tcscpy wcscpy + #define _tcsncpy wcsncpy + #define _tcslen wcslen + #define _tcscmp wcscmp + #define _tcsnccmp wcsncmp + #define _tcsftime wcsftime + #endif // _UNICODE + + #define _gcvt gcvt + #define _ecvt ecvt + + #define _istspace isspace + #define _istdigit isdigit + #define _istalnum isalnum + + //////////////////////////////////////////////////////////////////////////////////////////// + // + // \ru Функции конвертации чисел в строку и обратно \en Functions for the convertation of numbers to strings and strings to numbers. + // + //////////////////////////////////////////////////////////////////////////////////////////// + #define _saprintf sprintf // char* + + #ifndef __MOBILE_VERSION__ + //#define _sntprintf sprintf // TCHAR* + //#define _tcscat strcat + #ifdef _UNICODE + #define _sntprintf swprintf // TCHAR* + #define _tcscat wcscat + #else // _UNICODE + #define _sntprintf snprintf // TCHAR* + #define _tcscat strcat + #endif // _UNICODE + #else // __MOBILE_VERSION__ + #ifdef _UNICODE + #define _sntprintf swprintf // TCHAR* + #define _tcscat wcscat + #else // _UNICODE + #define _sntprintf snprintf // TCHAR* + #define _tcscat strcat + #endif // _UNICODE + #endif // __MOBILE_VERSION__ + + #define AF_I32D "%d" + #define AF_I64D "%ld" + #define AF_I32H "%x" + #define AF_I64H "%lx" + + #define F_I32D _T("%d") + #define F_I64D _T("%ld") + #define F_I32U _T("%u") + #define F_I64U _T("%lu") + #define F_I32H _T("%x") + #define F_I64H _T("%lx") + #define F_I32D_03 _T("%03d") + #define F_I32D_06 _T("%06d") + #define F_I64D_03 _T("%03ld") + #define F_I64D_06 _T("%06ld") + + #if defined(_UNICODE) + #if defined(PLATFORM_64) + #define LF_TD L"%ld" + #else // PLATFORM_64 + #define LF_TD L"%d" + #endif // PLATFORM_64 + #endif // _UNICODE + + #if defined( __MOBILE_VERSION__ ) + #define LLOG_PATH L"~/Logs/" + #define LF_I32D L"%d" + #if defined(PLATFORM_64) + #define LF_TU L"%lu" + #define LF_TH L"%lx" + #define LF_TD_03 L"%03ld" + #define LF_TD_06 L"%06ld" + #else // PLATFORM_64 + #define LF_TU L"%u" + #define LF_TH L"%x" + #define LF_TD_03 L"%03d" + #define LF_TD_06 L"%06d" + #endif // PLATFORM_64 + #endif + + #ifndef _UNICODE + #define _acstoi strtol // char* -> int32 + #define _acstoi64 strtol // char* -> int64 + #define _acstoui strtoul // char* -> uint32 + #define _acstoui64 strtoul // char* -> uint64 + #define _acstod strtod // char* -> double + + #define _tcstoi strtol // TCHAR* -> int32 + #define _tcstoi64 strtol // TCHAR* -> int64 + #define _tcstoui strtoul // TCHAR* -> uint32 + #define _tcstoui64 strtoul // TCHAR* -> uint64 + #define _tcstod strtod // TCHAR* -> double + + #define _as16toi strtol // char* (HEX_IMAGE) -> int32 + #else // _UNICODE + #define _acstoi wcstol // char* -> int32 + #define _acstoi64 wcstol // char* -> int64 + #define _acstoui wcstoul // char* -> uint32 + #define _acstoui64 wcstoul // char* -> uint64 + #define _acstod wcstod // char* -> double + + #define _tcstoi wcstol // TCHAR* -> int32 + #define _tcstoi64 wcstol // TCHAR* -> int64 + #define _tcstoui wcstoul // TCHAR* -> uint32 + #define _tcstoui64 wcstoul // TCHAR* -> uint64 + #define _tcstod wcstod // TCHAR* -> double + + #define _as16toi wcstol // char* (HEX_IMAGE) -> int32 + #endif // _UNICODE + + #if defined(PLATFORM_64) + #define _acstot _acstoi64 // char* -> ptrdiff_t + #define _acstout _acstoui64 // char* -> size_t + #define _tcstot _tcstoi64 // TCHAR* -> ptrdiff_t + #define _tcstout _tcstoui64 // TCHAR* -> size_t + + #define AF_TD AF_I64D + #define AF_TH AF_I64H + + #define F_TD F_I64D + #define F_TU F_I64U + #define F_TH F_I64H + #define F_TD_03 F_I64D_03 + #define F_TD_06 F_I64D_06 + #else // PLATFORM_64 + #define _acstot _acstoi // char* -> ptrdiff_t + #define _acstout _acstoui // char* -> size_t + #define _tcstot _tcstoi // TCHAR* -> ptrdiff_t + #define _tcstout _tcstoui // TCHAR* -> size_t + + #define AF_TD AF_I32D + #define AF_TH AF_I32H + + #define F_TD F_I32D + #define F_TU F_I32U + #define F_TH F_I32H + #define F_TD_03 F_I32D_03 + #define F_TD_06 F_I32D_06 + #endif // PLATFORM_64 + +//#ifndef _MSC_VER + + #define _tcsrev reverse_string + + inline TCHAR *reverse_string( TCHAR *s ) { + size_t len = _tcslen( s ); + + if ( len > 1 ) { + TCHAR *a = s; + TCHAR *b = s + len - 1; + + for (; a < b; ++a, --b) { + TCHAR _save = *a; *a = *b; *b = _save; + } + } + return s; + } +//#endif // _MSC_VER + +#else // C3D_WINDOWS + + //////////////////////////////////////////////////////////////////////////////////////////// + // + // \ru Функции конвертации чисел в строку и обратно \en Functions for the convertation of numbers to strings and strings to numbers + // + //////////////////////////////////////////////////////////////////////////////////////////// + #define _saprintf sprintf // char* + // #define _sntprintf // TCHAR* + #define F_I32D _T("%d") + #define F_I64D _T("%I64d") + #define F_I32U _T("%u") + #define F_I64U _T("%I64u") + #define F_I32H _T("%x") + #define F_I64H _T("%I64x") + #define F_I32D_03 _T("%03d") + #define F_I32D_06 _T("%06d") + #define F_I64D_03 _T("%03I64d") + #define F_I64D_06 _T("%06I64d") + + #define AF_I32D "%d" + #define AF_I64D "%I64d" + #define AF_I32U "%u" + #define AF_I64U "%I64u" + #define AF_I32H "%x" + #define AF_I64H "%I64x" + #define AF_I32D_03 "%03d" + #define AF_I32D_06 "%06d" + #define AF_I64D_03 "%03I64d" + #define AF_I64D_06 "%06I64d" + +#if defined(PLATFORM_64) + #define AF_TD AF_I64D + #define AF_TH AF_I64H +#else + #define AF_TD AF_I32D + #define AF_TH AF_I32H +#endif + + #define _acstoi strtol // char* -> int32 +#ifdef __BORLANDC__ + #define _acstoi64 strtoll // char* -> int64 (long long) + #define _acstoui64 strtoull // char* -> uint64 (unsigned long long) + #define _tcstoi64 wcstoll // TCHAR* -> int64 (long long) + #define _tcstoui64 wcstoull // TCHAR* -> uint64 (unsigned long long) + //#define _tcstod // TCHAR* -> double +#else + #define _acstoi64 _strtoi64 // char* -> int64 + #define _acstoui64 _strtoui64 // char* -> uint64 +#endif + #define _acstoui strtoul // char* -> uint32 + #define _acstod strtod // char* -> double + + #define _tcstoi _tcstol // TCHAR* -> int32 + #define _tcstoui _tcstoul // TCHAR* -> uint32 + + #define _as16toi strtol // char* (HEX_IMAGE) -> int32 + + #if defined(PLATFORM_64) + #define _acstot _acstoi64 // char* -> ptrdiff_t + #define _acstout _acstoui64 // char* -> size_t + #define _tcstot _tcstoi64 // TCHAR* -> ptrdiff_t + #define _tcstout _tcstoui64 // TCHAR* -> size_t + + #define F_TD F_I64D + #define F_TU F_I64U + #define F_TH F_I64H + #define F_TD_03 F_I64D_03 + #define F_TD_06 F_I64D_06 + #else // PLATFORM_64 + #define _acstot _acstoi // char* -> ptrdiff_t + #define _acstout _acstoui // char* -> size_t + #define _tcstot _tcstoi // TCHAR* -> ptrdiff_t + #define _tcstout _tcstoui // TCHAR* -> size_t + + #define F_TD F_I32D + #define F_TU F_I32U + #define F_TH F_I32H + #define F_TD_03 F_I32D_03 + #define F_TD_06 F_I32D_06 + #endif // PLATFORM_64 +#endif //C3D_WINDOWS + + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ +/** \brief \ru Определение строки для модуля ядра C3D. + \en Definition of the string used by the C3D kernel. \~ + \ingroup Base_Tools_String +*/ +typedef std::basic_string string_t; +typedef TCHAR mt_char; +typedef string_t mt_string; + +#ifdef C3D_WINDOWS //_MSC_VER +typedef string_t path_string; +#else +typedef std::string path_string; +#endif + + +#ifdef _UNICODE +typedef std::wofstream t_ofstream; +typedef std::wifstream t_ifstream; +#else // _UNICODE +typedef std::ofstream t_ofstream; +typedef std::ifstream t_ifstream; +#endif // _UNICODE + + +typedef std::vector StringTVector; +typedef std::vector& StringTVectorRef; +typedef const std::vector& StringTVectorCRef; +typedef string_t& StringTRef; +typedef const string_t& StringTCRef; + +typedef path_string& PathStringRef; +typedef const path_string& PathStringCRef; + + +//------------------------------------------------------------------------------ +/** \brief \ru Размер строки в памяти. + \en Memory allocated by string. \~ + \ingroup Base_Tools_String +*/ +inline size_t size_of( string_t s ) +{ + size_t size = sizeof( string_t ); + size += s.length() * sizeof(TCHAR); + return size; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования мультибайтовой строки к строке с широким символом. + \en String transformation from multibyte to wide-char. \~ + \ingroup Base_Tools_String +*/ +inline std::wstring StdToWString( const std::string & s ) { + std::wstring result; + if ( !s.empty() ) { + wchar_t * str = mbsnewwcs( s.c_str() ); + if ( str ) + result.assign( str ); + delete [] str; + } + return result; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки с широким символом к мультибайтовой. + \en String transformation from wide-char to multibyte. \~ + \ingroup Base_Tools_String +*/ +inline std::string WToStdString( const std::wstring & s ) { + std::string result; + if ( !s.empty() ) { + char* str = wcsnewmbs( s.c_str() ); + if ( str ) + result.assign( str ); + delete [] str; + } + return result; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к формату C3D. + \en String transformation to the C3D form. \~ + \ingroup Base_Tools_String +*/ +inline string_t ToC3Dstring( const std::string & s ) +{ +#ifdef _UNICODE + return StdToWString(s); +#else // _UNICODE + return s.empty() ? string_t() : s.c_str(); +#endif // _UNICODE +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline std::string ToSTDstring( const string_t & s ) +{ +#ifdef _UNICODE + return WToStdString(s); +#else // _UNICODE + return s.empty() ? std::string() : s.c_str(); +#endif // _UNICODE +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к формату C3D. + \en String transformation to the C3D form. \~ + \ingroup Base_Tools_String +*/ +inline string_t ToC3Dstring( const std::wstring & s ) +{ +#ifdef _UNICODE + return s.empty() ? string_t() : s.c_str(); +#else // _UNICODE + return WToStdString(s); +#endif // _UNICODE +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандратной для пути. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline path_string WToPathstring( const std::wstring & s ) +{ +#ifdef C3D_WINDOWS //_MSC_VER +#ifdef _UNICODE + return s; +#else // _UNICODE + return WToStdString(s); +#endif // _UNICODE + #else + return WToStdString(s); + #endif +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline std::wstring ToWstring( const string_t & s ) +{ +#ifdef _UNICODE + return s.empty() ? std::wstring() : s.c_str(); +#else // _UNICODE + return StdToWString(s); +#endif // _UNICODE +} + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline std::string PathToSTDstring( const path_string & s ) +{ +#ifdef _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return WToStdString(s); + #else // C3D_WINDOWS + return s; + #endif // C3D_WINDOWS +#else // _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return s; + #else // C3D_WINDOWS + return s; + #endif // C3D_WINDOWS +#endif // _UNICODE +} + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline string_t PathToC3Dstring( const path_string & s ) +{ +#ifdef _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + /*string_t result; + if ( !s.empty() ) { + char* str = wcsnewmbs( s.c_str() ); + if ( str ) + result.assign( str ); + delete [] str; + } + return result;*/ + return s; + #else // C3D_WINDOWS + return ToC3Dstring( s ); + #endif // C3D_WINDOWS +#else // _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return s; + #else // C3D_WINDOWS + return s; + #endif // C3D_WINDOWS +#endif // _UNICODE +} + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline path_string StdToPathstring( const std::string & s ) +{ +#ifdef _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return StdToWString(s); + #else // C3D_WINDOWS + return s; + #endif // C3D_WINDOWS +#else // _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return s; + #else // C3D_WINDOWS + return s; + #endif // C3D_WINDOWS +#endif // _UNICODE +} + +//------------------------------------------------------------------------------ +/** \brief \ru Функция преобразования строки к стандартной. + \en String transformation to the standard form. \~ + \ingroup Base_Tools_String +*/ +inline path_string C3DToPathstring( const string_t & s ) +{ +#ifdef _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return s; + #else // C3D_WINDOWS + return ToSTDstring( s ); + #endif // C3D_WINDOWS +#else // _UNICODE + #ifdef C3D_WINDOWS //_MSC_VER + return s; + #else // C3D_WINDOWS + return ToSTDstring( s ); + #endif // C3D_WINDOWS +#endif // _UNICODE +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Перевести символы в нижний регистр. + \en convert symbols to lower case. \~ + \ingroup Base_Tools_String +*/ +inline void ToLower( ::std::string & v ) { + for( size_t i = 0, sz = v.size(); i < sz; i++ ) + v[i] = char(tolower( v[i] )); +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Перевести символы в нижний регистр. + \en convert symbols to lower case. \~ + \ingroup Base_Tools_String +*/ +inline void ToLower( ::std::wstring & v ) { + for( size_t i = 0, sz = v.size(); i < sz; i++ ) + v[i] = towlower( v[i] ); +} + + +} // namespace C3D + + +#endif // __TOOL_CSTRING_H diff --git a/C3d/Include/tool_enabler.h b/C3d/Include/tool_enabler.h new file mode 100644 index 0000000..58c8372 --- /dev/null +++ b/C3d/Include/tool_enabler.h @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Включатель модулей ядра. + \en Kernel modules enabler \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _TOOL_ENABLER_H_ +#define _TOOL_ENABLER_H_ + +#include + + +//------------------------------------------------------------------------------ +/** \brief \ru Включить модули ядра. + \en Enable kernel modules. \~ + \details \ru Включить соответствующие модули ядра. + \en Enable the corresponding kernel modules. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (void) EnableMathModules( const char * name, int nameLength, const char * key, int keyLength ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить ключ активации на валидность. + \en Verify key. \~ + \details \ru Проверить ключ активации на валидность. + \en Verify key. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) VerifyLicenseKey( const char * name, const char * key, const char * pub_key ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить контроллер защиты моделировщика. + \en Check the controller of the Modeler. \~ + \details \ru Проверить контроллер защиты моделировщика. + \en Check the controller of the Modeler. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) IsMathModelerEnable(); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить контроллер защиты конвертеров. + \en Check the controller of the Converter. \~ + \details \ru Проверить контроллер защиты конвертеров. + \en Check the controller of the Converter. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) IsMathConverterEnable(); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить контроллер защиты решателя. + \en Check the controller of the Solver. \~ + \details \ru Проверить контроллер защиты решателя. + \en Check the controller of the Solver. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) IsMathSolverEnable(); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить контроллер защиты визуализатора. + \en Check the controller of the Vision. \~ + \details \ru Проверить контроллер защиты визуализатора. + \en Check the controller of the Vision. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) IsMathVisionEnable(); + + +//------------------------------------------------------------------------------ +/** \brief \ru Проверить контроллер защиты преобразователя сеток в BRep. + \en Check the controller of the BShaper. \~ + \details \ru Проверить контроллер защиты преобразователя сеток в BRep. + \en Check the controller of the BShaper. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (bool) IsMathBShaperEnable(); + + +//------------------------------------------------------------------------------ +/** \brief \ru Отпустить контролера работы модулей ядра. + \en Free the controller of the kernel modules work. \~ + \details \ru Отпустить контролера работы модулей ядра. + \en Free the controller of the kernel modules work. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC (void) FreeMathModulesChecker(); + + +#endif // _TOOL_ENABLER_H_ diff --git a/C3d/Include/tool_err_handling.h b/C3d/Include/tool_err_handling.h new file mode 100644 index 0000000..40f98ba --- /dev/null +++ b/C3d/Include/tool_err_handling.h @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Сервис для обработки ошибок. + \en Error-handling services. \~ +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_ERR_HANDLING_H +#define __TOOL_ERR_HANDLING_H + +#include + + +//------------------------------------------------------------------------------ +/** + \brief \ru Определение режима обработки исключений. + \en Definition of mode for exception handling. \~ + \details \ru Определяет, пробрасывать ли исключение дальше после его обработки. По умолчанию исключения подавляются. \n + \en Defines, whether to throw exception further after its processing. By default, exceptions are suppressed. \~ + \ingroup Base_Tools +*/ +//--- +class MATH_CLASS ExceptionMode +{ + static bool sExptEnabled; +public: + // \ru Установить режим обработки исключений: true, чтобы пробрасывать исключения дальше; false, чтобы подавлять исключения. + // Возвращает предыдущий режим. + // \en Set mode for exception handling: true - to throw exceptions further; false - to suppress exceptions. + // Return the previous mode. + static bool Enable( bool enabled = true ); + + // \ru Получить текущий режим обработки исключений (true - пробрасывать исключение дальше; false - нет). + // \en Get current exception handling mode (true - to throw exception further; false - to not throw). + static bool IsEnabled(); +}; + +//------------------------------------------------------------------------------ +/** + \brief \ru Меняет режим обработки исключений в области видимости. + \en Alter mode for exception handling in a scope. \~ + \ingroup Base_Tools +*/ +//--- +class MATH_CLASS ScopedExceptionMode +{ + bool m_oldMode; +public: + ScopedExceptionMode( bool mode = true ) { m_oldMode = ExceptionMode::Enable( mode ); } + ~ScopedExceptionMode() { ExceptionMode::Enable( m_oldMode ); } +}; + + +//------------------------------------------------------------------------------ +/** + \brief \ru Бросить указанное исключение, если режим позволяет. + \en Throw the specified exception if allowed by the exception mode. \~ + \ingroup Base_Tools +*/ +//--- +#define C3D_CONTROLED_THROW_EX(expt) if( ExceptionMode::IsEnabled() ) throw expt; + +//------------------------------------------------------------------------------ +/** + \brief \ru Бросить исключение, если режим позволяет. + \en Throw exception if allowed by the mode for exception handling. \~ + \ingroup Base_Tools +*/ +//--- +#define C3D_CONTROLED_THROW if( ExceptionMode::IsEnabled() ) throw; + +#endif // __TOOL_ERR_HANDLING_H diff --git a/C3d/Include/tool_log.h b/C3d/Include/tool_log.h new file mode 100644 index 0000000..7001f1c --- /dev/null +++ b/C3d/Include/tool_log.h @@ -0,0 +1,124 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Логирование информации. + \en Information logging. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_LOG_H +#define __TOOL_LOG_H + +#include +#include +#include + +//------------------------------------------------------------------------------ +// \ru Потокобезопасные интерфейсы для ведение журнала сообщений и записи его в файл. +// Для каждого потока ведется отдельный лог, который записывается в отдельный файл. +// Доступны в дебаге. +// \en Thread-safe interfaces for logging messages and writing the log to the file. +// Keep a separate log for each thread which is saved to a separate file. +// Available in debug configuration. +// +/* \ru Пример использования. \en Usage sample. + int k = 0; + START_LOGGING; // \ru Начинаем логирование. \en Start logging. + LOG_MSG( _T("Samplelog") ); // \ru Добавляем указанную строку в лог. \en Put a specified string to the log. + ... + // \ru Форматируем строку лога (оператор << Logger::Endl добавляет ее в лог). \en Format a log line (operator << Logger::Endl puts it to the log). + Logger::Get() << _T("Value ") << k << Logger::Endl; + ... + WRITE_LOG_FILE( _T("sample.log") ); // \ru Записываем лог в файл. \en Write the log to the file. + END_LOGGING; // \ru Заканчиваем логирование. \en Stop logging. +*/ +// --- +#ifdef C3D_DEBUG + +//------------------------------------------------------------------------------ +// \ru Класс позволяет форматировать строку для лога и добавлять ее в лог. +// \en Class allows to format a line to the log and put it to the log. +// --- +class MATH_CLASS Logger +{ +public: + // \ru Получить логгер. \en Get the logger. + static Logger& Get(); + + // \ru Следующие методы позволяют форматировать строку для лога. Работают с текущей строкой лога. + // \en Next methods allow to format a line to the log. Work with the current line of the log. + + // \ru Добавить строку в текущую строку лога. \en Add a string to the current line of the log. + virtual Logger& operator << ( const TCHAR * ) = 0; + // \ru Добавить integer в текущую строку лога. \en Add integer to the current line of the log. + virtual Logger& operator << ( const int & ) = 0; +#if defined(PLATFORM_64) // \ru x32 совпадение типов ptrdiff_t и int \en x32 coincidence of ptrdiff_t and int types + // \ru Добавить ptrdiff_t в текущую строку лога. \en Add ptrdiff_t to the current line of the log. + virtual Logger& operator << ( const ptrdiff_t & ) = 0; +#endif + // \ru Добавить size_t в текущую строку лога. \en Add size_t to the current line of the log. + virtual Logger& operator << ( const size_t & ) = 0; + // \ru Добавить double в текущую строку лога. \en Add double to the current line of the log. + virtual Logger& operator << ( const double & ) = 0; + // \ru Завершить форматирование текущей строки и добавить ее в лог. Следующий вызов оператора << создаст новую текущую строку. + // \en Finish formatting of the current line and add it to the log. Next call to the operator << will create new current line. + virtual Logger& operator << ( Logger& (*man)( Logger& ) ) = 0; + + // \ru Манипулятор-признак завершения форматирования текущей строки лога. + // \en Manipulator-indicator of finishing formatting of the current line of the log. + static Logger& Endl( Logger& ); +}; + +// \ru Начать или закончить логирование. \en Start or stop logging. +MATH_FUNC(void) SetLogging( bool allow ); + +// \ru Записать лог в файл. Лог для каждого потока записывается в отдельный файл. +// \en Write the log to the file. Log of each thread writes to a separate file. +MATH_FUNC(void) WriteLog( const TCHAR *fileName ); + +// \ru Записать указанную строку в лог. \en Write a specified string to the log. +MATH_FUNC(void) LogMessage( const c3d::string_t &msg ); + +// \ru Макросы для операций логирования. \en Logging macros. + +// \ru Начать логирование. \en Start logging. +#define START_LOGGING SetLogging( true ); +// \ru Закончить логирование. \en Stop logging. +#define END_LOGGING SetLogging( false ); +// \ru Положить форматированную строку в лог. \en Put a formatted string to the log. +#define LOG_MSG(msg) LogMessage( msg ); +// \ru Записать лог в файл. Лог для каждого потока записывается в отдельный файл. +// \en Write the log to the file. Log of each thread writes to a separate file. +#define WRITE_LOG_FILE(fileName) WriteLog( fileName ); + +#else +inline void CALL_DECLARATION SetLogging( bool ){} +inline void CALL_DECLARATION WriteLog( const TCHAR * ){} +inline void CALL_DECLARATION LogMessage( const c3d::string_t & ){} + +#define START_LOGGING +#define END_LOGGING +#define LOG_MSG(msg) +#define WRITE_LOG_FILE(fileName) + +#endif + + +namespace c3d //namespace c3d +{ + +//------------------------------------------------------------------------------ +/** \brief \ru Включить контроль утечек памяти. + \en Enable memory leakage control. \~ + \details \ru Включить контроль утечек памяти. + \en Enable memory leakage control. \~ + \ingroup Base_Tools +*/ +// --- +MATH_FUNC(void) EnableMemoryLeakDump(); + +} //namespace c3d + + +#endif // __TOOL_LOG_H diff --git a/C3d/Include/tool_memory_debug.h b/C3d/Include/tool_memory_debug.h new file mode 100644 index 0000000..9f6d8b9 --- /dev/null +++ b/C3d/Include/tool_memory_debug.h @@ -0,0 +1,421 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Контроль выделения памяти под отладкой. + \en Memory allocation control during the debugging process. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __MEMORY_DEBUG_H +#define __MEMORY_DEBUG_H + +//#define __DEBUG_MEMORY_ALLOCATE_FREE_ +//#define __MEMSET_USED_FREE_HEAP_HEAR__ +//#define __REALLOC_ARRAYS_STATISTIC_ + +#include +#include +#include + +#ifdef C3D_DEBUG + #if defined(C3D_MacOS) // mac + #include + #elif defined(C3D_FreeBSD) + #include + #else + #include + #endif // mac + + #ifndef __DISABLE_MEMORY_CONTROL__ // \ru Чтобы можно было отключать в других проектах \en To allow to disable it in other projects + #ifndef __BORLANDC__ + #define USE_REALLOC_IN_ARRAYS // no _aligned_realloc in bcc32c + #endif + #endif // __DISABLE_MEMORY_CONTROL__ +#endif // C3D_DEBUG + +#ifdef __REALLOC_ARRAYS_STATISTIC_ +//#include +#include +#include +#endif + + +#ifdef __DEBUG_MEMORY_ALLOCATE_FREE_ + +//------------------------------------------------------------------------------ +/// \ru Проверить указатель и значение. \en Check pointer and value. \~ \ingroup Base_Tools +// --- +inline void CheckPointerAndValue( void * ptr, size_t size ) +{ +#if defined (C3D_WINDOWS) && !defined(ALL_WARNINGS) //_MSC_VER // Set warnings level +#pragma warning(disable: 4312) +#endif + C3D_ASSERT( ptr != (ptrdiff_t *)0xEEEEEEEE ); + C3D_ASSERT( ptr != (ptrdiff_t *)0xFFFFFFFF ); +#if defined (C3D_WINDOWS) && !defined(ALL_WARNINGS) //_MSC_VER // Set warnings level +#pragma warning(default: 4312) +#endif + + if ( ptr ) { + // \ru Надо доработать для 64-бит \en It should be adapted for the 64-bit version + if ( size > 11 ) { + uint32* _ptr = (uint32 *)ptr; + uint32 value1 = *_ptr++; + uint32 value2 = *_ptr++; + uint32 value3 = *_ptr; + C3D_ASSERT( value1 != 0xEEEEEEEE || value2 != 0xEEEEEEEE || value3 != 0xEEEEEEEE ); + C3D_ASSERT( value1 != 0xFFFFFFFF || value2 != 0xFFFFFFFF || value3 != 0xFFFFFFFF ); + } + else if ( size > 7 ) { + uint32 * _ptr = (uint32 *)ptr; + uint32 value1 = *_ptr++; + uint32 value2 = *_ptr; + C3D_ASSERT( value1 != 0xEEEEEEEE && value2 != 0xEEEEEEEE ); + C3D_ASSERT( value1 != 0xFFFFFFFF || value2 != 0xFFFFFFFF ); + } + else if ( size > 3 ) { + uint32 value = *(uint32 *)ptr; + C3D_ASSERT( value != 0xEEEEEEEE ); + C3D_ASSERT( value != 0xFFFFFFFF ); + } + else if ( size > 1 ) { + uint16 value = *(uint16 *)ptr; + C3D_ASSERT( value != 0xEEEE ); + C3D_ASSERT( value != 0xFFFF ); + } + } +} + +//------------------------------------------------------------------------------ +/// \ru Выделить память указанного размера. \en Allocate memory of the given size. \~ \ingroup Base_Tools +// --- +inline void * Allocate( size_t size, const char * ) // className ) +{ + void * ptr = ::malloc( size ); + // \ru Дабы работал _msize: void * ptr = ::operator new( size ); \en For working of _msize: void * ptr = ::operator new( size ); + + if ( ptr ) { + ::memset( ptr, 0xFF, size ); + } + return ptr; +} + +//------------------------------------------------------------------------------ +/// \ru Выделить память указанного размера под массив. \en Allocate memory of the given size for an array. \~ \ingroup Base_Tools +// --- +inline void * AllocateArray( size_t size, const char * ) // className ) +{ + void * ptr = ::malloc( size ); + // \ru Дабы работал _msize: void *ptr = ::operator new [] ( size ); \en For working of _msize: void *ptr = ::operator new [] ( size ); + + if ( ptr ) { +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ + ::memset( ptr, 0xFFFFFFFF, size ); // \ru OV - надо доработать для 64-бит \en OV - it should be adapted for the 64-bit version +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ + } + return ptr; +} + +//------------------------------------------------------------------------------ +/// \ru Освободить память указанного размера. \en Free memory of the given size. \~ \ingroup Base_Tools +// --- +inline void Free( void * ptr, size_t size, const char * ) // className ) +{ + if ( ptr ) { + ::CheckPointerAndValue( ptr, size ); + +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ + size_t ptr_size = ::_msize( ptr ); + C3D_ASSERT( ptr_size > 0 && ptr_size < 0xFFFFFFFF ); // \ru Надо доработать для 64-бит. \en It should be adapted for the 64-bit version. + if ( ptr_size ) { + C3D_ASSERT( size <= ptr_size ); + ::memset( ptr, 0xEE, ptr_size ); + } +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ + + ::free( ptr ); + } +} + +//------------------------------------------------------------------------------ +/// \ru Освободить память, выделенную под массив. \en Free the memory allocated for the array. \~ \ingroup Base_Tools +// --- +// \ru ЯТ можно перегрузить в классах operator delete [] ( void *, size_t ) и передать \en ЯТ it is pertinent to overload the operator delete [] ( void *, size_t ) and pass +// \ru в эту функцию size_t size, но это будет не размер массива, а размер Type, \en to this function size_t size, but this will be not the size of an array but the size of 'Type', +// \ru массив которых распределялся. То есть эта информация здесь не нужна (делать \en an array of which was not distribute. I.e. this information is not needed here ( +// \ru ::memset не нее НЕЛЬЗЯ!) \en it is forbidden to do ::memset here) +// --- +inline void FreeArray( void * ptr, const char * ) // className ) +{ + if ( ptr ) { + ::CheckPointerAndValue( ptr, 0/*size*/ ); + +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ + size_t size = ::_msize( ptr ); + C3D_ASSERT( size > 0 && size < 0xFFFFFFFF ); // \ru OV - надо доработать для 64-бит \en OV - it should be adapted for the 64-bit version + ::CheckPointerAndValue( ptr, size ); + if ( size ) + ::memset( ptr, 0xEE, size ); +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ + + ::free( ptr ); + } +} + +#endif // __DEBUG_MEMORY_ALLOCATE_FREE_ + + +#ifdef __REALLOC_ARRAYS_STATISTIC_ + +struct OneArrayTypeStatistic { +public: + size_t reallocCountSuccess; // \ru кол-во успешных перераспределений памяти \en A number of successfully reallocations of the memory + size_t firstAlloc ; // \ru кол-во первичных распределений \en the number of primary allocations + size_t lastAlloc ; // \ru кол-во освобождений \en the number of releases + size_t realAllocIncremet ; // \ru кол-во запросов на увеличение \en the number of requests for an increment + size_t realAllocDecremet ; // \ru кол-во запросов на уменьшение \en the number of requests for a decrement + size_t fullLength ; // \ru суммарный размер в байтах \en the total size in bites + size_t maxOneArrayLength ; // \ru максимальный размер одного массива \en the minimal size of one array + size_t sumCurrLength ; // \ru суммарный размер памяти во всех массивах этого типа в данный момент \en the total size of the memory in all arrays of this type at this moment + size_t maxOneTimeLength ; // \ru максимальный одновременный размер памяти во всех массивах этого типа \en the maximum simultaneous size of the memory in all arrays of this type + size_t minDelta ; // \ru минимальное приращение \en minimum increment + size_t maxDelta ; // \ru максимальное приращение \en maximum increment +public: + OneArrayTypeStatistic() { Clear(); } + void Clear() { + reallocCountSuccess = 0; + firstAlloc = 0; + lastAlloc = 0; + realAllocIncremet = 0; + realAllocDecremet = 0; + fullLength = 0; + maxOneArrayLength = 0; + sumCurrLength = 0; + maxOneTimeLength = 0; + minDelta = SYS_MAX_T; // \ru минимальное приращение \en minimum increment + maxDelta = 0; // \ru максимальное приращение \en maximum increment + } +}; + +const size_t STAT_ARRAY_COUNT = 6; +static OneArrayTypeStatistic statisticArray[STAT_ARRAY_COUNT] + = { OneArrayTypeStatistic(), OneArrayTypeStatistic(), OneArrayTypeStatistic(), + OneArrayTypeStatistic(), OneArrayTypeStatistic(), OneArrayTypeStatistic() }; + +static size_t allReallocCount = 0; + +//------------------------------------------------------------------------------ +// \ru Уменьшение uint с проверкой \en A decrement of uint with the check +// --- +inline void DecrementUint( size_t & val, size_t delta ) { + val = (delta < val) ? (val - delta) : 0; +} + +//------------------------------------------------------------------------------ +/// \ru Статистика изменений размера массива. \en Statistics of array size changes. \~ \ingroup Base_Tools +// arrayType : +// \ru 0 - SArray (или наследники), \en 0 -SAray (or inheritors) +// \ru 1 - RParray (или наследники), \en 1 -RPAray (or inheritors) +// 2 - Array2, +// 3 - LiSArray, +// 4 - CcArray, +// \ru 5 - неопознанные (вообще-то, такого не должно быть) \en 5 - not defined (it should not happen) +// --- +inline void ReallocArrayStatistic( void * oldParr, size_t oldSize, + void * newParr, size_t newSize, + uint arrayType ) +{ + if ( oldParr || newSize ) { + allReallocCount++; + + // \ru найдем статистическую запись про данный тип массива \en find a statistic record about the given type of array + size_t index = (size_t)arrayType; + if ( index >= STAT_ARRAY_COUNT ) + index = STAT_ARRAY_COUNT - 1; + OneArrayTypeStatistic & stat = statisticArray[index]; + + if ( newSize > stat.maxOneArrayLength ) + stat.maxOneArrayLength = newSize; + + if ( !oldParr ) { // \ru первичное распределение \en primary allocation + stat.firstAlloc++; + stat.fullLength += newSize; // \ru общее кол-во байт в этом типе массива \en the total number of bites in this type of an array + stat.sumCurrLength += newSize; // \ru суммарный размер памяти во всех массивах этого типа в данный момент \en the total size of the memory in all arrays of this type at this moment + } + + if ( oldParr && !newSize ) { // \ru полное освобождение \en full release + stat.lastAlloc++; + // \ru максимальный одновременный размер памяти во всех массивах этого типа \en the maximum simultaneous size of the memory in all arrays of this type + if ( stat.sumCurrLength > stat.maxOneTimeLength ) + stat.maxOneTimeLength = stat.sumCurrLength; + // \ru суммарный размер памяти во всех массивах этого типа в данный момент \en the total size of the memory in all arrays of this type at this moment + ::DecrementUint( stat.sumCurrLength, oldSize ); + } + + if ( oldParr && newSize > oldSize ) { // \ru запрос на увеличение \en a request to increase + stat.realAllocIncremet++; + size_t delta = newSize - oldSize; + stat.fullLength += delta; // \ru общее кол-во байт в этом типе массива \en the total number of bites in this type of an array + stat.sumCurrLength += delta; // \ru суммарный размер памяти во всех массивах этого типа в данный момент \en the total size of the memory in all arrays of this type at this moment + + if ( delta < stat.minDelta ) + stat.minDelta = delta; // \ru минимальное приращение \en minimum increment + if ( delta > stat.minDelta ) + stat.maxDelta = delta; // \ru максимальное приращение \en maximum increment + } + + if ( oldParr && newSize && newSize < oldSize ) { // \ru запрос на уменьшение \en a request to decrease + stat.realAllocDecremet++; + // \ru максимальный одновременный размер памяти во всех массивах этого типа \en the maximum simultaneous size of the memory in all arrays of this type + if ( stat.sumCurrLength > stat.maxOneTimeLength ) + stat.maxOneTimeLength = stat.sumCurrLength; + // \ru суммарный размер памяти во всех массивах этого типа в данный момент \en the total size of the memory in all arrays of this type at this moment + ::DecrementUint( stat.sumCurrLength, oldSize - newSize ); + } + +#ifdef USE_REALLOC_IN_ARRAYS + if ( oldParr && oldParr == newParr && newSize != oldSize ) + stat.reallocCountSuccess++; +#endif // USE_REALLOC_IN_ARRAYS + } +} + + +//------------------------------------------------------------------------------ +/// \ru Отчет по статистике изменений размера массива. \en A report by the statistics of array size changes. \~ \ingroup Base_Tools +// --- +inline void ReallocReport( bool clear, const char * title = NULL ) +{ + std::string text( title ); + + if ( text.length() > 0 ) + text.append( "\n" ); + + char buf[256]; + ::sprintf( buf, "Общее кол-во realloc %d", ::LoUint32( allReallocCount ) ); + text.append( buf ); + + for ( size_t i = 0; i < STAT_ARRAY_COUNT; i++ ) { + OneArrayTypeStatistic & stat = statisticArray[i]; + + // \ru если данных нет, то и писать про них не будем \en if there is no data then we will not write about it + if ( stat.firstAlloc || stat.lastAlloc || stat.realAllocIncremet || stat.realAllocDecremet ) { + + switch ( i ) { + case 0 : text.append( "\n\n SArray (или наследники)" ); break; + case 1 : text.append( "\n\n RParray (или наследники)" ); break; + case 2 : text.append( "\n\n Array2" ); break; + case 3 : text.append( "\n\n LiSArray (или наследники)" ); break; + case 4 : text.append( "\n\n CcArray" ); break; + case 5 : text.append( "\n\n неопознанные" ); break; + } + + ::sprintf( buf, "\n всего байт \t %d", ::LoUint32( stat.fullLength ) ); + text.append( buf ); + ::sprintf( buf, "\n макс.размер \t %d", ::LoUint32( stat.maxOneArrayLength ) ); + text.append( buf ); + ::sprintf( buf, "\n первичных \t %d", ::LoUint32( stat.firstAlloc ) ); + text.append( buf ); + ::sprintf( buf, "\n освобождений \t %d", ::LoUint32( stat.lastAlloc ) ); + text.append( buf ); + if ( stat.realAllocIncremet ) { + ::sprintf( buf, "\n на увеличение \t %d", ::LoUint32( stat.realAllocIncremet ) ); + text.append( buf ); + } + if ( stat.realAllocDecremet ) { + ::sprintf( buf, "\n на уменьшение \t %d", ::LoUint32( stat.realAllocDecremet ) ); + text.append( buf ); + } +#ifdef USE_REALLOC_IN_ARRAYS + if ( stat.reallocCountSuccess ) { + ::sprintf( buf, "\n удачных realloc \t %d", ::LoUint32( stat.reallocCountSuccess ) ); + text.append( buf ); + } +#endif + ::sprintf( buf, "\n max одновременно %d", ::LoUint32( stat.maxOneTimeLength ) ); + text.append( buf ); + if ( stat.realAllocIncremet ) { + ::sprintf( buf, "\n Delta (min, max) \t %d, %d", ::LoUint32( stat.minDelta ), ::LoUint32( stat.maxDelta ) ); + text.append( buf ); + } + } + } + + { + const char * outName = "C:\\Logs\\ADRAFT_TTEST.txt"; + std::ofstream out( outName, std::ios::out|std::ios::app ); + out << "\n Статистика использования памяти \n"; + //out << text; + out << "\n"; + } + + if ( clear ) { + // \ru очистить, чтобы в следующий раз цифры были новые, а не накопленные \en clear to renew numbers + allReallocCount = 0; + for ( size_t i = 0; i < STAT_ARRAY_COUNT; i++ ) + statisticArray[i].Clear(); + } +} + +#endif // __REALLOC_ARRAYS_STATISTIC_ + + +//------------------------------------------------------------------------------ +// \ru Использовать realloc для изменения размера массивов \en Use realloc to change arrays sizes +// \ru (если не определено, то по-старому, через new и delete) \en (if it is not defined then use new and delete operators) +//--- +#ifdef USE_REALLOC_IN_ARRAYS + +#ifdef C3D_DEBUG + +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ +//------------------------------------------------------------------------------ +/// \ru Функция перезахватов памяти в массивах. \en Function of memory reallocation in arrays. \~ \ingroup Base_Tools +// --- +inline void * ReallocArraySize( void * arr_parr, size_t newBytesCount, bool clear ) +#else // __MEMSET_USED_FREE_HEAP_HEAR__ +//------------------------------------------------------------------------------ +/// \ru Функция перезахватов памяти в массивах. \en Function of memory reallocation in arrays. \~ \ingroup Base_Tools +// --- +inline void * ReallocArraySize( void * arr_parr, size_t newBytesCount, bool ) +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ +{ +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ + if ( newBytesCount == 0 || clear ) { + size_t arr_parr_size = ::_msize( arr_parr ); + C3D_ASSERT( arr_parr ? (arr_parr_size > 0 && arr_parr_size < 0xFFFFFFFF) : true ); // \ru OV - надо доработать для 64-бит \en OV - it should be adapted for the 64-bit version + if ( arr_parr_size ) + ::memset( arr_parr, 0xEE, arr_parr_size ); + } +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ + +#if defined( _AFXDLL ) && defined( C3D_DEBUG ) + void * tmp_parr = _realloc_dbg( arr_parr, newBytesCount, _NORMAL_BLOCK, __FILE__, __LINE__ ); +#else + void * tmp_parr = ::realloc( arr_parr, newBytesCount ); +#endif + + PRECONDITION( newBytesCount == 0 || tmp_parr != NULL ); // \ru проверка на нехватку памяти в массивах \en check the memory deficit in arrays + +#ifdef __MEMSET_USED_FREE_HEAP_HEAR__ + if ( clear ) { + size_t tmp_parr_size = ::_msize( tmp_parr ); + C3D_ASSERT( tmp_parr ? (tmp_parr_size > 0 && tmp_parr_size < 0xFFFFFFFF) : true ); // \ru OV - надо доработать для 64-бит \en OV - it should be adapted for the 64-bit version + if ( tmp_parr_size ) + ::memset( tmp_parr, 0xEE, tmp_parr_size ); + } +#endif // __MEMSET_USED_FREE_HEAP_HEAR__ + + return tmp_parr; +} + +#define REALLOC_ARRAY_SIZE(p,s,c) ::ReallocArraySize((p),(s),(c)) +#else // C3D_DEBUG +#define REALLOC_ARRAY_SIZE(p,s,c) ::realloc((p),(s)) +#endif // C3D_DEBUG + +#endif // USE_REALLOC_IN_ARRAYS + + +#endif // __MEMORY_DEBUG_H diff --git a/C3d/Include/tool_memory_leaks_check.h b/C3d/Include/tool_memory_leaks_check.h new file mode 100644 index 0000000..15c452e --- /dev/null +++ b/C3d/Include/tool_memory_leaks_check.h @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Слежение за утечками +/** + \file + \brief Содержит класс MemoryLeaksVerifiable - базовый для контролируемых классов +*/ +// +//////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +#if ( defined(STANDARD_C11) && (_MSC_VER > 1800) ) +#define ENABLE_MEMORY_LEAKS_CHECK +#endif + + +namespace c3d // namespace C3D +{ + +#ifdef ENABLE_MEMORY_LEAKS_CHECK + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый класс для контролируемых классов. + \en . \~ + \details \ru На конструкторе объект регистрируется в менеджере утечек, в деструкторе удаляется из списка зарегистрированных. + Информация о всех объектах, которые остались в регистраторе, будет выведена. \n + \en . \n \~ + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS MemoryLeaksVerifiable +{ +protected: + MemoryLeaksVerifiable(); + virtual ~MemoryLeaksVerifiable(); +}; + +#else + +class MATH_CLASS MemoryLeaksVerifiable {}; + +#endif // ENABLE_MEMORY_LEAKS_CHECK + +} // namespace C3D + + + diff --git a/C3d/Include/tool_memory_leaks_utils.h b/C3d/Include/tool_memory_leaks_utils.h new file mode 100644 index 0000000..cf6659d --- /dev/null +++ b/C3d/Include/tool_memory_leaks_utils.h @@ -0,0 +1,64 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Утилиты Слежения за утечками +/** + \file + \brief Содержит интерфейс MemoryLeaksController - контроллер утечек памяти +*/ +// +//////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + + +namespace c3d // namespace C3D +{ +#ifdef ENABLE_MEMORY_LEAKS_CHECK + +typedef std::unordered_map MemoryLeaksRegisteredData; +typedef std::unique_ptr MemoryLeaksControllerPtr; + +//---------------------------------------------------------------------------------------- +/** \brief \ru Контроллер утечек памяти. + \en Memory Leaks Controller. \~ + \details \ru Контроллер утечек памяти. При выходе из приложения, вызывается метод OnLeakDetect, в который передается информация об утечках. + \en Memory Leaks Controller. When you exit the application, the OnLeakDetect method is called, to which information about leaks is transmitted. \~ + \ingroup Base_Tools +*/ +//--- +struct MemoryLeaksController +{ + MemoryLeaksController() {} + virtual ~MemoryLeaksController() {} + virtual void OnLeakDetect( const MemoryLeaksRegisteredData & ) const = 0; +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Добавить контроллер утечек памяти. + \en Add memory leaks controller. \~ +\ingroup Base_Tools +*/ +// --- +MATH_FUNC( void ) AddController( MemoryLeaksControllerPtr ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Собрать утечки. Необходимо вызвать перед выходом из приложения, чтобы выполнить именование утекающих объектов. + \en Collect leaks. The function should be called before exiting the application to names the leaking objects. \~ +\ingroup Base_Tools +*/ +// --- +MATH_FUNC( void ) CollectLeaks(); + +#else + +MATH_FUNC( void ) CollectLeaks() {} + +#endif // ENABLE_CHECK_MEMLEAK + +} // namespace c3d + diff --git a/C3d/Include/tool_multithreading.h b/C3d/Include/tool_multithreading.h new file mode 100644 index 0000000..fd270a5 --- /dev/null +++ b/C3d/Include/tool_multithreading.h @@ -0,0 +1,490 @@ +//////////////////////////////////////////////////////////////////////////////// +/** +\file +\brief \ru Управление параллельной обработкой данных. + \en Managing of parallel data processing. \~ +\details \ru Управление параллельной обработкой данных.\n + \en Managing of parallel data processing. \n \~ +*/ +//////////////////////////////////////////////////////////////////////////////// +#ifndef __TOOL_MULTITHREADING_H +#define __TOOL_MULTITHREADING_H + +#include +#include + +//------------------------------------------------------------------------------ +/** +\brief \ru Режимы многопоточных вычислений. + \en Multithreading modes. \~ +\details \ru Режимы многопоточных вычислений. \n + \en Multithreading modes. \n \~ +\ingroup Data_Structures +*/ +//--- +enum MbeMultithreadedMode { + // \ru Многопоточность ядра отключена. \en Kernel multithreading is off. + mtm_Off = 0, + // \ru Включена многопоточность ядра при обработке независимых объектов (без общих данных). + // \en Kernel multithreading is ON for independent objects (without common data). + mtm_Standard = 1, + // \ru Обеспечивается потокобезопасность объектов типа MbItem. Выключена многопоточность ядра при обработке объектов, имеющих общие данные. + // \en Ensured thread-safety of objects MbItem. Kernel multithreading is OFF for objects with shared data. + mtm_SafeItems = 2, + // \ru Обеспечивается потокобезопасность объектов типа MbItem. Включена многопоточность ядра при обработке объектов с общими данными. + // \en Ensured thread-safety of objects MbItem. Kernel multithreading is ON for objects with shared data. + mtm_Items = 3, + // \ru Включена максимальная многопоточность ядра. \en Maximal kernel multithreading is ON. + mtm_Max = 31 +}; + +//------------------------------------------------------------------------------ +/** + \brief \ru Базовый класс для объектов, требующих сборки мусора. + \en Base class for objects which require a garbage collection. \~ +\details \ru Базовый класс для объектов, требующих сборки мусора. + Класс, наследующий от CacheCleaner, должен реализовать метод ResetCacheData, + который будет вызываться для сборки мусора. + \en Base class for objects which require a garbage collection. + A class, inheriting from CacheCleaner, should implement the method ResetCacheData, + which will be called for garbage collection. \~ +\ingroup Base_Tools +*/ +//--- +class MATH_CLASS CacheCleaner +{ + int subscribed; +public: + CacheCleaner(); + virtual ~CacheCleaner(); + + /** \brief \ru Подписан ли объект на сборку мусора. + \en Whether the object is subscribed for garbage collection. \~ + */ + bool IsSubscribed() { return subscribed > 0; } + + /** \brief \ru Очистить кэшированные данные. Возвращает true, если объект был отписан от сборки мусора. + \en Reset cached data. Return true if the object was unsubscribed from garbage collection.\~ + */ + virtual bool ResetCacheData() = 0; + + /** \brief \ru Подписаться на сборку мусора. + \en Subscribe for garbage collection. \~ + */ + void SubcribeOnCleaning(); + + /** \brief \ru Отписаться от сборки мусора. + \en Unsubscribe from garbage collection. \~ + */ + void UnsubcribeOnCleaning(); +}; + +//------------------------------------------------------------------------------ +/** + \brief \ru Сборщик мусора в объектах, использующих кэширование данных. + \en Garbage collector in objects which use data caching. \~ +\details \ru Сборщик мусора. По требованию очищает кэши в зарегистрированных объектах CacheCleaner, + вызывая метод ResetCacheData каждого объекта. \n + \en Garbage collector. At request clears caches in registered CacheCleaner objects + by calling the method ResetCacheData of each object. \n \~ +\ingroup Base_Tools +*/ +//--- +class MATH_CLASS MbGarbageCollection +{ +public: + + /** \brief \ru Подписать объект на сборку мусора. + \en Subscribe the object for garbage collection. \~ + */ + static void Subscribe( CacheCleaner * obj ); + + /** \brief \ru Отписать объект от сборки мусора. + \en Unsubscribe the object from garbage collection. \~ + */ + static void Unsubscribe( CacheCleaner * obj ); + + /** \brief \ru Выполнить сборку мусора. \en Perform garbage collection. + \details \ru Выполнить сборку мусора. Должна вызываться в последовательном участке кода. + При вызове в параллельном регионе ничего не делает. + \en Perform garbage collection. Should be called in sequential code. + When called in a parallel region, does nothing. + \param[in] force - \ru Если false, то инициируется сборка мусора в кэшах, созданных для потоков, которые уже завершены, + если true, то инициируется принудительная сборка мусора во всех кэшах. + \en If false, then run garbage collection in caches created for threads which are finished, + if true, then force garbage collection in all caches. + \return \ru Возвращает TRUE, если сборка проведена. \en Returns TRUE if the garbage collection is done. \~ + */ + static bool Run( bool force = false ); + + /** \brief \ru Активировать/деактивировать сбор данных для проведения сборки мусора. + По умолчанию, сбор данных для сборки мусора активирован. + \en Enable/disable collecting data for garbage collection. + By default, collecting data for garbage collection is enabled. \~ + */ + static void Enable( bool allow = true ); +}; + +//------------------------------------------------------------------------------ +// \ru Принудительно вернуть освобожденную динамическую память операционной системе. +// Может быть полезна после выполнения операций с интенсивным использованием памяти. +// \en Force to return freed heap memory to the operating system. +// May be useful after performing memory-intensive operations. +// --- +MATH_FUNC( void ) ReleaseMemory(); + +//------------------------------------------------------------------------------ +/** +\brief \ru Родительский класс данных для менеджера параллельной обработки. + \en Parent class of data for manager of parallel processing. \~ +\details \ru Родительский класс для данных, которые могут обрабатываться параллельно + с помощью менеджера кэшей. + \en Parent class for data which could be processed in parallel using the cache manager. \~ + \ingroup Base_Tools +*/ +// --- +class AuxiliaryData { +public: + AuxiliaryData() {} + AuxiliaryData( const AuxiliaryData & ) {} + virtual ~AuxiliaryData() {} + + /** \brief \ru Объединить с указанными данными. + \en Merge with specified data. + \details \ru Функция вызывается Менеджером кэшей для данных основного потока + с данными каждого многопоточного кэша в качестве параметра. + После завершения функции Менеджер кэшей удаляет многопоточный кэш. + \en The function is called by CacheManager for the main thread data with + each multithreaded cache data as a parameter. When the function completed, + the CacheManager deletes the multithreaded cache. \~ + */ + virtual void MergeWith( AuxiliaryData * ) {} +}; + +//#define CACHE_DELETE_LOCK +//------------------------------------------------------------------------------ +/** +\brief \ru Менеджер параллельной обработки данных (менеджер кэшей) с возможностью пост-обработки кэшей потоков. + \en Manager for parallel data processing (the cache manager) with support of caches post-processing. \~ +\details \ru Менеджер кэшей представляет шаблон, содержащий: + longTerm - данные главного потока при последовательном выполнении и + tcache - список кэшей с данными, которые используются при параллельном выполнении. + Каждый поток по идентификатору threadKey использует только свою копию данных. + Для многопоточной обработки зависимых (имеющих общие данные) объектов должен использоваться режим + многопоточных вычислений не ниже mtm_SafeItems. + Менеджер предоставляет функцию Postprocess() для пост-обработки кэшей, которая вызывается после + выхода из параллельных вычислений. Указанная функция итерируется по кэшам, использованным + при параллельных вычислениях, и вызывает функцию longTerm.MergeWith() с данными каждого кэша + в качестве параметра. После завершения работы функции Postprocess() кэши удаляются. \n + \en The cache manager is a template which contains: + longTerm - data of the main thread in sequential execution, and + tcache - a list of caches with data which are used in parallel calculations. + Each thread uses its own copy of data according to threadKey. + For multithreaded processing of dependent (with shared data) objects the multithreading mode mtm_SafeItems + or higher should be used. + The Manager provides a Postprocess() function for caches post-processing which is called + after exiting parallel computing. The specified function iterates through the caches used + in parallel computing and calls the function longTerm.MergeWith() with the data of the each cache + as a parameter. After the function Postprocess() finished the caches are destroyed. \n \~ +*/ +// --- +template +class CacheManager : public CacheCleaner { + struct List + { + unsigned int _id; + T* _data; + List* _next; + bool _valid; + List( unsigned int id, T* data ) : + _id( id ), + _data( data != NULL ? data : new T() ), // Always _data != NULL. + _next( NULL ), + _valid( true ) {} + ~List() { + if ( _data != NULL ) + delete _data; + _data = NULL; + if ( _next != NULL ) // Also deletes linked List. + delete _next; + _next = NULL; + } + private: + List() : _id( 0 ), _data( NULL ), _next( NULL ) {} + }; + +private: + T* longTerm; // \ru Данные главного потока при последовательном выполнении. \en Data of the main thread in sequential execution. + List* tcache; // \ru Данные, которые используются при параллельном выполнении. \en Caches which are used in parallel execution. + CommonMutex* lock; // \ru Блокировка для операций с кэшами. \en Lock for operations with caches. + +public: +#ifdef CACHE_DELETE_LOCK + CacheManager( bool createLock = false ); +#else + CacheManager( bool createLock = true ); +#endif + CacheManager( const CacheManager & ); + ~CacheManager(); + + /** \brief \ru Оператор (). Возвращает указатель на кэш (данные) текущего потока. Всегда возвращает ненулевое значение. + \en Operator (). Returns a pointer to the cache (data) of the current thread. Always returns non-null value. \~ + */ + T * operator ()(); + + /** \brief \ru Удалить данные в кэшах. Если resetLongTerm == true, удалить также данные кэша главного потока. + \en Delete caches data. If resetLongTerm == true, also delete data of the main thread cache. + */ + void Reset ( bool resetLongTerm = false ); + + /** \brief \ru Получить указатель на кэш (данные) главного потока. Всегда возвращает ненулевое значение. + Все операции с кэшем главного потока должны быть защищены блокировкой кэша. + \en Get a pointer to cache (data) of the main thread. Always returns non-null value. + All operations with the main thread cache should be protected by the cache lock. \~ + */ + T * LongTerm (); + + /** \brief \ru Получить указатель на блокировку для операций с кэшем главного потока, учитывая, исполняется ли код параллельно + Может возвращать нулевое значение (удобно для использования с ScopedLock). + \en Get a pointer to the lock for operations with the main thread cache, considering whether the code runs in parallel. + Can return null value (good for use with ScopedLock). \~ + */ + CommonMutex* GetLock() { if ( IsInParallel() ) return GetLockHard(); return lock; } + + /** \brief \ru Функция очистки, используемая сборщиком мусора. + \en Cleaning function, used by the garbage collector. \~ + */ + virtual bool ResetCacheData() { CleanAll(); return true; } + +private: + /** \brief \ru Удалить все кэши и отписаться от сборки мусора. Должна вызываться в последовательном участке кода. + \en Delete all caches and unsubscribe from the garbage collection. Should be called in sequential code. \~ + */ + void CleanAll( bool doPostproc = true ); + + /** \brief \ru Получить указатель на блокировку для операций с кэшем главного потока. Всегда возвращает ненулевое значение. + \en Get a pointer to the lock for operations with the main thread cache. Always returns non-null value. \~ + */ + CommonMutex* GetLockHard(); + + /** \brief \ru Пост-обработка кэшей после выхода из параллельных вычислений. + \en Caches post-processing after exiting the parallel calculations. \~ + */ + void Postprocess(); + + CacheManager & operator = ( const CacheManager & ); // \ru Не разрешен. \en Not allowed. +}; + + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +template +inline CacheManager::CacheManager( bool createLock ) + : longTerm ( NULL ) + , tcache ( NULL ) + , lock ( NULL ) +{ + if ( createLock ) + lock = new CommonMutex(); +} + + +#define C3D_NULLKEY 0 + +//------------------------------------------------------------------------------ +// \ru Конструктор. \en Constructor. +// --- +template +inline CacheManager::CacheManager( const CacheManager & item ) + : longTerm ( NULL ) + , tcache ( NULL ) + , lock ( NULL ) +{ + if ( item.longTerm != NULL ) + longTerm = new T( *item.longTerm ); +#ifndef CACHE_DELETE_LOCK + lock = new CommonMutex(); +#endif +} + + +//------------------------------------------------------------------------------ +// \ru Деструктор. \en Destructor. +// --- +template +inline CacheManager::~CacheManager() +{ + CleanAll( false ); + if ( longTerm != NULL ) + delete longTerm; + if ( lock != NULL ) + delete lock; +} + +//------------------------------------------------------------------------------ +// \ru Получить указатель на кэш главного потока. Всегда возвращает ненулевое значение. +// Все операции с кэшем главного потока должны быть защищены блокировкой кэша. +// \en Get a pointer to the main thread cache. Always returns non-null value. +// All operations with the main thread cache should be protected by the cache lock. +// --- +template +inline T* CacheManager::LongTerm () +{ + if ( longTerm == NULL ) + longTerm = new T(); + return longTerm; +} + +//------------------------------------------------------------------------------ +// \ru Получить указатель на блокировку для операций с кэшем главного потока. Всегда возвращает ненулевое значение. +// \en Get a pointer to the lock for operations with the main thread cache. Always returns non-null value. +// --- +template +inline CommonMutex* CacheManager::GetLockHard() +{ + if ( lock == NULL ) { + CommonMutex* ll = GetGlobalLock(); + ll->lock(); + if ( lock == NULL ) + lock = new CommonMutex(); + ll->unlock(); + } + return lock; +} + +//------------------------------------------------------------------------------ +// \ru Оператор (). Возвращает указатель на кэш текущего потока (всегда ненулевое значение). +// \en Operator (). Returns a pointer to the current thread cache (always non-null value). +// --- +template +inline T * CacheManager::operator()() +{ +// \ru Создать данные по данным кэша главного потока. \en Create data using the data of the main thread cache. +#define INIT_BY_LONGTERM ( longTerm != NULL ? new T( *longTerm ) : new T() ) + + if ( !IsSafeMultithreading() || !IsInParallel() ) { + CleanAll(); + return LongTerm(); + } + + T * res = NULL; + unsigned int threadKey = GetThreadKey(); + + if ( tcache == NULL ) { + // \ru Подписаться на сборку мусора, так как используются многопоточные кэши. + // \en Subscribe on garbage collection because using multithreaded caches. + SubcribeOnCleaning(); + { + // \ru Используется блокировка при изменении списка кэшей. \en Use lock when changing the cache list. + ScopedLock sl( GetLock(), false ); + if ( tcache == NULL ) { + tcache = new List( threadKey, INIT_BY_LONGTERM ); + return tcache->_data; + } + } + } + + List* entry = tcache; + while( entry != NULL ) { + if ( entry->_id == threadKey ) { + if ( !entry->_valid ) { + delete entry->_data; + entry->_data = INIT_BY_LONGTERM; + entry->_valid = true; + } + return entry->_data; + } + // \ru Если кэш не найден в списке, 'entry' содержит последний (на данный момент) элемент в списке. + // \en If cache not found in the list, 'entry' contains the last element in the list (at that point). + if ( entry->_next == NULL ) + break; + entry = entry->_next; + } + res = INIT_BY_LONGTERM; + List* newList = new List( threadKey, res ); + { + // \ru Используется блокировка при изменении списка кэшей. \en Use lock when changing the cache list. + ScopedLock sl( GetLock(), false ); + // \ru На данный момент, entry может быть не последним элементом в списке. + // \en At that point, entry could be not a last element in the list. + while ( entry->_next != NULL ) { + entry = entry->_next; + } + entry->_next = newList; + } // ScopedLock + + return res; + +} + + +//------------------------------------------------------------------------------ +// \ru Удалить данные в кэшах. Если resetLongTerm == true, удалить также данные кэша главного потока. +// \en Delete caches data. If resetLongTerm == true, also delete data of the main thread cache. +// --- +template +inline void CacheManager::Reset( bool resetLongTerm ) +{ + if ( tcache != NULL ) { + ScopedLock sl( GetLock() ); + List* entry = tcache; + while ( entry != NULL ) { + entry->_valid = false; + entry = entry->_next; + } + } + if ( resetLongTerm ) { + ScopedLock sl( GetLock() ); + delete longTerm; + longTerm = NULL; + // \ru Если нет параллельности, удаляется блокировка. \en If no parallelism, delete the lock. +#ifdef CACHE_DELETE_LOCK + if ( !sl.IsLocked() ) { + if ( lock != NULL ) + delete lock; + lock = NULL; + } +#endif + } +} + +//------------------------------------------------------------------------------ +// \ru Удалить все кэши и отписаться от сборки мусора. Должна вызываться в последовательном участке кода. +// \en Delete all caches and unsubscribe from the garbage collection.Should be called in sequential code. +// --- +template +inline void CacheManager::CleanAll( bool doPostproc ) +{ + if ( tcache != NULL ) { + if ( IsSubscribed() ) + UnsubcribeOnCleaning(); + if ( doPostproc ) + Postprocess(); + delete tcache; + tcache = NULL; + } +#ifdef CACHE_DELETE_LOCK + if ( lock != NULL ) { + delete lock; + lock = NULL; + } +#endif +} + +//------------------------------------------------------------------------------ +// \ru Пост-обработка кэшей после выхода из параллельных вычислений. +// \en Caches post-processing after exiting the parallel calculations. \~ +// --- +template +inline void CacheManager::Postprocess() +{ + T * main = LongTerm(); + List * entry = tcache; + while ( entry != NULL ) { + main->MergeWith( entry->_data );// Incorporate thread data into main thread data. + entry = entry->_next; + } +} + +#endif // __TOOL_MULTITHREADING_H diff --git a/C3d/Include/tool_mutex.h b/C3d/Include/tool_mutex.h new file mode 100644 index 0000000..32f8f0c --- /dev/null +++ b/C3d/Include/tool_mutex.h @@ -0,0 +1,478 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Реализация блокировок на базе системных механизмов синхронизации + и OpenMP блокировок. + \en Locks implementation on base of system synchronization mechanisms + and OpenMP locks. \~ + details \ru Реализация блокировок (в том числе блокировки в области видимости) + на базе системных механизмов синхронизации и OpenMP блокировок.\n + \en Implementation of locks (including scoped lock) on base of + system synchronization mechanisms and OpenMP locks.\n \~ +*/ +//////////////////////////////////////////////////////////////////////////////// +#ifndef __TOOL_MUTEX_H +#define __TOOL_MUTEX_H + +#include + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Управление блокировками. +// \en Locks management. \~ +// +// \ru Переменная C3D_NATIVE_LOCK включает использование блокировок на базе +// \ru системных механизмов синхронизации вместо OpenMP, +// \ru что позволяет использование механизмов распараллеливания, отличных от OpenMP. +// +// \en The variable C3D_NATIVE_LOCK enables using locks on base of system +// \en synchronization mechanisms instead of OpenMP, that allows +// \en use of parallelization frameworks, other than OpenMP. \~ +// +//////////////////////////////////////////////////////////////////////////////// +#define C3D_NATIVE_LOCK + + +#ifdef C3D_NATIVE_LOCK +class ToolLock; + +//------------------------------------------------------------------------------ +/** \brief \ru Класс блокировки. \en Lock class. \~ + \details \ru Класс блокировки (реализация на базе системных механизмов синхронизации). + \en Lock class (implementation on base of system synchronization mechanisms). \~ + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS CommonMutex +{ + ToolLock* m_lock; +public: + CommonMutex(); + ~CommonMutex(); + + void lock(); + void unlock(); + +private: + // \ru Запрет копирования. \en Copy forbidden. + CommonMutex ( const CommonMutex& ); + CommonMutex& operator = ( const CommonMutex& ); +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Одинаковая реализация CommonMutex и CommonRecursiveMutex. + \en Same implementation of CommonMutex and CommonRecursiveMutex. \~ + \ingroup Base_Tools +*/ +#define CommonRecursiveMutex CommonMutex + +#else // C3D_NATIVE_LOCK + +//------------------------------------------------------------------------------ +/** \brief \ru Класс блокировки. + \en Lock class. \~ + \details \ru Класс блокировки на базе OpenMP lock. + \en Lock class on base of OpenMP lock. \~ + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS CommonMutex +{ + omp_lock_t m_lock; +public: + // For correct work, CommonMutex implementation should be encapsulated in cpp. + CommonMutex(); + ~CommonMutex(); + void lock(); + void unlock(); +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Класс блокировки на базе вложенного OpenMP lock. + \en Wrapper for nested OpenMP lock. \~ + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS CommonRecursiveMutex +{ + omp_nest_lock_t m_lock; +public: + // For correct work, CommonRecursiveMutex implementation should be encapsulated in cpp. + CommonRecursiveMutex(); + ~CommonRecursiveMutex(); + void lock(); + void unlock(); +}; + +#endif // C3D_NATIVE_LOCK + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Поддержка многопоточности при использовании произвольного параллельного фреймворка +// \ru в пользовательском приложении. +// \ru Чтобы использовать интерфейсы ядра в нескольких потоках, +// \ru для ядра должен быть установлен режим многопоточных вычислений не ниже mtm_SafeItems. +// +// \ru При использовании параллельных механизмов, отличных от OpenMP, пользовательское приложение +// \ru обязано нотифицировать ядро о входе в каждый параллельный регион и выходе из него. +// \ru Для этого могут быть использованы класс ParallelRegionGuard (защитник параллельного региона +// \ru в области видимости), функции EnterParallelRegion и ExitParallelRegion +// или макросы ENTER_PARALLEL и EXIT_PARALLEL. +// \ru Примеры: +// { +// ParallelRegionGuard l; +// std::thread t1( function1 ); +// std::thread t2( function2 ); +// t1.join(); +// t2.join(); +// } +// { +// EnterParallelRegion(); +// std::thread t1( function1 ); +// std::thread t2( function2 ); +// t1.join(); +// t2.join(); +// ExitParallelRegion(); +// } +// +// +// \en Support of multithreading when using an arbitrary parallel framework in user application. +// +// \en For using the kernel interfaces in several threads, the multithreading mode mtm_SafeItems +// \en or higher should be defined for the kernel. +// +// \en When using a parallel framework other than OpenMP in user code, the application must notify +// \en the kernel about entering and exiting a parallel region. +// \en For that, the class ParallelRegionGuard (a scoped guard of parallel region), +// \en the functions EnterParallelRegion and ExitParallelRegion, +// or macros ENTER_PARALLEL and EXIT_PARALLEL could be used. +// \en Examples: +// { +// ParallelRegionGuard l; +// std::thread t1( function1 ); +// std::thread t2( function2 ); +// t1.join(); +// t2.join(); +// } +// { +// EnterParallelRegion(); +// std::thread t1( function1 ); +// std::thread t2( function2 ); +// t1.join(); +// t2.join(); +// ExitParallelRegion(); +// } +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +/** \brief \ru Защитник параллельного региона в области видимости. + \en Scoped guard of parallel region. \~ + \details \ru Класс защищает регион кода, выполняющийся параллельно. + Работает в области видимости. + Должен использоваться для защиты параллельного кода, + если используются средства распараллеливания, отличные от OpenMP. + Пример использования: + { + ParallelRegionGuard l; + std::thread t1( function1 ); + std::thread t2( function2 ); + t1.join(); + t2.join(); + } + \en The class guards a code region running in parallel. + Works in scope. + Should be used to protect parallel code if parallel framework other than OpenMP is used. + Example of use: + { + ParallelRegionGuard l; + std::thread t1( function1 ); + std::thread t2( function2 ); + t1.join(); + t2.join(); + } + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS ParallelRegionGuard +{ +public: + ParallelRegionGuard(); + ~ParallelRegionGuard(); +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Функция нотифицирует ядро о входе в параллельный блок кода. + Вызов функции должен стоять перед началом параллельного блока. + \en The function notifies the kernel about entering a parallel region. + The function call should be placed before the start of a parallel block +*/ +// --- +MATH_FUNC( void ) EnterParallelRegion(); + +//------------------------------------------------------------------------------ +/** \brief \ru Функция нотифицирует ядро о выходе из параллельного блока кода. + Вызов функции должен стоять после окончания параллельного блока. + \en The function notifies the kernel about exiting a parallel region. + The function call should be placed after the end of the parallel block. +*/ +// --- +MATH_FUNC( void ) ExitParallelRegion(); + + +//------------------------------------------------------------------------------ +// \ru Макросы для нотификации о входе и выходе из параллельного цикла. +// Вызов макросов при использовании OpenMP не обязателен, однако значительно ускоряет +// выполнение параллельного цикла. +// Вызов ENTER_PARALLEL должен стоять перед началом параллельного блока. +// Вызов EXIT_PARALLEL должен стоять после окончания параллельного блока. +// Пример использования: +// bool useParallel = Math::CheckMultithreadedMode( mtm_Items ); +// ENTER_PARALLEL( useParallel ); +// #pragma omp parallel for +// for ( ptrdiff_t i = 0; i < count; ++i ) { +// /* Cycle body */ +// } +// EXIT_PARALLEL( useParallel ); +// +/// \ru Macros for notification of entering and exiting a parallel block. +// Calling the macros when using OpenMP is not required, but significantly speeds up +// the execution of parallel cycle. +// The call ENTER_PARALLEL should be placed before the start of a parallel block. +// The call EXIT_PARALLEL should be placed after the end of the parallel block. +// Example of use: +// bool useParallel = Math::CheckMultithreadedMode( mtm_Items ); +// ENTER_PARALLEL( useParallel ); +// #pragma omp parallel for +// for ( ptrdiff_t i = 0; i < count; ++i ) { +// /* Cycle body */ +// } +// EXIT_PARALLEL( useParallel ); +// --- + +//------------------------------------------------------------------------------ +/** \brief \ru Если useParallel == true, нотифицирует ядро о входе в параллельный блок кода. + \en If useParallel == true, notifies the kernel about entering a parallel region. + \details \ru Если useParallel == true, нотифицирует ядро о входе в параллельный блок кода. + Вызов должен стоять перед началом параллельного блока (перед прагмой OpenMP). + Использование макроса значительно ускоряет параллельные циклы OpenMP. + \en If useParallel == true, notifies the kernel about entering a parallel region. + The call should be placed before the start of a parallel block (before OpenMP pragma). + Using a macro speeds up parallel OpenMP cycles significantly. +*/ +// --- +#define ENTER_PARALLEL(useParallel) if ( useParallel ) EnterParallelRegion(); + +//------------------------------------------------------------------------------ +/** \brief \ru Если useParallel == true, нотифицирует ядро о выходе из параллельного блока кода. + \en If useParallel == true, notifies the kernel about exiting a parallel region. + \details \ru Если useParallel == true, нотифицирует ядро о выходе из параллельного блока кода. + Вызов должен стоять после окончания параллельного блока. + Использование макроса значительно ускоряет параллельные циклы OpenMP. + \en If useParallel == true, notifies the kernel about exiting a parallel region. + The call should be placed after the end of the parallel block. + Using a macro speeds up parallel OpenMP cycles significantly. +*/ +// --- +#define EXIT_PARALLEL(useParallel) if ( useParallel ) ExitParallelRegion(); + +//------------------------------------------------------------------------------ +/** \brief \ru Функция определяет, выполняется ли код параллельно. + \en The function determines whether the code is executed in parallel. +*/ +// --- +MATH_FUNC( bool ) IsInParallel(); + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Блокировки и другие средства синхронизации. +// \en Locks and other synchronization objects. \~ + +// \ru В качестве блокировок должны использоваться CommonMutex и CommonRecursiveMutex +// \ru (OpenMP lock не должны использоваться напрямую). +// +// \en CommonMutex and CommonRecursiveMutex should be used as locks +// \en (OpenMP locks should not be used directly). +// +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +/** \brief \ru Блокировка в области видимости. Может принимать нулевой указатель на мьютекс. + Блокировка происходит, если указатель на мьютекс ненулевой и код выполняется параллельно. + \en Scoped lock. Can accept a null pointer to a mutex. + Locking occurs if the pointer to the mutex is nonzero and the code runs in parallel. \~ + \ingroup Base_Tools +*/ +// --- +class MATH_CLASS ScopedLock +{ + CommonMutex* m_mutex; +public: + ScopedLock( CommonMutex* mutex, bool parallelCheck = true ); + ~ScopedLock(); + + // \ru Выполнена ли реальная блокировка. \en Whether a real locking performed. + bool IsLocked(); + +private: + ScopedLock(); + ScopedLock ( const ScopedLock& ); + ScopedLock& operator = ( const ScopedLock& ); +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Рекурсивная блокировка в области видимости. Может принимать нулевой указатель на мьютекс. + Блокировка происходит, если указатель на мьютекс ненулевой и код выполняется параллельно. + \en Recursive scoped lock. Can accept a null pointer to a mutex. + Locking occurs if the pointer to the mutex is nonzero and the code runs in parallel. \~ +\ingroup Base_Tools +*/ +// --- +class MATH_CLASS ScopedRecursiveLock +{ + CommonRecursiveMutex* m_mutex; +public: + ScopedRecursiveLock( CommonRecursiveMutex* mutex, bool parallelCheck = true ); + ~ScopedRecursiveLock(); + + // \ru Выполнена ли реальная блокировка. \en Whether a real locking performed. + bool IsLocked(); + +private: + ScopedRecursiveLock(); + ScopedRecursiveLock ( const ScopedRecursiveLock& ); + ScopedRecursiveLock& operator = ( const ScopedRecursiveLock& ); +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый объект синхронизации с отложенной инициализацией. + \en Base synchronization object with lazy initialization. \~ + \details \ru Базовый объект, предоставляющий средства синхронизации и создающий блокировку при необходимости. \n + \en Base object which provides means of synchronization and creates a lock when needed. \n \~ +\ingroup Base_Tools +*/ +// --- +class MATH_CLASS MbSyncItem { +protected: + mutable CommonMutex * m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object. + mutable bool m_locked; + +public: + MbSyncItem(); + virtual ~MbSyncItem(); + + // \ru Включить блокировку (блокировка происходит только при наличии параллельности). + // \en Switch lock on (locking happens only in parallel region). + void Lock() const; + // \ru Снять блокировку, если она была установлена. + // \en Switch lock off if locking has been set. + void Unlock() const; + + // \ru Выдать указатель на объект мьютекса. Возращает NULL, если параллельности нет. Для использования в ScopedLock. + // \en Get a pointer to the mutex object. Return NULL if no parallelism. For use in ScopedLock. + CommonMutex * GetLock() const; +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый объект синхронизации с отложенной инициализацией, поддерживающий множественные блокировки. + \en Base synchronization object with lazy initialization which supports nested locks. \~ + \details \ru Базовый объект синхронизации, поддерживающий множественные блокировки и создающий блокировку при необходимости. \n + \en Base synchronization object with support of nested locks which creates a lock if necessary. \n \~ +\ingroup Base_Tools +*/ +// --- +class MATH_CLASS MbNestSyncItem { +protected: + mutable CommonRecursiveMutex * m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object. + mutable bool m_locked; + +public: + MbNestSyncItem(); + virtual ~MbNestSyncItem(); + + // \ru Включить блокировку (блокировка происходит только при наличии параллельности). + // \en Switch lock on (locking happens only in parallel region). + void Lock() const; + // \ru Снять блокировку, если она была установлена. + // \en Switch lock off if locking has been set. + void Unlock() const; + + // \ru Выдать указатель на объект мьютекса. Возращает NULL, если параллельности нет. Для использования в ScopedLock. + // \en Get a pointer to the mutex object. Return NULL if no parallelism. For use in ScopedLock. + CommonRecursiveMutex * GetLock() const; +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый объект, предоставляющий средства синхронизации. + \en Base object providing means of synchronization. \~ + \details \ru Базовый объект, предоставляющий средства синхронизации. \n + \en Base object providing means of synchronization. \n \~ +\ingroup Base_Tools +*/ +// --- +class MATH_CLASS MbPersistentSyncItem { +protected: + mutable CommonMutex m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object. + +public: + MbPersistentSyncItem(); + virtual ~MbPersistentSyncItem(); + + void Lock() const; + void Unlock() const; +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Базовый объект синхронизации, поддерживающий множественные блокировки. + \en Base synchronization object with support of nested locks. \~ + \details \ru Базовый объект синхронизации, поддерживающий множественные блокировки. \n + \en Base synchronization object with support of nested locks. \n \~ +\ingroup Base_Tools +*/ +// --- +class MATH_CLASS MbPersistentNestSyncItem { +protected: + mutable CommonRecursiveMutex m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object. + +public: + MbPersistentNestSyncItem(); + virtual ~MbPersistentNestSyncItem(); + + void Lock() const; + void Unlock() const; +}; + + +//------------------------------------------------------------------------------ +// \ru Установлен ли режим безопасной многопоточности (используется в CacheManager). +// \en Whether is enabled a safe multithreading mode (used in CacheManager). +// --- +MATH_FUNC(bool) IsSafeMultithreading(); + +//------------------------------------------------------------------------------ +// \ru Получить идентификатор текущего потока. +// \en Get a current thread identifier. +// --- +MATH_FUNC( unsigned int ) GetThreadKey(); + +//------------------------------------------------------------------------------ +// \ru Получить указатель на глобальный мьютекс (используется в CacheManager). +// \en Get a pointer to the global mutex (used in CacheManager). +// --- +MATH_FUNC( CommonMutex* ) GetGlobalLock(); + +//------------------------------------------------------------------------------ +// \ru Получить указатель на глобальный рекурсивный мьютекс (используется для операций выделения и освобождения памяти). +// \en Get a pointer to the global recursive mutex (used for memory allocation and deallocation operations). +// --- +MATH_FUNC( CommonRecursiveMutex* ) GetGlobalRecursiveLock(); + +//------------------------------------------------------------------------------ +// \ru Установить блокировку в области видимости для операций выделения и освобождения памяти. +// \en Set scoped lock for memory allocation and deallocation operations. +// --- +#define SET_MEMORY_SCOPED_LOCK ScopedRecursiveLock memScopedLock( GetGlobalRecursiveLock() ); + +#endif // __TOOL_MUTEX_H diff --git a/C3d/Include/tool_progress_indicator.h b/C3d/Include/tool_progress_indicator.h new file mode 100644 index 0000000..68f8cc3 --- /dev/null +++ b/C3d/Include/tool_progress_indicator.h @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_PROGRESS_INDICATOR_H +#define __TOOL_PROGRESS_INDICATOR_H + + +//------------------------------------------------------------------------------ +/** \brief \ru Индикатор прогресса выполнения. + \en A run progress indicator. \~ + \details \ru Интерфейс индикатора прогресса выполнения. \n + \en Interface of the execution progress indicator. \n \~ + \note \ru Геометрическое ядро обеспечивает потокобезопасность использования индикатора прогресса. + Пользователь должен обеспечить потокобезопасность внутренней реализации IfProgressIndicator. + \en The geometric kernel provides the thread-safe use of the progress indicator. + The user is responsible for thread-safety of IfProgressIndicator internal implementation. \~ + \ingroup Base_Tools +*/ +// --- +struct IfProgressIndicator +{ + /// \ru Инициализация. \en Initialization. + virtual void StartProgress ( ptrdiff_t minValue, ptrdiff_t maxValue, const TCHAR * lpszNewText, bool resetTxt, bool aPIcall = false ) = 0; + /// \ru Установка текущего значения. \en Setting of the current value. + virtual void SetProgress ( ptrdiff_t nCurr, const TCHAR * lpszNewText, bool resetTxt, bool aPIcall = false ) = 0; + /// \ru Остановить индикатор. \en Stop the indicator. + virtual void StopProgress ( const TCHAR * lpszNewText, bool resetTxt, bool aPIcall = false ) = 0; + /// \ru Получить строку из индикатора. \en Get the string from the indicator. + virtual const TCHAR * GetStrBuild () const = 0; + /// \ru Установить строку в индикатор. \en Set the string to the indicator. + virtual void StBarSetMessageText( const TCHAR * msg, bool aPIcall = false ) = 0; // \ru Переименовано для отличия от аналогичных функций в окне, процессе и приложении \en Renamed to make different the similar functions in window, in process and in application + /// \ru Запущен ли какой-нибудь процесс с индикатором. \en Whether any process with indicator is run. + virtual bool IsProgressStarted() const = 0; +}; + + +#endif // __TOOL_PROGRESS_INDICATOR_H diff --git a/C3d/Include/tool_quick_sort.h b/C3d/Include/tool_quick_sort.h new file mode 100644 index 0000000..2228ea4 --- /dev/null +++ b/C3d/Include/tool_quick_sort.h @@ -0,0 +1,465 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Функция сортировки. + \en A sorting function. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Стандартная функция void qsort( void *base, size_t num, size_t width, int ( *compare )(const void *elem1, const void *elem2 ) ) +// определенная в and может работать неверно на массивах длиной <= 8. Пожалуйста, избегайте ее применения. +// \en Standard function void qsort( void *base, size_t num, size_t width, int ( *compare )(const void *elem1, const void *elem2 ) ) +// defined in and may work uncorrectly in arrays with length <= 8. Please, avoid using of this. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_QUICK_SORT_H +#define __TOOL_QUICK_SORT_H + + +#include +#include + + +//------------------------------------------------------------------------------ +// \ru Функция сравнения \en A comparison function +//--- +typedef int (CALL_DECLARATION *KsQSortCompFunc)( const void*, const void* ); + + +namespace c3d // namespace C3D +{ + +//------------------------------------------------------------------------------ + /** \brief \ru Поменять местами два элемента. \en Swap two elements. + \details \ru Поменять местами два элемента размером width. \en Swap two elements of 'width' size. + \param[in] a - \ru Указатель на элемент массива. \en Pointer to the array element. \~ + \param[in] b - \ru Указатель на элемент массива. \en Pointer to the array element. \~ + \param[in] width - \ru Размер каждого элемента в байтах. \en Size in bytes of each element. \~ + */ +//--- +static void CALL_DECLARATION swap( char * a, char * b, size_t width ) +{ + if ( a != b ) { + char tmp; + // \ru Менять местами по одному символу, чтобы избежать возможных проблем выравнивания. + // \en Swap one character at a time to avoid potential alignment problems. + while ( width-- ) { + tmp = *a; + *a++ = *b; + *b++ = tmp; + } + } +} + +} // namespace C3D + + +//------------------------------------------------------------------------------ + /** \brief \ru Cортировка массива. + \en An array sorting. \~ + \details \ru Реализует быструю сортировку. Сортирует на месте. + \en Implements a quicksort of the array of elements. Sorts in place. \~ + \param[out] base - \ru Указатель на основание массива. \en Pointer to the base of the array. \~ + \param[in] num - \ru Количество элементов массиве. \en Number of elements in the array. \~ + \param[in] width - \ru Размер элемента массива в байтах. \en Size in bytes of the array element. \~ + \param[in] compareFunc - \ru Указатель на функцию сравнения элементов первого массива. + Аналог функции strcmp, предоставляемый пользователем для сравнения элементов массива. + Принимает 2 указателя на элементы и возвращает: + отрицательное значение, если 1<2; 0, если 1=2; положительное значение, если 1>2. \~ + \en Pointer to the comparison function for the elements of the first array. + Analog of strcmp for strings, supplied by user for comparing the array elements. + Accepts 2 pointers to elements and returns: + negative value, if 1<2; 0, if 1=2; positive value, if 1>2. \~ +*/ +//--- +inline void KsQSort( void * base, + size_t num, + size_t width, + KsQSortCompFunc compareFunc ) +{ + // \ru Границы сортируемого подмассива. \en Boundaries of a subarray currently being sorted. + char *lowElem, *hiElem; + // \ru Серединный элемент сортируемого подмассива. \en Middle element of a subarray currently being sorted. + char *midElem; + // \ru Бегущие указатели для разбиения подмассива. \en Traveling cursors for a subarray partitioning. + char *lowCursor, *hiCursor; + // ru Размер подмассива. \en Size of a subarray. + size_t size; + // \ru Стек для хранения границ сортируемых подмассивов. Количество требуемых записей стека <= 1 + log2(size), + // поэтому для сортировки любого массива достаточно глубины 30. + // \en Stack to store the boundaries of subarrays to be sorted. Number of stack entries required is <= 1 + log2(size), + // so the depth of 30 is sufficient for sorting any array. + char *lowStack[30], *hiStack[30]; + // \ru Текущий указатель стека. // \en Current stack pointer. + int stackPtr = -1; // \ru Пустой стек. \en Empty stack. + + if (num < 2 || width == 0) + return; + + lowElem = (char *)base; + hiElem = (char *)base + width * (num-1); + + if ( num == 2 ) { + if ( compareFunc( lowElem, hiElem ) >= 0 ) + c3d::swap( lowElem, hiElem, width ); + return; + } + + // \ru Точка входа псевдо-рекурсии. Сортируется подмассив между lowElem и hiElem (включительно). + // \en Entry point of a pseudo-recursion. Sort a subarray between lowElem and hiElem (inclusive). + for ( ;;) { + + size = ( hiElem - lowElem ) / width + 1; // \ru Количество сортируемых элементов. \en Number of elements to sort. + + // ru В качестве разделяющего выбрать серединный элемент и поместить его в начало подмассива. + // \en Choose a middle element as a partitioning one and swap it to the beginning of the subarray. + midElem = lowElem + ( size / 2 ) * width; + c3d::swap( midElem, lowElem, width ); + + lowCursor = lowElem; + hiCursor = hiElem + width; + + // \ru hiCursor уменьшается, а lowCursor увеличивается на каждой итерации, поэтому цикл должен закончиться. + // \en hiCursor decreases and lowCursor increases on every iteration, so loop must terminate. + for ( ;;) { + do { + lowCursor += width; + } while ( lowCursor <= hiElem && compareFunc( lowCursor, lowElem ) <= 0 ); + + do { + hiCursor -= width; + } while ( hiCursor > lowElem && compareFunc( hiCursor, lowElem ) >= 0 ); + + // \ru Цикл закончился. \en The loop terminates. + if ( hiCursor < lowCursor ) + break; + + c3d::swap( lowCursor, hiCursor, width ); + } + + // ru Возвратить разделяющий элемент на место. /en Put the partition element in place. + c3d::swap( lowElem, hiCursor, width ); + + // \ru Теперь будут сортироваться подмассивы [lowElem, hiCursor-1] и [lowCursor, hiElem]. + // Сначала меньшие по размеру, чтобы минимизировать глубину стека. + // \en Now sort the subarrays [lowElem, hiCursor-1] and [lowCursor, hiElem]]. + // The smaller one first to minimize stack usage. + if ( hiCursor - 1 - lowElem >= hiElem - lowCursor ) { + // \ru Сохранить больший подмассив для последующей обработки. \en Save the bigger subarray for later processing. + if ( lowElem + width < hiCursor ) { + lowStack[++stackPtr] = lowElem; + hiStack[stackPtr] = hiCursor - width; + } + + // \ru Обработать меньший подмассив. \en Process smaller subarray. + if ( lowCursor < hiElem ) { + lowElem = lowCursor; + continue; + } + } + else { + // \ru Сохранить больший подмассив для последующей обработки. \en Save the bigger subarray for later processing. + if ( lowCursor < hiElem ) { + lowStack[++stackPtr] = lowCursor; + hiStack[stackPtr] = hiElem; + } + + // \ru Обработать меньший подмассив. \en Process smaller subarray. + if ( lowElem + width < hiCursor ) { + hiElem = hiCursor - width; + continue; + } + } + + // \ru Текущий подмассив отсортирован. Проверить наличие отложенных сортировок в стеке. + // \en Current subarray have been sorted. Check for any pending sorts on the stack. + if ( stackPtr < 0 ) + break; // \ru Все подмассивы обработаны. \en All subarrays are done. + lowElem = lowStack[stackPtr]; + hiElem = hiStack[stackPtr--]; + } +} + +//------------------------------------------------------------------------------ + /** \brief \ru Перестановка 2 элементов в массиве. \en Swapping of 2 elements in the array. \~ + \details \ru Переставляются заданные элементы массива. \en Swapping of given elements in the array. \~ + \param[out] base - \ru Указатель на массив. \en Pointer to the array. \~ + \param[in] ind1 - \ru Индекс первого элемента. \en Index of the first element. \~ + \param[in] ind2 - \ru Индекс второго элемента. \en Index of the second element. \~ +\ingroup Base_Algorithms +*/ +//--- +template +void Swap( Type* arr, size_t ind1, size_t ind2 ) +{ + Type tmp = arr[ind1]; + arr[ind1] = arr[ind2]; + arr[ind2] = tmp; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Сортировка массива с возможностью синхронной перестановки элементов в двух других массивах. + Эффективна для небольших массивов. + \en An array sorting with an ability of synchronous rearrangement in two other specified arrays. + Effective for small arrays.\~ + \details \ru Первый массив сортируется по возрастанию параметра. Элементы второго и третьего массивов + переставляются синхронно с элементами первого. Подразумевается, что массивы имеют одинаковый размер. + \en First array is sorted in ascending order. Elements of the second and third arrays + are rearranged synchronously with the first one. Assumed that arrays have the same size. \~ + \param[out] base - \ru Указатель на первый массив, который требуется отсортировать. + \en Pointer to the first array to sort. \~ + \param[in] num - \ru Количество элементов в массиве. + \en Number of elements in the array. \~ + \param[in] compareFunc - \ru Указатель на функцию сравнения элементов первого массива. + Аналог функции strcmp, предоставляемый пользователем для сравнения элементов массива. + Принимает 2 указателя на элементы и возвращает: + отрицательное значение, если 1<2; 0, если 1=2; положительное значение, если 1>2. \~ + \en Pointer to the comparison function for the elements of the first array. + Analog of strcmp for strings, supplied by user for comparing the array elements. + Accepts 2 pointers to elements and returns: + negative value, if 1<2; 0, if 1=2; positive value, if 1>2. \~ + \param[out] base2 - \ru Указатель на второй массив (может быть NULL). + \en Pointer to the second array (could be NULL). \~ + \param[out] base3 - \ru Указатель на третий массив (может быть NULL). + \en Pointer to the third array (could be NULL). \~ +\ingroup Base_Algorithms +*/ +//--- +template +void InsertSort( Type * base, + size_t num, + KsQSortCompFunc compareFunc, Type2* base2 = NULL, Type3* base3 = NULL ) + +{ + if ( num < 2 ) + return; + + if ( num == 2 ) { + if ( compareFunc( base, base + 1 ) >= 0 ) { + Swap( base, 0, 1 ); + if ( base2 != NULL ) { + Swap( base2, 0, 1 ); + if ( base3 != NULL ) + Swap( base3, 0, 1 ); + } + } + return; + } + + for ( ptrdiff_t i = 1; i < (ptrdiff_t)num; ++i ) { + for ( ptrdiff_t j = i; j > 0 && compareFunc( base + j - 1, base + j ) >= 0; j-- ) { + Swap( base, j - 1, j ); + if ( base2 != NULL ) { + Swap( base2, j - 1, j ); + if ( base3 != NULL ) + Swap( base3, j - 1, j ); + } + } + } +} + +//------------------------------------------------------------------------------ + /** \brief \ru Сортировка массива с возможностью синхронной перестановки элементов в двух других массивах. + Работает с массивами элементов, которые предоставляют оператор присваивания. + Не гарантирует сохранение порядка равных элементов. + \en An array sorting with an ability of synchronous rearrangement in two other specified arrays. + Works with arrays of elements which support assignment operators. + Not guarantees preserving of the order of equal elements. \~ + \details \ru Первый массив сортируется по возрастанию параметра. + Элементы второго и третьего массивов переставляются синхронно с элементами первого. + Подразумевается, что массивы имеют одинаковый размер. + \en First array is sorted in ascending order. + Elements of the second and third arrays are rearranged synchronously with the first one. + Assumed that arrays have the same size. \~ + \param[out] base - \ru Указатель на первый массив, который требуется отсортировать. + \en Pointer to the first array to sort. \~ + \param[in] num - \ru Количество элементов в массиве. + \en Number of elements in the array. \~ + \param[in] compareFunc - \ru Указатель на функцию сравнения элементов первого массива. + Аналог функции strcmp, предоставляемый пользователем для сравнения элементов массивы. + Принимает 2 указателя на элементы и возвращает: + отрицательное значение, если 1<2; + 0, если 1=2, + положительное значение, если 1>2. \~ + \en Pointer to the comparison function for the elements of the first array. + Analog of strcmp for strings, supplied by user for comparing the array elements. + Accepts 2 pointers to elements and returns: + negative value, if 1<2; + 0, if 1=2, + positive value, if 1>2. \~ + \param[out] base2 - \ru Указатель на второй массив (может быть NULL). + \en Pointer to the second array (could be NULL). \~ + \param[out] base3 - \ru Указатель на третий массив (может быть NULL). + \en Pointer to the third array (could be NULL). \~ +\ingroup Base_Algorithms +*/ +//--- +template +void QuickSort( Type * base, + size_t num, + KsQSortCompFunc compareFunc, Type2* base2 = NULL, Type3* base3 = NULL ) +{ + #define QSORT_THRESHOLD 25 // \ru Порог перехода на другой тип сортировки.\en Threshold of transition to another sorting. + + ptrdiff_t lInd = 0, rInd = 0; // \ru Промежуточные левый и правый индексы.\en Intermediate left and right indices. + ptrdiff_t leftIndex, rightIndex; // \ru Текущие левый и правый индексы. \en Current left and right indices. + ptrdiff_t midIndex; // \ru Текущий базовый индекс.\en Current base indices. + c3d::NumbersPair iterStack[30]; + int stackCount = 0; + + if ( num < 2 ) + return; + + if ( num == 2 ) { + if ( compareFunc( base, base + 1 ) >= 0 ) { + Swap( base, 0, 1 ); + if ( base2 != NULL ) { + Swap( base2, 0, 1 ); + if ( base3 != NULL ) + Swap( base3, 0, 1 ); + } + } + return; + } + + if ( num <= QSORT_THRESHOLD ) + return InsertSort( base, num, compareFunc, base2, base3 ); + + iterStack[stackCount] = std::make_pair( 0, num - 1 ); + + while ( stackCount >= 0 ) { + leftIndex = iterStack[stackCount].first; + rightIndex = iterStack[stackCount--].second; + + // \ru Выбирается базовый элемент (используется средний). \en Select a base element (use the middle one). + midIndex = ( rightIndex + leftIndex ) / 2; + Swap( base, midIndex, leftIndex ); + if ( base2 != NULL ) { + Swap( base2, midIndex, leftIndex ); + if ( base3 != NULL ) + Swap( base3, midIndex, leftIndex ); + } + + // \ru Далее массив делится на 3 части: + // часть из элементов, которые <= базовому элементу, + // часть из элементов, которые == базовому элементу, + // часть из элементов, которые >= parts элементу, + // \en Divide the array into three pieces: + // the part of elements which <= the base element, + // the part of elements which == the base element, + // the part of elements which >= the base element. + + lInd = leftIndex; + rInd = rightIndex + 1; + + for ( ;;) { + do { + lInd++; + } while ( lInd <= rightIndex && compareFunc( base + lInd, base + leftIndex ) <= 0 ); + + do { + rInd--; + } while ( rInd > leftIndex && compareFunc( base + rInd, base + leftIndex ) >= 0 ); + + if ( rInd < lInd ) + break; + + Swap( base, lInd, rInd ); + if ( base2 != NULL ) { + Swap( base2, lInd, rInd ); + if ( base3 != NULL ) + Swap( base3, lInd, rInd ); + } + } + + Swap( base, leftIndex, rInd ); + if ( base2 != NULL ) { + Swap( base2, leftIndex, rInd ); + if ( base3 != NULL ) + Swap( base3, leftIndex, rInd ); + } + + // \ru Теперь будут сортироваться подмассивы [leftIndex, rInd-1] и [lInd, rigthIndex]. + // Сначала меньшие по размеру, чтобы минимизировать глубину стека. + // \en Now sort the subarrays [leftIndex, rInd-1] and [lInd, rigthIndex]. + // The smaller one first to minimize stack usage. + if ( rInd - 1 - leftIndex >= rightIndex - lInd ) { + if ( leftIndex + 1 < rInd ) { + ptrdiff_t count = rInd - leftIndex; + if ( count <= QSORT_THRESHOLD ) + InsertSort( base + leftIndex, count, compareFunc, base2, base3 ); + else + iterStack[++stackCount] = std::make_pair( leftIndex, rInd - 1 ); + } + + if ( lInd < rightIndex ) { + ptrdiff_t count = rightIndex - lInd + 1; + if ( count <= QSORT_THRESHOLD ) + InsertSort( base + lInd, count, compareFunc, base2, base3 ); + else + iterStack[++stackCount] = std::make_pair( lInd, rightIndex ); + } + } + else { + if ( lInd < rightIndex ) { + ptrdiff_t count = rightIndex - lInd + 1; + if ( count <= QSORT_THRESHOLD ) + InsertSort( base + lInd, count, compareFunc, base2, base3 ); + else + iterStack[++stackCount] = std::make_pair( lInd, rightIndex ); + } + + if ( leftIndex + 1 < rInd ) { + ptrdiff_t count = rInd - leftIndex; + if ( count <= QSORT_THRESHOLD ) + InsertSort( base + leftIndex, count, compareFunc, base2, base3 ); + else + iterStack[++stackCount] = std::make_pair( leftIndex, rInd - 1 ); + } + } + } // while +} + +//------------------------------------------------------------------------------ +// \ru Функция для сортировки элементов double по возрастанию. \en A function for sorting of double elements in ascending order. +// --- +inline int DoubleCompare( const double * first, const double * second ) { + return *second < *first ? 1 : -1; +} + +//------------------------------------------------------------------------------ +/// \ru Функция автоматического наращивания памяти \en A function of automatic allocating of the memory +/**\ru Функция применяется в библиотеке шаблонов Sys для автоматического наращивания памяти SArray, RPArray, SQueue ... + \en This function is used for the template library Sys for the automatic allocation of the memory in SArray, RPArray, SQueue ... \~ +*/ +//--- +inline size_t KsAutoDelta( size_t count ) +{ + return std_min( (size_t)1024, std_max( (size_t)4, count / 8) ); //-V112 +} + + +//------------------------------------------------------------------------------ +// \ru Вычисление автоматического выделения памяти массива \en Calculating of the automatic memory allocation of an array. +// (this avoids heap fragmentation in many situations) +//--- +inline size_t KsAutoDelta( size_t count, uint16 delta ) +{ + return ( delta > 2 ) ? delta : KsAutoDelta( count ); +} + + +//------------------------------------------------------------------------------ +// \ru тест на запрос распределения памяти в пределах половины адресного пространства для 32- и 64-разрядного приложения \en a test for the request of memory allocation inside a half of address space for 32- and 64-bit applications. +// --- +inline bool TestNewSize( size_t sizeOfType, size_t count ) +{ + return ( double(count) * double(sizeOfType) < double(SYS_MAX_ST) ); +} + + +#endif // __TOOL_QUICK_SORT_H diff --git a/C3d/Include/tool_string_util.h b/C3d/Include/tool_string_util.h new file mode 100644 index 0000000..c06b678 --- /dev/null +++ b/C3d/Include/tool_string_util.h @@ -0,0 +1,437 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Вспомогательные функции по работе со строками. + \en Utility functions for working with strings. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_STRING_UTIL_H +#define __TOOL_STRING_UTIL_H + + +#include + +#ifdef C3D_WINDOWS // _MSC_VER + #include +#else // C3D_WINDOWS + #include +#endif // C3D_WINDOWS + +#ifdef __MOBILE_VERSION__ +#include +#endif // __MOBILE_VERSION__ + +// The keyword -D_CRT_SECURE_NO_WARNINGS added. Pragma below were disable deprecated warnings. +#if defined (C3D_WINDOWS) && !defined(ALL_WARNINGS) // _MSC_VER // Set warnings level +#pragma warning(push) // Preserve current state of warning settings +#pragma warning(disable: 4996) // This function or variable may be unsafe. Consider using strcpy_s instead. +#endif + +#ifndef C3D_WINDOWS // _MSC_VER +inline const char* strret( const char* str ) { return str; } /// \ru Возврат CHAR-строки. \en Return a CHAR-string. \~ \ingroup Base_Tools_String +#endif //C3D_WINDOWS + +//------------------------------------------------------------------------------ +/** \brief \ru Дублировать CHAR-строку. + \en Duplicate a CHAR-string \~ + \details \ru Дублировать CHAR-строку, удалять по delete[]. \n + \en Duplicate a CHAR-string, delete by the delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +//--- +inline char * strnewdup( const char * str, size_t minLen = 0 ) +{ + if ( !str ) + return NULL; + + size_t len = strlen( str ); + + if ( len < minLen ) + len = minLen; + + return strcpy( new char[len + 1], str ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Дублировать WCHAR-строку. + \en Duplicate a WCHAR-string. \~ + \details \ru Дублировать WCHAR-строку, удалять по delete[]. \n + \en Duplicate a WCHAR-string, delete by delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +// --- +inline wchar_t * wcsnewdup( const wchar_t * str, size_t minLen = 0 ) +{ + if ( !str ) + return NULL; + + size_t len = wcslen( str ); + + if ( len < minLen ) + len = minLen; + + return wcscpy( new wchar_t[len + 1], str ); +} + +//------------------------------------------------------------------------------ +/** \brief \ru Конвертировать CHAR в WCHAR строку. + \en Convert CHAR to WCHAR. \~ + \details \ru Конвертировать CHAR в WCHAR строку, удалять по delete[]. \n + \en Convert CHAR-string to WCHAR-string, delete by the delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +//--- +inline wchar_t * mbsnewwcs( const char * str ) +{ + wchar_t * res = NULL; + + if ( str ) + { +#ifndef __MOBILE_VERSION__ +#ifdef C3D_WINDOWS // _MSC_VER + size_t n = mbstowcs( NULL, str, 0 ); +#else // C3D_WINDOWS + size_t n = std::mbstowcs( NULL, str, 0 ); +#endif // C3D_WINDOWS + + if ( n != NSIZE ) + { + n++; + res = new wchar_t[n]; +#ifdef C3D_WINDOWS // _MSC_VER + mbstowcs( res, str, n ); +#else // C3D_WINDOWS + std::mbstowcs( res, str, n ); +#endif // C3D_WINDOWS + } + // \ru ID K12 Ошибка 42704 \en ID K12 Error 42704 + else // \ru переводим по одному символу, вместо непереведенных ставим "?" \en convert by word and replace not converted words by the symbol "?" + { + size_t len = strlen( str ); + res = new wchar_t[len + 1]; + memset( res, 0, (len + 1)*sizeof(wchar_t) ); + + for ( size_t i = 0; i < len; i++ ) + { +#ifdef C3D_WINDOWS // _MSC_VER // \ru Актуально только под Windows см. Ошибка 42704 \en It is actual only for Windows Error 42704 + wchar_t c; + if ( mbtowc(&c, &str[i], 1) == sizeof(char) ) // \ru только для однобайтных символов! \en only for single-byte symbols + res[i] = c; + else +#endif // C3D_WINDOWS + res[i] = '?'; + } + } +#else // __MOBILE_VERSION__ + res = cp1251_to_WChar(str); + //wchar_t unChar = L'?'; + //size_t len = strlen( str ); + //res = new wchar_t[len + 1]; + //memset( res, 0, (len + 1)*sizeof(wchar_t) ); + //for ( size_t i = 0; i < len; i++ ) + //{ + // if ( str[i] < 128 ) + // memcpy( res+i, str+i, 1 ); + // else + // memcpy( res+i, &unChar, 1 ); + //} + //std::mbstowcs( res, str, len ); +#endif // __MOBILE_VERSION__ + } + + return res; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Конвертировать WCHAR в CHAR строку. + \en Convert WCHAR-string to CHAR-string. \~ + \details \ru Конвертировать WCHAR в CHAR строку, удалять по delete[]. \n + \en Convert WCHAR-string to CHAR-string, delete by the delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +//--- +inline char * wcsnewmbs( const wchar_t * str ) +{ + char * res = NULL; + + if ( str ) + { + // \ru один WCHAR может занять более одного CHAR! \en one WCHAR may replace more than one CHAR! +#ifdef C3D_WINDOWS // _MSC_VER + size_t n = wcstombs( NULL, str, 0 ); +#else // C3D_WINDOWS + size_t n = std::wcstombs( NULL, str, 0 ); +#endif // C3D_WINDOWS + + if ( n != NSIZE ) + { + n++; + res = new char[n]; +#ifdef C3D_WINDOWS // _MSC_VER + wcstombs( res, str, n ); +#else // C3D_WINDOWS + std::wcstombs( res, str, n ); +#endif // C3D_WINDOWS + } + else // \ru переводим по одному символу, вместо непереведенных ставим "?" \en convert by word and replace not converted words by the symbol "?" + { + size_t len = wcslen( str ); + res = new char[len + 1]; + ::memset( res, 0, len + 1 ); + + for ( size_t i = 0; i < len; i++ ) + { +#ifdef C3D_WINDOWS // _MSC_VER // \ru Актуально только под Windows см. Ошибка 42704 \en It is actual only for Windows Error 42704 + char c; + if ( ::wctomb( &c, str[i] ) == sizeof(char) ) + res[i] = c; + else +#endif // C3D_WINDOWS + res[i] = '?'; + } + } + + } + + return res; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Буфер CHAR-строки. + \en A buffer of a CHAR-string \~ + \details \ru Буфер CHAR-строки. \n + \en A buffer of a CHAR-string \n \~ + \ingroup Base_Tools_String +*/ +// --- +class strbuf +{ + char * buf; ///< \ru Буфер строки. \en A buffer of a string. + +public: + /// \ru Конструктор дублирования. \en Constructor of duplicating. + strbuf( const char * str ) { + buf = strnewdup( str ); + } + /// \ru Конструктор конвертирования из WCHAR. \en Constructor of converting from WCHAR. + strbuf( const wchar_t * str ) { + buf = wcsnewmbs( str ); + } + /// \ru Конструктор резервирования. \en Constructor of reservation. + strbuf( size_t len ) { + buf = new char[len]; + *buf = 0; + } + /// \ru Деструктор. \en Destructor. + ~strbuf() { + delete [] buf; + } + /// \ru Оператор доступа. \en An access operator. + operator const char * () const { return buf; } + /// \ru Оператор доступа. \en An access operator. + operator char * () { return buf; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Буфер WCHAR-строки. + \en A buffer of a WCHAR-string. \~ + \details \ru Буфер WCHAR-строки. \n + \en A buffer of a WCHAR-string. \n \~ + \ingroup Base_Tools_String +*/ +// --- +class wcsbuf +{ + wchar_t * buf; ///< \ru Буфер строки. \en A buffer of a string. + +public: + /// \ru Конструктор дублирования. \en Constructor of duplicating. + wcsbuf( const wchar_t * str ) { + buf = wcsnewdup( str ); + } + /// \ru Конструктор конвертирования из CHAR. \en Constructor of converting from CHAR. + wcsbuf( const char * str ) { + buf = mbsnewwcs( str ); + } + /// \ru Конструктор резервирования. \en Constructor of reservation. + wcsbuf( size_t len ) { + buf = new wchar_t[len]; + *buf = 0; + } + /// \ru Деструктор. \en Destructor. + ~wcsbuf() { + delete [] buf; + } + /// \ru Оператор доступа. \en An access operator. + operator const wchar_t * () const { return buf; } + /// \ru Оператор доступа. \en An access operator. + operator wchar_t * () { return buf; } +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Конвертирование CHAR, WCHAR и TCHAR-строк \en Converting of CHAR-, WCHAR- and TCHAR-strings +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef C3D_WINDOWS // _MSC_VER + +#ifdef _UNICODE + +#define _tcsbuf wcsbuf ///< \ru Буфер TCHAR-строки \en A buffer of a TCHAR-string +#define _tcsnewdup wcsnewdup ///< \ru Дублировать TCHAR-строку \en Duplicate a TCHAR-string + +inline const wchar_t * wcsret( const wchar_t * str ) { return str; } /// \ru Возврат WCHAR-строки. \en Return a WCHAR-string \~ \ingroup Base_Tools_String + +// \ru Конвертирование CHAR, WCHAR и TCHAR-строк НА СТЕКЕ! \en Converting of CHAR-, WCHAR- and TCHAR-strings ON STACK! +#define _tcs2str strbuf // \ru TCHAR в CHAR те WCHAR в CHAR \en TCHAR to CHAR i.e. WCHAR to CHAR +#define _str2tcs wcsbuf // \ru CHAR в TCHAR те CHAR в WCHAR \en CHAR to TCHAR i.e. CHAR to WCHAR +#define _tcs2wcs wcsret // \ru TCHAR в WCHAR те WCHAR в WCHAR \en TCHAR to WCHAR i.e. WCHAR to WCHAR +#define _wcs2tcs wcsret // \ru WCHAR в TCHAR те WCHAR в WCHAR \en TCHAR to WCHAR i.e. WCHAR to WCHAR + +#define _tcsNstr wcsnewmbs // \ru TCHAR в CHAR \en TCHAR to CHAR +#define _strNtcs mbsnewwcs // \ru CHAR в TCHAR \en CHAR to TCHAR + +#else // _UNICODE + +#define _tcsbuf strbuf +#define _tcsnewdup strnewdup ///< \ru Дублировать TCHAR-строку \en Duplicate a TCHAR-string + +inline const char * strret( const char * str ) { return str; } /// \ru Возврат CHAR-строки. \en Return a CHAR-string. \~ \ingroup Base_Tools_String + +// \ru Конвертирование CHAR, WCHAR и TCHAR-строк НА СТЕКЕ! \en Converting of CHAR-, WCHAR- and TCHAR-strings ON STACK! +#define _tcs2str strret // \ru TCHAR в CHAR те CHAR в CHAR \en TCHAR to CHAR i.e. CHAR to CHAR +#define _str2tcs strret // \ru CHAR в TCHAR те CHAR в CHAR \en CHAR to TCHAR i.e. CHAR to CHAR +#define _tcs2wcs wcsbuf // \ru TCHAR в WCHAR те CHAR в WCHAR \en TCHAR to WCHAR i.e. CHAR to WCHAR +#define _wcs2tcs strbuf // \ru WCHAR в TCHAR те WCHAR в CHAR \en WCHAR to TCHAR i.e. WCHAR to CHAR + +#define _tcsNstr strnewdup // \ru TCHAR в CHAR \en TCHAR to CHAR +#define _strNtcs strnewdup // \ru CHAR в TCHAR \en CHAR to TCHAR + +#endif // _UNICODE + +#else // C3D_WINDOWS + +// \ru Linux: заменяем реализацию string на стандартную (std::string); \en Linux: replace implementation of string by the standard (std::string); +// \ru все вызовы внутри математики переделаны под стандартную реализацию строк (std::string) \en all calls inside the mathematics reimplemented for the standard implementation of strings (std::string) +// \ru Под Linux определение _UNICODE не должно влиять на компиляцию кода \en In Linux the definition _UNICODE should not influence the code compiling + +#ifdef _UNICODE + +#define _tcsbuf wcsbuf +#define _tcsnewdup wcsnewdup ///< \ru Дублировать TCHAR-строку \en Duplicate a TCHAR-string + +//inline const char* strret( const char* str ) { return str; } /// \ru Возврат CHAR-строки. \en Returns CHAR-string. \~ \ingroup Base_Tools_String + +// \ru Конвертирование CHAR, WCHAR и TCHAR-строк НА СТЕКЕ! \en Converting of CHAR-, WCHAR- and TCHAR-strings ON STACK! +#define _tcs2str strret // \ru TCHAR в CHAR те CHAR в CHAR \en TCHAR to CHAR i.e. CHAR to CHAR +#define _str2tcs strret // \ru CHAR в TCHAR те CHAR в CHAR \en CHAR to TCHAR i.e. CHAR to CHAR +#define _tcs2wcs wcsbuf // \ru TCHAR в WCHAR те CHAR в WCHAR \en TCHAR to WCHAR i.e. CHAR to WCHAR +#define _wcs2tcs strbuf // \ru WCHAR в TCHAR те WCHAR в CHAR \en WCHAR to TCHAR i.e. WCHAR to CHAR + +#define _tcsNstr wcsnewmbs // \ru TCHAR в CHAR \en TCHAR to CHAR +#define _strNtcs mbsnewwcs // \ru CHAR в TCHAR \en CHAR to TCHAR + +#else // _UNICODE + +#define _tcsbuf strbuf +#define _tcsnewdup strnewdup ///< \ru Дублировать TCHAR-строку \en Duplicate a TCHAR-string + +//inline const char* strret( const char* str ) { return str; } /// \ru Возврат CHAR-строки. \en Returns CHAR-string. \~ \ingroup Base_Tools_String + +// \ru Конвертирование CHAR, WCHAR и TCHAR-строк НА СТЕКЕ! \en Converting of CHAR-, WCHAR- and TCHAR-strings ON STACK! +#define _tcs2str strret // \ru TCHAR в CHAR те CHAR в CHAR \en TCHAR to CHAR i.e. CHAR to CHAR +#define _str2tcs strret // \ru CHAR в TCHAR те CHAR в CHAR \en CHAR to TCHAR i.e. CHAR to CHAR +#define _tcs2wcs wcsbuf // \ru TCHAR в WCHAR те CHAR в WCHAR \en TCHAR to WCHAR i.e. CHAR to WCHAR +#define _wcs2tcs strbuf // \ru WCHAR в TCHAR те WCHAR в CHAR \en WCHAR to TCHAR i.e. WCHAR to CHAR + +#define _tcsNstr strnewdup // \ru TCHAR в CHAR \en TCHAR to CHAR +#define _strNtcs strnewdup // \ru CHAR в TCHAR \en CHAR to TCHAR + +#endif // _UNICODE + +#endif // C3D_WINDOWS + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// \ru Конвертирование UTF-16(ISO-10646-UTF-16 encoded) и UCS-4(ISO-10646-UCS-4 encoded) -строк \en Converting of UTF-16(ISO-10646-UTF-16 encoded) and UCS-4(ISO-10646-UCS-4 encoded) -strings +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +/** \brief \ru Конвертировать UTF-16 в UCS-4 строку. + \en Convert from UTF-16 to UCS-4 string. \~ + \details \ru Конвертировать UTF-16 в UCS-4 строку, удалять по delete[]. \n + \en Convert from UTF-16 to UCS-4 string, delete with delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +//--- +inline uint32* Utf16ToUcs4( uint16* source, size_t* calculateCountSymbol = NULL ) +{ + size_t count = 0; // \ru количество символов в строке \en a number of symbols in string + uint32 * outBuf = NULL; + if ( source ) + { + while (source[count] != 0) + ++count; + + outBuf = new uint32[count + 1]; // \ru буфер для выдачи наружу \en a buffer for external using + memset( outBuf, 0, sizeof(uint32/*outBuf*/)*(count + 1) ); + for ( size_t i = 0; i < count; ++i ) + outBuf[i] = MkUint32( source[i], 0 ); + } + + if ( calculateCountSymbol ) + *calculateCountSymbol = count; + + return outBuf; +} + +//------------------------------------------------------------------------------ +/** \brief \ru Конвертировать UCS-4 в UTF-16 строку. + \en Convert from UCS-4 to UTF-16 string. \~ + \details \ru Конвертировать UCS-4 в UTF-16 строку, удалять по delete[]. \n + \en Convert from UCS-4 to UTF-16 string, delete with delete[] operator. \n \~ + \ingroup Base_Tools_String +*/ +//--- +inline uint16* Ucs4ToUtf16( uint32* source, size_t* calculateCountSymbol = NULL ) +{ + size_t count = 0; // \ru количество символов в строке \en a number of symbols in string + uint16 * outBuf = NULL; + if ( source ) + { + while (source[count] != 0) + ++count; + + outBuf = new uint16[count + 1]; // \ru буфер для выдачи наружу \en a buffer for external using +#ifndef __MOBILE_VERSION__ + memset( outBuf, 0, sizeof(uint16/*BUG_82447 outBuf*/)*(count + 1) ); + for ( size_t i = 0; i < count; ++i ) + if ( HiUint16( source[i] ) == 0 ) + outBuf[i] = LoUint16( source[i] ); + else + outBuf[i] = (uint16)'?'; +#else // __MOBILE_VERSION__ + for ( size_t i = 0; i < count; ++i ) + outBuf[i] = LoUint16( source[i] ); + outBuf[count] = uint16(0); +#endif // __MOBILE_VERSION__ + } + + if ( calculateCountSymbol ) + *calculateCountSymbol = count; + + return outBuf; +} + +#if defined (C3D_WINDOWS) && !defined(ALL_WARNINGS) // _MSC_VER // Set warnings level +#pragma warning(pop) // Restore state of warning settings +#endif + +#endif // __TOOL_STRING_UTIL_H diff --git a/C3d/Include/tool_time_test.h b/C3d/Include/tool_time_test.h new file mode 100644 index 0000000..e0f5c74 --- /dev/null +++ b/C3d/Include/tool_time_test.h @@ -0,0 +1,259 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Отладочное средство для сбора информации о времени выполнения алгоритмов. + \en A debug tool for collection of the information about the algorithm running time. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOL_TIME_TEST_H +#define __TOOL_TIME_TEST_H + + +#define __TIMETEST__ + +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------ +// +// --- +class MATH_CLASS TimeTestStruct +{ +public: + c3d::string_t name; // \ru имя замера \en a name of measurement + c3d::string_t attitude; // \ru отношение действия \en a relation of the action + uint64 timeResult; // \ru время замера в тактах процессора \en a time of the measurement in processor cycles + +public: + TimeTestStruct( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult ); + TimeTestStruct( const TimeTestStruct & ); + ~TimeTestStruct(); +public: + void Init( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult ); + void Init( const TimeTestStruct & other ); + double GetMiliseconds(); // \ru перевести timeResult в миллисекунды и выдать \en convert timeResult to milliseconds and return. +private: + const TimeTestStruct & operator = ( const TimeTestStruct & other ) { Init( other ); return *this; } +}; + + +//------------------------------------------------------------------------------ +// +// --- +struct MATH_CLASS TimeTestNode : public TimeTestStruct +{ +public: + size_t selfId; // \ru собственный Id \en own Id + size_t parentId; // \ru Id родителя \en Id of the parent + +public: + explicit TimeTestNode( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult ); + TimeTestNode( const TimeTestNode & ); + ~TimeTestNode(); +public: + void Init( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult, size_t _selfId, size_t _parentId ); + void Init( const TimeTestNode & other ); +public: + const TimeTestNode & operator = ( const TimeTestNode & other ) { Init( other ); return *this; } +}; + + +//------------------------------------------------------------------------------ +// +// --- +struct MATH_CLASS TimeTestResult : public TimeTestStruct { +public: + size_t count; + size_t averageTime; + +public: + explicit TimeTestResult( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult ) + : TimeTestStruct( _name, _attitude, _timeResult ) + , count ( 1 ) + , averageTime( 0 ) + { + } + TimeTestResult( const TimeTestResult & other ) + : TimeTestStruct( other ) + , count ( other.count ) + , averageTime ( other.averageTime ) + { + } + ~TimeTestResult() + { + } +public: + void Init( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _timeResult ) + { + TimeTestStruct::Init( _name, _attitude, _timeResult ); + count = 1; + averageTime= 0; + } + void Init( const TimeTestResult & other ) + { + TimeTestStruct::Init( other ); + count = other.count; + averageTime = other.averageTime; + } +public: + const TimeTestResult & operator = ( const TimeTestResult & other ) { Init( other ); return *this; } +}; + + +//------------------------------------------------------------------------------ +// +// --- +class TimeTestAsCalc : public TimeTestNode { +public: + uint64 beginTime; // \ru время начала замера в тактах процессора \en a time of the measurement start in processor cycles + +public: + explicit TimeTestAsCalc( const c3d::string_t & _name, const c3d::string_t & _attitude, uint64 _beginTime ) + : TimeTestNode( _name, _attitude, 0 ) + , beginTime( _beginTime ) + { + } + TimeTestAsCalc( const TimeTestAsCalc & other ) + : TimeTestNode( other ) + , beginTime( other.beginTime ) + { + } + ~TimeTestAsCalc() + { + } +public: + const TimeTestAsCalc & operator = ( const TimeTestAsCalc & other ) { TimeTestNode::Init( other ); beginTime = other.beginTime; return *this; } +}; + + +//------------------------------------------------------------------------------ +// +// --- +class MATH_CLASS TimeTest { +public: + std::vector results; + std::vector ttAsCalcs; + size_t countEnd; + bool searchErr; // \ru поиск ошибки \en an error search + +public: + TimeTest(); + ~TimeTest(); + +public: + TimeTest * GetTimeTest (); + std::vector & GetListResult () { return results; } + void BeginTime ( const TCHAR * name, const TCHAR * attitude ); // \ru начало замера \en start of the measurement + void EndTime ( const TCHAR * name ); // \ru окончание замера \en end of the measurement + void ClearTime (); + +private: + TimeTest( const TimeTest & ); + const TimeTest & operator = ( const TimeTest & ); +}; + + +//------------------------------------------------------------------------------ +// \ru сброс \en reset +// --- +MATH_FUNC(void) SetTimeTest( bool allow ); + + +//------------------------------------------------------------------------------ +// \ru проверить измерения \en check measurements +// --- +MATH_FUNC(bool) CheckTimeTest(); + + +//------------------------------------------------------------------------------ +// \ru начало замера \en start of the measurement +// --- +MATH_FUNC(void) BeginTime( const TCHAR * name, const TCHAR * attitude ); + + +//------------------------------------------------------------------------------ +// \ru окончание замера \en end of the measurement +// --- +MATH_FUNC(void) EndTime( const TCHAR * name ); + + +//------------------------------------------------------------------------------ +// \ru Выдать результат в LOG_PATH + fileName \en Return the result in LOG_PATH + fileName +// --- +MATH_FUNC(void) TimeTestReport( const TCHAR * fileName ); + + +//------------------------------------------------------------------------------ +// \ru выдать все результаты \en return all results +// --- +MATH_FUNC(TimeTest *)GetTimeTestResults (); +MATH_FUNC(void) SortResultMeasuring( TimeTest &, std::vector & ); + + +//////////////////////////////////////////////////////////////////////////////// +// +// \ru Как этим пользоваться \en The usage +// \ru 1. вписать в начало функции BEGIN_TIME(name,group) (БЕЗ ; !!!) \en 1. inscribe to the begin of the function BEGIN_TIME(name,group) (WITHOUT ";" at the end !!!) +// \ru где name - имя_класса::имя_функции, \en where 'name' is name_of_class::name_of_function, +// \ru group - группа к которой относится эта функция \en 'group' - a group which the function belongs to +// +// \ru 2. вписать в конец функции END_TIME(name) (БЕЗ ; !!!) \en 2. inscribe to the end of the function END_TIME(name) (WITHOUT ";" at the end !!!) +// \ru так-же можно окружить любое место кода, но name должно быть уникальное ВО ВСЕЙ ЗАДАЧЕ!!! \en in the same way any part of the code may be bounded by these calls. Note that 'name' should be unique in THE ENTIRE SOLUTION!!! +// \ru количество BEGIN_TIME должно быть строго равно количеству END_TIME осторожно \en the number of BEGIN_TIME calls should be equal to the number of END_TIME calls, be careful +// +// \ru KYA K12 первому вызову замера верить нельзя, т.к. в BeginTime тратится время на выделение памяти! \en KYA K12 the result of first call of measurement is not significant, because in BeginTime function a lot of time consumes for the memory allocation! +// +//////////////////////////////////////////////////////////////////////////////// + + +#if defined(C3D_DEBUG) + + #define TB_OTHERS _T("Разные операции:") + + #define TB_MATH_BASE _T("MATH_BASE:") + #define TB_MATH_BUILDINGS _T("MATH_BUILDINGS:") + #define TB_MATH_COMPUTATIONS _T("MATH_COMPUTATIONS:") + #define TB_MATH_CONSTRAINTS _T("MATH_CONSTRAINTS:") + #define TB_MATH_CONVERTERS _T("MATH_CONVERTERS:") + #define TB_TEST _T("Test.exe:") + + #define SET_TIME_TEST(allow) ::SetTimeTest ( allow ); + #define CHECK_TIME_TEST() ::CheckTimeTest (); + + #define BEGIN_TIME1(name,attitude) ::BeginTime ( name, attitude ); // \ru копирование оболочек, методы пересечения \en copying of shells, intersection methods + #define END_TIME1(name) ::EndTime ( name ); + +#else // C3D_DEBUG + + #define TB_OTHERS + + #define TB_MATH_BASE + #define TB_MATH_BUILDINGS + #define TB_MATH_COMPUTATIONS + #define TB_MATH_CONSTRAINTS + #define TB_MATH_CONVERTERS + #define TB_TEST + + #define SET_TIME_TEST(allow) + #define CHECK_TIME_TEST() + + #define BEGIN_TIME1(name,attitude) + #define END_TIME1(name) + +#endif // C3D_DEBUG > 0 + + +#define SET_TIME_TEST_REL(allow) ::SetTimeTest( allow ); +#define BEGIN_TIME_REL(name,attitude) ::BeginTime( name, attitude ); +#define END_TIME_REL(name) ::EndTime( name ); +#define TIME_TEST_REPORT_REL(filename) ::TimeTestReport( filename ); + + +#endif // __TOOL_TIME_TEST_H diff --git a/C3d/Include/tool_uuid.h b/C3d/Include/tool_uuid.h new file mode 100644 index 0000000..b194937 --- /dev/null +++ b/C3d/Include/tool_uuid.h @@ -0,0 +1,288 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Глобально уникальный идентификатор. + \en Global unique identifier. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _TOOL_UUID_H_ +#define _TOOL_UUID_H_ + +#include +#include +#include +#include +#include + +class reader; +class writer; + + +const uint8 uuidSize = 16; + + +//------------------------------------------------------------------------------ +/** \brief \ru Глобально уникальный идентификатор. + \en Global unique identifier. \~ + \details \ru Глобально уникальный идентификатор - используется как идентификатор + типа пользовательского атрибута. + \en Global unique identifier - it is used as an identifier + of a type of user attribute. \~ + \ingroup Model_Attributes + */ +struct MbUuid +{ +protected: + uint8 data[uuidSize]; +private: + mutable ThreeStates isEmpty; + +public: + typedef uint8 * iterator; + typedef uint8 const * const_iterator; +public: + MbUuid() : isEmpty( ts_positive ) { ::memset( data, 0, uuidSize ); } + MbUuid( const MbUuid & id ) : isEmpty( id.isEmpty ) { ::memcpy( data, id.data, uuidSize ); } +public: + iterator begin() { isEmpty = ts_neutral; return data; } + iterator end() { isEmpty = ts_neutral; return data + uuidSize; } + + const_iterator cbegin() const { return data; } + const_iterator cend() const { return data + uuidSize; } + + size_t size() const { return uuidSize; } + + bool is_nil() const + { + if ( isEmpty == ts_neutral ) { + isEmpty = ts_positive; + for ( uint8 i = 0; i < uuidSize; i++ ) { + if ( data[i] != 0U ) { + isEmpty = ts_negative; + break; + } + } + } + return (isEmpty == ts_positive); + } + void swap( MbUuid & id ) + { + uint8 temp[16]; + ::memcpy( temp, data, uuidSize ); + ::memcpy( data, id.data, uuidSize ); + ::memcpy( id.data, temp, uuidSize ); + std::swap( isEmpty, id.isEmpty ); + } + +public: + MbUuid & operator = ( const MbUuid & id ) + { + ::memcpy( data, id.data, uuidSize ); + isEmpty = id.isEmpty; + return *this; + } + bool operator == ( const MbUuid & id ) const + { + //return std::equal( cbegin(), cend(), id.cbegin() ); + MbUuid::const_iterator first1 = cbegin(), last1 = cend(), first2 = id.cbegin(); + while ( first1 != last1 ) + { + if ( !(*first1 == *first2) ) + return false; + ++first1; ++first2; + } + return true; + } + bool operator != ( const MbUuid & id ) const { return !(*this == id); } + bool operator < ( const MbUuid & id ) const { return std::lexicographical_compare( cbegin(), cend(), id.cbegin(), id.cend() ); } + bool operator > ( const MbUuid & id ) const { return (id < *this); } + bool operator <= ( const MbUuid & id ) const { return !(id < *this); } + bool operator >= ( const MbUuid & id ) const { return !(*this < id); } + +public: + friend struct string_generator; + friend reader & CALL_DECLARATION operator >> ( reader & in, MbUuid & ref ); + friend writer & CALL_DECLARATION operator << ( writer & out, const MbUuid & ref ); + friend writer & CALL_DECLARATION operator << ( writer & out, MbUuid & ref ) { return operator << ( out, (const MbUuid &)ref ); } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Генератор MbUuid из string. + \en Generator of MbUuid from string. \~ + \details \ru Генератор MbUuid из string. Принимает следующие формы: \n + 0123456789abcdef0123456789abcdef, \n + 01234567-89ab-cdef-0123456789abcdef, \n + {01234567-89ab-cdef-0123456789abcdef}, \n + {0123456789abcdef0123456789abcdef}. \n + \en Generator of MbUuid from string. It accepts the next format: \n + 0123456789abcdef0123456789abcdef, \n + 01234567-89ab-cdef-0123456789abcdef, \n + {01234567-89ab-cdef-0123456789abcdef}, \n + {0123456789abcdef0123456789abcdef}. \n + \~ + \ingroup Model_Attributes +*/ +//--- +struct string_generator +{ + template + MbUuid operator()( std::basic_string const & s ) const { + return operator()( s.begin(), s.end() ); + }; + + MbUuid operator()( char const * const s ) const { + return operator()( s, s+std::strlen(s) ); + } + + MbUuid operator()( wchar_t const * const s ) const { + return operator()( s, s+std::wcslen(s) ); + } + + template + MbUuid operator()( CharIterator begin, CharIterator end ) const + { + typedef typename std::iterator_traits::value_type char_type; + + // \ru Проверяем открывающую скобку \en Check an opening parenthesis. + char_type c = get_next_char( begin, end ); + bool has_open_brace = is_open_brace(c); + char_type open_brace_char = c; + if ( has_open_brace ) { + c = get_next_char( begin, end ); + } + + bool has_dashes = false; + + MbUuid u; + bool isEmpty = true; + + int i = 0; + for ( MbUuid::iterator it_byte = u.begin(); it_byte != u.end(); ++it_byte, ++i ) { + if ( it_byte != u.begin() ) { + c = get_next_char( begin, end ); + } + if ( i == 4 ) { + if ( is_dash(c) ) { + c = get_next_char( begin, end ); + has_dashes = true; + } + } + if ( has_dashes ) { + if ( is_dash(c) ) { + c = get_next_char( begin, end ); + } + } + + *it_byte = get_value(c); + + c = get_next_char( begin, end ); + *it_byte <<= 4; + *it_byte |= get_value(c); + if ( *it_byte != 0U ) + isEmpty = false; + } + + // \ru Проверяем закрывающую скобку \en Check a closing parenthesis + if ( has_open_brace ) { + c = get_next_char( begin, end ); + check_close_brace( c, open_brace_char ); + } + + u.isEmpty = isEmpty ? ts_positive : ts_negative; + return u; + } + +private: + template + typename std::iterator_traits::value_type + get_next_char( CharIterator & begin, CharIterator end ) const { + if ( begin == end ) { + _ASSERT( false ); + } + return *begin++; + } + + unsigned char get_value( char c ) const { + static char const*const digits_begin = "0123456789abcdefABCDEF"; + static char const*const digits_end = digits_begin + 22; + + static unsigned char const values[] = + { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 + , static_cast(-1) }; + + char const * d = std::find( digits_begin, digits_end, c ); + return values[d - digits_begin]; + } + + unsigned char get_value( wchar_t c ) const { + static wchar_t const*const digits_begin = L"0123456789abcdefABCDEF"; + static wchar_t const*const digits_end = digits_begin + 22; + + static unsigned char const values[] = + { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 + , static_cast(-1) }; + + wchar_t const * d = std::find( digits_begin, digits_end, c ); + return values[d - digits_begin]; + } + + bool is_dash( char c ) const { return c == '-'; } + bool is_dash( wchar_t c ) const { return c == L'-'; } + + // \ru Возвращаем открывающую скобку \en Return an opening parenthesis. + bool is_open_brace( char c ) const { return (c == '{'); } + bool is_open_brace( wchar_t c ) const { return (c == L'{'); } + + bool check_close_brace( char c, char open_brace ) const { + if ( open_brace == '{' && c == '}' ) + return true; + _ASSERT( false ); + return false; + } + + bool check_close_brace( wchar_t c, wchar_t open_brace ) const { + if ( open_brace == L'{' && c == L'}' ) + return true; + _ASSERT( false ); + return false; + } +}; + + +struct hash8_generator +{ + uint8 operator()( const MbUuid & trg ) const + { + static uint8 rand8[256] = + { + 1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51, + 87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65, + 49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28, + 12, 181, 103, 70, 22, 58, 75, 78, 183, 167, 238, 157, 124, 147, 172, 144, + 176, 161, 141, 86, 60, 66, 128, 83, 156, 241, 79, 46, 168, 198, 41, 254, + 178, 85, 253, 237, 250, 154, 133, 88, 35, 206, 95, 116, 252, 192, 54, 221, + 102, 218, 255, 240, 82, 106, 158, 201, 61, 3, 89, 9, 42, 155, 159, 93, + 166, 80, 50, 34, 175, 195, 100, 99, 26, 150, 16, 145, 4, 33, 8, 189, + 121, 64, 77, 72, 208, 245, 130, 122, 143, 55, 105, 134, 29, 164, 185, 194, + 193, 239, 101, 242, 5, 171, 126, 11, 74, 59, 137, 228, 108, 191, 232, 139, + 6, 24, 81, 20, 127, 17, 91, 92, 251, 151, 225, 207, 21, 98, 113, 112, + 84, 226, 18, 214, 199, 187, 13, 32, 94, 220, 224, 212, 247, 204, 196, 43, + 249, 236, 45, 244, 111, 182, 153, 136, 129, 90, 217, 202, 19, 165, 231, 71, + 230, 142, 96, 227, 62, 179, 246, 114, 162, 53, 160, 215, 205, 180, 47, 109, + 44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184, + 163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120, 209 + }; + + uint8 h = 0; + MbUuid::const_iterator curr_iter = trg.cbegin(), end_iter = trg.cend(); + while ( curr_iter != end_iter ) + h = rand8[h ^ *curr_iter++]; + return h; + } +}; + + +#endif // _TOOL_UUID_H_ diff --git a/C3d/Include/topology.h b/C3d/Include/topology.h new file mode 100644 index 0000000..3b4955c --- /dev/null +++ b/C3d/Include/topology.h @@ -0,0 +1,1940 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Топологические объекты: вершина, ребра, цикл, грань. + \en Topological objects: vertices, edges, loop, face. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOPOLOGY_H +#define __TOPOLOGY_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbCurve; +class MATH_CLASS MbContour; +class MATH_CLASS MbMesh; +class MATH_CLASS MbCurve3D; +class MATH_CLASS MbContour3D; +class MATH_CLASS MbPlane; +class MATH_CLASS MbContourOnSurface; +class MATH_CLASS MbContourOnPlane; +class MATH_CLASS MbSurfaceIntersectionCurve; +class MATH_CLASS MbVertex; +class MATH_CLASS MbEdge; +class MATH_CLASS MbCurveEdge; +class MATH_CLASS MbOrientedEdge; +class MATH_CLASS MbLoop; +class MATH_CLASS MbFace; +class MATH_CLASS MbFunction; +class MATH_CLASS MbFaceTemp; +struct MATH_CLASS MbItemIndex; + + +namespace c3d // namespace C3D +{ +// vertices typedefs +typedef SPtr VertexSPtr; +typedef SPtr ConstVertexSPtr; + +typedef std::vector VerticesVector; +typedef std::vector ConstVerticesVector; + +typedef std::vector VerticesSPtrVector; +typedef std::vector ConstVerticesSPtrVector; + +// edges typedefs +typedef SPtr WireEdgeSPtr; +typedef SPtr ConstWireEdgeSPtr; + +typedef std::vector WireEdgesVector; +typedef std::vector ConstWireEdgesVector; + +typedef std::vector WireEdgesSPtrVector; +typedef std::vector ConstWireEdgesSPtrVector; + +// edges typedefs +typedef SPtr EdgeSPtr; +typedef SPtr ConstEdgeSPtr; + +typedef std::pair EdgeIndex; +typedef std::pair ConstEdgeIndex; + +typedef std::pair IndexEdge; +typedef std::pair IndexConstEdge; + +typedef std::pair EdgesPair; + +typedef std::vector EdgesVector; +typedef std::vector ConstEdgesVector; + +typedef std::vector EdgesSPtrVector; +typedef std::vector ConstEdgesSPtrVector; + +typedef std::set EdgesSet; +typedef EdgesSet::iterator EdgesSetIt; +typedef EdgesSet::const_iterator EdgesSetConstIt; +typedef std::pair EdgesSetRet; + +typedef std::set EdgesSPtrSet; +typedef EdgesSPtrSet::iterator EdgesSPtrSetIt; +typedef EdgesSPtrSet::const_iterator EdgesSPtrSetConstIt; +typedef std::pair EdgesSPtrSetRet; + +typedef std::set ConstEdgesSet; +typedef ConstEdgesSet::iterator ConstEdgesSetIt; +typedef ConstEdgesSet::const_iterator ConstEdgesSetConstIt; +typedef std::pair ConstEdgesSetRet; + +typedef std::set ConstEdgesSPtrSet; +typedef ConstEdgesSPtrSet::iterator ConstEdgesSPtrSetIt; +typedef ConstEdgesSPtrSet::const_iterator ConstEdgesSPtrSetConstIt; +typedef std::pair ConstEdgesSPtrSetRet; + +// oriented edges typedefs +typedef SPtr OrientEdgeSPtr; +typedef SPtr ConstOrientEdgeSPtr; + +typedef std::pair EdgeOrient; +typedef std::pair ConstEdgeOrient; + +typedef std::pair EdgeSPtrOrient; +typedef std::pair ConstEdgeSPtrOrient; + +typedef std::vector OrientEdgesSPtrVector; +typedef std::vector ConstOrientEdgesSPtrVector; + +typedef std::vector EdgeOrientVector; +typedef std::vector ConstEdgeOrientVector; + +typedef std::vector EdgeSPtrOrientVector; +typedef std::vector ConstEdgeSPtrOrientVector; + +// loops typedefs +typedef SPtr LoopSPtr; +typedef SPtr ConstLoopSPtr; + +typedef std::pair LoopIndex; +typedef std::pair ConstLoopIndex; + +typedef std::pair LoopNumber; +typedef std::vector LoopNumberVector; + +typedef std::vector LoopsVector; +typedef std::vector ConstLoopsVector; + +typedef std::vector LoopsSPtrVector; +typedef std::vector ConstLoopsSPtrVector; + +// faces typedefs +typedef SPtr FaceSPtr; +typedef SPtr ConstFaceSPtr; + +typedef std::pair FaceIndex; +typedef std::pair ConstFaceIndex; + +typedef std::vector FacesVector; +typedef std::vector ConstFacesVector; + +typedef std::vector FacesSPtrVector; +typedef std::vector ConstFacesSPtrVector; + +typedef std::set FacesSet; +typedef FacesSet::iterator FacesSetIt; +typedef FacesSet::const_iterator FacesSetConstIt; +typedef std::pair FacesSetRet; + +typedef std::set FacesSPtrSet; +typedef FacesSPtrSet::iterator FacesSPtrSetIt; +typedef FacesSPtrSet::const_iterator FacesSPtrSetConstIt; +typedef std::pair FacesSPtrSetRet; + +typedef std::set ConstFacesSet; +typedef ConstFacesSet::iterator ConstFacesSetIt; +typedef ConstFacesSet::const_iterator ConstFacesSetConstIt; +typedef std::pair ConstFacesSetRet; + +typedef std::set ConstFacesSPtrSet; +typedef ConstFacesSPtrSet::iterator ConstFacesSPtrSetIt; +typedef ConstFacesSPtrSet::const_iterator ConstFacesSPtrSetConstIt; +typedef std::pair ConstFacesSPtrSetRet; + +typedef std::map FaceIndexMap; +typedef std::map ConstFaceIndexMap; +typedef std::map IndexFaceMap; +typedef std::map IndexConstFaceMap; + +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Вершина. + \en Vertex. \~ + \details \ru Вершина служит для описания стыковки рёбер и + представляет собой точку, в которой стыкуются рёбра. + В вершине может стыковаться любое конечное число рёбер. + Стыкующиеся рёбра указывают на одну и ту же общую для них вершину. + Для вершины известна максимальная погрешностью стыковки рёбер. + При неточной стыковке рёбер погрешность расположения вершины + равна расстоянию от точки вершины до края наиболее удалённого ребра. + \en Vertex is used to describe connections of edges and + it is a point where edges are connected. + Any number of edges may be connected by one vertex. + Adjacent edges point to the same common vertex. + The maximum tolerance of edges connection is known for a vertex. + When the connection is not accurate, the tolerance of the vertex location + equals the distance between the point of the vertex and the end of the farthest edge. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbVertex : public MbTopologyItem { +protected : + MbCartPoint3D point; ///< \ru Точка. \en A point. + double tolerance; ///< \ru Максимальное расстояние от точки до примыкающих ребер. \en Maximum distance from a point to incident edges. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbVertex( const MbVertex &, MbRegDuplicate * ); +public : + /// \ru Конструктор по точке. \en Constructor by point. + MbVertex( const MbCartPoint3D & ); + /// \ru Конструктор по точке и расстоянию. \en Constructor by point and distance. + MbVertex( const MbCartPoint3D &, double s ); + /// \ru Конструктор-копия. \en Copy constructor. + MbVertex( const MbVertex & ); + /// \ru Деструктор. \en Destructor. + virtual ~MbVertex(); + +public : + VISITING_CLASS( MbVertex ); + + // \ru Функции топологического объекта. \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + /// \ru Создать новую вершину копированием всех данных исходной вершины. \en Create new vertex by copying all data of the initial vertex. + virtual MbVertex * DataDuplicate( MbRegDuplicate * = NULL ) const; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Move along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate around an axis. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbTopologyItem & other, double accuracy ) const; + /// \ru Построить полигональную копию объекта mesh. \en Construct a polygonal copy of an object mesh). + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + /// \ru Выдать декартову точку вершины. \en Get the Cartesian point of a vertex. + const MbCartPoint3D & GetCartPoint() const { return point; } + /// \ru Выдать декартову точку вершины. \en Get the Cartesian point of a vertex. + MbCartPoint3D & SetCartPoint() { return point; } + + /// \ru Выдать декартову точку вершины. \en Get the Cartesian point of a vertex. + void GetCartPoint( MbCartPoint3D & cp ) const { cp = point; } + /// \ru Установить декартову точку вершины. \en Set the Cartesian point of a vertex. + void SetCartPoint( const MbCartPoint3D & cp ) { point = cp; SetOwnChanged( tct_Replaced ); } + /// \ru Вычислить ближайшее расстояние до ребра. \en Calculate the nearest distance to an edge. + double DistanceToEdge( const MbCurveEdge & edge, MbCartPoint3D & p0, MbCartPoint3D & p1 ) const; + /// \ru Вычислить ближайшее расстояние до грани. \en Calculate the nearest distance to a face. + double DistanceToFace( const MbFace & face, MbCartPoint3D & p0, MbCartPoint3D & p1 ) const; + + /// \ru Получить погрешность стыковки рёбер. \en Get a tolerance of edges connection. + double GetTolerance() const { return std_max( METRIC_REGION, tolerance ); } + /// \ru Установить погрешность стыковки рёбер. \en Set a tolerance of edges connection. + void SetTolerance( double a ) { tolerance = a; } + /// \ru Установить погрешность стыковки рёбер. \en Set a tolerance of edges connection. + double & SetTolerance() { return tolerance; } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + +private: + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + void operator = ( const MbVertex & ); + + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbVertex ) +}; + +IMPL_PERSISTENT_OPS( MbVertex ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Ребро. + \en Edge. \~ + \details \ru Ребро представляет собой кривую, которой приписано направление. \n + Направление кривой MbCurve3D жёстко связано с направлением возрастания её параметра. + В отличие от кривой ребро может быть направлено как в сторону возрастания параметра, + так и в сторону уменьшения параметра кривой. + Ребро всегда начинается и оканчивается в некоторой вершине MbVertex. \n + \en An edge is a curve with direction. \n + Direction of a curve MbCurve3D is rigidly connected with direction of increasing of its parameter. + In contrast to a curve an edge may be directed either in the direction of increase of parameter + or in the direction of decrease of parameter. + An edge always starts and ends at some vertex MbVertex. \n \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbEdge : public MbTopologyItem { +protected : + MbCurve3D * curve; ///< \ru Кривая, по которой проходит ребро (всегда не NULL). \en A curve, an edge passes by (it is always not NULL). + bool sameSense; ///< \ru Признак совпадения направления ребра с направлением кривой. \en An attribute of coincidence between direction of curve and direction of edge. + MbVertex * begVertex; ///< \ru Вершина-начало (всегда не NULL). \en Start vertex (always not NULL). + MbVertex * endVertex; ///< \ru Вершина-конец (всегда не NULL). \en End vertex (always not NULL). + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbEdge( const MbEdge & init, MbRegDuplicate * iReg ); + +public : + /// \ru Конструктор по кривой, ее ориентации и вершинам. \en Constructor by curve, its orientation and vertices. + MbEdge( const MbCurve3D & initCurve, bool sense, const MbVertex & beg, const MbVertex & end ); + + /** \brief \ru Конструктор по кривой, ее ориентации и вершинам. + \en Constructor by curve, its orientation and vertices. \~ + \details \ru Конструктор ребра по кривой, ее ориентации и вершинам. + Проводится проверка существования и правильности положения точек-вершин ребра. \n + \en Constructor of edge by curve, its orientation and vertices. + There is performed a check of existence and correctness of location of edge vertices points. \n \~ + */ + MbEdge( const MbCurve3D & initCurve, bool sense, const MbVertex * beg, const MbVertex * end ); + + /** \brief \ru Конструктор по кривой и ее ориентации. + \en Constructor by curve and its orientation. \~ + \details \ru Конструктор ребра по кривой и ее ориентации. + Вершины формируются на основе граничных точек кривой. \n + \en Constructor of edge by curve and its orientation. + Vertices are constructed by boundary points of curve. \n \~ + */ + MbEdge( const MbCurve3D & initCurve, bool sense ); + + /// \ru Конструктор копирования с использованием другой кривой. \en Copy constructor using other curve + MbEdge( const MbEdge & other, const MbCurve3D & newCurve ); + /// \ru Деструктор. \en Destructor. + virtual ~MbEdge(); + +public : + VISITING_CLASS( MbEdge ); + + // \ru Функции топологического объекта \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + /// \ru Создать новое ребро копированием всех данных исходного ребра. \en Create new edge by copying all data of the initial edge. + virtual MbEdge * DataDuplicate( MbRegDuplicate * = NULL ) const; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Трансформация. \en Transformation. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Перемещение. \en Moving. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Вращение. \en Rotation. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + + /// \ru Установить флаг изменения в положение измененного объекта. \en Set the flag that the object has been changed. + virtual void SetOwnChangedThrough( MbeChangedType ); + /// \ru Изменить направление ребра на противоположной, не изменяя кривую. \en Change direction of edge without changing a curve. + virtual void Reverse(); + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbTopologyItem & other, double accuracy ) const; + /// \ru Построить полигональную копию объекта mesh. \en Construct a polygonal copy of an object mesh). + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + /// \ru Замена кривой ребра на кривую crv. \en Replacement of a curve by the curve 'crv'. + virtual bool ChangeCurve( MbCurve3D & crv ); + + /// \ru Выдать кривую, по которой проходит ребро. \en Get a curve where an edge passes. + const MbCurve3D & GetCurve() const { return *curve; } + /// \ru Выдать кривую, по которой проходит ребро. \en Get a curve where an edge passes. + MbCurve3D & SetCurve() { return *curve; } + /// \ru Выдать направление по отношению к кривой. \en Get the direction relative to the curve. + bool IsSameSense() const { return sameSense; } + /// \ru Установить направление по отношению к кривой. \en Set the direction relative to the curve. + void SetSameSense( bool s ); + + /// \ru Выдать вершину-начало. \en Get the start vertex. + const MbVertex * GetBegVertexPointer() const { return begVertex; } + /// \ru Выдать вершину-конец. \en Get the end vertex. + const MbVertex * GetEndVertexPointer() const { return endVertex; } + + /// \ru Выдать вершину-начало. \en Get the start vertex. + const MbVertex & GetBegVertex() const { return *begVertex; } + /// \ru Выдать вершину-конец. \en Get the end vertex. + const MbVertex & GetEndVertex() const { return *endVertex; } + /// \ru Выдать вершину по номеру (0 - вершина-начало, 1 - вершина-конец). \en Get vertex by number (0 - start vertex, 1 - end vertex). + const MbVertex & GetVertex( size_t i ) const { return i ? *endVertex : *begVertex; } + /// \ru Выдать вершину-начало. \en Get the start vertex. + MbVertex & SetBegVertex() { return *begVertex; } + /// \ru Выдать вершину-конец. \en Get the end vertex. + MbVertex & SetEndVertex() { return *endVertex; } + /// \ru Выдать вершину по номеру (0 - вершина-начало, 1 - вершина-конец). \en Get vertex by number (0 - start vertex, 1 - end vertex). + MbVertex & SetVertex( size_t i ) { return i ? *endVertex : *begVertex; } + /// \ru Установить вершину-начало. \en Set the start vertex. + void SetBegVertex( const MbVertex & ver ); + /// \ru Установить вершину-конец. \en Set the end vertex. + void SetEndVertex( const MbVertex & ver ); + + /// \ru Выдать вершину, соответствующую начальной точке кривой. \en Get a vertex corresponding to the start point of a curve. + const MbVertex & GetTMinVertex() const { return sameSense ? *begVertex : *endVertex; } + /// \ru Выдать вершину, соответствующую конечной точке кривой. \en Get a vertex corresponding to the end point of a curve. + const MbVertex & GetTMaxVertex() const { return sameSense ? *endVertex : *begVertex; } + /// \ru Выдать вершину, соответствующую начальной точке кривой. \en Get a vertex corresponding to the start point of a curve. + MbVertex & SetTMinVertex() { return sameSense ? *begVertex : *endVertex; } + /// \ru Выдать вершину, соответствующую конечной точке кривой. \en Get a vertex corresponding to the end point of a curve. + MbVertex & SetTMaxVertex() { return sameSense ? *endVertex : *begVertex; } + /// \ru Установить вершину, соответствующую начальной точке кривой. \en Set a vertex corresponding to the start point of a curve. + void SetTMinVertex( const MbVertex & ver ); + /// \ru Установить вершину, соответствующую конечной точке кривой. \en Set a vertex corresponding to the end point of a curve. + void SetTMaxVertex( const MbVertex & ver ); + + /// \ru Выдать параметр кривой, соответствующий начальной вершине. \en Get curve parameter corresponding to the start vertex. + double GetTBegVertex() const; + /// \ru Выдать параметр кривой, соответствующий конечной вершине. \en Get curve parameter corresponding to the end vertex. + double GetTEndVertex() const; + + /// \ru Является ли ребро прямолинейным? \en Is an edge rectilinear? + bool IsStraight() const; + /// \ru Выдать декартову точку начальной вершины. \en Get Cartesian point of start vertex. + void GetBegVertexPoint( MbCartPoint3D & cp ) const { begVertex->GetCartPoint(cp); } + /// \ru Выдать декартову точку конечной вершины. \en Get Cartesian point of end vertex. + void GetEndVertexPoint( MbCartPoint3D & cp ) const { endVertex->GetCartPoint(cp); } + /// \ru Параллельно ли ребро плейсменту? \en Is an edge parallel to the placement? + bool IsColinear( const MbPlacement3D & p, double epsilon = Math::angleRegion ) const; + /// \ru Является ли ребро циклически замкнутым? \en Is an edge cyclic closed? + bool IsClosed() const; + + /// \ru Установить метку себе и вершинам. \en Set a label for self and vertices. + void SetLabelThrough( MbeLabelState l, void * key = NULL ) const; + /// \ru Установить метку себе и вершинам. \en Set a label for self and vertices. + void SetLabelThrough( MbeLabelState l, void * key, bool setLock ) const; + /// \ru Удалить частную метку себе и вершинам. \en Remove private label for self and vertices. + void RemovePrivateLabelThrough( void * key ) const; + /// \ru Проверка того, что вершина принадлежит ребру. \en Check that vertices belong to an edge. + bool IsVertexOn( const MbVertex * vertex ) const { return vertex == begVertex || vertex == endVertex; } + /// \ru Нахождение общей вершины ребер. \en A search of common vertex between edges. + const MbVertex * IsConnectedWith( const MbEdge & edge ) const; + + /// \ru Добавить вершины ребра в множество вершин (если их там нет). \en Add vertices in a set of vertices (if they do not exist). + void GetVerticesArray ( RPArray & ); + /// \ru Добавить вершины ребра в множество вершин (если их там нет). \en Add vertices in a set of vertices (if they do not exist). + void GetVerticesArray ( RPArray & ) const; + + /// \ru Дать параметр для кривой по параметру ребра (0 <= w <= 1). \en Get parameter on a curve by the parameter on an edge (0 <= w <= 1). + double GetCurveParam( double w ) const; + /// \ru Дать параметр от 0(начало) до 1(конец) для ребра по параметру кривой. \en Get parameter from 0 (start) to 1 (end) for an edge by the parameter of a curve. + double GetEdgeParam( double t ) const; + /// \ru Вычислить точка на ребре (0 <= t <= 1). \en Calculate point on the edge (0 <= t <= 1). + void Point( double t, MbCartPoint3D & ) const; + /// \ru Получить точку в начальной вершине. \en Get point at start vertex. + void GetBegPoint( MbCartPoint3D & p ) const { Point( 0, p ); } + /// \ru Получить точку в конечной вершине. \en Get point at end vertex. + void GetEndPoint( MbCartPoint3D & p ) const { Point( 1, p ); } + /// \ru Выдать касательный вектор к ребру ( 0 <= t <= 1 ). \en Get tangent vector to the edge (0 <= t <= 1). + void Tangent( double t, MbVector3D & ) const; + /// \ru Выдать касательный вектор в начальной вершине. \en Get tangent vector at start vertex. + void GetBegTangent( MbVector3D & v ) const { Tangent( 0, v ); } + /// \ru Выдать касательный вектор в конечной вершине. \en Get the tangent vector at the end vertex. + void GetEndTangent( MbVector3D & v ) const { Tangent( 1, v ); } + /// \ru Вычислить производную в середине ребра. \en Calculate derivative in the middle of an edge. + void GetMiddleDerive( MbVector3D & ) const; + + /// \ru Выдать метрическую длину ребра. \en Get the metric length of an edge. + double GetMetricLength() const; + /// \ru Выдать оценку метрической длины ребра. \en Get the estimate of metric length of an edge. + double GetLengthEvaluation() const; + /// \ru Вычислить ближайшее расстояние до ребра. \en Calculate the nearest distance to an edge. + double DistanceToEdge( const MbEdge & edge, MbCartPoint3D & p0, MbCartPoint3D & p1 ) const; + /// \ru Вычислить ближайшее расстояние до грани. \en Calculate the nearest distance to a face. + double DistanceToFace( const MbFace & face, MbCartPoint3D & p0, MbCartPoint3D & p1 ) const; + /// \ru Вычислить ближайшее расстояние до поверхности. \en Calculate the nearest distance to a surface. + double DistanceToSurface( const MbSurface & surf, MbCartPoint3D & p0, MbCartPoint3D & p1 ) const; + /// \ru Вычислить проекцию точки на ребро. \en Calculate the point projection on the edge. + double PointProjection( const MbCartPoint3D & ) const; + /// \ru Вычислить проекцию точки на продолжение прямого ребра. \en Calculate the point projection on extension of a straight edge. + bool PointProjection( const MbCartPoint3D & p0, MbCartPoint3D & pOnEdge, double & distance ) const; + /// \ru Вычислить угол между прямыми ребрами. \en Calculate an angle between straight edges. + bool AngleWithEdge( const MbEdge &, double & angle ) const; + /// \ru Создать проекцию ребра на плоскость. \en Create projection of an edge to the plane. + MbCurve * GetProjection( const MbPlacement3D &, VERSION version ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + OBVIOUS_PRIVATE_COPY( MbEdge ) + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbEdge ) +}; + +IMPL_PERSISTENT_OPS( MbEdge ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Ребро грани. + \en Face edge. \~ + \details \ru Ребро грани представляет собой кривую пересечения поверхностей + MbSurfaceIntersectionCurve, которой приписано направление. + В отличие от ребра MbEdge ребро MbCurveEdge описывает не просто кривую, + а гладкий участок стыковки двух граней или гладкий участок края грани. \n + Ребро грани служит для описания участка стыковки двух граней или для описания участка края грани. \n + Если ребро описывает участок стыковки двух граней, то указатели на грань слева и грань справа ненулевые. \n + Ребро, описывающее участок стыковки циклически замкнутой грани самой с собой, называется швом. \n + В последнем случае указатели на грань слева и грань справа одинаковые. \n + Если ребро описывает участок края грани, то указатель на грань слева или грань справа равен нулю. \n + Ребро, описывающее участок края грани, стянутый в точку, называется полюсным ребром. \n + Если ребро описывает участок края грани, то кривая пересечения поверхностей также является граничной, + то есть состоит из двух одинаковых кривых на поверхности. \n + Ребро начинается и заканчивается в вершинах MbVertex. + Если кривая ребра циклически замкнута, то ребро начинается и заканчивается в одной и той же вершине. \n + \en A face edge is a curve of surfaces intersection + MbSurfaceIntersectionCurve with direction. + In contrast to an edge MbEdge an edge MbCurveEdge describes not just a curve, + but a smooth piece of connection between two faces or a smooth piece of face boundary. \n + A face edge is used to describe a piece of connection between two faces or a piece of face boundary. \n + If an edge describes a piece of connection between two faces then the both pointers to faces are not null. \n + An edge describing a piece of connection of a cyclic closed faces with itself is called seam. \n + In the last case pointers to the left face and to the right face are the same. \n + If an edge describes a piece of face boundary then the pointer to the left face or the pointer to the right face equals null. \n + An edge describing a contracted to a point piece of face boundary is called a pole edge. \n + If an edge describes a piece of face boundary then a curve of surfaces intersection is boundary too, + i.e. it consists of two equal curves on surface. \n + An edge starts and ends in vertices MbVertex. + If a curve of an edge is cyclic closed, then an edge starts and ends at the same vertex. \n \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbCurveEdge : public MbEdge { +protected : + MbFace * facePlus; ///< \ru Грань слева, в которой направление ребра совпадает с направлением цикла. \en A face on the left, where the direction of edge coincides with the direction of loop. + MbFace * faceMinus; ///< \ru Грань справа, в которой направление ребра не совпадает с направлением цикла. \en A face on the right, where the direction of edge does not coincide with the direction of loop. + +protected : + /// \ru Конструктор копирования. \en Copy constructor. + MbCurveEdge( const MbCurveEdge &, MbRegDuplicate * iReg ); + +public : + /// \ru Конструктор по вершинам, кривой пересечения и ее ориентации в ребре. \en Constructor by vertices, intersection curve and its orientation on edge. + MbCurveEdge( const MbVertex & beg, const MbVertex & end, const MbSurfaceIntersectionCurve & initCurve, bool sense ); + + /** \brief \ru Конструктор по вершинам, кривой пересечения и ее ориентации в ребре. + \en Constructor by vertices, intersection curve and its orientation on edge. \~ + \details \ru Конструктор ребра по вершинам, кривой пересечения и ее ориентации в ребре. + Проводится проверка существования и правильности положения точек-вершин ребра. \n + \en Constructor of edge by vertices, intersection curve and its orientation on edge. + There is performed a check of existence and correctness of location of edge vertices points. \n \~ + */ + MbCurveEdge( const MbVertex * beg, const MbVertex * end, const MbSurfaceIntersectionCurve & initCurve, bool sense ); + + /** \brief \ru Конструктор по кривой пересечения. + \en Constructor by intersection curve. \~ + \details \ru Конструктор ребра по кривой пересечения. + Вершины формируются на основе граничных точек кривой. \n + \en Constructor of edge by intersection curve. + Vertices are constructed by boundary points of curve. \n \~ + */ + MbCurveEdge( const MbSurfaceIntersectionCurve &, bool sense ); + + /// \ru Конструктор копирования с использованием другой кривой. \en Copy constructor using other curve + MbCurveEdge( const MbCurveEdge & other, const MbSurfaceIntersectionCurve & newCurve ); + /// \ru Деструктор. \en Destructor. + virtual ~MbCurveEdge(); + +public : + VISITING_CLASS( MbCurveEdge ); + + // \ru Функции топологического объекта \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + /// \ru Создать новое ребро копированием всех данных исходного ребра. \en Create new edge by copying all data of the initial edge. + virtual MbCurveEdge * DataDuplicate( MbRegDuplicate * = NULL ) const; + virtual void SetOwnChangedThrough( MbeChangedType ); // \ru Установить флаг изменения в положение измененного объекта. \en Set the flag that the object has been changed. + virtual void Reverse(); // \ru Изменить направление ребра на противоположной, не изменяя кривую. \en Change direction of edge without changing a curve. + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbTopologyItem &, double accuracy ) const; + + /// \ru Замена кривой ребра на кривую crv. \en Replacement of a curve by the curve 'crv'. + virtual bool ChangeCurve( MbCurve3D & crv ); + + /// \ru Выдать кривую пересечения поверхностей. \en Get surfaces intersection curve. + const MbSurfaceIntersectionCurve & GetIntersectionCurve() const { return (const MbSurfaceIntersectionCurve &)*curve; } + /// \ru Выдать кривую пересечения поверхностей для модификации. \en Get surfaces intersection curve for modification. + MbSurfaceIntersectionCurve & SetIntersectionCurve() { return ( MbSurfaceIntersectionCurve &)*curve; } + /// \ru Дать пространственную копию кривой пересечения поверхностей. \en Get a spatial copy of surfaces intersection curve. + const MbCurve3D * GetSpaceCurve() const; + /// \ru Построить пространственную копию кривой пересечение поверхностей. \en Construct a spatial copy of surfaces intersection curve. + MbCurve3D * MakeCurve() const; + + /// \ru Выдать грань слева. \en Get a face on the left. + MbFace * GetFacePlus () const { return facePlus; } + /// \ru Выдать грань справа. \en Get a face on the right. + MbFace * GetFaceMinus() const { return faceMinus; } + /// \ru Выдать грань по индексу (0 - справа от ребра, 1 - слева от ребра. \en Get a face by index (0 - on the right from an edge, 1 - on the left from an edge). + MbFace * GetFace( size_t i ) const { return i ? facePlus : faceMinus; } + /// \ru Установить грань слева. \en Set a face on the left. + void SetFacePlus ( MbFace * f ) { facePlus = f; } + /// \ru Установить грань справа. \en Set a face on the right. + void SetFaceMinus( MbFace * f ) { faceMinus = f; } + /// \ru Является ли ребро гладким? \en Is an edge smooth? + bool IsSmooth( double epsilon = Math::paramPrecision ) const; + /// \ru Является ли ребро швом? \en Is an edge a seam? + bool IsSeam () const; + /// \ru Является ли ребро разбиением грани? \en Is an edge a face splitting? + bool IsSplit( bool strict = false ) const; + /// \ru Является ли ребро полюсным? \en Is an edge pole? + bool IsPole () const; + /// \ru Является ли ребро обычным ребром пересечения (толерантное по флагу)? \en Is an edge a usual edge of intersection (tolerant by the flag)? + bool IsUsual( bool tolerantIsUsual ) const; + + /// \ru Установить метки ориентированных ребер. \en Set labels of oriented edges. + void SetOrientedEdgesLabel( MbeLabelState, void * key = NULL ); + /// \ru Найти ориентированное ребро. \en Find an oriented edge. + bool FindOrientedEdge( bool orient, const MbFace * face, MbLoop *& findLoop, size_t & index ) const; + /// \ru Найти ориентированное ребро. \en Find an oriented edge. + bool FindOrientedEdgePlus ( size_t & loopIndex, MbLoop *& findLoop, size_t & index ) const; + /// \ru Найти ориентированное ребро. \en Find an oriented edge. + bool FindOrientedEdgeMinus( size_t & loopIndex, MbLoop *& findLoop, size_t & index ) const; + /// \ru Удалить ориентированные ребра на данном ребре. \en Delete oriented edges of the given edge. + void DeleteOrientedEdges(); + + /** \brief \ru Замена поверхности. + \en Replacement of a surface. \~ + \details \ru Замена в кривой поверхности oldSurf на поверхность newSurf. + \en Replacement of the surface oldSurf to the surface newSurf in a curve. \~ + \param[in] oldSurf - \ru Заменяемая поверхность грани. + \en Replaced surface of a face. \~ + \param[in] newSurf - \ru Заменяющая (новая) поверхность грани. + \en Replacing (new) surface of a face. \~ + \param[in] faceSense - \ru Совпадение направления нормали грани и нормали поверхности. + \en Coincidence between the face normal direction and the surface normal direction. \~ + \param[in] orient - \ru Ориентация ребра в цикле грани. + \en Orientation of an edge in the face loop. \~ + */ + void ChangeSurface( const MbSurface & oldSurf, MbSurface & newSurf, bool faceSense, bool orient ); + + /** \brief \ru Замена поверхности. + \en Replacement of a surface. \~ + \details \ru Замена в кривой поверхности item на поверхность init при объединении подобных граней. + \en Replacement of the surface 'item' to the surface 'init' when combining the similar faces. \~ + \param[in] item - \ru Заменяемая поверхность грани. + \en Replaced surface of a face. \~ + \param[in] init - \ru Заменяющая (новая) поверхность грани. + \en Replacing (new) surface of a face. \~ + \param[in] matr - \ru Матрица преобразования двумерных кривых кривой пересечения curve при замене поверхностей. + \en A transformation matrix of two-dimensional curves of intersection curve when replacing surfaces. \~ + \return \ru Выполнена ли замена и преобразование? + \en Are replacement and transformation performed? \~ + */ + bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); + /// \ru Построение нормалей грани face и векторов от ребра в обе стороны. \en Construction of normals of a face and vectors from an edge to both sides. + bool GetTraverses( const MbFace * face, const MbFace * other, bool plus, double t, + double paramStep, double metricStep, MbCartPoint & p0, + MbVector3D & leftNorm, MbVector3D & rightNorm, MbVector3D & left, MbVector3D &right, + VERSION version = Math::DefaultMathVersion() ) const; + /// \ru Построить вектор от ребра вне/внутрь грани (out==true/false). \en Construct a vector from edge to the outside/inside of a face(out==true/false). + bool GetOutTraverse( const MbFace & face, bool plus, double t, double metricStep, MbCartPoint3D & q0, MbVector3D & outv, + MbCartPoint & p0, MbVector & tv, bool & out ) const; + /// \ru Построить перпендикуляр к ребру (0 <= t <= 1) внутрь грани facePlus/faceMinus (plus==true/false). \en Construct perpendicular to an edge (0 <= t <= 1) to the inside of a facePlus/faceMinus (plus==true/false). + bool Transversal( double t, MbVector3D & f, bool plus ) const; + /// \ru Построить перпендикуляр к ребру (0 <= t <= 1) внутрь грани facePlus/faceMinus (plus==true/false). \en Construct perpendicular to an edge (0 <= t <= 1) to the inside of a facePlus/faceMinus (plus==true/false). + bool Transversal( double t, MbVector & f, MbCartPoint & p, bool plus ) const; + /// \ru Построить перпендикуляр к ребру (0 <= t <= 1) внутрь грани facePlus/faceMinus (plus==true/false). \en Construct perpendicular to an edge (0 <= t <= 1) to the inside of a facePlus/faceMinus (plus==true/false). + bool TransversalReper( double t, MbPlacement3D & pl, bool plus ) const; + /// \ru Вычислить на ребре (0 <= t <= 1) двумерную точку p в области параметров поверхности surf. \en Calculate on an edge (0 <= t <= 1) a two-dimensional point p in the region of parameters of the surface surf. + bool PointBy( const MbSurface & surf, bool faceSense, bool orient, double t, MbCartPoint & p ) const; + /// \ru Вычислить на ребре двумерную точку p в области параметров поверхности surf по значению параметра t кривой ребра. \en Calculate two-dimensional point p on the edge in the region of parameters of the surface surf by the value of parameter t on the edge curve. + bool PointOn( const MbSurface & surf, bool faceSense, bool orient, double & t, MbCartPoint & p ) const; + /// \ru Вычислить на ребре двумерную точку p в области параметров поверхности грани face по значению параметра t кривой ребра. \en Calculate two-dimensional point p on the edge in the region of parameters of the ace 'face' by the value of parameter t on the edge curve. + bool PointOn( const MbFace * face, bool orient, double & t, MbCartPoint & p ) const; + /// \ru Нормаль к грани facePlus или faceMinus на ребре (0 <= t <= 1). \en A normal to the face facePlus or faceMinus on the edge (0 <= t <= 1). + bool FaceNormal( double t, MbVector3D & n, bool plus ) const; + /// \ru Нормаль к грани поверхности surf на ребре (0 <= t <= 1) поверхности surf. \en A normal to the surface surf on the edge (0 <= t <= 1) of the surface surf. + bool FaceNormal( const MbSurface & surf, bool faceSense, double t, MbVector3D & p ) const; + /// \ru Средняя нормаль на ребре (0 <= t <= 1) наружу оболочки. \en Calculate a normal on the edge (0 <= t <= 1) outside of the shell. + bool EdgeNormal( double t, MbVector3D & p ) const; + /// \ru Вычислить среднюю нормаль в вершине begin ребра edge. \en Calculate the middle normal at the vertex 'begin' of the edge 'edge'. + bool VertexNormal( bool begin, MbVector3D & normal ) const; + /// \ru Выбор двумерной кривой на поверхности surf в направлении цикла. \en Selection of two-dimensional curve on the surface 'surf' by direction of the loop. + MbCurve * ChooseCurve( const MbSurface & surf, bool faceSene, bool orient ) const; + /// \ru Выбор двумерной кривой на поверхности surf в направлении цикла. \en Selection of two-dimensional curve on the surface 'surf' by direction of the loop. + MbCurve * ChooseCurve( const MbFace * face, bool orient ) const; + /// \ru Дать параметр t крайней точки ребра и соответствующие ему точки на поверхностях кривой пересечения. \en Get parameter t of edge boundary point and the corresponding points on surfaces of the intersection curve. + bool GetLimitParam( bool beg, MbCartPoint & pPlus, MbCartPoint & pMinus, double & t ) const; + /// \ru Вычислить угол ребра (0 <= t <= 1): для выпуклого ребра угол больше нуля, для вогнутого ребра угол меньше нуля. \en Calculate an angle of the edge (0 <= t <= 1). an angle is more than null for a convex edge and less than null for a concave edge. + double FacesAngle( double t ) const; + + /** \brief \ru Выпуклое ли ребро? + \en Is an edge convex? \~ + \details \ru Выпуклое ли ребро по среднему параметру ребра (или среднему параметру указанного диапазона)? + Расчет верен для не меняющего выпуклость ребра. + Для гладких рёбер возвращает ts_neutral. + \en Is an edge convex by its middle parameter (or middle parameter of input range)? + The calculation is correct for edges which do not change a convexity. + Returns ts_neutral for smooth edges. \~ + */ + ThreeStates IsConvex( double angleEps = EXTENT_EPSILON, const MbRect1D * tRange = NULL ) const; + + /**\ru Скопировать из копии готовые метрические оценки, которые в оригинале не были рассчитаны. + \en Copy from the copy ready estimates which were not calculated in the original. \~ + \warning \ru Внимание: для скорости проверка идентичности оригинала и копии не выполняется! + \en Attention: a check of identity between a copy and an original is not performed for the time saving! \~ + */ + bool CopyReadyMutable( const MbCurveEdge & e ); + + /** \brief \ru Вычислить двумерный вектор сдвига двумерной кривой. + \en Calculate two-dimensional vector of two-dimensional curve shift. \~ + \details \ru Вычислить двумерный вектор сдвига двумерной кривой. \n + \en Calculate two-dimensional vector of two-dimensional curve shift. \n \~ + */ + bool GetMoveVector( const MbSurface & surf, bool faceSene, bool orient, MbVector & to ) const; + + /**\ru Где лежат кривые пересечения поверхностей (граней): \n + curveOne на facePlus, curveTwo на faceMinus => +1 \n + curveOne на faceMinus, curveTwo на facePlus => -1 \n + иначе => 0 + \en Where surfaces (faces) intersection curves lie: \n + curveOne on facePlus, curveTwo on faceMinus => +1 \n + curveOne on faceMinus, curveTwo on facePlus => -1 \n + otherwise => 0 \~ + */ + int IsCurveOneOnFacePlus() const; + + /// \ru Cдвиг одной двумерной кривой. \en A shift of two-dimensional curve. + bool MoveBy( const MbSurface & surf, bool faceSense, bool orient, const MbVector & to ); + + /** \brief \ru Разбить ребро на два ребра по параметру его кривой. + \en Split an edge by the parameter of its curve. \~ + \details \ru Если beginSafe == true - ребро сохранит начальный участок, + разбиваемое ребро сохранит начальную вершину и будет кончаться в вершине breakVertex, + новое ребро newEdge будет начинаться в вершине breakVertex и кончаться в бывшей конечной вершине разбиваемого ребра + Если beginSafe == false - ребро сохранит конечный участок, + разбиваемое ребро сохранит конечную вершину и будет начинаться в вершине breakVertex, + новое ребро newEdge будет начинаться в начальной вершине разбиваемого ребра и кончаться в вершине breakVertex \n + Параметр 'surface' необходим только для толерантной кривой пересечения. + Новое ребро встраиваются в циклы смежных граней. Вернет новое ребро. + \en If beginSafe == true then the edge saves its starting piece, + the spit edge will save its start vertex and will end at the vertex breakVertex, + the new edge newEdge will start at the vertex breakVertex and will end at the ex-end vertex of the spit edge + If beginSafe == false then the edge saves its ending piece, + the spit edge will save its end vertex and will start at the vertex breakVertex, + the new edge newEdge will start at the start vertex of the spit edge and will end at the vertex breakVertex.\n + The parameter 'surface' plays a role only for tolerant edge. + The new edge will be embedded in the loops of adjacent faces. + \param[in] t - \ru Параметр кривой пересечения для разбиения ребра, + \en Parameter of intersection curve of edge to split, \~ + \param[in] beginSafe - \ru Ребро сохранит начальную половину (true) или ребро сохранит конечную половину (false), + \en The edge will keep a beginning piece (true) or the edge will keep an end piece (false) \~ + \param[in] surface - \ru Для толерантной кривой требуется указать поверхность, к кривой которой относится параметр. + \en For tolerant curve it is required to specify a surface which contain a curve a parameter belongs to. \~ + \return \ru Возвращает отрезанную часть ребра. + \en Returns a cut edge. \~ + */ + MbCurveEdge * CuttingEdge( double t, bool beginSafe, const MbSurface * surface ); + + /** \brief \ru Усечь ребро по параметру его кривой. + \en Truncate an edge by the parameter of its curve. \~ + \details \ru Если beginCutting == true - отрезается начало ребра, + Если beginCutting == false - отрезается конец ребра. + \en If beginCutting == true - then the starting part of an edge is cut. + If beginCutting == false - then the ending part of an edge is cut. \~ + \param[in] t - \ru Параметр кривой пересечения для усечения ребра. + \en Parameter of intersection curve of edge to truncate. \~ + \param[in] beginCutting - \ru Ребро сохранит начальную половину (false) или ребро сохранит конечную половину (true). + \en The edge will keep a beginning piece (false) or the edge will keep an end piece (true). \~ + \param[in] surface - \ru Для толерантной кривой требуется указать поверхность, к кривой которой относится параметр. + \en For tolerant curve it is required to specify a surface which contain a curve a parameter belongs to. \~ + \return \ru Возвращает true, если усечение выполнено, false - в противном случае. + \en Returns true if the edge was truncated, otherwise returns false. \~ + */ + bool TruncateEdge ( double & t, bool beginCutting, const MbSurface * surface ); + + /** \brief \ru Разбить ребро по параметрам его кривой на несколько его частей. + \en Split the edge by the curve parameters into several pieces. \~ + \details \ru . Если beginSafe == true - ребро сохранит начальный участок, + Если beginSafe == false - ребро сохранит конечный участок. + По параметру 'eps' отсеиваются значения в контейнере 'params', совпадающие друг с другом и с начальным и конечным параметрами кривой пересечения. + Параметр 'surface' необходим только для толерантной кривой пересечения. + Контейнер 'edges' содержит отрезанные части. Отрезанные части встраиваются в циклы смежных граней. + \en . If beginSafe == true then the edge saves its starting piece, + If beginSafe == false then the edge saves its ending piece. + According to the parameter 'eps' drop out value in the container 'params', coinciding with each other and with the initial and final parameters of the intersection curve. + The parameter 'surface' plays a role only for tolerant edge. + The container 'edges' contains cut parts. The cut parts will be embedded in the loops of adjacent faces. \~ + \param[in] params - \ru Параметры кривой пересечения для разбиения ребра, + \en Parameters of intersection curve of edge to split, \~ + \param[in] beginSafe - \ru Ребро сохранит начальную половину (true) или ребро сохранит конечную половину (false), + \en The edge will keep a beginning piece (true) or the edge will keep an end piece (false) \~ + \param[in] eps - \ru Точность совпадения параметров разбиения, + \en Precision matching options of parameters to split, \~ + \param[in] surface - \ru Для толерантной кривой требуется указать поверхность грани, к кривой которой относятся параметры резки. + \en For tolerant curve it is required to specify a surface of face which contain a curve parameters belongs to. \~ + \param[out] edges - \ru Отрезанные части ребра. + \en The container of cut parts. \~ + \return \ru Возвращает true, если ребро было порезано. + \en Returns true, if the edge was cut. \~ + */ + bool CuttingEdge( SArray & params, bool beginSafe, double eps, const MbSurface * surface, + RPArray & edges ); + + /** \brief \ru Разбить ребро по точкам изменения выпуклости-вогнутости. + \en Split the edge by points where the convexity changes. \~ + \details \ru Разбить ребро по точкам изменения выпуклости-вогнутости и сложить отрезанные части в контейнер 'edges'. + Отрезанные части встраиваются в циклы смежных граней. + \en Split the edge by points where the convexity changes. + The container 'edges' contains cut parts of edge. The cut parts will be embedded in the loops of adjacent faces. \~ + \param[out] edges - \ru Отрезанные части ребра. + \en The container of cut parts. \~ + \return \ru Возвращает true, если ребро было порезано. + \en Returns true, if the edge was cut. \~ + */ + bool ConvexoConcaveCutting( RPArray & edges ); + bool ConvexoConcaveCutting( RPArray & edges, MbFunction & function, RPArray & functions ); + + /** \brief \ru Продолжить ребро. + \en Prolong an edge. \~ + \details \ru Продолжить кривую пересечения ребра до параметра t, лежащего за пределами области определения. \n + \en Continue the intersection curve of edge by the parameter t, lying outside of the curve. \n \~ + \param[in/out] t - \ru Параметра на продолжении кривой ребра. + \en Parameter outside of the intersection curve. \~ + \param[in] begin - \ru Начало (true) или конец (false) ребра продолжить. + \en The edge should be prolonged by the beginning (true) or by the ending (false). \~ + \param[in] deviateAngle - \ru Угловое отклонение для шага при движении вдоль кривой в общем случае. + \en The angular deviation step of the motion along the curve in the general case. \~ + \param[in] version - \ru Версия операции. + \en Version of operation. \~ + \return \ru Возвращает true, если продление выполнено, false - в противном случае. + \en Returns true if the edge was prolonged, otherwise returns false. \~ + */ + bool ProlongEdge ( double & t, bool begin, double deviateAngle, const VERSION version ); + + /** \brief \ru Объединение двух стыкующихся ребер. + \en Merging of two connected edges. \~ + \details \ru Объединение двух стыкующихся ребер: \n + перед вызовом на ребра надо сделать AddRef, т.к. одно из них может быть удалено, + а после вызова и использования ребер на них надо сделать Release. \n + \en Merging of two connected edges: \n + Before the call AddRef should be done on the edges, since one of the edges may be deleted, + and after the call and using the edges Release should be done on them. \n \~ + \param[in/out] edge2 - \ru Присоединяемое ребро. + \en Merging edge. \~ + \param[in] begin1 - \ru К началу (true) или к концу (false) ребра this стыкуется присоединяемое ребро. + \en This edge is joined by the beginning (true) or by the ending (false). \~ + \param[in] begin2 - \ru Началом (true) или концом (false) стыкуется присоединяемое ребро к ребру this. + \en The edge2 is joined by the beginning (true) or by the ending (false). \~ + \param[in] version - \ru Версия операции. + \en Version of operation. \~ + \param[in] addParentNamesAttributes - \ru Добавить атрибут имени с именами слитых ребер. + \en Add name attribute with names of merged edges. \~ + \return \ru Возвращает поглощенное ребро edge2, которое можно удалять. + \en Returns absorbed edge (edge2), which can be removed. \~ + */ + MbCurveEdge * MergeEdges( MbCurveEdge & edge2, bool begin1, bool begin2, VERSION version, bool addParentNamesAttributes ); + + /// \ru Собрать все ребра, стыкующиеся с заданным ребром в его начале begin==true (конце begin==false). \en Collect all edges which are connected with the given edge at its start vertex (begin==true) or at its end vertex (begin==false). + void GetConnectedEdges( bool begin, RPArray & edges, SArray & orients ) const; + /// \ru Собрать все ребра, гладко стыкующиеся с заданным ребром и образующие гладкую цепочку ребер. \en Collect all edges which are smoothly connected with the given edge and form a smooth chain of edges. + bool GetProlongEdges( RPArray & edges ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + /// \ru Является ли ребро граничным, по которому происходит разрыв оболочки? \en Is an edge a boundary edge where occurs a discontinuity of the shell? + bool IsBoundaryFace( double mEps = Math::metricEpsilon ) const; + /// \ru Получить тип кривой по построению. \en Get a type of a curve by the construction. + MbeCurveBuildType GetBuildType() const; + + /// \ru Вычислить и выдать толерантность кривой ребра. \en Calculate and get the tolerance of the edge curve. + double GetTolerance() const; + /// \ru Изменить точность построения кривой пересечения. \en Change the tolerance of construction of intersection curve. + void SetTolerance( double eps ); + /// \ru Является ли кривая толерантной? \en Is a curve tolerant? + bool IsTolerant() const; + + /// \ru Сделать ребро граничным (изменить кривую ребра). \en Make the edge boundary (change its curve). + bool MakeBoundaryCurve(); + + /// \ru Пересечение ребра с плоскостью, результат - множество параметров на плейсменте или множество двумерных кривых на плейсменте. \en An intersection between an edge and a plane, in result a set of parameters on the placement or a set of two-dimensional curves on the placement. + void CurveSection( const MbPlacement3D & place, SArray & points, RPArray & pCurve ) const; + /// \ru Получить параметры разрезки для периодического ребра. \en Get the cutting parameters for a periodic edge. + bool CutPeriodicEdge( const MbVector3D & eye, SSArray & trimParams, + double & delT1, double & delT2 ) const; + + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( MbCurveEdge ) + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCurveEdge ) +}; + +IMPL_PERSISTENT_OPS( MbCurveEdge ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Ориентированное ребро. + \en Oriented edge. \~ + \details \ru Ориентированное ребро описывает гладкий участок границы грани. + Последовательность ориентированных ребер описывает границу грани и образует цикл MbLoop. + Ориентированное ребро базируется на ребре MbCurveEdge и всегда ориентировано вдоль цикла грани. \n + При движении вдоль ориентированного ребра c внешней стороны грани грань всегда располагается слева. + \en An oriented edge describes a smooth piece of a face boundary. + A sequence of oriented edges describes a boundary and forms a loop MbLoop. + An oriented edge is based on the edge MbCurveEdge and always oriented along the loop of a face. \n + When moving along the oriented edge from the face external side the face always lies on the left. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbOrientedEdge : public MbTopItem { +protected: + MbCurveEdge * curveEdge; ///< \ru Ребро грани (всегда не NULL). \en Face edge (always not NULL). + bool orientation; ///< \ru Направление ребра грани в цикле. \en Direction of a face edge in the loop. + mutable MbLabel label; ///< \ru Временная метка для выполнения операций. \en Temporary label for performing of operations. +public : + /// \ru Конструктор ориентированного ребра. \en Constructor of oriented edge. + MbOrientedEdge( const MbCurveEdge & edge, bool orient ); + /// \ru Деструктор. \en Destructor. + virtual ~MbOrientedEdge (); + +public : + VISITING_CLASS( MbOrientedEdge ); + + // \ru Функции топологического объекта. \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + + /// \ru Инициализация по ребру и направлению. \en Initialization by edge and direction. + void InitEdge( MbCurveEdge & initEdge, bool orient ); + + /// \ru Выдать кривую пересечения поверхностей. \en Get surfaces intersection curve. + const MbSurfaceIntersectionCurve & GetIntersectionCurve() const { return curveEdge->GetIntersectionCurve(); } + /// \ru Выдать кривую пересечения поверхностей для модификации. \en Get surfaces intersection curve for modification. + MbSurfaceIntersectionCurve & SetIntersectionCurve() { return curveEdge->SetIntersectionCurve(); } + /// \ru Выдать кривую ребра. \en Get a curve of an edge. + const MbCurve3D & GetCurve() const { return curveEdge->GetCurve(); } + /// \ru Выдать кривую ребра для модификации. \en Get a curve of an edge for modification. + MbCurve3D & SetCurve() { return curveEdge->SetCurve(); } + + /// \ru Выдать грань, в которой лежит ребро. \en Get the face where an edge lies. + MbFace * GetFacePlus() const { return orientation ? curveEdge->GetFacePlus() : curveEdge->GetFaceMinus(); } + /// \ru Выдать соседнюю грань. \en Get adjacent face. + MbFace * GetFaceMinus() const { return orientation ? curveEdge->GetFaceMinus() : curveEdge->GetFacePlus(); } + + /// \ru Выдать вершину-начало. \en Get the start vertex. + const MbVertex & GetBegVertex() const { return orientation ? curveEdge->GetBegVertex() : curveEdge->GetEndVertex(); } + /// \ru Выдать вершину-конец. \en Get the end vertex. + const MbVertex & GetEndVertex() const { return orientation ? curveEdge->GetEndVertex() : curveEdge->GetBegVertex(); } + /// \ru Выдать вершину-начало. \en Get the start vertex. + MbVertex & SetBegVertex() { return orientation ? curveEdge->SetBegVertex() : curveEdge->SetEndVertex(); } + /// \ru Выдать вершину-конец. \en Get the end vertex. + MbVertex & SetEndVertex() { return orientation ? curveEdge->SetEndVertex() : curveEdge->SetBegVertex(); } + /// \ru Установить вершину-начало. \en Set the start vertex. + void SetBegVertex( const MbVertex & ver ); + /// \ru Установить вершину-конец. \en Set the end vertex. + void SetEndVertex( const MbVertex & ver ); + + /// \ru Выдать ребро грани MbCurveEdge. \en Get a face edge MbCurveEdge. + MbCurveEdge & GetCurveEdge() const { return *curveEdge; } + + /// \ru Выдать направление по отношению к кривой. \en Get the direction relative to the curve. + bool IsSameSense() const; + /// \ru Является ли ребро прямолинейным? \en Is an edge rectilinear? + bool IsStraight() const; + /// \ru Является ли ребро швом? \en Is an edge a seam? + bool IsSeam() const; + /// \ru Параллельно ли ребро плейсменту. \en Is an edge parallel to the placement? + bool IsColinear( const MbPlacement3D & ) const; + + /// \ru Принадлежит ли вершина ребру? \en Does a vertex belong an edge? + bool IsVertexOn( const MbVertex * vertex ) const { return vertex == &GetBegVertex() || vertex == &GetEndVertex(); } + /// \ru Выдать декартову точку начальной вершины. \en Get Cartesian point of start vertex. + void GetBegVertexPoint( MbCartPoint3D & cp ) const { GetBegVertex().GetCartPoint(cp); } + /// \ru Выдать декартову точку конечной вершины. \en Get Cartesian point of end vertex. + void GetEndVertexPoint( MbCartPoint3D & cp ) const { GetEndVertex().GetCartPoint(cp); } + + /// \ru Выдать множество вершин. \en Get a set of vertices. + template + void GetVerticesArray( VerticesVector & vertices, bool findSame = true ) const + { + const MbVertex * lastVertex= NULL; + if ( vertices.size() > 0 ) + lastVertex = vertices.back(); + + SPtr vertex; + vertex = const_cast( &GetBegVertex() ); + if ( vertex != lastVertex ) { + if ( !findSame || (std::find( vertices.begin(), vertices.end(), vertex ) == vertices.end()) ) + vertices.push_back( vertex ); + } + ::DetachItem( vertex ); + if ( vertex != &GetEndVertex() ) { + vertex = const_cast( &GetEndVertex() ); + if ( vertex != lastVertex ) { + if ( !findSame || (std::find( vertices.begin(), vertices.end(), vertex ) == vertices.end()) ) + vertices.push_back( vertex ); + } + ::DetachItem( vertex ); + } + } + + /// \ru Выдать ориентацию ребра грани. \en Get orientation of face edge. + bool GetOrientation() const { return orientation; } + /// \ru Установить ориентацию ребра грани. \en Set orientation of face edge. + void SetOrientation( bool o ); + + /// \ru Получить метку. \en Get label. + MbeLabelState GetLabel( void * key = NULL ) const { return (MbeLabelState)label.GetLabel(key);} + /// \ru Установить свою метку. \en Set label. + void SetOwnLabel( MbeLabelState l, void * key = NULL ) const { label.SetLabel( l, key ); } + /// \ru Установить метку ориентированному ребру, ребру грани и вершинам ребра. \en Set label for oriented edge, face edge and vertices of edge. + void SetLabelThrough( MbeLabelState l, void * key = NULL ) const; + /// \ru Установить метку ориентированному ребру, ребру грани и вершинам ребра. \en Set label for oriented edge, face edge and vertices of edge. + void SetLabelThrough( MbeLabelState l, void * key, bool setLock ) const; + /// \ru Удалить частную метку. \en Remove private label. + void RemovePrivateLabel ( void * key = NULL ) const { label.DeletePrivate(key); } + /// \ru Удалить частную метку ориентированному ребру, ребру грани и вершинам ребра. \en Remove private label for oriented edge, face edge and vertices of edge. + void RemovePrivateLabelThrough( void * key ) const; + + /// \ru Выдать точку на ребре (0 <= t <= 1). \en Get point on the edge (0 <= t <= 1). + void Point( double t, MbCartPoint3D & p ) const; + /// \ru Выдать точку в начальной вершине. \en Get point at start vertex. + void GetBegPoint( MbCartPoint3D & p ) const; + /// \ru Выдать точку в конечной вершине. \en Get point at start vertex. + void GetEndPoint( MbCartPoint3D & p ) const; + /// \ru Выдать касательную к ребру (0 <= t <= 1). \en Get tangent to the edge (0 <= t <= 1). + void Tangent( double t, MbVector3D & p ) const; + /// \ru Выдать касательный вектор в начальной вершине. \en Get tangent vector at start vertex. + void GetBegTangent( MbVector3D & p ) const; + /// \ru Выдать касательный вектор в конечной вершине. \en Get the tangent vector at the end vertex. + void GetEndTangent( MbVector3D & p ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + // \ru Дать информацию для конвертеров. \en Get information for converters. + void GetFinCurve( const MbSurface &, MbCurve *&, bool & ); + // \ru Дать информацию для конвертеров. \en Get information for converters. + void GetFin( const MbSurface &, bool, MbCurve *&, bool & ); + // \ru Нормализовать fin по ChooseCurve() и установить правило выбора для конвертеров. \en Normalize 'fin' by ChooseCurve() and set the rule for selection of convertors. + void NormalizeFin(); + // \ru Установить правило выбора для конвертеров. \en Set the rule for selection of converters. + void SetChooseRule(); + + // \ru Функции унификации объекта и вектора объектов в шаблонных функциях. \en Functions for compatibility of a object and a vector of objects in template functions. + size_t size() const { return 1; } ///< \ru Количество объектов при трактовке объекта как вектора объектов. \en Number of objects if object is interpreted as vector of objects. + const MbOrientedEdge * operator [] ( size_t ) const { return this; } ///< \ru Оператор доступа. \en An access operator. + +// \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. +OBVIOUS_PRIVATE_COPY( MbOrientedEdge ) +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbOrientedEdge ) +}; // MbOrientedEdge + +IMPL_PERSISTENT_OPS( MbOrientedEdge ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Цикл грани. + \en Face loop. \~ + \details \ru Цикл грани представляет собой замкнутую составную кривую, проходящую вдоль границы грани. \n + Цикл образован последовательностью ориентированных рёбер MbOrientedEdge. Цикл всегда замкнут. \n + Цикл направлен так, чтобы грань всегда для нас находилась бы слева, + если мы движемся вдоль цикла c внешней стороны грани. \n + \en A face loop represents a closed composite curve passing along the face boundary. \n + A loop is formed by a sequence of oriented edges MbOrientedEdge. A loop is always closed. \n + A loop is directed in such way that the face is always located on the left side, + if the moving along the loop is performed on the face external side. \n \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbLoop : public MbTopItem, public MbSyncItem { +protected: + RPArray edgeList; ///< \ru Массив ориентированных ребер, составляющих цикл. \en An array of edges forming a loop. + mutable MbRect rect; ///< \ru Габаритный прямоугольник в пространстве параметров поверхности. \en A bounding box in a surface parameter space. + mutable MbLabel label; ///< \ru Временная метка для выполнения операций. \en Temporary label for performing of operations. + +public : + /// \ru Пустой конструктор. \en Empty constructor. + MbLoop(); + /// \ru Конструктор по ребру или массиву ребер. \en Constructor by oriented edge or array of oriented edges. + template + MbLoop( const OrientEdges & initList ) + : MbTopItem() + , edgeList() + , rect() + , label( ls_Null ) + { + edgeList.reserve( initList.size() ); + for ( size_t i = 0, cnt = initList.size(); i < cnt; ++i ) { + MbOrientedEdge * initEdge = &const_cast( *initList[i] ); + ::AddRefItem( initEdge ); + edgeList.push_back( initEdge ); + } + } + /// \ru Деструктор. \en Destructor. + virtual ~MbLoop(); + +public : + VISITING_CLASS( MbLoop ); + + // \ru Функции топологического объекта. \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + + /// \ru Проверить и согласовать вершины цикла. \en Check and reconcile vertices of the loop. + void CheckVertices(); + /// \ru Выдать количество ребер цикла. \en Get the number of edges of the loop. + size_t GetEdgesCount() const { return edgeList.size(); } + + /// \ru Получить метку цикла. \en Get a label of the loop. + MbeLabelState GetLabel( void * key = NULL ) const { return (MbeLabelState)label.GetLabel(key); } + /// \ru Установить метку. \en Set a label of the loop. + void SetOwnLabel( MbeLabelState l, void * key = NULL ) const { label.SetLabel( l, key ); } + /// \ru Установить метку себе и ребрам цикла. \en Set a label for self and loop vertices. + void SetLabelThrough( MbeLabelState l, void * key = NULL ) const; + /// \ru Установить метку себе и ребрам цикла. \en Set a label for self and loop vertices. + void SetLabelThrough( MbeLabelState l, void * key, bool setLock ) const; + /// \ru Удалить частную метку себе и ребрам цикла. \en Remove private label for self and loop edges. + void RemovePrivateLabelThrough( void * key ) const; + /// \ru Установить метку ребрам. \en Set a label for edges. + void SetCurveEdgesLabel( MbeLabelState, void * key = NULL ) const; + /// \ru Проверить метки рёбер и установить свою метку. \en Check edges labels and set own label. + void CheckEdgesLabel( void * key = NULL ) const; + /// \ru Удалить частную метку. \en Remove private label. + void RemovePrivateLabel ( void * key = NULL ) const { label.DeletePrivate(key); } + + /// \ru Выдать множество вершин цикла. \en Get a set of loop vertices. + template + void GetVertices( VerticesVector & vertices ) const + { + size_t edgesCnt = edgeList.size(); + vertices.reserve( vertices.size() + edgesCnt * 2 ); + for ( size_t i = 0; i < edgesCnt; ++i ) + edgeList[i]->GetVerticesArray( vertices ); + } + /// \ru Выдать множество ребер грани. \en Get a set of face edges. + template + void GetEdges( EdgesVector & edges, bool findSame = true ) const + { + size_t edgesCnt = edgeList.size(); + edges.reserve( edges.size() + edgesCnt ); + c3d::EdgeSPtr edge; + for ( size_t i = 0; i < edgesCnt; ++i ) { + edge = const_cast( &edgeList[i]->GetCurveEdge() ); + if ( !findSame || (std::find( edges.begin(), edges.end(), edge ) == edges.end()) ) + edges.push_back( edge ); + ::DetachItem( edge ); + } + } + /// \ru Выдать множество ориентированных ребер. \en Get a set of oriented edges. + template + void GetOrientedEdges( OrientedEdgesVector & edges, bool findSame = true ) const + { + size_t edgesCnt = edgeList.size(); + edges.reserve( edges.size() + edgesCnt ); + c3d::OrientEdgeSPtr edge; + for ( size_t i = 0; i < edgesCnt; ++i ) { + edge = const_cast( edgeList[i] ); + if ( !findSame || (std::find( edges.begin(), edges.end(), edge ) == edges.end()) ) + edges.push_back( edge ); + ::DetachItem( edge ); + } + } + + /// \ru Замена базового ребра. \en Replacement of the basis edge. + void InitOrientedEdge( size_t edgeIndex, MbCurveEdge & initEdge, bool initOrientation, bool replaceVertices ); + /// \ru Выдать ориентированное ребро по номеру. \en Get an oriented edge by the number. + MbOrientedEdge * GetOrientedEdge( size_t index ) const { return (index < edgeList.size()) ? edgeList[index] : NULL; } + /// \ru Выдать ориентированное ребро по номеру без проверки корректности индекса. \en Get an oriented edge by the number without check of correctness of the index. + MbOrientedEdge *_GetOrientedEdge( size_t index ) const { return edgeList[index]; } + + /// \ru Добавить ребро без проверки. \en Add an edge without check. + void _AddEdge ( const MbOrientedEdge & ); + /// \ru Вставить ребро перед ребром с указанным индексом без проверки корректности индекса. \en Insert an edge at the given index without check of index correctness. + void _InsertEdge ( size_t k, const MbOrientedEdge & ); + /// \ru Добавить ребро после ребра с указанным индексом без проверки корректности индекса. \en Add an edge after an edge at the given index without check of index correctness. + void _AddEdgeAfter( const MbOrientedEdge &, size_t k ); + /// \ru Добавить ребро. \en Add an edge. + void AddEdge ( const MbOrientedEdge & ); + /// \ru Вставить ребро перед ребром с указанным индексом. \en Insert an edge before an edge at the given index + void InsertEdge ( size_t k, MbOrientedEdge & ); + /// \ru Добавить ребро после ребра с указанным индексом. \en Add an edge after an edge at the given index + void AddEdgeAfter( MbOrientedEdge &, size_t k ); + + /// \ru Отсоединить ребро с заданным индексом. \en Detach an edge at the given index. + MbOrientedEdge * DetachEdge( size_t index ); + /// \ru Удалить ребро с заданным индексом. \en Delete an edge at the given index. + void DeleteEdge ( size_t index ); + /// \ru Отцепить все ребра от цикла. \en Detach all edges from the loop. + void DetachEdges(); + /// \ru Удалить все ребра из цикла. \en Delete all edges of the loop. + void DeleteEdges(); + + /// \ru Дать номер ребра грани в цикле. \en Get the number of a face edge in the loop. + size_t GetEdgeIndex( const MbCurveEdge & edge, bool orient ) const; + /// \ru Найти следующее ребро за данным (next == true) или перед данным (next == false). \en Find the next edge after the given one (next==true) or before the given one (next==false). + bool FindNeighbourEdge( const MbCurveEdge & edge, bool orient, bool next, MbCurveEdge *& findEdge, bool & findOrient ) const; + + /// \ru Изменить ориентацию цикла (порядок следования ориентированных рёбер и их ориентацию). \en Change orientation of the loop (the order of oriented edges and their orientation). + void PartialReverse(); + /// \ru Изменить порядок следования ориентированных рёбер без изменения их ориентации. \en Change the order of oriented edges without changing of their orientation. + void Inverse(); + + /// \ru Принадлежит ли вершина пути. \en Does a vertex belong a path? + bool IsVertexOn( const MbVertex * vertex, size_t * index = NULL ) const; + /// \ru Замена указателей на поверхность. \en Replacement of the pointers to a surface. + void ChangeSurface( MbSurface & oldSurf, MbSurface & newSurf, bool orient ); + + /// \ru Найти вершину цикла по имени. \en Find loop vertex by name. + const MbVertex * FindVertexByName( const MbName & ) const; + /// \ru Найти ребро цикла по имени. \en Find loop edge by name. + const MbCurveEdge * FindEdgeByName( const MbName & ) const; + + /// \ru Создать двумерный контур по циклу. \en Create two-dimensional contour by loop. + MbContour & MakeContour( const MbSurface & surf, bool faceSense, bool doExact, + MbRegDuplicate * iReg, bool calculateMetricLength = true ) const; + /// \ru Создать двумерный контур по циклу. \en Create two-dimensional contour by loop. + MbContour & MakeContour( const MbSurface & surf, bool faceSense, bool calculateMetricLength = true ) const; + /// \ru Создать контур на поверхности по циклу. \en Create contour on surface by loop. + MbContourOnSurface & MakeContourOnSurface( const MbSurface & surf, bool faceSense, bool doExact = false ) const; + /// \ru Создать пространственный контур по циклу. \en Create spatial contour by loop. + MbContour3D & MakeContour3D( bool doExact = false ) const; + + /// \ru Вычислить габаритный прямоугольник цикла. \en Calculate bounding box of loop. + bool CalculateGabarit( const MbSurface &, bool faceSense ) const; + /// \ru Выдать габаритный прямоугольник цикла. \en Calculate bounding rectangle of loop. + bool GetGabarit( const MbSurface &, bool faceSense, MbRect & r ) const; + /// \ru Прямой доступ к переменной габарита с вызовом расчета. \en Direct access to the variable of bounding box with a call of calculation. + const MbRect & GetGabarit( const MbSurface & surf, bool faceSense ) const { + if ( rect.IsEmpty() ) + CalculateGabarit( surf, faceSense ); + return rect; + } + /// \ru Прямой доступ к переменной габарита без вызова расчета. \en Direct access to the variable of bounding box without a call of calculation. + const MbRect & GetGabarit() const { return rect; } + /// \ru Скопировать габарит с контура. \en Copy bounding box from contour. + void CopyGabarit( const MbContour & c ); + /// \ru Скопировать габарит цикла. \en Copy bounding box of loop. + void CopyGabarit( const MbLoop & c ) const { rect = c.rect; } + /// \ru Сбросить габарит - сделать его не определённым. \en Reset bounding box - make it undefined. + void SetEmptyGabarit() const { rect.SetEmpty(); } + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + /// \ru Преобразовать объект согласно матрице. \en Transform an object according to the matrix. + void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); + /// \ru Сдвинуть объект вдоль вектора. \en Move an object along a vector. + void Move ( const MbVector3D &, MbRegTransform * = NULL ); + /// \ru Повернуть объект вокруг оси на заданный угол. \en Rotate an object at a given angle around an axis. + void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); + /// \ru Сдвинуть двумерные кривые вдоль вектора в области параметров поверхности (все сразу). \en Move two-dimensional curves along the vector in the surface parameter region (all at once). + void Move( MbVector &, const MbSurface &, bool ); + /// \ru Является ли контур граничным? \en Is a contour boundary? + bool IsBoundaryFace( double mEps = Math::metricEpsilon ) const; + + /// \ru Зарезервировать место под столько элементов. \en Reserve space for a given number of elements. + void EdgesReserve( size_t additionalSpace ) { edgeList.Reserve( additionalSpace ); } + /// \ru Удалить лишнюю память. \en Free the unnecessary memory. + void EdgesAdjust () { edgeList.Adjust(); } + + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( MbLoop ) + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbLoop ) +}; // MbLoop + +IMPL_PERSISTENT_OPS( MbLoop ) + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметр самопересечения циклов грани. + \en Parameter of loops self-intersection. \~ + \details \ru Параметр самопересечения циклов грани. + \en Parameter of loops self-intersection. \~ + \ingroup Topology_Items +*/ +// --- +struct LoopCrossParam { +public: + size_t loopIndex; ///< \ru Номер цикла грани. \en Loop index of the face. + const MbCurveEdge * edge; ///< \ru Ребро цикла. \en Loop edge. + double curveParam; ///< \ru Параметр двумерной кривой ребра, лежащей на поверхности грани. \en The parameter of two-dimensional curve that lies on the surface of a face and is contained in the edge. +public: + LoopCrossParam() : loopIndex( SYS_MAX_T), edge( NULL ), curveParam( UNDEFINED_DBL ) {} + LoopCrossParam( size_t li, const MbCurveEdge * e, double t ) : loopIndex( li ), edge( e ), curveParam( t ) {} + LoopCrossParam( const LoopCrossParam & obj ) : loopIndex( obj.loopIndex ), edge( obj.edge ), curveParam( obj.curveParam ) {} + + const LoopCrossParam & operator = ( const LoopCrossParam & obj ) + { + loopIndex = obj.loopIndex; + edge = obj.edge; + curveParam = obj.curveParam; + return *this; + } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Грань. + \en Face. \~ + \details \ru Грань представляет собой связный конечный кусок поверхности, + которому приписано направление нормали. \n + Сторону грани, при взгляде на которую мы смотрим навстречу нормали, + будем называть внешней, другую сторону грани будем называть внутренней. \n + Стороны поверхности MbSurface не обладают равноправием относительно нормали, + так как у поверхности одна сторона всегда внешняя, а другая сторона всегда внутренняя. + В отличие от поверхности для грани мы имеем возможность назначить направление нормали + и тем самым назначить внешнюю и внутреннюю стороны. \n + Границы грани описываются циклами MbLoop. + Количество циклов грани равно количеству границ грани. + Один из циклов грани будем называть внешним, а остальные - внутренними. + Внутренние циклы целиком лежат внутри внешнего цикла. + Внешний цикл грани ориентирован против часовой стрелки, + а внутренние циклы ориентированы по часовой стрелке, + если смотреть навстречу выбранной нормали грани. \n + Циклы грани не могут пересекать друг друга и сами себя. \n + \en A face is connected finite piece of a surface + with a normal direction. \n + A side of a face which is seen when looking towards a normal + is called external side, other side is called internal side. \n + Sides of a surface MbSurface do not have equal rights with respect to normal direction, + because one side of surface is always external and other is internal. + In contrast to surface, it is possible to assign a normal direction for a face + and thereby to assign an external and internal sides. \n + Face boundaries are described by loops MbLoop. + A number of face loops is equal to a number of face boundaries. + One loop is external, other loops are internal. + Internal loops entirely lie inside the external loop. + External loop of a face is oriented counterclockwise, + but internal loops are oriented clockwise, + when looking towards the chosen normal of a face. \n + Loops do not intersect each other and themselves. \n \~ + \internal BUG_69306: \n \endinternal +\ru Если два цикла грани имеют общую точку, то эта точка в обоих + циклах должна быть вершиной ребра.\n +\en If two loops of a face have a common point then this point in both + loops should be a vertex of an edge.\n \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbFace : public MbTopologyItem, public MbSyncItem { +protected: + MbSurface * surface; ///< \ru Поверхность грани (всегда не NULL). \en Face surface (always not NULL). + bool sameSense; ///< \ru Признак совпадения направления нормали грани с нормалью поверхности. \en An attribute of coincidence between the face normal direction and the surface normal direction. + RPArray loops; ///< \ru Границы грани (первая граница должна быть внешней). \en Face boundaries (the first boundary should be external). +private: + mutable MbFaceTemp * temporal; ///< \ru Объект сопровождения грани (для скорости) \en An object for maintenance of a face (to improve speed) + +public: + /// \ru Конструктор по поверхности и ориентации нормали грани относительно нормали поверхности. \en Constructor by surface and orientation of face normal in relation to surface normal. + MbFace( const MbSurface &, bool sense ); + /// \ru Конструктор по циклу, поверхности и ориентации нормали грани относительно нормали поверхности. \en Constructor by loop, surface and orientation of face normal in relation to surface normal. + explicit MbFace( MbLoop & bnd, const MbSurface & surf, bool sense ); + /// \ru Конструктор по циклам, поверхности и ориентации нормали грани относительно нормали поверхности. \en Constructor by loops, surface and orientation of face normal in relation to surface normal. + MbFace( MbLoop & bnd0, MbLoop & bnd1, const MbSurface & surf, bool sense ); + /// \ru Конструктор по циклам, поверхности и ориентации нормали грани относительно нормали поверхности. \en Constructor by loops, surface and orientation of face normal in relation to surface normal. + template + MbFace( const Loops & bnds, const MbSurface & surf, bool sense ) + : MbTopologyItem() + , loops( bnds.size(), 1 ) + , surface( const_cast(&surf) ) + , sameSense( sense ) // признак совпадения нормали + , temporal( NULL ) + { + surface->AddRef(); + for ( size_t i = 0, cnt = bnds.size(); i < cnt; ++i ) { + if ( bnds[i] != NULL ) + AddLoop( *bnds[i] ); + } + } + + /// \ru Конструктор по другой грани, новой поверхности и ориентации нормали грани относительно нормали этой поверхности. \en Constructor by other face, new surface and orientation of face normal in relation to normal of this surface. + MbFace( const MbFace & other, const MbSurface & newSurface, bool surfaceSense ); + /// \ru Деструктор. \en Destructor. + virtual ~MbFace(); + +public: + VISITING_CLASS( MbFace ); + + // \ru Функции топологического объекта. \en Functions of topological object + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + /// \ru Создать новую грань копированием всех данных исходной грани. \en Create new face by copying all data of the initial face. + virtual MbFace * DataDuplicate( MbRegDuplicate * = NULL ) const; + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Трансформация. \en Transformation. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Перемещение. \en Moving. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Вращение. \en Rotation. + virtual double DistanceToPoint( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate bounding box in the local coordinate system. + + /// \ru Выдать поверхность грани. \en Get a surface of a face. + virtual const MbSurface & GetSurface() const; + /// \ru Выдать поверхность грани для модификации. \en Get a surface of a face for modifications. + virtual MbSurface & SetSurface(); + /// \ru Является ли грань плоской? \en Is a face planar? + virtual bool IsPlanar() const; + /// \ru Дать плоскость (или только возможность ее выдачи). \en Get a plane (or only a possibility of getting a plane) + virtual bool GetPlacement( MbPlacement3D * ) const; + /// \ru Выдать направление нормали грани по отношению к нормали поверхности. \en Get direction of face normal in relation to the direction of surface normal. + bool IsSameSense() const { return sameSense; } + /// \ru Установить направление нормали грани по отношению к нормали поверхности. \en Set direction of face normal in relation to the direction of surface normal. + void SetSameSense( bool s ); + + /// \ru Дать ось вращения для поверхности, если это возможно. \en Get a rotation axis of a surface if it is possible. + bool GetCylinderAxis( MbAxis3D & axis ) const; + /// \ru Дать локальную систему координат плоскости грани, если это возможно. \en Get a local coordinate system of a face plane, if it is possible. + bool GetPlanePlacement( MbPlacement3D & ) const; + /// \ru Дать локальную систему координат плоскости поверхности, если это возможно. \en Get a local coordinate system of a surface plane, if it is possible. + bool GetSurfacePlacement( MbPlacement3D & ) const; + /// \ru Дать локальную систему координат грани в средней точке, если это возможно. \en Get a local coordinate system in a face middle point, if it is possible. + bool GetControlPlacement( MbPlacement3D & ) const; + /// \ru Сориентировать ось Х плейсмента вдоль линии его пересечения с поверхностью грани, ось Y - с нормалью. \en Orient the axis X of a placement along the line of its intersection with a surface of a face, the axis Y - with a normal. + bool OrientPlacement( MbPlacement3D & ) const; + + /// \ru Дать нормаль грани. \en Get the face normal. + void Normal( double u, double v, MbVector3D & ) const; + /// \ru Параллельно ли ребро грани? \en Is an edge parallel to a face? + bool IsColinear( const MbCurveEdge & ) const; + + /// \ru Выдать количество циклов (границ) грани . \en Get the number of loops (boundaries) of face. + size_t GetLoopsCount() const { return loops.size(); } + /// \ru Установить метку грани, циклам, рёбрам и вершинам. \en Set a label of face to its loops, edges and vertices. + void SetLabelThrough( MbeLabelState l, void * key = NULL ) const; + /// \ru Установить метку грани, циклам, рёбрам и вершинам. \en Set a label of face to its loops, edges and vertices. + void SetLabelThrough( MbeLabelState l, void * key, bool setLock ) const; + /// \ru Удалить частную метку грани, циклам, рёбрам и вершинам. \en Remove a private label of face to its loops, edges and vertices. + void RemovePrivateLabelThrough( void * key ) const; + + /// \ru Модифицирована ли грань или ее ребро? \en Has been face or it edges modified? + bool IsOwnChangedItem( bool checkVertices = false ) const; + + /// \ru Выдать множество вершин грани. \en Get a set of face vertices. + template + void GetVertices( VerticesVector & vertices ) const + { + size_t loopsCnt = loops.size(); + vertices.reserve( vertices.size() + loopsCnt * 4 ); + for ( size_t i = 0; i < loopsCnt; ++i ) { + if ( loops[i] != NULL ) + loops[i]->GetVertices( vertices ); + } + } + /// \ru Выдать множество ребер грани. \en Get a set of face edges. + template + void GetEdges( EdgesVector &, size_t mapThreshold = 50 ) const; + /// \ru Выдать множество ребер внешнего цикла грани. \en Get a set of edges in outer loop of face. + template + void GetOuterEdges( EdgesVector &, size_t mapThreshold = 50 ) const; + /// \ru Выдать множество смежных граней. \en Get a set of adjacent faces. + template + void GetNeighborFaces( FacesVector & ) const; + /// \ru Есть ли смежные грани? \en Is there any neighbor face? + bool HasNeighborFace() const; + + /// \ru Выдать границу (цикл) с проверкой корректности индекса. \en Get a boundary (a loop) with a check of index correctness. + MbLoop * GetLoop( size_t index ) const { size_t cnt = loops.size(); return cnt ? loops[index % cnt] : NULL; } + /// \ru Выдать границу (цикл) без проверки корректности индекса. \en Get a boundary (a loop) without a check of index correctness. + MbLoop *_GetLoop( size_t index ) const { return loops[index]; } + /// \ru Обнулить количество ребер в цикле с указанным индексом. \en Set to null the number of edges in loop with the given index. + void SetNullLoop( size_t index ); + /// \ru Поменять местами циклы. \en Swap loops. + void ExchangeLoops( size_t i1, size_t i2 ); + /// \ru Добавить новый цикл грани. \en Add a new loop to a face. + void AddLoop ( MbLoop & l ); + /// \ru Вставить цикл по индексу. \en Insert a loop by an index. + void InsertLoop( size_t index, MbLoop & l ); + /// \ru Заменить цикл другим. \en Replace a loop by other loop. + void ChangeLoop( MbLoop & oldLoop, MbLoop & newLoop ); + /// \ru Отцепить цикл с указанным индексом. \en Detach a loop with the given index. + MbLoop * DetachLoop( size_t index ); + /// \ru Удалить цикл с указанным индексом. \en Delete a loop with the given index. + void DeleteLoop( size_t index ); + /// \ru Удалить все циклы грани. \en Delete all loops of a face. + void DeleteLoops(); + /// \ru Скопировать границы поверхности с циклов грани. \en Copy face boundaries from face loops. + void AdjustContours(); + + /// \ru Установить указатели ребер цикла на грань. \en Set the pointers of loop edges to the face. + void SetFaceToLoopEdges( MbLoop & ); + /// \ru Установить указатели на грань слева или грань справа в ребрах цикла на NULL. \en Set to null the pointers to the face on the left or to the face on the right in edges of loop. + void SetNullToLoopEdges( MbLoop & ); + /// \ru Установить указатели на грань слева или грань справа в ребрах циклов на NULL. \en Set to null the pointers to the face on the left or to the face on the right in edges of loops. + void SetNullToLoopsEdges(); + /// \ru Обнулить указатели на грань слева или грань справа, указывающие на смежную грань delFace, в ребрах циклов. \en Set to null pointers to the face on the left or to the face on the right which point to the adjacent face delFace in edges of loops. + void SetNullToFace( const MbFace * delFace ); + /// \ru Установить указатели на грань слева или грань справа в ребрах циклов на данную грань и параметры поверхности по данным циклов грани (setBounds = true). \en Set the pointers to the face on the left or to the face on the right to the given face in edges of loops and parameters of surface by loops of face (setBounds = true). + void MakeRight( bool setBounds = false); + + /// \ru Принадлежит ли вершина грани? \en Does a vertex belong an edge? + bool IsVertexOn( const MbVertex * vertex, size_t * indLoop = NULL, size_t * indEdge = NULL ) const; + + /** \brief \ru Изменить ориентацию грани. + \en Change an orientation of a face. \~ + \details \ru Инвертировать ориентацию ребер в цикле и инвертировать флаг ориентации грани. + \en Invert an orientation of edges in loop and invert a flag of face orientation. \~ + */ + void PartialReverse(); + + /** \brief \ru Изменить ориентацию грани. + \en Change an orientation of a face. \~ + \details \ru Инвертировать ориентацию ребер в цикле, + поменять местами указатели на грани справа и слева в ребрах циклов, + инвертировать флаг ориентации грани. \n + \en Invert an orientation of edges in loop, + swap pointers to a face on the left and to a face on the right in edges of loops, + invert a flag of face orientation. \n \~ + */ + void TotalReverse(); + + /** \brief \ru Изменить ориентацию цикла с указанным индексом. + \en Invert an orientation of a loop with the given index. \~ + \details \ru Инвертировать ориентацию ребер в цикле с указанным индексом, + инвертировать ориентацию соответствующих ребер в циклах соседних граней, + установить указатели ребер цикла на нужные грани. \n + \en Invert orientation of edges in loop with the given index. + invert an orientation of corresponding edges in loops of adjacent faces, + set the pointers of loop edges to the required faces. \n \~ + */ + void PartialReverseLoopWithNeighbours( size_t index ); + + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbTopologyItem & other, double accuracy ) const; + /// \ru Построить полигональную копию объекта mesh. \en Construct a polygonal copy of an object mesh). + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + void CalculateWire( const MbStepData & stepData, MbMesh & mesh ) const // The method deprecated. It will be removed at 2019. Use CalculateMesh( stepData, MbFormNote(true, false), mesh ); \~ + { CalculateMesh( stepData, MbFormNote(true, false), mesh ); } + /// \ru Связаны ли грани? \en Are faces connected? + bool IsConnectedWith( const MbFace * face, RPArray * commonEdges = NULL ) const; + /// \ru Подобны ли поверхности для объединения трансформацией по матрице (первичная проверка)? \en Are surfaces similar for merge by transformation by the matrix (a primary check)? + bool IsSimilarToFace( const MbFace & face, bool & normal, bool & planeType, VERSION version, double precision = METRIC_PRECISION ) const; + /// \ru Подобны ли поверхности для объединения путем замены (первичная проверка)? \en Are surfaces similar for merge by replacement (a primary check)? + bool IsSpecialSimilarToFace( const MbFace & face, bool & normal, bool & swap, VERSION version, double precision = METRIC_PRECISION ) const; + + /// \ru Заменить поверхность item на подобную поверхность init в грани и во всех её рёбрах. \en Replace the surface 'item' to the similar surface 'init' in the face and all edges. + bool ChangeCarrier ( const MbSurface & item, MbSurface & init ); + /// \ru Заменить поверхность item на подобную поверхность init в грани и во всех её рёбрах и преобразовать по матрице все двумерные кривые из области определения item. \en Replace the surface 'item' to the similar surface 'init' in the face and all edges and transform by the matrix all two-dimensional curves from the domain of 'item'. + bool ChangeCarrierBorne( const MbSurface & item, MbSurface & init, const MbMatrix & matr ); + /// \ru Заменить поверхность грани поверхностью присланной грани. \en Replace the face surface by the sent face surface. + bool ChangeCarrierBorneSpecial( const MbFace & face ); + /// \ru Подобны ли поверхности для замены с преобразованием по матрице двумерных кривых? \en Are surfaces similar for replacement with transformation of two-dimensional curves by the matrix? + bool IsSimilarExactly ( const MbFace & face, MbMatrix & matr, VERSION version, double precision = METRIC_PRECISION ) const; + /// \ru Подобны ли поверхности граней для замены с преобразованием двумерных кривых? \en Are surfaces similar for replacement with transformation of two-dimensional curves? + bool IsSpecialSimilarExactly( const MbFace & face, bool doSwap, double precision = METRIC_PRECISION ) const; + + /// \ru Найти следующее ребро за данным (next == true) или перед данным (next == false). \en Find the next edge after the given one (next==true) or before the given one (next==false). + bool FindNeighbourEdge( const MbCurveEdge & edge, bool orient, bool next, MbCurveEdge *& findEdge, bool & findOrient ) const; + /// \ru Найти индекс цикла в грани и индекс ребра в найденном цикле. \en Find the index of a loop in a face and the index of an edge in the found loop. + bool FindEdgeIndex( const MbCurveEdge & edge, bool orient, size_t & loopIndex, size_t & edgeIndex ) const; + /// \ru Найти индекс цикла в грани и индекс ребра в найденном цикле. \en Find the index of a loop in a face and the index of an edge in the found loop. + bool FindEdgeIndex( const MbCurveEdge & edge, ThreeStates orient, size_t & loopIndex, size_t & edgeIndex ) const; + /// \ru Дать ребро по индексам цикла грани и ребра в цикле. \en Get an edge by the indices of a face loop and an edge in the loop. + MbCurveEdge * GetEdgeByIndex( size_t loopIndex, size_t edgeIndex ) const; + /// \ru Найти ориентированное ребро по ребру грани. \en Find an oriented edge by the edge of a face. + MbOrientedEdge * GetOrientedEdge( const MbCurveEdge & curveEdge ) const; + /// \ru Найти номера для рёбер. \en Find numbers for the edges. + bool FindIndexByEdges( const RPArray & initEdges, SArray & indexes ) const; + /// \ru Найти рёбра по номерам. \en Find edges by numbers. + bool FindEdgesByIndex( SArray & indexes, RPArray & initEdges ) const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + const MbVertex * FindVertexByName( const MbName & ) const; + /// \ru Найти ребро по имени. \en Find edge by name. + const MbCurveEdge * FindEdgeByName( const MbName & ) const; + + /// \ru Установить метку ориентированного ребра. \en Set a label for an oriented edge. + void SetOrientedLabel ( const MbCurveEdge & edge, MbeLabelState n, void * key = NULL ); + /// \ru Вычислить ближайшее расстояние до ребра и ближайшие точки грани и ребра. \en Calculate the nearest distance to an edge and the nearest points of an edge. + double DistanceToEdge ( const MbCurveEdge & edge, MbCartPoint3D & p, MbCartPoint3D & edgeP ) const; + /// \ru Вычислить ближайшее расстояние до грани и ближайшие точки граней. \en Calculate the nearest distance to a face and the nearest points of faces. + double DistanceToFace ( const MbFace & face, MbCartPoint3D & p, MbCartPoint3D & faceP ) const; + /// \ru Найти угол между прямым ребром и плоской гранью. \en Find an angle between straight edge and planar face. + bool AngleWithEdge( const MbEdge &, double & angle ) const; + /// \ru Найти угол между плоскими гранями. \en Find an edge between planar faces. + bool AngleWithFace( const MbFace &, double & angle ) const; + + /// \ru Найти проекцию точки на ближайшее ребро грани. \en Find a point projection to the nearest edge of a face. + bool GetNearestEdge( const MbCartPoint & pOnFace, c3d::IndicesPair & edgeLoc, double & tEdgeCurve, bool & orientation, double & distance ) const; + + /// \ru Найти ребра, пересекающиеся с габаритом своим габаритами. \en Find edges by intersections of two-dimensional bounding boxes. + bool GetRectIntersectingEdges( const MbRect & rect, std::vector & edgeLocs, double eps ) const; + + /** \brief \ru Найти параметрическое расстояние до ближайшей границы. + \en Find a parametric distance to the nearest boundary. \~ + \details \ru Найденное расстояние до ближайшей границы имеет положительное значение, если точка находится внутри, и отрицательное - если снаружи. + \en The calculated distance is positive if the point is inside, and is negative if it is outside. \~ + \param[in] point - \ru Исследуемая точка. + \en A point. \~ + \param[out] precision - \ru Погрешность вычислений. + \en Precision of calculation. \~ + \return \ru Возвращает расстояние до ближайшей границы в пространстве параметров поверхности. \n + \en Returns the distance to the nearest boundary in 2D space of the surface parameters. \~ + \ingroup Topology_Items + */ + double DistanceToBorder( const MbCartPoint & point, double & precision ) const; + /// \ru Найти параметрическое расстояние до ближайшей границы. \en Find a parametric distance to the nearest boundary. + double DistanceToBorder( const MbCartPoint & point, MbVector & normal, double & precision ) const; + /// \ru Найти параметрическое расстояние до ближайшей границы. \en Find a parametric distance to the nearest boundary. + double DistanceToBorder( const MbCartPoint & point, + size_t & loopNumber, + size_t & edgeNumber, + double & precision ) const; + /** \brief \ru Найти параметрическое расстояние до ближайшей границы. + \en Find a parametric distance to the nearest boundary. \~ + \details \ru Найденное расстояние до ближайшей границы имеет положительное значение, если точка находится внутри, и отрицательное - если снаружи. + \en The calculated distance is positive if the point is inside, and is negative if it is outside. \~ + \param[in] point - \ru Проецируемая точка. + \en A point. \~ + \param[out] normal - \ru Двумерная нормаль границы границы в ближайшей точке. + \en Two-dimensional normal of border at its closest point. \~ + \param[out] loopNumber - \ru Индекс ближайшего цикла. + \en Index of nearest loop. \~ + \param[out] loopNumber - \ru Индекс ближайшего ребра в цикле. + \en Index of nearest edge. \~ + \param[out] corner - \ru 0, если проекция не располагается на стыке ребер, + 1, если проекция располагается в конце ориентированного ребра с индексом edgeLoc, + -1, если проекция располагается в начале ориентированного ребра с индексом edgeLoc. + \en 0, if the projection is not located on the edge, + 1, if the projection is located at the end of the oriented edge with index edgeLoc, + -1, if the projection is located at the begining of the oriented edge with index edgeLoc. \~ + \param[out] tEdgeCurve - \ru Параметр кривой ближайшего ребра. + \en Curve parameter of the nearest edge. \~ + \param[out] precision - \ru Погрешность вычислений. + \en Precision of calculation. \~ + \return \ru Возвращает расстояние до ближайшей границы в пространстве параметров поверхности. \n + \en Returns the distance to the nearest boundary in 2D space of the surface parameters. \~ + \ingroup Topology_Items + */ + double DistanceToBorder( const MbCartPoint & point, + MbVector & normal, + size_t & loopNumber, + size_t & edgeNumber, + ptrdiff_t & corner, + double & tEdgeCurve, + double & precision ) const; + + /** \brief \ru Найти ближайшую проекцию точки на грань. + \en Find the nearest projection of the point on face. \~ + \details \ru Найти ближайшую проекцию точки p на поверхность грани или ее границу: ребро или вершину. \n + \en Find the nearest projection of the point on face or it border. \n \~ + \param[in] point - \ru Проецируемая точка. + \en A point. \~ + \param[out] u - \ru Найденный первый параметр поверхности. + \en Found u parameter of surface. \~ + \param[out] v - \ru Найденный второй параметр поверхности. + \en Found v parameter of surface. \~ + \param[out] normal - \ru Нормаль поверхности или ее границы (ребра или вершины) в точке проекции. + \en Normal of surface or boundaries (edges or vertices) at the point of the projection. \~ + \param[out] edgeLoc - \ru Если проекция не попала на ребро, то равен SYS_MAX_T, SYS_MAX_T. + Если проекция попала на ребро, то индексы цикла и ребра в цикле. + \en If the projection is not no the edge, then SYS_MAX_T, SYS_MAX_T. + If the projection is on the edge, then the loop index and edge index in the loop. \~ + \param[out] corner - \ru 0, если проекция не располагается на стыке ребер, + 1, если проекция располагается в конце ориентированного ребра с индексом edgeLoc, + -1, если проекция располагается в начале ориентированного ребра с индексом edgeLoc. + \en 0, if the projection is not located on the edge, + 1, if the projection is located at the end of the oriented edge with index edgeLoc, + -1, if the projection is located at the begining of the oriented edge with index edgeLoc. \~ + \return \ru Возвращает положение проекции относительно границ поверхности. + \en Returns the location of the projection point relative to the surface boundaries. \~ + \ingroup Topology_Items + */ + MbeItemLocation NearPointProjection( const MbCartPoint3D & point, + double & u, + double & v, + MbVector3D & normal, + c3d::IndicesPair & edgeLoc, + ptrdiff_t & corner ) const; + + /// \ru Разбить рёбра грани точкой на поверхности. \en Split edges of a face by a point on surface. + bool CuttingEdges( const MbCartPoint & p, double xEpsilon, double yEpsilon, + double paramPrecision ); + /// \ru Найти самопересечения циклов. \en Find self-intersections of loops. + bool LoopSelfIntersection( std::vector & siParams1, + std::vector & siParams2, + std::vector * crossCrossings, + bool checkInsideEdges, + double metricNear, + VERSION version ) const; + /// \ru Построить нормальные ЛСК конструктивных плоскостей. \en Construct normal placements of constructive planes. + bool CreateNormalPlacements ( const MbVector3D & axisZ, double angle, SArray & places ) const; + /// \ru Построить касательные ЛСК конструктивных плоскостей. \en Construct tangent placements of constructive planes. + bool CreateTangentPlacements( const MbVector3D & axisZ, SArray & places ) const; + /// \ru Дать некоторую точку и нормаль на грани. \en Get some point and normal on face. + bool GetAnyPointOn( MbCartPoint3D & pnt, MbVector3D & nor ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + /// \ru Заменить поверхность на заданную. \en Replace the surface by the given one. + void ChangeSurface( const MbSurface & newSurf ); + + /// \ru Дать параметры грани (0 <= faceU <= 1, 0 <= faceV <= 1) для параметров поверхности surfaceU и surfaceV. \en Get the face parameters (0 <= faceU <= 1, 0 <= faceV <= 1) for surface parameters surfaceU and surfaceV. + void GetFaceParam ( const double surfaceU, + const double surfaceV, + double & faceU, + double & faceV ) const; + /// \ru Дать параметры поверхности surfaceU и surfaceV по параметрам грани (0 <= faceU <= 1, 0 <= faceV <= 1). \en Get surface parameters surfaceU and surfaceV for the face parameters (0 <= faceU <= 1, 0 <= faceV <= 1). + void GetSurfaceParam( const double faceU, + const double faceV, + double & surfaceU, + double & surfaceV ) const; + /// \ru Дать точку point грани по абстрактным параметрам (0 <= faceU <= 1, 0 <= faceV <= 1). \en Get a point on a face by abstract parameters (0 <= faceU <= 1, 0 <= faceV <= 1). + void Point( double faceU, double faceV, MbCartPoint3D & point ) const; + /// \ru Дать точку point грани по параметрам её поверхности. \en Get a point on a face by surface parameters. + void PointOn( double surfaceU, double surfaceV, MbCartPoint3D & point ) const; + + /// \ru Является ли грань граничной (имеет ли ребра, которые не стыкуются с другими гранями)? \en Is a face boundary? (Does it have edges where it is not connected with other faces? ) + bool IsBoundaryFace( double mEps = Math::metricEpsilon ) const; + /// \ru Выдать множество граничных ребер грани. \en Get a set of boundary face edges. + template + void GetBoundaryEdges( ConstEdgesVector & ) const; + + /// \ru Дать топологическое состояние. \en Get topological state. + bool GetTopologyState( ptrdiff_t & cntAdjacentFaces, RPArray *& adjacentFaces, + bool & boundaryFace, ptrdiff_t & cntLoops ) const; + + /// \ru Зарезервировать место под циклы. \en Reserve memory for loops. + void LoopsReserve( size_t additionalSpace ) { loops.Reserve( additionalSpace ); } + /// \ru Удалить лишнюю память. \en Free the unnecessary memory. + void LoopsAdjust() { loops.Adjust(); } + /// \ru Пересечение поверхности грани с плоскостью, результат - множество кривых на поверхности и двумерных кривых на плоскости . \en Intersection between face and plane, the result is a set of curves on surface and two-dimensional curves on plane. + void SurfaceSection( const MbPlacement3D & place, PArray & pCurve ); + + /// \ru Построить копию поверхности и двумерные контуры по циклам для операций выдавливания и вращения кривых. \en Construct copy of surface and two-dimensional contours by loops for operations of extrusion and rotation of curves. + MbSurface * GetSurfaceCurvesData( RPArray & contours ) const; + /// \ru Построить копию поверхности и двумерные контуры по циклам для операций выдавливания и вращения кривых. \en Construct copy of surface and two-dimensional contours by loops for operations of extrusion and rotation of curves. + MbSurface * GetSurfaceCurvesData( std::vector > & contours ) const; + + /// \ru Обновить границы поверхности, ограниченной кривыми, по циклам грани. \en Update boundaries of a face bounded by curves by face loops. + bool UpdateSurfaceBounds( bool curveBoundedOnly = true ); + /// \ru Выдать габарит грани. \en Get bounding box of face. \~ + MbCube GetCube() const; + /// \ru Выдать габарит области параметров. \en Get bounding box of the space of parameters. \~ + MbRect GetRect() const; + /// \ru Обновить габарит цикла с указанным индексом. \en Update rectangle bound of loop by index. + bool UpdateLoopRect( size_t loopIndex ); + +public: + /// \ru Создан ли временный объект сопровождения грани? \en Is a temporary object for the maintenance of a face created? + bool IsTemporal() const { return (temporal != NULL); } + /// \ru Удалить временный объект сопровождения. \en Delete a temporary maintenance object. + void RemoveTemporal() const; + /// \ru Создать новый временный объект сопровождения. \en Create new temporary maintenance object. + const MbFaceTemp * CreateTemporal( bool keepExisting ) const; + /// \ru Обновить временный объект сопровождения, если он уже создан. \en Update temporary maintenance object if it is already created. + bool UpdateTemporal() const; + + + // \ru Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration of the assignment operator without implementation to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY( MbFace ) + DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFace ) +}; + +IMPL_PERSISTENT_OPS( MbFace ) + + +//------------------------------------------------------------------------------ +// \ru Выдать множество ребер грани. \en Get a set of face edges. +// --- +template +void MbFace::GetEdges( EdgesVector & edges, size_t mapThreshold ) const +{ + size_t loopsCnt = loops.size(); + edges.reserve( edges.size() + loopsCnt * 4 ); + + bool useMap = false; + + if ( edges.size() < 1 ) { + size_t checkCnt = 0; + for ( size_t i = 0; i < loopsCnt; ++i ) { + if ( loops[i] != NULL ) { + checkCnt += loops[i]->GetEdgesCount(); + if ( checkCnt > mapThreshold ) { + useMap = true; + break; + } + } + } + if ( useMap ) { // performance + std::map mapEdges; + std::map::iterator mapIt; + + size_t edgeIndex = 0; + c3d::EdgeSPtr edge; + for ( size_t i = 0; i < loopsCnt; ++i ) { + MbLoop * loop = loops[i]; + if ( loop != NULL ) { + for ( size_t j = 0, edgesCnt = loop->GetEdgesCount(); j < edgesCnt; ++j ) { + if ( loop->_GetOrientedEdge( j ) != NULL ) { + edge = &loop->_GetOrientedEdge( j )->GetCurveEdge(); + mapIt = mapEdges.find( edge ); + if ( mapIt == mapEdges.end() ) { + mapEdges.insert( std::make_pair( edge, edgeIndex ) ); + edges.push_back( edge ); + ++edgeIndex; + } + ::DetachItem( edge ); + } + } + } + } + } + } + if ( !useMap ) { + for ( size_t i = 0; i < loopsCnt; ++i ) { + if ( loops[i] != NULL ) + loops[i]->GetEdges( edges ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Выдать множество ребер внешнего цикла грани. \en Get a set of edges in outer loop of face. +// --- +template +void MbFace::GetOuterEdges( EdgesVector & edges, size_t mapThreshold ) const +{ + size_t loopsCnt = loops.size(); + edges.reserve( edges.size() + loopsCnt * 4 ); + + bool useMap = false; + + if ( edges.size() < 1 ) { + size_t checkCnt = 0; + if ( loops.front() != NULL ) { + checkCnt += loops.front()->GetEdgesCount(); + if ( checkCnt > mapThreshold ) + useMap = true; + } + if ( useMap ) { // performance + std::map mapEdges; + std::map::iterator mapIt; + + size_t edgeIndex = 0; + c3d::EdgeSPtr edge; + MbLoop * loop = loops.front(); + for ( size_t j = 0, edgesCnt = loop->GetEdgesCount(); j < edgesCnt; ++j ) { + if ( loop->_GetOrientedEdge( j ) != NULL ) { + edge = &loop->_GetOrientedEdge( j )->GetCurveEdge(); + mapIt = mapEdges.find( edge ); + if ( mapIt == mapEdges.end() ) { + mapEdges.insert( std::make_pair( edge, edgeIndex ) ); + edges.push_back( edge ); + ++edgeIndex; + } + ::DetachItem( edge ); + } + } + } + } + if ( !useMap ) { + if ( loops.front() != NULL ) + loops.front()->GetEdges( edges ); + } +} + + +//------------------------------------------------------------------------------ +// \ru Выдать множество граничных ребер грани. \en Get a set of boundary face edges. +// --- +template +void MbFace::GetBoundaryEdges( ConstEdgesVector & boundaryEdges ) const +{ + for ( size_t i = 0, loopsCnt = loops.size(); i < loopsCnt; ++i ) { + const MbLoop * loop = loops[i]; + if ( loop == NULL ) + continue; + c3d::EdgeSPtr edge; + for ( size_t j = 0, edgesCnt = loop->GetEdgesCount(); j < edgesCnt; ++j ) { + const MbOrientedEdge * orientEdge = loop->_GetOrientedEdge( j ); + if ( orientEdge == NULL ) + continue; + edge = const_cast( &orientEdge->GetCurveEdge() ); + if ( edge->IsBoundaryFace() ) { + boundaryEdges.push_back( edge ); + } + ::DetachItem( edge ); + } + } +} + + +//------------------------------------------------------------------------------ +// \ru Выдать множество смежных граней. \en Get a set of adjacent faces. +// --- +template +void MbFace::GetNeighborFaces( FacesVector & neighborFaces ) const +{ + const size_t loopsCnt = GetLoopsCount(); + + if ( loopsCnt > 0 ) { + std::vector< std::pair > facesLabels; + facesLabels.reserve( neighborFaces.size() + 5 ); + size_t k; + + // save labels for faces added before + size_t neighborsCnt0 = neighborFaces.size(); + for ( k = 0; k < neighborsCnt0; k++ ) { + const MbFace * neighborFace = neighborFaces[k]; + if ( neighborFace != NULL ) + facesLabels.push_back( std::make_pair( neighborFace, neighborFace->GetLabel() ) ); + } + neighborsCnt0 = facesLabels.size(); + + // mark neighbour faces by the first label + for ( k = 0; k < loopsCnt; ++k ) { + const MbLoop * loop = loops[k]; + if ( loop == NULL ) + continue; + for ( size_t edgeInd = 0, edgesCnt = loop->GetEdgesCount(); edgeInd < edgesCnt; ++edgeInd ) { + const MbOrientedEdge * edge = loop->_GetOrientedEdge( edgeInd ); + if ( edge == NULL ) + continue; + const MbFace * neighborFace = edge->GetFaceMinus(); + if ( neighborFace != NULL && neighborFace != this ) { + facesLabels.push_back( std::make_pair( neighborFace, neighborFace->GetLabel() ) ); // save initial label + neighborFace->SetOwnLabel( ls_Used ); + } + } + } + size_t neighborsCnt1 = facesLabels.size(); + + // mark faces added before by the second label (label of initial state) + for ( k = 0; k < neighborsCnt0; ++k ) { + facesLabels[k].first->SetOwnLabel( ls_Null ); + } + // add faces with the first label + neighborFaces.reserve( neighborsCnt1 ); + c3d::FaceSPtr neighborFace; + for ( k = neighborsCnt0; k < neighborsCnt1; ++k ) { + neighborFace = const_cast(facesLabels[k].first); + if ( neighborFace->GetLabel() == ls_Used ) { + neighborFace->SetOwnLabel( facesLabels[k].second ); // restore initial label + neighborFaces.push_back( neighborFace ); + } + ::DetachItem( neighborFace ); + } + // restore initial labels for faces added before + for ( k = 0; k < neighborsCnt0; ++k ) { + facesLabels[k].first->SetOwnLabel( facesLabels[k].second ); // restore initial label + } + } +} + + +#endif // __TOPOLOGY_H diff --git a/C3d/Include/topology_faceset.h b/C3d/Include/topology_faceset.h new file mode 100644 index 0000000..2fa50f8 --- /dev/null +++ b/C3d/Include/topology_faceset.h @@ -0,0 +1,1492 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Множество граней или оболочка. + \en Shell or set of faces. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOPOLOGY_FACESET_H +#define __TOPOLOGY_FACESET_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbCube; +class MATH_CLASS MbFunction; +struct MATH_CLASS MbEdgeFacesIndexes; +class MATH_CLASS MbShellHistory; +class MATH_CLASS MbPntLoc; +class MATH_CLASS MbFaceSetTemp; +struct MATH_CLASS MbEdgeFunction; +struct MATH_CLASS MbCheckTopologyParams; +class MATH_CLASS MbFaceShell; +class MATH_CLASS MbShellsDistanceData; + +namespace c3d // namespace C3D +{ +typedef SPtr ShellSPtr; +typedef SPtr ConstShellSPtr; + +typedef std::pair IndexShell; +typedef std::pair IndexConstShell; + +typedef std::vector ShellsVector; +typedef std::vector ConstShellsVector; + +typedef std::vector ShellsSPtrVector; +typedef std::vector ConstShellsSPtrVector; + +typedef std::set ShellsSet; +typedef ShellsSet::iterator ShellsSetIt; +typedef ShellsSet::const_iterator ShellsSetConstIt; +typedef std::pair ShellsSetRet; + +typedef std::set ConstShellsSet; +typedef ConstShellsSet::iterator ConstShellsSetIt; +typedef ConstShellsSet::const_iterator ConstShellsSetConstIt; +typedef std::pair ConstShellsSetRet; +} + + +template +void GetEdges( const FacesVector & faceSet, EdgesVector & edges ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Множество граней или оболочка. + \en Shell or set of faces. \~ + \details \ru Оболочка представляет собой составную поверхность, образованную конечным множеством граней MbFace, + стыкующихся друг с другом по рёбрам MbCurveEdge. \n + В общем случае оболочка может быть многосвязной, то есть описывать несколько не связанных между собой поверхностей. \n + Оболочка называется замкнутой, если она не имеет края, в противном случае оболочка называется незамкнутой. \n + Замкнутость оболочки указывает на возможность использования множества её внутренних точек в операциях над телами MbSolid. + Формально множество граней не ограничено никакими условиями, + но реально грани множества удовлетворяют некоторым условиям. + Чтобы подчеркнуть эту особенность оболочки, вводится понятие "Однородная оболочка". + Оболочки, удовлетворяющие нижеперечисленным требованиям, называются однородными. \n + 1. Оболочки являются конечными. \n + 2. Оболочки не пересекают сами себя. \n + 3. Оболочки являются двусторонними (ориентируемыми). \n + 4. В каждом ребре оболочки стыкуются не более двух граней. Две грани оболочки стыкуются так, + что внешняя сторона одной грани переходит во внешнюю сторону другой грани.\n + 5. При любом обходе любой вершины замкнутой оболочки по её поверхности, + мы обязательно посетим все примыкающие к данной вершине грани и пересечём все выходящие из неё рёбра.\n + Так как внешняя сторона грани переходит во внешнюю сторону соседней грани, + то однородная оболочка также имеет внешнюю и внутреннюю стороны. + Замкнутая однородная оболочка делит трёхмерное пространство на две части, одна из которых находится внутри оболочки. + Назовем замкнутую однородную оболочку внешней, если её внешняя сторона направлена вне ограничиваемой оболочкой части пространства.\n + Назовем замкнутую однородную оболочку внутренней, если её внешняя сторона направлена внутрь ограничиваемой оболочкой части пространства. + \en A shell is a composite surface formed by finite set of faces MbFace, + connected together by edges MbCurveEdge. \n + In general case a shell may be multiply connected, i.e. it may describe several pairwise not connected surfaces. \n + A shell is called closed if it has not a boundary, otherwise a shell is called unclosed. \n + The closedness of a shell indicates the possibility of using of a set of its internal points in operations with solids MbSolid. + Formally, a set of faces is not restricted by any conditions, + but actually faces of the set satisfy certain conditions. + In order to highlight this feature of a shell, the concept "manifold shell" is introduced. + Shells which satisfy the below requirements are called manifold. \n + 1. Shells are finite. \n + 2. Shells do not intersect themselves. \n + 3. Shells are two-sided (oriented). \n + 4. At each edge of a shell not more than two faces are connected. Two faces of shell connected in such way, + that the external side of one face turns to the external side of another face.\n + 5. With any go-round of any vertex of closed shell on its surface, + one will visit all faces connected with this vertex of a face and intersect all outgoing edges.\n + Since the external side of a face turns to the external side of adjacent face, + a manifold shell also has the external and internal sides. + A closed manifold shell divides the three-dimensional space into two parts, one of which is located inside the shell. + Let closed manifold shell be called external shell, if its external side is directed out from a part of space bounding by the shell.\n + Let closed manifold shell be called an internal shell, if its external side is directed inside a part of space bounding by the shell. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbFaceShell : public MbTopItem, public MbSyncItem { +protected: + RPArray faceSet; ///< \ru Множество граней. \en A set of faces. + bool closed; ///< \ru Признак замкнутости указывает на отсутствие края. \en An attribute of closedness indicates the absence of boundary. +private: + mutable MbFaceSetTemp * temporal; ///< \ru Объект сопровождения множества граней (для скорости) \en An object for maintenance of a set of faces (to improve speed) + +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbFaceShell(); + /// \ru Конструктор по набору граней. \en Constructor by a set of faces. + template + MbFaceShell( const Faces & initFaces ); + /// \ru Конструктор по грани. \en Constructor by face. + explicit MbFaceShell( const MbFace & face ); + /// \ru Конструктор по граням другой оболочки. \en Constructor by faces of other shell. + explicit MbFaceShell( const MbFaceShell & init ); + /// \ru Деструктор. \en Destructor. + virtual ~MbFaceShell(); + + /// \ru Функции оболочки. \en Functions of shell. + + virtual MbeTopologyType IsA() const; // \ru Тип элемента. \en A type of element. + + /** \brief \ru Создать копию. + \en Create a copy. \~ + \details \ru Создать копию оболочки с копированием части данных и + перекладыванием из оригинала в копию остальной части данных. \n + Параметр history используется, если режим копирования cm_KeepHistory. + \en Create a copy of a shell with copying of a part of data and + moving another part of data from the original to the copy. \n + The parameter 'history' is used if the copying mode is cm_KeepHistory. \~ + \param[in] sameShell - \ru Способ передачи данных при копировании оболочки MbeCopyMode: \n + sameShell == cm_Same - в качестве копии возвращяетчя исходная оболока (оболочка не копируется, но выставляются правильно указатели в рёбрах на грани справа и грани слева); \n + sameShell == cm_KeepHistory - копируется часть данных (исходная оболочка и её копия имеют общие базовые поверхности и вершины) и заполняются множества граней объекта history; \n + sameShell == cm_KeepSurface - копируется часть данных (исходная оболочка и её копия имеют общие базовые поверхности); \n + sameShell == cm_Copy - обычное копирование (исходная оболочка и её копия не имеет общих данных). \n + \en A way of data transferring when copying of a shell MbeCopyMode: \n + sameShell == cm_Same - an initial shell is returned as the copy (a shell is not copied but the pointers of edges to the faces are correctly set); \n + sameShell == cm_KeepHistory - a part of data is copied (the initial shell and its copy have the common basis surfaces and vertices) and the sets of faces of the object 'history' are filled; \n + sameShell == cm_KeepSurface - a part of data is copied (the initial shell and its copy have the common basis surfaces); \n + sameShell == cm_Copy - an ordinary copying (the initial shell and its copy have no the common data). \n \~ + \param[in] history - \ru История копий граней используется после операции для замены неизменённых копий граней их оригиналами. + \en A history of faces copies is used after the operation for the replacement of unchanged copies by their originals. \~ + \return \ru Копия объекта или оригинал(в случае режима копирования cm_Same). + \en Copy of an object or original (in a case of the mode cm_Same). \~ + */ + MbFaceShell * Copy( MbeCopyMode sameShell, MbShellHistory * history = NULL ); + + /** \brief \ru Создать копию. + \en Create a copy. \~ + \details \ru Создать копию оболочки с регистратором. + \en Create a copy of a shell with registrator. \~ + \return \ru Копия объекта. + \en Copy of the object. \~ + */ + MbFaceShell * Duplicate( MbRegDuplicate * iReg = NULL ) const; + + /// \ru Замкнутая ли оболочка? \en Is shell closed? + bool IsClosed() const { return closed; } + /// \ru Установить (не)замкнутость оболочки. \en Set shell (un-) closedness. + void SetClosed( bool c ) { closed = c; } + /// \ru Выдать количество граней. \en Get the number of faces. + size_t GetFacesCount() const { return faceSet.size(); } + /// \ru Выдать максимальный индекс грани. \en Get the maximum index of a face. + ptrdiff_t GetFacesMaxIndex() const { return ((ptrdiff_t)faceSet.size() - 1); } + /// \ru Добавить грань в оболочку. \en Add a face into a shell. + void AddFace( const MbFace & ); + /// \ru Добавить грани в оболочку. \en Add faces into a shell. + template + void AddFaces( const FacesVector & newFaces, bool justAdd ) + { + if ( !newFaces.empty() ) { + bool delTemporal = false; + for ( size_t i = 0, cnt = newFaces.size(); i < cnt; ++i ) { + const MbFace * newFace = newFaces[i]; + if ( newFace == NULL ) + continue; + if ( justAdd || ( std::find( faceSet.begin(), faceSet.end(), newFace ) == faceSet.end() ) ) { + faceSet.push_back( const_cast(newFace) ); + C3D_ASSERT( !newFace->ToDelete() ); + ::AddRefItem( newFace ); + delTemporal = true; + } + } + if ( delTemporal ) + RemoveTemporal(); + } + } + /// \ru Вставить грань перед гранью с заданным индексом. \en Insert a face before the face with the given index. + void InsertFace( size_t index, const MbFace & ); + /// \ru Заменить грань с заданным индексом. \en Replace a face with the given index. + void ChangeFace( size_t index, const MbFace & ); + /// \ru Удалить грань с заданным индексом. \en Delete a face at the given index. + void DeleteFace( size_t index ); + /// \ru Удалить грань. \en Delete a face. + void DeleteFace( const MbFace * ); + /// \ru Отсоединить грань от оболочки с заданным индексом. \en Detach a face from a shell with the given index. + MbFace * DetachFace( size_t index ); + /// \ru Отсоединить грань. \en Detach face. + void DetachFace( const MbFace * ); + /// \ru Удалить все грани оболочки. \en Delete all faces of shell. + void DeleteFaces(); + /// \ru Отсоединить все грани оболочки. \en Detach all faces from shell. + void DetachFaces(); + /// \ru Поменять местами грани оболочки. \en Swap shell faces. + void ExchangeFaces( size_t i1, size_t i2 ); + /// \ru Установить правильную (текущую) информацию в ребрах о соединяемых ими гранях и параметры поверхностей по данным циклов граней (setBounds = true). \en Set the correct (the current) information in edges about the connected by them faces and parameters of surfaces by loops of faces (setBounds = true). + void MakeRight( bool setBounds = false ); + /// \ru Верно ли установлены указатели в ребрах на соединяемые ими грани. \en Are the pointers in edges to the connected by them faces correctly set? + bool IsRight() const; + /// \ru Обнулить указатели в ребрах на отсутствующую в оболочке грань. \en Set to null in edges the pointers to a face which is absent face + void SetNullToFace( const MbFace * delFace ); + + /** \brief \ru Преобразовать согласно матрице. + \en Transform according to the matrix. \~ + \details \ru Преобразование оболочки согласно матрице. + В оболочке одни и те же геометрические объекты, например поверхности, используются как в гранях, так и в рёбрах. + Для преобразования каждого геометрического объекта только один раз используется регистратор. + \en The transformation of a shell according to a matrix. + In a shell the same geometric objects, for example, surfaces, are used in both faces and in edges. + For the transformation of each geometric object only once a registrator is used. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор объектов. + \en Registrator of objects: \~ + */ + void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ); + + /** \brief \ru Сдвинуть вдоль вектора. + \en Move along a vector. \~ + \details \ru Сдвиг оболочки вдоль вектора. + В оболочке одни и те же геометрические объекты, например поверхности, используются как в гранях, так и в рёбрах. + Для преобразования каждого геометрического объекта только один раз используется регистратор. + \en Move of a shell along a vector. + In a shell the same geometric objects, for example, faces, are used in both faces and in edges. + For the transformation of each geometric object only once a registrator is used. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Move( const MbVector3D & to, MbRegTransform * iReg = NULL ); + + /** \brief \ru Повернуть вокруг оси. + \en Rotate around an axis. \~ + \details \ru Поворот оболочки вокруг оси. + В оболочке одни и те же геометрические объекты, например поверхности, используются как в гранях, так и в рёбрах. + Для преобразования каждого геометрического объекта только один раз используется регистратор. + \en The rotation of a shell around an axis. + In a shell the same geometric objects, for example, faces, are used in both faces and in edges. + For the transformation of each geometric object only once a registrator is used. \~ + \param[in] axis - \ru Ось поворота. + \en The rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + */ + void Rotate( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ); + /// \ru Рассчитать расстояние до точки. \en Calculate the distance to a point. + double DistanceToPoint( const MbCartPoint3D & to ) const; + /// \ru Вывернуть оболочку наизнанку - переориентировать все грани. \en Revert the shell - reorientation of the whole set of faces. + void Reverse(); + /// \ru Являются ли объекты равными. \en Determine whether objects are equal. + bool IsSame( const MbFaceShell & faces, double accuracy ) const; + /// \ru Установить метки всем объектам, имеющим таковые. \en Set labels for all objects which have them. + void SetLabelThrough( MbeLabelState, void * = NULL ) const; + /// \ru Установить метки всем объектам, имеющим таковые. \en Set labels for all objects which have them. + void SetLabelThrough( MbeLabelState, void *, bool ) const; + /// \ru Удалить частные метки всем объектам, имеющим таковые. \en Remove private labels for all objects which have them. + void RemovePrivateLabelThrough( void * ) const; + /// \ru Установить флаги изменённости объектов. \en Set flags that objects have been changed. + void SetOwnChangedThrough( MbeChangedType n ); + /// \ru Установить флаги в начальное состояние. \en Set flags to initial state. + void ResetFlags( void * = NULL ); + /// \ru Забрать в оболочку множество граней из оболочки faces. \en Move a set of faces to the shell from another shell. + bool UnionWith( MbFaceShell & faces, c3d::FacesSet * sharedSet = NULL ); + /// \ru Установить заданную метку всем вершинам оболочки. \en Set the given label for all vertices of the shell. + size_t SetVerticesLabel( MbeLabelState, void * = NULL) const; + /// \ru Установить заданную метку всем рёбрам оболочки. \en Set the given label for all edges of the shell. + size_t SetEdgesLabel ( MbeLabelState, void * = NULL) const; + /// \ru Установить заданную метку всем граням оболочки. \en Set the given label for all faces of the shell. + void SetFacesLabel ( MbeLabelState, void * = NULL) const; + + /// \ru Выдать множество вершин оболочки. \en Get a set of vertices of the shell. + template + void GetVertices( VerticesVector & ) const; + /// \ru Выдать множество ребер оболочки. \en Get a set of edges of the shell. + template + void GetEdges( EdgesVector & edges ) const + { + if ( edges.size() < 1 ) + ::GetEdges< RPArray, EdgesVector >( faceSet, edges ); + else { + size_t count = faceSet.size(); + edges.reserve( edges.size() + count * 2 ); + for ( size_t i = 0; i < count; i++ ) + faceSet[i]->GetEdges( edges ); + } + } + /// \ru Выдать множество граней оболочки. \en Get a set of faces of the shell. + template + void GetFaces( FacesVector & faces ) const + { + faces.reserve( faces.size() + faceSet.size() ); + SPtr face; + for ( size_t k = 0, kcnt = faceSet.size(); k < kcnt; ++k ) { + face = const_cast( faceSet[k] ); + faces.push_back( face ); + ::DetachItem( face ); + } + } + /// \ru Выдать множество граней оболочки. \en Get a set of faces of the shell. + template + void GetFacesSet( FacesSet & faces ) const + { + for ( size_t k = 0, kcnt = faceSet.size(); k < kcnt; ++k ) { + if ( faceSet[k] != NULL ) + faces.insert( faceSet[k] ); + } + } + /// \ru Выдать множество вершин и множество ребер оболочки. \en Get a set of vertices and a set of edges of the shell. + template + void GetItems( VerticesVector & vertices, EdgesVector & edges ) const; + /// \ru Выдать множество вершин, множество ребер и множество граней оболочки. \en Get a set of vertices, a set of edges and a set of faces of the shell. + void GetItems( RPArray & list ) const; + + /// \ru Выдать вершину по индексу. \en Get a vertex by an index. + MbVertex * GetVertex ( size_t index ) const; + /// \ru Выдать ребро по индексу. \en Get an edge by an index. + MbCurveEdge * GetEdge ( size_t index ) const; + /// \ru Выдать грань по индексу. \en Get a face by an index. + MbFace * GetFace ( size_t index ) const; + /// \ru Выдать грань по индексу без проверки корректности индекса. \en Get a face by an index without a check of index correctness. + MbFace * _GetFace ( size_t index ) const { return faceSet[index]; } + /// \ru Выдать поверхность грани по индексу. \en Give a surface of a face by an index. + const MbSurface * GetSurface( size_t index ) const; + /// \ru Выдать индекс вершины. \en Get an index of a vertex. + size_t GetVertexIndex( const MbVertex & vertex ) const; + /// \ru Выдать индекс ребра. \en Get an index of an edge. + size_t GetEdgeIndex( const MbCurveEdge & edge ) const; + /// \ru Выдать индекс грани. \en Get an index of a face. + size_t GetFaceIndex( const MbFace & face ) const { return faceSet.FindIt( &face ); } + /// \ru Найти индекс грани в оболочке. \en Find an index of a face in the shell. + size_t Find( const MbFace * face ) const { return faceSet.FindIt( face ); } + /// \ru Определить количество связных поверхностей, описываемых оболочкой. \en Define the number of connected faces describing by the shell. + size_t GetShellCount() const; + + /** \brief \ru Вычислить ближайшее расстояние до оболочки. + \en Calculate the nearest distance to a shell. \~ + \details \ru Вычислить ближайшее расстояние до оболочки с заданным допуском с той же системой координат. В случае пересечения или касания оболочек возвращается нулевая дистанция. + \en Calculate the nearest distance to a shell with a specified tolerance with the same coordinate system. In case of intersection or tangent of the shells returns to zero distance.\~ + \note \ru При многократном использовании оболочки следует создать объекты сопровождения оболочки и её граней. + \en When multiply use shell, you should create objects for maintenance this shell and its faces. \~ + \param[in] shell - \ru Оболочка. + \en Shell. \~ + \param[in] lowerLimitDistance - \ru Минимально допустимое расстояние. + \en Minimum allowed distance. \~ + \param[in] tillFirstLowerLimit - \ru Остановить поиск после первого найденного расстояния меньшего либо равного минимально допустимому. + \en Stop the search after the first found distance is less or equal than to the minimum allowable. \~ + \param[in] epsilon - \ru Погрешность вычисления расстояния между поверхностями граней оболочек. + \en Accuracy of distanse between shell face surfaces. \~ + \param[out] shellsDistanceData - \ru Данные ближайщего расстояния между оболочками. + \en The data of nearest distance beetwen shells. \~ + + \return \ru Удалось ли определить минимальное расстояние между оболочками. + \en Whether the minimum distance between shells was successfully defined. \~ + */ + bool DistanceToShell( const MbFaceShell & shell, + double lowerLimitDistance, bool tillFirstLowerLimit, + double epsilon, + std::vector & shellsDistanceData ) const; + + /** \brief \ru Определить расстояния от точки до оболочки. + \en Define the distance from a point to the shell. \~ + \details \ru Определить расстояния от точки до оболочки и положение точки: + снаружи оболочки, на оболочке, внутри оболочки. + \en Define the distance from a point to the shell and location of a point: + outside the shell, on the shell, inside the shell. \~ + \param[in] pnt - \ru Точка. + \en Point. \~ + \param[in] accuracy - \ru Заданная точность определения положения. + \en A given tolerance for the location definition. \~ + \param[out] finFaceData - \ru Информация об окружении проекции точки pnt на ближайшую грань оболочки. + \en An information about surroundings of the point 'pnt' projection to the nearest face of the shell. \~ + \param[out] rShell - \ru Результат определения: снаружи оболочки (-1), на оболочке (0), внутри оболочки (+1). + \en The result of definition: outside the shell (-1), on the shell (0), inside the shell (+1). \~ + \return \ru Удалось ли определить расстояния от точки до оболочки. + \en Whether the distance from a point to the shell was successfully defined.. \~ + */ + bool DistanceToBound( const MbCartPoint3D & pnt, double accuracy, + MbPntLoc & finFaceData, + MbeItemLocation & rShell ) const; + + /** \brief \ru Определить положение точки относительно оболочки. + \en Define the point location relative to the shell. \~ + \details \ru Определить положение точки относительно оболочки: снаружи оболочки, на оболочке, внутри оболочки. + \en Define the point location relative to the shell: outside the shell, on the shell, inside the shell. \~ + \param[in] pnt - \ru Точка. + \en Point. \~ + \param[in] accuracy - \ru Заданная точность определения положения. + \en A given tolerance for the location definition. \~ + \param[out] shellPoint - \ru Ближайшая к точке pnt точка оболочки. + \en A point on the shell which is the nearest to the point 'pnt'. \~ + \param[out] shellNormal - \ru Нормаль в ближайшей к точке pnt точке оболочки. + \en A normal to the nearest to the 'pnt' point on the shell. \~ + \param[out] rShell - \ru Результат определения: снаружи оболочки (-1), на оболочке (0), внутри оболочки (+1). + \en The result of definition: outside the shell (-1), on the shell (0), inside the shell (+1). \~ + \return \ru Удалось ли определить положение точки относительно оболочки. + \en Whether the point location relative to the shell was successfully defined. \~ + */ + bool PointClassification( const MbCartPoint3D & pnt, double accuracy, + MbCartPoint3D & shellPoint, MbVector3D & shellNormal, + MbeItemLocation & rShell ) const; + + /** \brief \ru Определить положение точки относительно оболочки. + \en Define the point location relative to the shell. \~ + \details \ru Определить положение точки относительно оболочки: снаружи оболочки, на оболочке, внутри оболочки. + \en Define the point location relative to the shell: outside the shell, on the shell, inside the shell. \~ + \param[in] pnt - \ru Точка. + \en Point. \~ + \param[in] accuracy - \ru Заданная точность определения положения. + \en A given tolerance for the location definition. \~ + \param[out] shellPoint - \ru Ближайшая к точке pnt точка оболочки. + \en A point on the shell which is the nearest to the point 'pnt'. \~ + \param[out] shellNormal - \ru Нормаль в ближайшей к точке pnt точке оболочки. + \en A normal to the nearest to the 'pnt' point on the shell. \~ + \param[out] rShell - \ru Положение точки относительно оболочки. + \en The point location relative to the shell. \~ + \return \ru Удалось ли определить положение точки относительно оболочки. + \en Whether the point location relative to the shell was successfully defined. \~ + */ + bool PointClassification( const MbCartPoint3D & pnt, double accuracy, + MbCartPoint3D & shellPoint, MbVector3D & shellNormal, + MbPntLoc & rShell ) const; + + /** \brief \ru Вычислить точку оболочки. + \en Calculate a point of the shell. \~ + \details \ru Вычислить точку оболочки для заданной грани по заданным параметрам её поверхности. + \en Calculate a point for the given face by the given parameters of its surface. \~ + \param[in] n - \ru Индекс грани оболочки. + \en An index of a face of the shell. \~ + \param[in] u - \ru Первый параметр поверхности грани. + \en The first parameter of the face surface. \~ + \param[in] v - \ru Второй параметр поверхности грани. + \en The second parameter of the face surface. \~ + \param[out] p - \ru Вычисленная точка оболочки. + \en Calculated point of the shell. \~ + */ + void PointOn( size_t n, double & u, double & v, MbCartPoint3D & p ) const; + + /** \brief \ru Вычислить нормаль оболочки. + \en Calculate a normal of the shell. \~ + \details \ru Вычислить нормаль оболочки для заданной грани по заданным параметрам её поверхности. \n + \en Calculate a normal of the shell for the given face by the given parameters of its surface. \n \~ + \param[in] n - \ru Индекс грани оболочки. + \en An index of a face of the shell. \~ + \param[in] u - \ru Первый параметр поверхности грани. + \en The first parameter of the face surface. \~ + \param[in] v - \ru Второй параметр поверхности грани. + \en The second parameter of the face surface. \~ + \param[out] p - \ru Вычисленная нормаль оболочки. + \en Calculated normal of the shell. \~ + */ + void Normal ( size_t n, double & u, double & v, MbVector3D & p ) const; + + /** \brief \ru Найти все проекции точки на оболочку. + \en Find the point projection to the shell. \~ + \details \ru Найти все проекции точки на все грани оболочки. \n + \en Find all point projections to all faces of the shell. \n \~ + \param[in] p - \ru Проецируемая точка. + \en A point to project. \~ + \param[out] nums - \ru Массив номера граней в оболочки, синхронный с массивом параметров проекций. + \en An array of faces numbers in the shell, synchronized with the array of projections parameters \~ + \param[out] uv - \ru Массив параметров проекций. + \en An array of projections parameters. \~ + */ + void NearPointProjection( const MbCartPoint3D & p, SArray & nums, SArray & uv ) const; + + /** \brief \ru Найти ближайшую проекцию точки на оболочку. + \en Find nearest point projection to the shell. \~ + \details \ru Найти номер грани и параметры её поверхности для ближайшей проекции точки на оболочку. \n + \en Find face index and surface parameters for the nearest point projection to the shell. \n \~ + \param[in] p - \ru Проецируемая точка. + \en A point to project. \~ + \param[out] faceIndex - \ru Номер грани в оболочке для ближайшей проекции. + \en The index of nearest face of the shell. \~ + \param[out] u - \ru Первый параметр поверхности грани проекций для ближайшей проекции точки на оболочку. + \en The first parameter of the face surface for the nearest projection. \~ + \param[out] v - \ru Второй параметр поверхности грани проекций для ближайшей проекции точки на оболочку. + \en The second parameter of the face surface for the nearest projection. \~ + \return \ru Удалось ли определить положение точки. + \en Whether the point projection was successfully defined. \~ + */ + bool NearPointProjection( const MbCartPoint3D & p, size_t & faceIndex, double & u, double & v ) const; + + /** \brief \ru Найти все проекции точки на оболочку вдоль вектора в любом из двух направлений. + \en Find the point projection to the shell along a vector in either of two directions. \~ + \details \ru Найти все проекции точки на все грани оболочки вдоль вектора в любом из двух направлений. \n + \en Find all point projections to all faces of the shell along a vector in either of two directions. \n \~ + \param[in] p - \ru Проецируемая точка. + \en A point to project. \~ + \param[in] vect - \ru Вектор направления проецирования. + \en The vector of direction. \~ + \param[out] nums - \ru Массив номера граней в оболочки, синхронный с массивом параметров проекций. + \en An array of faces numbers in the shell, synchronized with the array of projections parameters \~ + \param[out] uv - \ru Массив параметров проекций. + \en An array of projections parameters. \~ + */ + void DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect, SArray & nums, SArray & uv ) const; + + /** \brief \ru Найти ближайшую проекцию точки на оболочку в направлении вектора. + \en Find nearest point projection to the shell in the direction of the vector. \~ + \details \ru Найти номер грани и параметры её поверхности для ближайшей проекции точки на оболочку в направлении вектора. \n + \en Find face index and surface parameters for the nearest point projection to the shell in the direction of the vector. \n \~ + \param[in] p - \ru Проецируемая точка. + \en A point to project. \~ + \param[out] faceIndex - \ru Номер грани в оболочке для ближайшей проекции. + \en The index of nearest face of the shell. \~ + \param[in] vect - \ru Вектор направления проецирования. + \en The vector of direction. \~ + \param[out] u - \ru Первый параметр поверхности грани проекций для ближайшей проекции точки на оболочку в направлении вектора. + \en The first parameter of the face surface for the nearest projection in the direction of the vector. \~ + \param[out] v - \ru Второй параметр поверхности грани проекций для ближайшей проекции точки на оболочку в направлении вектора. + \en The second parameter of the face surface for the nearest projection in the direction of the vector. \~ + \param[in] onlyPositiveDirection - \ru Искать только в положительном направлении вектора vect от точки p. + \en Find in the positive direction of vector vect from point p \~ + \return \ru Удалось ли определить положение точки. + \en Whether the point projection was successfully defined. \~ + */ + bool NearDirectPointProjection( const MbCartPoint3D & p, size_t & faceIndex, const MbVector3D & vect, double & u, double & v, + bool onlyPositiveDirection = false ) const; + + /** \brief \ru Существует ли проекция в направлении вектора? + \en Does the projection in direction of the vector exist? \~ + \details \ru Определить, существует ли хотя бы одна проекция точки на оболочку в направлении вектора. + \en Define whether at least one projection of a point to the shell in direction of the vector exists. \~ + \param[in] p - \ru Проецируемая точка. + \en A point to project. \~ + \param[in] vect - \ru Вектор, задающий направление проецирования. + \en A vector which defines the direction of projection. \~ + \return \ru true, если нашлась хотя бы одна проекция. + \en True if at least one projection is found. \~ + */ + bool DirectPointProjection( const MbCartPoint3D & p, const MbVector3D & vect ) const; + + /** \brief \ru Пересечение оболочки и кривой. + \en Intersection between a shell and a curve. \~ + \details \ru Найти пересечения кривой с гранями оболочки. + \en Find intersections between a curve and faces of a shell. \~ + \param[in] curve - \ru Кривая. + \en Curve. \~ + \param[out] nn -\ru Номера граней оболочки, у которых есть пересечения с кривой. + \en Indices of shell faces that have intersections with the curve. \~ + \param[out] uv -\ru Параметрические точки пересечений на поверхностях граней оболочки. + \en Parametric points of intersections on faces' surfaces. \~ + \param[out] tt -\ru Параметры пересечений на кривой. + \en Intersection parameters on the curve. \~ + */ + void CurveIntersection( const MbCurve3D & curve, SArray & nn, + SArray & uv, SArray & tt ) const; + /// \ru Добавить свой габарит в габаритный куб. \en Add your own bounding box into bounding cube. + void AddYourGabaritTo( MbCube & ) const; + /// \ru Рассчитать габарит оболочки. \en Calculate bounding box of the shell. + void CalculateGabarit( MbCube & ) const; + /// \ru Рассчитать габарит в локальной системы координат, заданной матрицей matrToLocal преобразования в неё \en Calculate bounding box in the local coordinate system which is given by the matrix 'matrToLocal ' of transformation to it. + void CalculateLocalGabarit( const MbMatrix3D & matrToLocal, MbCube & cube ) const; + /// \ru Рассчитать габарит в локальной системы координат localPlace. \en Calculate bounding box in the local coordinate system 'localPlace'. + void CalculateLocalGabarit( const MbPlacement3D & localPlace, MbCube & cube ) const; + + /** \brief \ru Построить полигональную копию оболочки. + \en Construct a polygonal copy of the shell. \~ + \details \ru Построить полигональную копию оболочки заполнить ею полигональный объект (сетку) mesh. + \en Construct a polygonal copy of a shell and fill a polygonal object (a mesh) by it. \~ + \note \ru В многопоточном режиме m_Items выполняется параллельно. \en In multithreaded mode m_Items runs in parallel. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[in] note - \ru Способ построения полигонального объекта. + \en Way for polygonal object constructing. \~ + \param[out] mesh - \ru Заполняемый полигональный объект. + \en A polygonal object that being filled. \~ + */ + void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; + + /// \ru Выдать свойства объекта. \en Get properties of the object. + void GetProperties( MbProperties & ); + /// \ru Установить свойства объекта. \en Set properties of the object. + void SetProperties( const MbProperties & ); + + /// \ru Установить главное имя и вставить старое в индекс копирования. \en Set the main name and insert an old name to the copy index. + void SetMainName ( SimpleName mainName, bool addOldMainName ); + /// \ru Установить главное имя и модифицировать имена граней, рёбер и вершин для оболочки-копии для предотвращения совпадения имен нескольких копий. \en Set the main name and modify names of faces, edges and vertices for the shell-copy in order to prevent coincidence of several copies names. + void MakeNewNames ( SimpleName mainName, SimpleName modifier ); + /// \ru Установить главное имя и модифицировать имена граней для оболочки-копии для предотвращения совпадения имен нескольких копий. \en Set the main name and modify names of faces for the shell-copy in order to prevent coincidence of several copies names. + void MakeNewNames ( const MbSNameMaker &, SimpleName modifier ); + /// \ru Проименовать грани, рёбра и вершины оболочки. \en Rename faces, edges and vertices of the shell. + void SetShellNames ( const MbSNameMaker & names ); + /// \ru Заменить в имени метку копирования на index. \en Replace in a name a copying label by 'index'. + void SetNamesCopyIndex ( SimpleName index ); + /// \ru Проименовать грани оболочки именами оболочки s. \en Name shell faces by names of the shell 's'. + void SetShellNames ( const MbFaceShell * s ); + /// \ru Очистить все имена в оболочке. \en Clear all shell names. + void ClearShellNames (); + /// \ru Очистить имена ребер в оболочке. \en Clear all shell edges names. + void ClearEdgesNames ( bool clearVerticesNames = true ); + + /** \brief \ru Проверка оболочки: вершин (удаление совпадающих и лишних), ребер (со слиянием). + \en Validation of the shell: vertices (deletion of coincident and extra), edges (with merge). \~ + \details \ru Проверка оболочки: вершин (удаление совпадающих и лишних), ребер (со слиянием). + \en Validation of the shell: vertices (deletion of coincident and extra), edges (with merge). \~ + \param[in] checkParams - \ru Параметры функции. + \en Function parameters. \~ + */ + MbResultType CheckTopology( MbCheckTopologyParams & checkParams ); + + /// \ru Определение замкнутости оболочки с модификацией флага. \en Check shell closedness with flag modification. + void CheckClosed( bool checkChangedOnly = false ); + /// \ru Найти граничные рёбра и сделать граничными их кривые. \en Find the boundary edges, make their curve boundary. + bool MakeBoundaryCurve(); + /// \ru Получить краевые ребра оболочки. \en Get boundary edges of the shell. + bool GetBoundaryEdges( RPArray & ) const; + /// \ru Получить краевые ребра оболочки. \en Get boundary edges of the shell. + bool GetBoundaryEdges( c3d::ConstEdgesVector & ) const; + + /// \ru Для множества ребер найти номера ребер и номера ее граней. \en For a set of edges find their indices and indices of their faces. + bool FindFacesIndexByEdges( const RPArray & init, SArray & indexes, bool any = false ) const; + /// \ru Для множества структур (ребер и функций изменения радиусов) найти номера ребер и номера ее граней. \en For a set of structures (edges and functions of radii changing) find indices of edges and their faces. + bool FindFacesIndexByEdges( const SArray & init, + RPArray & functions, SArray & indexes ) const; + /// \ru Для множества номеров ребер и номеров ее граней найти ребра. \en For a set of edge indices and indices of their faces find edges. + bool FindEdgesByFacesIndex( const SArray & indexes, RPArray * functions, + RPArray & initCurves, RPArray & initFunctions ) const; + /// \ru Найти номера граней по ребру. \en Find faces indices by the edge. + bool FindFacesIndexByEdge( const MbCurveEdge & edge, size_t & ind1, size_t & ind2, bool any = false ) const; + /// \ru Для множества граней найти множество их номеров. \en For a set of faces find a set of their indices. + bool FindFacesIndexByFaces( const RPArray & init, SArray & ind0 ) const; + /// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices. + template // ItemIndices - MbItemIndex vector + bool FindIndexByFaces( const FacesPointersVector &, ItemIndices &, size_t mapThreshold = 50 ) const; + /// \ru Найти множество граней по множеству комбинированных индексов. \en Find a set of faces by a set of combined indices. + template // ItemIndices - MbItemIndex vector + bool FindConstFacesByIndex( const ItemIndices &, ConstFacesPointersVector & ) const; + template // ItemIndices - MbItemIndex vector + bool FindFacesByIndex( const ItemIndices &, FacesPointersVector & ); + + bool FindItemIndexByIndex( const std::vector & indexes, + std::vector< std::pair > & ind0 ) const; + /// \ru Для множества вершин найти множество их комбинированных номеров. \en For a set of vertices find a set of their combined indices. + bool FindIndexByVertices( const RPArray & init, SArray & indexes ) const; + /// \ru Найти множество вершин по множеству комбинированных индексов. \en Find a set of vertices by a set of combined indices. + bool FindVerticesByIndex( const SArray & indexes, RPArray & init ) const; + /// \ru Найти комбинированный индекс грани. \en Find combined index of a face. + bool FindIndexByFace( const MbFace &, MbItemIndex & ) const; + /// \ru Найти грань по комбинированному индексу. \en Find a face by combined index. + const MbFace * FindFaceByIndex( MbItemIndex & ) const; + /// \ru Найти грань по комбинированному индексу. \en Find a face by combined index. + MbFace * FindFaceByIndex( MbItemIndex & ); + /// \ru Найти множество ребер с общей заданной вершиной. \en Find a set of edges with the common given vertex. + void FindEdgesForVertex( const MbVertex & vertex, RPArray & findEdges ) const; + /// \ru Найти множество граней с общей заданной вершиной. \en Find a set of faces with the common given vertex. + void FindFacesForVertex( const MbVertex & vertex, RPArray & findFaces ) const; + /// \ru Для ребра edge найти индекс грани, индекс цикла и индекс ребра в этом цикле. \en For the edge 'edge' find an index of face, an index of loop and an index of edge in this loop. + bool FindEdgeNumbers( const MbCurveEdge & edge, size_t & faceN, size_t & loopN, size_t & edgeN ) const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + const MbVertex * FindVertexByName( const MbName & ) const; + /// \ru Найти ребро по имени. \en Find edge by name. + const MbCurveEdge * FindEdgeByName ( const MbName & ) const; + /// \ru Найти грань по имени. \en Find face by name. + const MbFace * FindFaceByName ( const MbName & ) const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + MbVertex * FindVertexByName( const MbName & ); + /// \ru Найти ребро по имени. \en Find edge by name. + MbCurveEdge * FindEdgeByName ( const MbName & ); + /// \ru Найти грань по имени. \en Find face by name. + MbFace * FindFaceByName ( const MbName & ); + + /// \ru Объединить подобные грани. \en Merge similar faces. + bool MergeSimilarFaces(); + + /// \ru Создан ли временный объект сопровождения? \en Is a temporary object for the maintenance created? + bool IsTemporal() const { return (temporal != NULL); } + /// \ru Удалить временный объект сопровождения. \en Delete a temporary maintenance object. + void RemoveTemporal() const; + /// \ru Создать новый временный объект сопровождения. \en Create new temporary maintenance object. + const MbFaceSetTemp * CreateTemporal( bool keepExisting ) const; + /// \ru Обновить временный объект сопровождения грани. \en Update a temporary maintenance object of a face. + /// \ru changedOnly = true использовать только при не измененной оболочке (после резки ребер), не обновляется дерево габаритов. \en changedOnly = true can only be used intact shell (after cutting edges). + bool UpdateTemporal( bool changedOnly = false ) const; + /// \ru Создан ли временный объект сопровождения грани? \en Is a temporary object for the maintenance of a face created? + bool IsTemporal( size_t k ) const; + /// \ru Получить временный объект сопровождения грани. \en Get a temporary maintenance object of a face. + bool CreateTemporal( size_t k, bool keepExisting ) const; + + /// \ru Удалить атрибуты типа имя с родительскими именами. \en Delete attributes of name type with parent names. + void RemoveParentNamesAttributes(); + +private: + // \ru Объявление (перегрузка) оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en Declaration (overload) of the assignment operator without its implementation, to prevent the default assignment. + void operator = ( const MbFaceShell & ); // \ru НЕЛЬЗЯ! \en NOT ALLOWED !!! + // \ru Создать копию набора граней с такой же или противоположной ориентацией. \en Create a copy of face set with such or an opposite orientation. + void DataDuplicate( RPArray & faces, bool in, bool sameSurface, bool sameVertices, + MbRegDuplicate * iReg ) const; + // \ru Создать копию. \en Create a copy. + MbFaceShell * ShellDuplicate( bool sameSurface, bool sameVertices, MbRegDuplicate * iReg ) const; + // \ru Создать копию. \en Create a copy. + MbFaceShell * ShellDuplicate( MbShellHistory & history, MbRegDuplicate * iReg ) const; + + /// \ru Обновить временный объект сопровождения после добавлении части оболочки. \en Update a temporary maintenance object after adding a shell. + bool UpdateTemporalAddingShell( size_t innerBegInd ) const; + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbFaceShell ) +}; + +IMPL_PERSISTENT_OPS( MbFaceShell ) + + +//------------------------------------------------------------------------------ +// \ru Конструктор по набору граней. \en Constructor by a set of faces. +// --- +template +MbFaceShell::MbFaceShell( const Faces & initFaces ) + : MbTopItem() + , faceSet ( initFaces.size(), 1 ) + , closed ( true ) + , temporal ( NULL ) +{ + for ( size_t i = 0, cnt = initFaces.size(); i < cnt; ++i ) { + if ( initFaces[i] != NULL ) + AddFace( *initFaces[i] ); + } +} + +//------------------------------------------------------------------------------ +// \ru Выдать множество вершин оболочки. \en Get a set of vertices of the shell. +// --- +template +void MbFaceShell::GetVertices( VerticesVector & vertices ) const +{ + if ( vertices.size() == 0 ) { + // set label + ptrdiff_t maxCount = SetVerticesLabel( ls_Used ); + vertices.reserve( vertices.size() + maxCount ); + + SPtr vertex; + + // reset label + for ( size_t i = 0, fcount = faceSet.size(); i < fcount; ++i ) { + const MbFace * face = faceSet[i]; + for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) { + const MbLoop * loop = face->_GetLoop( j ); + + for ( size_t k = 0, ecount = loop->GetEdgesCount(); k < ecount; k++ ) { + const MbCurveEdge * edge = &loop->_GetOrientedEdge( k )->GetCurveEdge(); + + vertex = const_cast(&edge->GetBegVertex()); + if ( vertex->GetLabel() == ls_Used ) { + vertices.push_back( vertex ); + vertex->SetOwnLabel( ls_Null ); + } + ::DetachItem( vertex ); + + vertex = const_cast(&edge->GetEndVertex()); + if ( vertex->GetLabel() == ls_Used ) { + vertices.push_back( vertex ); + vertex->SetOwnLabel( ls_Null ); + } + ::DetachItem( vertex ); + } + } + } + } + else { + size_t count = faceSet.size(); + vertices.reserve( vertices.size() + count * 2 ); + for ( size_t i = 0; i < count; ++i ) + faceSet[i]->GetVertices( vertices ); + } +} + +//------------------------------------------------------------------------------ +// \ru Выдать множество вершин и множество ребер оболочки. \en Get a set of vertices and a set of edges of the shell. +// --- +template +void MbFaceShell::GetItems( VerticesVector & vertices, EdgesVector & edges ) const +{ + if ( edges.size() == 0 && vertices.size() == 0 ) { + size_t maxCount = 1; + + size_t i, fcount; + // set label + for ( i = 0, fcount = faceSet.size(); i < fcount; ++i ) { + const MbFace * face = faceSet[i]; + for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) { + const MbLoop * loop = face->_GetLoop( j ); + + size_t ecount = loop->GetEdgesCount(); + for ( size_t k = 0; k < ecount; k++ ) { + MbCurveEdge * edge = const_cast(&loop->_GetOrientedEdge( k )->GetCurveEdge()); + edge->SetOwnLabel( ls_Used ); + edge->GetBegVertex().SetOwnLabel( ls_Used ); + edge->GetEndVertex().SetOwnLabel( ls_Used ); + } + maxCount += ecount; + } + } + + size_t estVertsCnt = maxCount / 3; + size_t estEdgesCnt = maxCount / 2; + { // C3D-289 + estVertsCnt = std_max( (size_t)4, estVertsCnt ); + estEdgesCnt = std_max( (size_t)4, estEdgesCnt ); + } + vertices.reserve( vertices.size() + estVertsCnt ); + edges.reserve( edges.size() + estEdgesCnt ); + + // опускаем флаг + for ( i = 0, fcount = faceSet.size(); i < fcount; ++i ) { + const MbFace * face = faceSet[i]; + for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) { + const MbLoop * loop = face->_GetLoop( j ); + + SPtr edge; + SPtr vertex; + for ( size_t k = 0, ecount = loop->GetEdgesCount(); k < ecount; ++k ) { + edge = const_cast(&loop->_GetOrientedEdge( k )->GetCurveEdge()); + + if ( edge->GetLabel() == ls_Used ) { + edges.push_back( edge ); + edge->SetOwnLabel( ls_Null ); + } + + vertex = const_cast(&edge->GetBegVertex()); + if ( vertex->GetLabel() == ls_Used ) { + vertices.push_back( vertex ); + vertex->SetOwnLabel( ls_Null ); + } + ::DetachItem( vertex ); + + vertex = const_cast(&edge->GetEndVertex()); + if ( vertex->GetLabel() == ls_Used ) { + vertices.push_back( vertex ); + vertex->SetOwnLabel( ls_Null ); + } + ::DetachItem( vertex ); + + ::DetachItem( edge ); + } + } + } + } + else { + size_t count = faceSet.size(); + size_t count2x = count * 2; + edges.reserve( edges.size() + count2x ); + vertices.reserve( vertices.size() + count2x ); + + for ( size_t i = 0; i < count; ++i ) { + const MbFace * face = faceSet[i]; + face->GetEdges( edges ); + face->GetVertices( vertices ); + } + } +} + +//------------------------------------------------------------------------------ +// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices. +// --- +template +bool MbFaceShell::FindIndexByFaces( const FacesPointersVector & initFaces, ItemIndices & indices, size_t mapThreshold ) const +{ + const size_t initFacesCount = initFaces.size(); + + if ( initFacesCount > 0 ) { + indices.reserve( indices.size() + initFacesCount ); + MbItemIndex index; + + bool directFind = true; + + if ( initFacesCount > mapThreshold ) { // performance + c3d::ConstFaceIndexMap fiMap; + size_t facesCount = faceSet.size(); + for ( size_t i = 0; i < facesCount; ++i ) + fiMap.insert( std::make_pair( faceSet[i], i ) ); + + for ( size_t i = 0; i < initFacesCount; ++i ) { + const MbFace * face = initFaces[i]; + if ( face != NULL ) { + size_t i0 = SYS_MAX_T; + c3d::ConstFaceIndexMap::iterator it = fiMap.find( face ); + if ( it != fiMap.end() ) + i0 = it->second; + if ( i0 != SYS_MAX_T ) { + index.Init( *face, i0 ); + indices.push_back( index ); + } + } + } + directFind = false; + } + if ( directFind ) { + for ( size_t i = 0; i < initFacesCount; ++i ) { + const MbFace * face = initFaces[i]; + if ( face != NULL ) { + size_t i0 = GetFaceIndex( *face ); + if ( i0 != SYS_MAX_T ) { + index.Init( *face, i0 ); + indices.push_back( index ); + } + } + } + } + } + return (indices.size() > 0); +} + +//------------------------------------------------------------------------------ +// \ru Найти множество граней по множеству комбинированных индексов. \en Find a set of faces by a set of combined indices. +// --- +template +bool MbFaceShell::FindConstFacesByIndex( const ItemIndices & indices, ConstFacesPointersVector & initFaces ) const +{ + c3d::ConstFaceSPtr findFace; + initFaces.reserve( initFaces.size() + indices.size() ); + for ( size_t j = 0, indicesCnt = indices.size(); j < indicesCnt; ++j ) { + MbItemIndex & index = const_cast(indices[j]); // у stl доступ честный как const, у SArray дает на редактирование + findFace = FindFaceByIndex( index ); + if ( findFace != NULL ) { + initFaces.push_back( findFace ); + ::DetachItem( findFace ); + } + } + + return initFaces.size() > 0; +} + +//------------------------------------------------------------------------------ +// \ru Найти множество граней по множеству комбинированных индексов. \en Find a set of faces by a set of combined indices. +// --- +template +bool MbFaceShell::FindFacesByIndex( const ItemIndices & indices, FacesPointersVector & initFaces ) +{ + c3d::FaceSPtr findFace; + initFaces.reserve( initFaces.size() + indices.size() ); + for ( size_t j = 0, indicesCnt = indices.size(); j < indicesCnt; ++j ) { + MbItemIndex & index = const_cast(indices[j]); // у stl доступ честный как const, у SArray дает на редактирование + findFace = const_cast(FindFaceByIndex( index )); + if ( findFace != NULL ) { + initFaces.push_back( findFace ); + ::DetachItem( findFace ); + } + } + + return initFaces.size() > 0; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Параметры функции проверки топологии оболочки. + \en Parameters of validation of the shell. \~ + \details \ru Параметры функции проверки топологии оболочки. \n + \en Parameters of validation of the shell. \n \~ + \ingroup Data_Structures +*/ +//--- +struct MATH_CLASS MbCheckTopologyParams { +protected: + bool mergeEdges; ///< \ru Флаг слияния ребер. \en Merge flag for edges. + bool addNameAttributes; ///< \ru Добавить атрибут имени с именами слитых ребер. \en Add name attribute with names of merged edges. + VERSION version; ///< \ru Версия. \en Version. + c3d::ConstFacesVector controlFaces; ///< \ru Грани, по которым может быть взведена ошибка. \en Faces where an error may occur. + c3d::ConstEdgesVector boundaryEdges; ///< \ru Исходные краевые ребра (до операции). \en Initial boundary edges (before an operation). +public: + explicit MbCheckTopologyParams( bool doMergingEdges, const MbSNameMaker & nameMaker ) + : mergeEdges ( doMergingEdges ) + , addNameAttributes( nameMaker.GetParentNamesAttributes() ) + , version ( nameMaker.GetMathVersion() ) + , controlFaces ( ) + , boundaryEdges ( ) + {} + explicit MbCheckTopologyParams( bool doMergingEdges, VERSION ver, bool addNameAttrs ) + : mergeEdges ( doMergingEdges ) + , addNameAttributes( addNameAttrs ) + , version ( ver ) + , controlFaces ( ) + , boundaryEdges ( ) + {} + template + explicit MbCheckTopologyParams( bool doMergingEdges, const MbSNameMaker & nameMaker, + const Faces & faces ) + : mergeEdges ( doMergingEdges ) + , addNameAttributes( nameMaker.GetParentNamesAttributes() ) + , version ( nameMaker.GetMathVersion() ) + , controlFaces ( ) + , boundaryEdges ( ) + { + size_t facesCnt = faces.size(); + if ( facesCnt > 0 ) { + controlFaces.reserve( facesCnt ); + for ( size_t k = 0; k < facesCnt; ++k ) + controlFaces.push_back( faces[k] ); + std::sort( controlFaces.begin(), controlFaces.end() ); + } + } + template + explicit MbCheckTopologyParams( bool doMergingEdges, VERSION ver, bool addNameAttrs, + const Faces & faces ) + : mergeEdges ( doMergingEdges ) + , addNameAttributes( addNameAttrs ) + , version ( ver ) + , controlFaces ( ) + , boundaryEdges ( ) + { + size_t facesCnt = faces.size(); + if ( facesCnt > 0 ) { + controlFaces.reserve( facesCnt ); + for ( size_t k = 0; k < facesCnt; ++k ) + controlFaces.push_back( faces[k] ); + std::sort( controlFaces.begin(), controlFaces.end() ); + } + } + template + explicit MbCheckTopologyParams( bool doMergingEdges, const MbSNameMaker & nameMaker, + const Faces & faces, const c3d::ConstEdgesVector & edges ) + : mergeEdges ( doMergingEdges ) + , addNameAttributes( nameMaker.GetParentNamesAttributes() ) + , version ( nameMaker.GetMathVersion() ) + , controlFaces ( ) + , boundaryEdges ( edges ) + { + size_t facesCnt = faces.size(); + if ( facesCnt > 0 ) { + controlFaces.reserve( facesCnt ); + for ( size_t k = 0; k < facesCnt; ++k ) + controlFaces.push_back( faces[k] ); + std::sort( controlFaces.begin(), controlFaces.end() ); + } + std::sort( boundaryEdges.begin(), boundaryEdges.end() ); + } + ~MbCheckTopologyParams() {} +public: + bool MergeEdges () const { return mergeEdges; } + bool AddNameAttributes() const { return addNameAttributes; } + VERSION MathVersion () const { return version; } + + void ClearControlFaces() { controlFaces.clear(); } + void SetControlFaces( const c3d::ConstFacesVector & faces ) + { + controlFaces = faces; + std::sort( controlFaces.begin(), controlFaces.end() ); + } + bool DeleteTheseSortedFaces( const c3d::ConstFacesVector & sortedDelFaces ) + { + bool res = false; + if ( controlFaces.size() > 0 && sortedDelFaces.size() > 0 ) { + for ( size_t k = controlFaces.size(); k--; ) { + if ( std::binary_search( sortedDelFaces.begin(), sortedDelFaces.end(), controlFaces[k] ) ) { + controlFaces[k] = NULL; + res = true; + } + } + if ( res ) { + std::sort( controlFaces.begin(), controlFaces.end() ); + controlFaces.erase( std::unique( controlFaces.begin(), controlFaces.end() ), controlFaces.end() ); + if ( controlFaces.front() == NULL ) + controlFaces.erase( controlFaces.begin() ); + } + } + return res; + } + + const c3d::ConstFacesVector & GetSortedControlFaces() const { return controlFaces; } + const c3d::ConstEdgesVector & GetSortedBoundaryEdges() const { return boundaryEdges; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Структура для передачи ребра и функции. + \en A structure for edge and function transferring. \~ + \details \ru Структура передаёт информацию о ребре и функции изменения радиуса скругления ребра. + Структура используется в алгоритмах скругления ребер переменным радиусом. \n + Начальный параметр функции изменения радиуса соответствует начальной вершине ребра. + Конечный параметр функции изменения радиуса соответствует конечной вершине ребра. \n + \en A structure transmits an information about an edge and a function of edge fillet radius changing. + A structure is used in algorithms of edge fillet by the variable radius. \n + The starting parameter of radius changing function corresponds to the starting vertex of the edge. + The ending parameter of radius changing function corresponds to the ending vertex of the edge. \n \~ + \ingroup Data_Structures +*/ +// --- +struct MATH_CLASS MbEdgeFunction { +private: + const MbCurveEdge * edge; ///< \ru Ребро. \en An edge. + const MbFunction * function; ///< \ru Функция изменения радиуса по относительной длине ребра. \en A function of radius changing by relative edge length. + +public: + /// \ru Конструктор по умолчанию \en Default constructor + MbEdgeFunction () : edge(NULL), function(NULL) {} + /// \ru Конструктор по ребру и функции. \en Constructor by an edge and function. + MbEdgeFunction ( const MbCurveEdge * e, const MbFunction * f ) : edge(e), function(f) {} + /// \ru Конструктор по другому ребру с функцией. \en Constructor by other edge with a function. + MbEdgeFunction ( const MbEdgeFunction & other ) : edge(other.edge), function(other.function) {} + ~MbEdgeFunction() {} +public: + /// \ru Функция инициализации по ребру и функции. \en A function of initialization by an edge and a function. + void Init( const MbCurveEdge * e, const MbFunction * f ) { edge = e; function = f; } + /// \ru Дать ребро. \en Get an edge. + const MbCurveEdge * Edge() const { return edge; } + /// \ru Дать функцию изменения радиуса. \en Get a function of radius changing. + const MbFunction * Function() const { return function; } + /// \ru Оператор присваивания. \en Assignment operator. + void operator = ( const MbEdgeFunction & other ) { edge = other.edge; function = other.function; } +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Данные минимального расстояния между двумя оболочками. + \en The data of the minimum distance between two shells. \~ + \details \ru Данные минимального расстояния между двумя оболочками. + \en The data of the minimum distance between two shells. \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbShellsDistanceData { +public: + struct ShellDetail { + size_t faceIndex; ///< \ru Номер грани первой оболочки. \en Face index of the first shell. + MbCartPoint point; ///< \ru Параметрическая точка на грани первой оболочки. \en Parametric point on a face of the first shell. ; + size_t loopIndex; ///< \ru Номер цикла грани первой оболочки. \en Face loop index of the first shell. + size_t edgeIndex; ///< \ru Номер ребра в цикле первой оболочки, если точка на ребре. \en Loop edge index of the first shell if the point on the edge. + double curveParam; ///< \ru Параметр на кривой ребра первой оболочки, если точка лежит на ребре. \en Parameter on the edge curve of the first shell, if the point on the edge. ; + /// \ru Конструктор по умолчанию. \en Default constructor. + ShellDetail() + : faceIndex ( SYS_MAX_T ) + , point() + , loopIndex ( SYS_MAX_T ) + , edgeIndex ( SYS_MAX_T ) + , curveParam( UNDEFINED_DBL ) + { + } + /// \ru Конструктор копирования. \en Copy-constructor. + ShellDetail( const ShellDetail & obj ) + : faceIndex ( obj.faceIndex ) + , point ( obj.point ) + , loopIndex ( obj.loopIndex ) + , edgeIndex ( obj.edgeIndex ) + , curveParam( obj.curveParam ) + { + } + }; +private: + double minDist; ///< \ru Минимальное расстояние между оболочками. \en Minimum distance between the shells. + std::pair shellDetail; ///< \ru Детализированная информация минимального расстояния между оболочками. \en Detailed information of the minimum distance between the shells. +public: + /** \brief \ru Конструктор по умолчанию. + \en Default constructor. \~ + \details \ru Конструктор данных расстояними между двумя телами. + \en Constructor of distance date between two solids. \~ + */ + MbShellsDistanceData() + : minDist ( UNDEFINED_DBL ) + , shellDetail() +{ +} + /// \ru Конструктор копирования. \en Copy-constructor. + MbShellsDistanceData( const MbShellsDistanceData & obj ) + : minDist ( obj.minDist ) + , shellDetail( obj.shellDetail ) +{ +} +public: + /// \ru Получить минимальную дистанцию между оболочками. \en Get the minimum distance between the shells. + double GetMinDistanse() const { return minDist; } + /// \ru Получить индекс грани оболочки. \en Get the face index of the shell. + size_t GetFaceIndex( size_t i ) const { return ( i == 1 ) ? shellDetail.first.faceIndex : shellDetail.second.faceIndex; } + /// \ru Получить параметрическую точку на грани оболочки. \en Get the parametric point on a face of the shell. + MbCartPoint GetPoint( size_t i ) const { return ( i == 1 ) ? shellDetail.first.point : shellDetail.second.point; } + /// \ru Получить номер цикла грани оболочки. \en Get the face loop index of the shell. + size_t GetLoopIndex( size_t i ) const { return ( i == 1 ) ? shellDetail.first.loopIndex : shellDetail.second.loopIndex; } + /// \ru Получить номер ребра в цикле грани оболочки. \en Get the face loop edge index of the shell. + size_t GetEdgeIndex( size_t i ) const { return ( i == 1 ) ? shellDetail.first.edgeIndex : shellDetail.second.edgeIndex; } + /// \ru Получить параметр на кривой ребра оболочки. \en Get parameter on the edge curve of the shell. + double GetCurveParam( size_t i ) const { return ( i == 1 ) ? shellDetail.first.curveParam : shellDetail.second.curveParam; } + + /// \ru Рассчитать данные минимального расстояния. \en Get Calculate the minimum distance. + void CalculateDistance( const MbFace & face1, const MbFace & face2 ); + /// \ru Вычислить набор дополнительных данных по расстоянию между гранями. \en Calculate a set of additional data by distance between faces. + void CalculateAdditionData( const MbFace & face1, size_t faceInd1, const MbFace & face2, size_t faceInd2 ); + /// \ru Сбросить все данные. \en Reset all data. + void Reset() + { + minDist = UNDEFINED_DBL; + shellDetail.first.faceIndex = SYS_MAX_T; + shellDetail.second.faceIndex = SYS_MAX_T; + shellDetail.first.point = MbCartPoint( 0.0, 0.0 ); + shellDetail.second.point = MbCartPoint( 0.0, 0.0 ); + shellDetail.first.loopIndex = SYS_MAX_T; + shellDetail.second.loopIndex = SYS_MAX_T; + shellDetail.first.edgeIndex = SYS_MAX_T; + shellDetail.second.edgeIndex = SYS_MAX_T; + shellDetail.first.curveParam = UNDEFINED_DBL; + shellDetail.second.curveParam = UNDEFINED_DBL; + } + /// \ru Поменять местами данные первой и второй оболочки. \en Switch the data of first and second shells. + void SwapDetail() + { + std::swap( shellDetail.first, shellDetail.second ); + } + /// \ru Оператор присваивания. \en Assignment operator. + MbShellsDistanceData & operator = ( const MbShellsDistanceData & obj ) + { + minDist = obj.minDist; + shellDetail.first.faceIndex = obj.shellDetail.first.faceIndex; + shellDetail.second.faceIndex = obj.shellDetail.second.faceIndex; + shellDetail.first.point = obj.shellDetail.first.point; + shellDetail.second.point = obj.shellDetail.second.point; + shellDetail.first.loopIndex = obj.shellDetail.first.loopIndex; + shellDetail.second.loopIndex = obj.shellDetail.second.loopIndex; + shellDetail.first.edgeIndex = obj.shellDetail.first.edgeIndex; + shellDetail.second.edgeIndex = obj.shellDetail.second.edgeIndex; + shellDetail.first.curveParam = obj.shellDetail.first.curveParam; + shellDetail.second.curveParam = obj.shellDetail.second.curveParam; + return (*this); + } +}; + +//------------------------------------------------------------------------------ +/** \brief \ru Объект с информацией о положении точки относительно оболочки. + \en An object with information about the point location relative to the shell. \~ + \details \ru Объект содержит необходимую информацию о положении точки относительно оболочки. \n + \en An object contains necessary information about the point location relative to the shell. \n \~ + \ingroup Data_Structures +*/ +// --- +class MATH_CLASS MbPntLoc { +private: + MbeItemLocation pntLoc; ///< \ru Положение точки относительно оболочки. \en The point location relative to the shell. + const MbFaceShell * shell; ///< \ru Оболочка. \en A shell. + size_t ind; ///< \ru Номер грани. \en A face index. + double dist; ///< \ru Расстояние до грани. \en Distance to a face. + MbCartPoint uv; ///< \ru Точка на грани. \en A point on a face. + double n; ///< \ru Характеристика углового расположения (модульная). \en Characteristic of angular location (modular). + MbCartPoint3D pnt; ///< \ru Точка на грани. \en A point on a face. + MbVector3D norm; ///< \ru Нормаль в точке на грани. \en A normal in a face point. + MbeItemLocation loc2d; ///< \ru Классификация попадания на поверхность грани (не путать с классификацией отн-но оболочки). \en Classification of location on a face surface (do not confuse it with classification relative to the shell). + c3d::IndicesPair edgeLoc; ///< \ru Ближайшее ребро, на которое попали. \en The nearest edge, where the location is + bool corn; ///< \ru Попадание в вершину. \en Getting into a vertex. + +public: + /// \ru Конструктор по умолчанию. \en Default constructor. + MbPntLoc() + : pntLoc ( iloc_Undefined ) + , shell ( NULL ) + , ind ( SYS_MAX_T ) + , dist ( MB_MAXDOUBLE ) + , n ( MB_MAXDOUBLE ) + , loc2d ( iloc_OutOfItem ) + , edgeLoc ( SYS_MAX_T, SYS_MAX_T ) + , corn ( false ) + {} + /// \ru Конструктор копирования. \en Copy-constructor. + MbPntLoc( const MbPntLoc & d ) + : pntLoc ( d.pntLoc ) + , shell ( d.shell ) + , ind ( d.ind ) + , dist ( d.dist ) + , n ( d.n ) + , loc2d ( d.loc2d ) + , edgeLoc ( d.edgeLoc ) + , corn ( d.corn ) + {} + +public: + /// \ru Получить положение пространственной точки. \en Get location of spatial point + MbeItemLocation GetLocation() const { return pntLoc; } + /// \ru Выбрана ли грань? \en Is a face chosen? + bool IsFaceSelected() const { return ((shell != NULL) && (ind < shell->GetFacesCount()) && (shell->GetFace(ind) != NULL)); } + /// \ru Выполнена ли классификация по грани? \en Is classification by the face performed? + bool IsFaceData() const { return (IsFaceSelected() && !shell->IsTemporal(ind)) ? true : false; } + /// \ru Выполнена ли классификация по грани сопровождения? \en Is classification by the face of maintenance performed? + bool IsTempData() const { return (IsFaceSelected() && shell->IsTemporal(ind)) ? true : false; } + + /// \ru Получить индекс грани. \en Get an index of a face. + size_t GetFaceIndex() const { return ind; } + /// \ru Получить грань. \en Get a face. + const MbFace * GetFace() const { return (IsFaceSelected() ? shell->GetFace(ind) : NULL); } + /// \ru Получить расстояние до точки проекции. \en Get the distance to projection point. + double GetDistance() const { return dist; } + /// \ru Получить двумерную точку проекции. \en Get two-dimensional projection point. + const MbCartPoint & GetFacePoint() const { return uv; } + double GetNormDisp() const { return n; } + /// \ru Получить точку проекции. \en Get projection point. + const MbCartPoint3D & GetPoint() const { return pnt; } + /// \ru Получить нормаль в точке проекции. \en Get the normal in projection point. + const MbVector3D & GetNormal() const { return norm; } + /// \ru Положение двумерной точки проекции относительно границ грани. \en Location of two-dimensional point relative to face boundaries. + MbeItemLocation GetFaceLoc() const { return loc2d; } + // \ru Получить ближайшее ребро. \en Get the nearest edge. + const c3d::IndicesPair & GetEdgeLoc() const { return edgeLoc; } + /// \ru Попали на ребро? \en Are we get to an edge? + bool IsEdge() const { return (edgeLoc.first != SYS_MAX_T && edgeLoc.second != SYS_MAX_T); } + /// \ru Попали в вершину? \en Are we get to a vertex? + bool IsCorner() const { return corn; } + + /// \ru Получить поверхности грани. \en Get surfaces of a face. + const MbSurface * GetFaceSurface() const { return (IsFaceSelected() ? &shell->GetFace(ind)->GetSurface() : NULL); } + /// \ru Получить ориентацию грани относительно поверхности. \en Get face orientation relative a surface. + bool GetFaceSense() const { return (IsFaceSelected() ? shell->GetFace(ind)->IsSameSense() : true); } + /// \ru Получить поверхность смежной грани. \en Get a surface of adjacent face. + const MbSurface * GetEdgeSurface( bool getAdjacent ) const; + /// \ru Попали на граничное ребро? \en Are we get to a boundary edge? + bool IsBorderEdge() const; + /// \ru Попали на шовное ребро? \en Are we get to a seam edge? + bool IsSeamEdge () const; + /// \ru Попали на точное ребро? \en Are we get to an exact edge? + bool IsExactEdge () const; + + /// \ru Сбросить все данные. \en Reset all data. + void Reset() + { + pntLoc = iloc_Undefined; + shell = NULL; + ind = SYS_MAX_T; + dist = MB_MAXDOUBLE; + n = MB_MAXDOUBLE; + loc2d = iloc_OutOfItem; + corn = false; + edgeLoc.first = SYS_MAX_T; + edgeLoc.second = SYS_MAX_T; + uv.SetZero(); + pnt.SetZero(); + norm.SetZero(); + } + /// \ru Установить положение пространственной точки. \en Set location of spatial point + void SetLocation( MbeItemLocation pLoc ) { pntLoc = pLoc; } + /// \ru Установить расстояние. \en Set the distance. + void SetDistance( double d ) { dist = d; } + /// \ru Установить нормаль. \en Set the normal. + void SetNormal ( const MbVector3D & v ) { norm = v; } + /// \ru Функция инициализации. \en Initialization function. + void InitData( size_t _ind, const MbFaceShell & _shell, double _dist, const MbCartPoint & _uv, + double _n, const MbCartPoint3D & _pnt, const MbVector3D & _norm, + MbeItemLocation _loc2d, const c3d::IndicesPair & _edgeLoc, bool _corn ) + { + shell = &_shell; + ind = _ind; + dist = _dist; + uv = _uv; + n = _n; + pnt = _pnt; + norm = _norm; + loc2d = _loc2d; + edgeLoc = _edgeLoc; + corn = _corn; + } + /// \ru Оператор присваивания. \en Assignment operator. + MbPntLoc & operator = ( const MbPntLoc & d ) + { + pntLoc = d.pntLoc; + shell = d.shell; + ind = d.ind; + dist = d.dist; + uv = d.uv; + n = d.n; + pnt = d.pnt; + norm = d.norm; + loc2d = d.loc2d; + edgeLoc = d.edgeLoc; + corn = d.corn; + return (*this); + } + /// \ru Вычислить набор дополнительных данных по проецированию точки на грань. \en Calculate a set of additional data by projected point to a face. + bool CalculateFaceData( const MbCartPoint3D & pnt, const MbFaceShell & shell, size_t ind ); +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить главное имя. + \en Set main name. \~ + \details \ru Установить главное имя mainName для имени name. \n + \en Set the main name 'mainName' for the name 'name'. \n \~ + \param[out] name - \ru Имя. + \en Name. \~ + \param[in] mainName - \ru Главное имя. + \en The main name. \~ + \param[in] addOldMainName - \ru При true запомнить заменяемое главное имя в индексе копирования. + \en When it is true remember replaced main name in the copying index. \~ + \ingroup Algorithms_3D +*/ +// --- +inline +void SetMainName( MbName & name, SimpleName mainName, bool addOldMainName ) +{ + if ( !name.IsEmpty() ) { + if ( addOldMainName ) + name.SetCopyIndex( name.GetMainName() ); + name.SetMainName( mainName ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Установить заданную метку всем рёбрам оболочки. + \en Set the specified label to all edges of the shell. \~ + \details \ru Установить заданную метку всем рёбрам оболочки. + \en Set the specified label to all edges of the shell. \~ + \param[in,out] faceSet - \ru Множество граней. + \en A set of faces. \~ + \param[in] label - \ru Метка. + \en Label. \~ + \ingroup Algorithms_3D +*/ +// --- +template +size_t SetEdgesLabel( const FacesVector & faceSet, MbeLabelState label, void * key = NULL ) +{ + size_t maxCount = 1; + + // поднимаем флаг + for ( size_t i = 0, fcount = faceSet.size(); i < fcount; ++i ) { + const MbFace * face = faceSet[i]; + for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) { + const MbLoop * loop = face->_GetLoop( j ); + size_t ecount = loop->GetEdgesCount(); + for ( size_t k = 0; k < ecount; ++k ) { + MbCurveEdge * edge = &loop->_GetOrientedEdge( k )->GetCurveEdge(); + edge->SetOwnLabel( label, key ); + } + maxCount += ecount; + } + maxCount++; // reserve for pole edges + } + + maxCount /= 2; // divide by two because every edge were calculated approximately twice. + + return ++maxCount; +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Выдать множество рёбер. + \en Get a set of edges. \~ + \details \ru Выдать множество рёбер из множества граней. + \en Get a set of edges from a set of faces. \~ + \param[in] faceSet - \ru Множество граней. + \en A set of faces. \~ + \param[out] edges - \ru Множество рёбер. + \en A set of edges. \~ + \ingroup Algorithms_3D +*/ +// --- +template +void GetEdges( const FacesVector & faceSet, EdgesVector & edges ) +{ + // поднимаем флаг + size_t maxCount = SetEdgesLabel( faceSet, ls_Used ); + edges.reserve( edges.size() + maxCount ); + + // опускаем флаг + for ( size_t i = 0, fcount = faceSet.size(); i < fcount; ++i ) { + const MbFace * face = faceSet[i]; + + SPtr edge; + for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) { + const MbLoop * loop = face->_GetLoop( j ); + for ( size_t k = 0, ecount = loop->GetEdgesCount(); k < ecount; k++ ) { + edge = const_cast( &loop->_GetOrientedEdge( k )->GetCurveEdge() ); + if ( edge->GetLabel() == ls_Used ) { + edge->SetOwnLabel( ls_Null ); + edges.push_back( edge ); + } + ::DetachItem( edge ); + } + } + } +} + + +#endif // __TOPOLOGY_FACESET_H diff --git a/C3d/Include/topology_item.h b/C3d/Include/topology_item.h new file mode 100644 index 0000000..84fed69 --- /dev/null +++ b/C3d/Include/topology_item.h @@ -0,0 +1,384 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Топологический объект в трехмерном пространстве. + \en Topological object in three-dimensional space. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TOPOLOGY_ITEM_H +#define __TOPOLOGY_ITEM_H + + +#include +#include +#include +#include +#include +#include +#include + + +class MATH_CLASS MbVector3D; +class MATH_CLASS MbCartPoint3D; +class MATH_CLASS MbMatrix3D; +class MATH_CLASS MbAxis3D; +class MATH_CLASS MbCube; +class MATH_CLASS MbMesh; +class MATH_CLASS MbStepData; +struct MATH_CLASS MbFormNote; +class MbRegTransform; +class MbRegDuplicate; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы топологических объектов. + \en Types of topological objects. \~ + \ingroup Topology_Items +*/ +// --- +enum MbeTopologyType { + + tt_Undefined = 0, ///< \ru Неизвестный объект. \en Unknown object. + tt_TopItem = 1, ///< \ru Топологический объект. \en A topological object. \n + + tt_Vertex = 101, ///< \ru Вершина. \en A vertex. + + tt_Edge = 201, ///< \ru Ребро, проходящее по кривой. \en An edge passing along a curve. + tt_CurveEdge = 202, ///< \ru Ребро, проходящее по кривой пересечения поверхностей. \en An edge passing along a surface intersection curve. + tt_OrientedEdge = 203, ///< \ru Ориентированное ребро. \en Oriented edge. + + tt_Loop = 301, ///< \ru Цикл. \en A loop. + + tt_Face = 401, ///< \ru Грань. \en A face. \n + + tt_FaceShell = 501, ///< \ru Множество граней. \en A set of faces. \n + + tt_FreeItem = 600, ///< \ru Тип для объектов, созданных пользователем. \en Type for the user-defined objects. + +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Типы состояний модификации топологического объекта. + \en The types of modification states of a topological object. \~ + \ingroup Topology_Items +*/ +// --- +enum MbeChangedType { + tct_Unchanged = 0x0000, ///< \ru Без изменений. \en Unchanged. + tct_Modified = 0x0001, ///< \ru Изменен. \en Modified. + tct_Created = 0x0002, ///< \ru Создан новый. \en Created (new). + tct_Transformed = 0x0004, ///< \ru Трансформирован. \en Transformed. + tct_Reoriented = 0x0008, ///< \ru Переориентирован. \en Reoriented. + tct_Deleted = 0x0010, ///< \ru Удален (элемент объекта или связь). \en Deleted (object's element or link). + tct_Truncated = 0x0020, ///< \ru Разрезан, усечен, продлен. \en Cut, truncated or extended. + tct_Merged = 0x0040, ///< \ru Объединен или сшито. \en Merged or sewn (stitched). + tct_Replaced = 0x0080, ///< \ru Заменен. \en Replaced. + tct_Added = 0x0100, ///< \ru Добавлен или вставлен (элемент объекта). \en Added or inserted (object's element). + tct_Renamed = 0x0200, ///< \ru Переименован. \en Renamed. +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Метка для выполнения операция. + \en A label for performing of operations. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbLabel : public MbSyncItem { + typedef std::map LabelMap; +private: + int8 own; ///< \ru Собственная временная метка для выполнения операций. \en Own label for performing of operations. + LabelMap privates;///< \ru Частные временные метки для выполнения операций. \en Private labels for performing of operations. +public: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbLabel(); + /// \ru Конструктор по собственное метке. \en Constructor by own label. + MbLabel( const MbeLabelState ); + /// \ru Конструктор по Label. \en Constructor by Label. + MbLabel( const MbLabel & ); + /// \ru Деструктор. \en Destructor without parameters. + ~MbLabel(); + /// \ru Установить частную или собственную метку (соответствующую ключу). \en Set own or private label (according to the key). + void SetLabel( const MbeLabelState, void * key = NULL ); + /// \ru Установить частную или собственную метку (соответствующую ключу). \en Set own or private label (according to the key). + void SetLabel( const MbeLabelState, void * key, bool setLock ); + /// \ru Получить частную или собственную метку (соответствующую ключу). \en Get own or private label (according to thew key). + int8 GetLabel( void * key = NULL ); + /// \ru Удалить частные метки(освободить память) соответствующие ключу. \en Remove private labels (free memory) according to the key. + void DeletePrivate( void * key ); + /// \ru Присвоить значение собственной метке. \en Assign values to own label. + void operator = ( const MbeLabelState lbl ) { own = (int8)lbl; } + /// \ru Присвоить значение собственной метке и скопировать частные. \en Assign values to own label and cope private labels. + void operator = ( const MbLabel & ); + /// \ru Проверить собственную метку на равенство. \en Check own label for equality. + bool operator == ( const MbeLabelState lbl ) const { return (own == (int8)lbl); } +private: + bool operator == ( const MbLabel & ); // \ru Не реализовано!!! \en Not implemented!!! +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Топологический объект в трехмерном пространстве. + \en Topological object in three-dimensional space. \~ + \details \ru Родительский класс топологических объектов в трехмерном пространстве.\n + Топологическими называют геометрические свойства, + которые не зависят от количественных характеристик (длин и углов), + а отражают непрерывную связь объекта с его окружением. \n + Топологические объекты описывают и геометрические свойства объекта, + зависящие от количественных характеристик, и геометрические свойства, + отражающие непрерывную связь объекта с соседними элементами. + Топологические объекты строятся на основе точек, кривых и поверхностей путём добавления к их данным, + свойствам и методам новых данных, свойств и методов. + \en A parent class of topological objects in three-dimensional space.\n + Geometric properties are called topological if they + are not depend on the quantitative characteristics (lengths and angles), + but reflect continuous connection between an object and its environment. \n + topological objects also describe the object geometric properties + which depend on quantitative characteristics and geometric properties, + which reflect continuous connection between an object and neighboring elements. + topological objects are constructed on the base of points, curves and surfaces by adding to their data, + properties and methods a new data, properties and methods. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbTopItem : public MbRefItem, public TapeBase { +protected: + /// \ru Конструктор. \en Constructor. + MbTopItem(); +public: + virtual ~MbTopItem(); +public: + /// \ru Регистрационный тип (для копирования, дублирования). \en Registration type (for copying, duplication). + virtual MbeRefType RefType() const; + /// \ru Тип элемента. \en A type of element. + virtual MbeTopologyType IsA() const = 0; + + /// \ru Подготовить объект к записи. \en Prepare an object for writing. + void PrepareWrite() { SetRegistrable( GetUseCount() > 1 ? registrable : noRegistrable ); } + + bool IsAVertex() const { return (IsA() == tt_Vertex); } ///< \ru Это вершина? \en Is it a vertex? + bool IsAWireEdge() const { return (IsA() == tt_Edge); } ///< \ru Это ребро каркаса? \en Is it an edge of wireframe? + bool IsAnEdge() const { return (IsA() == tt_CurveEdge); } ///< \ru Это ребро? \en Is it an edge? + bool IsAFace() const { return (IsA() == tt_Face); } ///< \ru Это грань? \en Is it a face? + bool IsAShell() const { return (IsA() == tt_FaceShell); } ///< \ru Это оболочка? \en Is it a shell? + +DECLARE_PERSISTENT_CLASS( MbTopItem ) +OBVIOUS_PRIVATE_COPY( MbTopItem ) +}; + +IMPL_PERSISTENT_OPS( MbTopItem ) + +//------------------------------------------------------------------------------ +/** \brief \ru Топологический объект с именем. + \en Topological object with name. \~ + \details \ru Родительский класс именованных топологических объектов. \n + Наследниками являются объекты, которые можно идентифицировать по имени, это + вершины, ребра, грани. + Наследники также имеют флаг изменённости и временную метку для использования в операция. + \en A parent class of named topological objects. \n + Inheritors are objects which may be identified by name, there are + vertices, edges, faces. + Also inheritors have a flag of being changed and temporary label for using in operations. \~ + \ingroup Topology_Items +*/ +// --- +class MATH_CLASS MbTopologyItem : public MbTopItem, public MbAttributeContainer { +private: + MbName name; ///< \ru Имя объекта. \en A name of an object. + uint16 changed; ///< \ru Флаг изменений объекта после выполнения операций: false - для не измененных, true - для измененных. \en A flag of object changes after performing of operations: false - for unchanged, true - for changed. +protected: + mutable MbLabel label; ///< \ru Временная метка для выполнения операций. \en Temporary label for performing of operations. + +protected: + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbTopologyItem(); + /// \ru Конструктор дублирования. \en Constructor of duplicating. + MbTopologyItem( const MbTopologyItem &, MbRegDuplicate * ); +public: + /// \ru Деструктор. \en Destructor. + virtual ~MbTopologyItem(); + +public : + VISITING_CLASS( MbTopologyItem ); + + /// \ru Тип элемента. \en A type of element. + virtual MbeTopologyType IsA() const = 0; + /// \ru Тип контейнера атрибутов. \en Type of attribute container. + virtual MbeImplicationType ImplicationType() const; + + /** \brief \ru Преобразовать согласно матрице. + \en Transform according to the matrix. \~ + \details \ru Преобразование объекта согласно матрице. + Данный объект может содержаться указателем в нескольких других объектах, подлежащих преобразованию. + Для предотвращения многократного преобразования данного объекта используется регистратор. + При преобразовании объекта с использованием регистратора проверяется наличие объекта в регистраторе. + Если такой объект отсутствует, то он заносится в регистратор и выполняется его преобразование, + в противном случае преобразование данного объекта не выполняется. + \en Transformation of an object according to the matrix. + This object can be contained as pointer in several other objects for transformations. + Registrar is used to prevent multiple transformation of this object. + When transforming the object with registrator, the existence of the object inside the registrator is verified. + If such object is absent, it is stored to the registrator and transformed, + otherwise, a transformation of the object is not performed. \~ + \param[in] matr - \ru Матрица преобразования. + \en A transformation matrix. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Topology_Items + */ + virtual void Transform( const MbMatrix3D & matr, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Сдвинуть вдоль вектора. + \en Move along a vector. \~ + \details \ru Сдвинуть объект вдоль вектора. + При преобразовании объекта с использованием регистратора проверяется наличие объекта в регистраторе. + Если такой объект отсутствует, то он заносится в регистратор и выполняется его преобразование, + в противном случае преобразование данного объекта не выполняется. + \en Move an object along a vector. + When transforming the object with registrator, the existence of the object inside the registrator is verified. + If such object is absent, it is stored to the registrator and transformed, + otherwise, a transformation of the object is not performed. \~ + \param[in] to - \ru Вектор сдвига. + \en Translation vector. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Topology_Items + */ + virtual void Move ( const MbVector3D & to, MbRegTransform * iReg = NULL ) = 0; + + /** \brief \ru Повернуть вокруг оси. + \en Rotate around an axis. \~ + \details \ru Повернуть объект вокруг оси на заданный угол. + При преобразовании объекта с использованием регистратора проверяется наличие объекта в регистраторе. + Если такой объект отсутствует, то он заносится в регистратор и выполняется его преобразование, + в противном случае преобразование данного объекта не выполняется. + \en Rotate an object at a given angle around an axis. + When transforming the object with registrator, the existence of the object inside the registrator is verified. + If such object is absent, it is stored to the registrator and transformed, + otherwise, a transformation of the object is not performed. \~ + \param[in] axis - \ru Ось вращения. + \en Rotation axis. \~ + \param[in] angle - \ru Угол поворота. + \en The rotation angle. \~ + \param[in] iReg - \ru Регистратор. + \en Registrator. \~ + \ingroup Topology_Items + */ + virtual void Rotate ( const MbAxis3D & axis, double angle, MbRegTransform * iReg = NULL ) = 0; + + /// \ru Вычислить расстояние до точки. \en Calculate the distance to a point. + virtual double DistanceToPoint( const MbCartPoint3D & ) const = 0; + /// \ru Добавить свой габарит в присланный габарит. \en Add your own bounding box into the sent bounding box. + virtual void AddYourGabaritTo( MbCube & ) const = 0; + /// \ru Рассчитать габарит в локальной системы координат, заданной матрицей преобразования в эту систему. \en Calculate bounding box in the local coordinate system which is given by the matrix of transformation to this system. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const = 0; + /// \ru Являются ли объекты равными? \en Determine whether objects are equal. + virtual bool IsSame( const MbTopologyItem &, double accuracy ) const = 0; + /// \ru Построить полигональную копию объекта mesh. \en Construct a polygonal copy of an object mesh). + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const = 0; + + /// \ru Выдать имя объекта. \en Get name of object. + const MbName & GetName() const { return name; } + /// \ru Выдать имя объекта для модификации. \en Get name of object for modification. + MbName & SetName() { return name; } + + /// \ru Выдать главное имя. \en Get main name. + SimpleName GetMainName() const { return name.GetMainName(); } + /// \ru Установить главное имя. \en Set main name. + void SetMainName( SimpleName n ) { name.SetMainName( n ); } + /// \ru Получить первое имя. \en Get first name. + SimpleName GetFirstName() const { return ( name.CountBase() > (size_t)MbName::i_First ) ? name.GetFirstNameDirect() : 0; } + /// \ru Выдать hash имени. \en Get hash of name. + SimpleName GetNameHash() const { return name.Hash(); } + /// \ru Установить имя. \en Set name. + void SetName( const MbName & n ) { name.SetName( n ); } + + /// \ru Получить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Get flag which indicates that an object has (not) been changed. + bool GetOwnChanged() const { return (changed != tct_Unchanged); } + /// \ru Получить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Get flag which indicates that an object has (not) been changed. + bool GetOwnChanged( MbeChangedType n ) const { return !!(changed & n); } + /// \ru Установить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Set flag which indicates that an object has (not) been changed. + void SetOwnChanged( MbeChangedType ); + /// \ru Копировать флаг, свидетельствующий о том, что объект был (не был) изменен. \en Copy flag which indicates that an object has (not) been changed. + void CopyOwnChanged( const MbTopologyItem & ti ) { changed = ti.changed; } + + /// \ru Получить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Get flag which indicates that an object has (not) been changed. + uint16 GetOwnChangedFlag() const { return changed; } + /// \ru Установить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Set flag which indicates that an object has (not) been changed. + template + void SetOwnChangedFlag( Uint n ) { changed = (uint16)n; } + + /// \ru Получить флаг, свидетельствующий о том, что объект был только переименован. \en Get flag which indicates that an object has been renamed only. + bool IsOwnRenamedOnly() const { return ( changed == ( tct_Renamed | tct_Modified ) ); } + /// \ru Получить флаг, свидетельствующий о том, что объект был только трансформирован. \en Get flag which indicates that an object has been transformed only. + bool IsOwnTransformedOnly() const { return ( changed == ( tct_Transformed | tct_Modified ) ); } + /// \ru Получить флаг, свидетельствующий о том, что объект был только переориентирован. \en Get flag which indicates that an object has been reoriented only. + bool IsOwnReorientedOnly() const { return ( changed == ( tct_Reoriented | tct_Modified ) ); } + /// \ru Получить флаг, свидетельствующий о том, что объект был создан, переименован, трансформирован или переориентирован. \en Get flag which indicates that an object has been only created, renamed, transformed or reoriented. + bool IsOwnChangedWeakly() const; + + /// \ru Получить метку. \en Get label. + MbeLabelState GetLabel( void * key = NULL ) const { return (MbeLabelState)label.GetLabel(key); } + /// \ru Установить метку. \en Set a label of the loop. + void SetOwnLabel( MbeLabelState l, void * key = NULL ) const { label.SetLabel( l, key ); } + /// \ru Установить метку. \en Set a label of the loop. + void SetOwnLabel( MbeLabelState l, void * key, bool setLock ) const { if ( setLock || GetUseCount() > 1 ) return SetOwnLabel( l, key ); label.SetLabel( l, key ); } + /// \ru Предназначен ли объект для удаления? Определяется по меткам. \en Is this object intended for deletion? This is defined by labels. + bool ToDelete() const { return( (MbeLabelState)label.GetLabel(NULL) == ls_Delete || (MbeLabelState)label.GetLabel(NULL) == ls_Error ); } + /// \ru Удалить частную метку. \en Remove private label. + void RemovePrivateLabel ( void * key = NULL ) const { label.DeletePrivate(key); } + + /// \ru Копирование данных объекта. \en Copying of the object data. + void Assign( const MbTopologyItem & ); + /// \ru Удалить атрибут типа имя с родительскими именами. \en Delete an attribute of name type with parent names. + void RemoveParentNamesAttribute(); + +DECLARE_PERSISTENT_CLASS( MbTopologyItem ) +OBVIOUS_PRIVATE_COPY( MbTopologyItem ) +}; + +IMPL_PERSISTENT_OPS( MbTopologyItem ) + +//------------------------------------------------------------------------------ +// \ru Установить флаг, свидетельствующий о том, что объект был (не был) изменен. \en Set flag which indicates that an object has (not) been changed. +// --- +inline void MbTopologyItem::SetOwnChanged( MbeChangedType n ) +{ + if ( n != tct_Unchanged ) { + changed |= n; + changed |= tct_Modified; + } + else { + changed = tct_Unchanged; + } +} + +//------------------------------------------------------------------------------ +// \ru Получить флаг, свидетельствующий о том, что объект был создан, переименован, трансформирован или переориентирован. \en Get flag which indicates that an object has been only created, renamed, transformed or reoriented. +// --- +inline bool MbTopologyItem::IsOwnChangedWeakly() const +{ + uint16 wrkFlag = (tct_Created | tct_Renamed | tct_Transformed | tct_Reoriented | tct_Modified); + wrkFlag = ~wrkFlag; + wrkFlag = (changed & wrkFlag); + if ( !wrkFlag ) + return true; + return false; +} + +//------------------------------------------------------------------------------ +// \ru Копирование данных. \en Data copying. +// --- +inline void MbTopologyItem::Assign( const MbTopologyItem & other ) +{ + AttributesAssign( other ); + name.SetName( other.GetName() ); + label = other.label; + changed = other.changed; +} + + +#endif // __TOPOLOGY_ITEM_H diff --git a/C3d/Include/tri_ball_pivoting.h b/C3d/Include/tri_ball_pivoting.h new file mode 100644 index 0000000..e1cbe66 --- /dev/null +++ b/C3d/Include/tri_ball_pivoting.h @@ -0,0 +1,249 @@ +#ifndef __TRI_BALL_PIVOTING_H +#define __TRI_BALL_PIVOTING_H + +#include +#include +#include +#include +#include + + +class MATH_CLASS MbGrid; +class MATH_CLASS MbCollection; + + +//------------------------------------------------------------------------------ +// Облако точек +// --- +class MbPointCloud +{ +protected: + enum { + pnt_Deleted = 0x0001, // Точка удалена из сетки. + pnt_Visited = 0x0010, // Точка используется в сетке (является вершиной построенного треугольника). + pnt_Border = 0x0020, // Точка находится на внешней границе построенной сетки. + pnt_Processed = 0x0100 // Точка уже обработана алгоритмом. + }; + +public: + const std::vector & points; // Множество точек. + const std::vector & normals; // Множество нормалей в точках (согласовано с множеством точек). + std::vector flags; // Множество битовых флагов для точек. + +public: + /// Конструктор. + MbPointCloud( const MbCollection & collection ) + : points ( collection.GetPoints() ) + , normals ( collection.GetNormals() ) + , flags ( collection.PointsCount(), 0 ) + { } + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbPointCloud( const MbPointCloud & ); + +public: + /// Выдать количество точек. + size_t PointsCount() const { return points.size(); } + /// Выдать точку по её номеру. + MbCartPoint3D GetPoint ( size_t i ) const { return points[i]; } + /// Выдать нормаль по её номеру. + MbVector3D GetNormal( size_t i ) const { return normals[i]; } + /// Находится ли точка на границе построенной сетки. + bool IsBorder( size_t i ) const { return (flags[i] & pnt_Border) != 0; } + /// Установить признак того, что точка находится на границе построенной сетки. + void SetBorder( size_t i ) { flags[i] |= pnt_Border; } + /// Очистить признак того, что точка находится на границе построенной сетки. + void ClearBorder( size_t i ) { flags[i] &= ~pnt_Border;} + /// Обработана ли точка алгоритмом. + bool IsUsed( size_t i ) const { return (flags[i] & pnt_Processed) != 0; } + /// Установить признак того, что точка обработана алгоритмом. + void SetUsed( size_t i ) { flags[i] |= pnt_Processed; } + /// Очистить признак того, что точка обработана алгоритмом. + void ClearUsed( size_t i ) { flags[i] &= ~pnt_Processed;} + /// Удалена ли точка из сетки. + bool IsDeleted( size_t i ) const { return (flags[i] & pnt_Deleted) != 0; } + /// Установить признак того, что точка удалена из сетки. + void SetDeleted( size_t i ) { flags[i] |= pnt_Deleted; } + /// Является ли точка вершиной уже построенного треугольника. + bool IsVisited( size_t i ) const { return (flags[i] & pnt_Visited) != 0; } + /// Установить признак того, что точка является вершиной построенного треугольника. + void SetVisited( size_t i ) { flags[i] |= pnt_Visited; } + /// Очистить признак того, что точка является вершиной построенного треугольника. + void ClearVisite( size_t i ) { flags[i] &= ~pnt_Visited; } + +private: + // Объявление оператора присваивания без реализации, чтобы не было присваивания по умолчанию. + void operator = ( const MbPointCloud & ); +}; + + +//------------------------------------------------------------------------------ +// Граница фронта. +// --- +class MbFrontEdge +{ +public: + size_t v0, v1, v2; // v0, v1 - описывают отрезок - границу фронта, + // v2 - точка внутри области, ограниченной фронтом. + bool active; // Является ли ребро границей фронта или внутренним ребром. + + // Цикл границ фронта рассматривается как двусвязный список. + std::list::iterator next; + std::list::iterator previous; + +public: + /// Конструктор. + MbFrontEdge() + {} + /// Конструктор по параметрам. + MbFrontEdge( size_t _v0, size_t _v1, size_t _v2 ) + : v0 ( _v0 ) + , v1 ( _v1 ) + , v2 ( _v2 ) + , active( true ) + { + C3D_ASSERT( v0 != v1 && v1 != v2 && v0 != v2 ); + } + /// Оператор сравнения. + bool operator== ( const MbFrontEdge & f ) const + { + return ( (v0 == f.v0) && (v1 == f.v1) && (v2 == f.v2) ); + } +}; + + +//------------------------------------------------------------------------------- +// Алгоритм подвижного фронта (Advancing Front Algorithm, R. Lohner) +// Основной идеей является расширение границ области (фронта) путем +// присоединения точки из набора и построения новых границ области из вершин +// текущей актиной границы до этой точки. Активная граница при этом убирается из +// фронта. +// Наследник этого класса должен определить правила: +// 1) Seed - правило выбора трех точек из набора для построения начального треугольника; +// 2) Place- правило выбора точки из набора для построения новых границ области из вершин +// текущей активной границы до этой точки. +// --- +class MbAdvancingFront +{ +public: + typedef std::list::iterator ListIterator; + + std::list front; // Список границ фронта области. + std::list internal; // Список внутренних границ области. + std::vector nb; // Вектор со значениями, соответствующими числу границ фронта, проходящих через точку с данным индексом. + MbPointCloud pointCloud; // Облако точек. + MbGrid & grid; // Объект триангуляции, который необходимо наполнить. + +public: + /// Конструктор. + MbAdvancingFront( const MbCollection & coll, MbGrid & _grid ) ; + /// Деструктор. + virtual ~MbAdvancingFront(); + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbAdvancingFront( const MbAdvancingFront & ); + +public: + /// Построить сетку. + void BuildMesh(); + +protected: + enum ListID { + edge_Front, // Внешняя граница. + edge_Internal // Внутреннее ребро. + }; + + typedef std::pair ResultIterator; + + // Найти точки для исходного(порождающего фронт) треугольника. + virtual bool Seed( size_t & v0, size_t & v1, size_t & v2 ) = 0; + // Найти точку для построения треугольника по заданному ребру. + virtual bool Place( MbFrontEdge & e, ResultIterator & touch, size_t & v ) = 0; + // Построить новый фронт по треугольнику. + bool SeedFace(); + // Расширить фронт путем поиска, присоединения точки и построения треугольника по активному ребру фронта. + bool Advance(); + // Добавить треугольник в сетку. + void AddTriangleToMesh( size_t v0, size_t v1, size_t v2 ); + // Проверить ребро: + // 1. На правильность ориентации, т.е. ребро (v0,v1) может быть включено в другие треугольники только с обратным направлением. + // 2. Ребро существует по краней мере в единственном экземпляре. + bool CheckEdge( size_t v0, size_t v1 ); + // Добавить новое ребро фронта в конец очереди. + ListIterator addNewEdge( const MbFrontEdge & e ); + // Квалифицировать ребро как внутреннюю границу. + void MoveEdgeToInternals( ListIterator e ); + // Удалить ребро. + void EraseEdge( ListIterator e ); + // Перемесить ребро в конец очереди. + void MoveBack( ListIterator e ); + // Перемесить ребро в начало очереди. + void MoveFront( ListIterator e ); + // Проверить, может ли ребро быть сшито с одним из соседей. + bool Glue( ListIterator e ); + // Склеить вместе два ребра, если a.next = b. + bool Glue( ListIterator a, ListIterator b ); + // Разорвать фронт в точке. + void Detach( size_t v ); + +private: + void operator = ( const MbAdvancingFront & ); +}; + + +//------------------------------------------------------------------------------- +// Алгоритм поворотного шара (Ball pivoting algorithm) +// Reference: Bernardini F., Mittleman J., Rushmeier H., Silva C., Taubin G. +// "The ball-pivoting algorithm for surface reconstruction", IEEE TVCG, 1999 +// 1) Точки, использованные в алгоритме маркируются как pnt_Visited; +// 2) Граничные точки сетки маркируются как pnt_Border; +// 3) В векторе nb по индексу вершины хранится количество ребер, проходяших через нее; +// 4) Точки, обработанные в алгоритме маркируются как pnt_Processed. +// --- +class MbBallPivoting: public MbAdvancingFront +{ +public: + double radius; // Радиус поворотного шара (абсолютная величина в единицах измерения сетки). + double minEdge; // Минимальная длина ребра. + double maxEdge; // Максимальная длина ребра. + double maxAngle; // Максимальный угол между двумя гранями сетки (косинус). + +public: + /// Конструктор. + MbBallPivoting( const MbCollection & coll, // Объект с облаком точек, + MbGrid & grid, // триангуляция, которую нужно наполнить/дополнить, + double radBall = 0.0, // радиус поворотного шара, если 0 будет предпринята попытка его автоопределения, + double radMin = 0.2, // радиус кластеризации ( в % от радиуса поворотного шара ), + double angle = M_PI / 2 ); // максимальный угол между двумя элементами сетки. + /// Деструктор. + ~MbBallPivoting(); + +protected: + // \ru Объявление конструктора копирования без реализации, чтобы не было копирования по умолчанию. \en The copy constructor without implementation prevents from copying by default. + MbBallPivoting( const MbBallPivoting & ); + +private: + /// Найти точки начального треугольника по алгоритму поворотного шара. + bool Seed( size_t & v0, size_t & v1, size_t & v2 ); + /// Найти точку для построения треугольника по заданному ребру согласно алгоритму поворотного шара. + bool Place( MbFrontEdge & edge, MbAdvancingFront::ResultIterator & touch, size_t & v ); + /// Найти сферу, проходящую через три заданных точки, такую что нормаль к грани через эти три точки направлена в центр сферы. + bool FindSphere( const MbCartPoint3D & p0, const MbCartPoint3D & p1, const MbCartPoint3D & p2, MbCartPoint3D & center ); + /// Рассчитать угол между векторами, учитывая ориентацию axis. + double OrientedAngleRad( MbVector3D p, MbVector3D q, const MbVector3D & axis ); + /// Пометить точку и ее соседей. + void Mark( size_t idx ); + +private: + size_t last_seed; // Испольуется для поиска нового фронта когда текущий фронт пуст. + MbCartPoint3D baricenter; // Используется для первого поиска. + KdTree * tree; // К-мерное дерево для поиска N ближайших соседей точки. + +private: + void operator = ( const MbBallPivoting & ); +}; + + +#endif // __TRI_BALL_PIVOTING_H \ No newline at end of file diff --git a/C3d/Include/tri_face.h b/C3d/Include/tri_face.h new file mode 100644 index 0000000..901bda7 --- /dev/null +++ b/C3d/Include/tri_face.h @@ -0,0 +1,76 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Аппроксимация грани массивом треугольных и четырёхугольных пластин. + \en Approximation of face by array of triangular and quadrangular plates. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TRI_FACE_H +#define __TRI_FACE_H + + +#include + + +class MATH_CLASS MbFace; +class MATH_CLASS MbGrid; +class MATH_CLASS MbCube; + + +//------------------------------------------------------------------------------ +/** \brief \ru Аппроксимировать грань. + \en Approximation of face. \~ + \details \ru Аппроксимировать грань массивом треугольных и четырёхугольных пластин.\n + \en Approximation of face by array of triangular and quadrangular plates.\n \~ + \param[in] face - \ru Грань. + \en A face. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \param[out] grid - \ru Результат - триангуляции: + для визуализации заполняются массивы params, points и normals;\n + для вычисления масс-инерционных характеристик - params;\n + для проверки столкновений тел - params и points;\n + для разбивки на конечные элементы - points и normals.\n + \en Triangulations as a result: + for visualization arrays 'params', 'points' and 'normals' are filled;\n + for calculation of the mass-inertial properties an array 'params' is filled;\n + for solids collision detection arrays 'params' and 'points' are filled;\n + for splitting into finite elements arrays 'points' and 'normals' are filled.\n \~ + \param[in] dualSeams - \ru Флаг сохранения полигонов шовных ребер и их совпадающих точек.\n + \en Whether to keep seam edges polygons and their coincident points. \~ + \param[in] quad - \ru Строить четырёхугольники (true) при триангуляции поверхностей (по возможности). + \en Whether to build quadrangles (true) in triangulations of surfaces (if possible). \~ + \ingroup Triangulation +*/ +// --- +MATH_FUNC (void) CalculateGrid( const MbFace & face, + const MbStepData & stepData, + MbGrid & grid, + bool dualSeams = true, + bool quad = false ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Настройка данных вычисления шага триангуляции stepData. + \en Configuring step data for triangulation. \~ + \details \ru Проверка и коррекция данных вычисления шага stepData так, + чтобы количество точек триангуляции не превосходило заданную величину на порядок. \n + \en Checking and Correction step data for triangulation so that the number of points + does not exceed a predetermined count on the order of magnitude of.\n \~ + \param[in] cube - \ru Габаритный куб. + \en A dimensional cube. \~ + \param[in] count - \ru Предположительное предельное количество точек триангуляции для одной грани (10 000 000).\n + \en Proposed limit on the number of triangulation points for one face. \~ + \param[in] stepData - \ru Данные для вычисления шага при триангуляции. + \en Data for step calculation during triangulation. \~ + \return \ru true - были внесены изменения в stepData, false - изменений не было. + \en True - stepData was change, false - there was no change. \~ + \ingroup Triangulation +*/ +// --- +MATH_FUNC (bool) StepDataTune( const MbCube & cube, size_t count, MbStepData & stepData ); + + +#endif // __TRI_FACE_H \ No newline at end of file diff --git a/C3d/Include/tri_lump.h b/C3d/Include/tri_lump.h new file mode 100644 index 0000000..b04cd0f --- /dev/null +++ b/C3d/Include/tri_lump.h @@ -0,0 +1,115 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Математическая грань и ее расчитанная решетка. + \en Mathematical face and its calculated grid. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TRI_LUMP_H +#define __TRI_LUMP_H + + +#include +#include +#include + + +class MATH_CLASS MbGrid; + + +//---------------------------------------------------------------------------------------- +/** \brief \ru Математическая грань и ее рассчитанная решетка. + \en Mathematical face and its calculated grid. \~ + \ingroup Polygonal_Objects +*/ +// --- +class MATH_CLASS MbFaceAndGrid +{ + SPtr face; ///< \ru Грань. \en A face. +public: + SPtr grid; ///< \ru Триангуляция грани. \en A face triangulation. + +public: + /** \brief \ru Конструктор по грани и ее триангуляции.\n + \en Constructor by face and its triangulation.\n \~ + \param[in] _face - \ru Грань. + \en A face. \~ + \param[in] _grid - \ru Соответствующая грани триангуляционная решетка. + \en A triangulation grid which is corresponded to a face. \~ + */ + MbFaceAndGrid( const MbFace & _face, const MbGrid & _grid ) + : face( &_face ) + , grid( &_grid ) + {} + + /// \ru Конструктор копирования. \en Copy-constructor. + MbFaceAndGrid( const MbFaceAndGrid & faceGrid ) + : face( faceGrid.face ) + , grid( faceGrid.grid ) + {} + + const MbFace & Face() const { return *face; } +//const MbGrid & Grid() const { return *grid; } + + MbFaceAndGrid & operator = ( const MbFaceAndGrid & faceGrid ) + { + face = faceGrid.face; + grid = faceGrid.grid; + return *this; + } + + const MbFace & GetFace() const { return *face; } // deprecated +}; + + +//------------------------------------------------------------------------------ +/** \brief \ru Тело с массивом граней и триангуляционных решеток. + \en A solid with an array of faces and triangulation grids. \~ + \details \ru Тело, определенное в системе координат, + с массивом граней и триангуляционных решеток. + \en A solid determined in the coordinate system + with an array of faces and triangulation grids. \~ + \ingroup Polygonal_Objects +*/ +// --- +struct MATH_CLASS MbLumpAndFaces +{ +public: + const void * m_comp; ///< \ru Указатель на компонент. \en A pointer to the component. + MbMatrix3D m_toWCS; ///< \ru Матрица пересчета в мир. \en A matrix of transformation to the world coordinate system. + std::vector faces; ///< \ru Множество пар "грань и её решетка". \en An array of pairs "a face and its grid". + double sag; ///< \ru Точность, с которой рассчитывали решетку. \en The tolerance which was used for the calculation of a grid. + +public: + /** \brief \ru Конструктор. + \en Constructor. \~ + \details \ru Конструктор по матрице и компоненту.\n Создается тело с пустым массивом граней. + \en Constructor by matrix and component.\n A solid with an empty array of faces is created. \~ + \param[in] _from - \ru Матрица преобразования. + \en A transform matrix. \~ + \param[in] _comp - \ru Указатель на компонент. + \en A pointer to the component. \~ + \param[in] _sag - \ru Точность, с которой рассчитывали решетку. + \en The tolerance which was used for the calculation of a grid. \~ + */ + MbLumpAndFaces( const MbMatrix3D & _from, void * _comp, double _sag ) + : m_comp ( _comp ) + , m_toWCS( _from ) + , faces() + , sag( _sag ) + {} + + /** \brief \ru Добавить грань с триангуляцией. \en Add face with triangulation. \~ + \param[in] face - \ru Грань с триангулюционной решеткой. + \en A face with triangulation grid. \~ + */ + void AddFace( const MbFaceAndGrid & face ) { faces.push_back( face ); } + + // \ru Объявление конструктора копирования и оператора присваивания без реализации, чтобы не было присваивания по умолчанию. \en The declaration without implementation of the copy-constructor and assignment operator to prevent an assignment by default. + OBVIOUS_PRIVATE_COPY(MbLumpAndFaces); +}; + + +#endif // __TRI_LUMP_H diff --git a/C3d/Include/wire_frame.h b/C3d/Include/wire_frame.h new file mode 100644 index 0000000..e1285cc --- /dev/null +++ b/C3d/Include/wire_frame.h @@ -0,0 +1,358 @@ +//////////////////////////////////////////////////////////////////////////////// +/** + \file + \brief \ru Трехмерный проволочный каркас. + \en Three-dimensional wire frame. \~ + +*/ +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __WIRE_FRAME_H +#define __WIRE_FRAME_H + + +#include +#include +#include +#include +#include +#include + +class MATH_CLASS MbWireFrame; + + +namespace c3d // namespace C3D +{ +typedef SPtr WireFrameSPtr; +typedef SPtr ConstWireFrameSPtr; + +typedef std::vector WireFramesVector; +typedef std::vector ConstWireFramesVector; + +typedef std::vector WireFramesSPtrVector; +typedef std::vector ConstWireFramesSPtrVector; +} // namespace C3D + + +//------------------------------------------------------------------------------ +/** \brief \ru Трехмерный проволочный каркас. + \en Three-dimensional wire frame. \~ + \details \ru Трехмерный проволочный каркас состоит из множества рёбер MbEdge. \n + Каркас может состоять из нескольких связных частей. + Связная часть может иметь топологию звезды, при которой в одной вершине стыкуется более двух рёбер. + Каркас может быть разбит на отдельные связные части. Каждая связная часть обладает функциями составной кривой. + \en Three-dimensional wire frame consists of a set of edges of a type MbEdge. \n + A wire frame may consist of several connected parts. + A connected part may have a topology of a star where one vertex is coincident with more than two edges + A wire frame may be split into separate connected parts. Each connected part has functions of a composite curve. \~ + \ingroup Model_Items +*/ +// --- +class MATH_CLASS MbWireFrame : public MbItem { +protected : + c3d::WireEdgesVector edges; ///< \ru Множество рёбер каркаса. \en A set of edges of the frame. + size_t partsCount; ///< \ru Количество связных частей объекта. \en A number of connected parts of an object. + bool closed; ///< \ru Замкнутость указывает на возможность получит множество замкнутых кривых. \en Closedness indicates to a possibility to get a set of closed curves. + mutable bool normal; ///< \ru Разложен ли каркас на связные части? \en Is a frame split into connected parts? + +private : + /// \ru Конструктор копирования с регистратором. \en Copy-constructor with the registrator. + explicit MbWireFrame( const MbWireFrame &, MbRegDuplicate * ); +public : + /// \ru Конструктор без параметров. \en Constructor without parameters. + MbWireFrame(); + /// \ru Конструктор по кривой и строителю. \en Constructor by a curve and creator. + MbWireFrame( const MbCurve3D &, MbCreator * = NULL ); + /// \ru Конструктор по множеству кривых и строителю. \en Constructor by a set of curves and creator. + MbWireFrame( const RPArray &, MbCreator * = NULL ); + /// \ru Конструктор по ребру и строителю. \en Constructor by an edge and creator. + MbWireFrame( MbEdge &, MbCreator * = NULL, bool same = true ); + /// \ru Конструктор по множеству рёбер и строителю. \en Constructor by a set of edges and creator. + MbWireFrame( const RPArray &, MbCreator * = NULL, bool same = true ); + /// \ru Деструктор. \en Destructor. + virtual ~MbWireFrame(); + +public : + VISITING_CLASS( MbWireFrame ); + + // \ru Общие функции геометрического объекта. \en Common functions of a geometric object. + + virtual MbeSpaceType IsA() const; // \ru Тип объекта. \en An object type. + virtual MbSpaceItem & Duplicate( MbRegDuplicate * iReg = NULL ) const; // \ru Создать копию. \en Create a copy. + virtual void Transform( const MbMatrix3D &, MbRegTransform * = NULL ); // \ru Преобразовать согласно матрице. \en Transform according to the matrix. + virtual void Move ( const MbVector3D &, MbRegTransform * = NULL ); // \ru Сдвинуть вдоль вектора. \en Translate along a vector. + virtual void Rotate ( const MbAxis3D &, double angle, MbRegTransform * = NULL ); // \ru Повернуть вокруг оси. \en Rotate about an axis. + virtual bool IsSame ( const MbSpaceItem &, double accuracy = LENGTH_EPSILON ) const; // \ru Являются ли объекты равными? \en Are the objects equal? + virtual bool IsSimilar( const MbSpaceItem & ) const; // \ru Являются ли объекты подобными? \en Are the objects similar? + virtual bool SetEqual ( const MbSpaceItem & ); // \ru Сделать объекты равными. \en Make the objects equal. + virtual double DistanceToPoint ( const MbCartPoint3D & ) const; // \ru Вычислить расстояние до точки. \en Calculate distance to point. + virtual void AddYourGabaritTo( MbCube & ) const; // \ru Добавь свой габарит в куб. \en Add bounding box into a cube. + virtual void CalculateLocalGabarit( const MbMatrix3D & into, MbCube & cube ) const; // \ru Рассчитать габарит в локальной системы координат. \en Calculate the bounding box in a local coordinate system. + virtual void CalculateMesh( const MbStepData & stepData, const MbFormNote & note, MbMesh & mesh ) const; // \ru Построить полигональную копию mesh. \en Build polygonal copy mesh. + + virtual void GetProperties( MbProperties & ); // \ru Выдать свойства объекта. \en Get properties of the object. + virtual void SetProperties( const MbProperties & ); // \ru Установить свойства объекта. \en Set properties of the object. + virtual void GetBasisItems ( RPArray & ); // \ru Дать базовые объекты. \en Get the basis objects. + virtual void GetBasisPoints( MbControlData3D & ) const; // \ru Выдать контрольные точки объекта. \en Get control points of object. + virtual void SetBasisPoints( const MbControlData3D & ); // \ru Изменить объект по контрольным точкам. \en Change the object by control points. + virtual bool GetPlacement( MbPlacement3D & ) const; // \ru Проинициализировать присланную локальную систему координат (совместить плоскость XY), если каркас плоский. \en Initialize the sent local coordinate system (combine the plane XY) if the frame is planar. + // \ru Перестроить объект по журналу построения. \en Reconstruct object according to the history tree. + virtual bool RebuildItem( MbeCopyMode sameShell, RPArray * items, IProgressIndicator * progInd ); + + // \ru Создать полигональный объект - упрощенную копию данного объекта. \en Create a polygonal object - a simplified copy of the given object. + virtual MbItem * CreateMesh( const MbStepData & stepData, const MbFormNote & note, MbRegDuplicate * iReg ) const; + + /** \ru \name Общие функции каркаса. + \en \name Common functions of a frame. + \{ */ + + /// \ru Выдать количество ребер каркаса. \en Get the number of edges of the frame. + size_t GetEdgesCount() const { return edges.size(); } + /// \ru Выдать объект по индексу. \en Get the item by index. + const MbEdge * GetEdge( size_t index ) const; + /// \ru Выдать объект по индексу для возможного редактирования. \en Get the item by index for the possible editing. + MbEdge * SetEdge( size_t index ); + /// \ru Добавить ребро по кривой и ее ориентации в ребре. \en Add an edge by a curve and its orientation in relation to an edge. + void AddEdge( MbCurve3D &, bool sense = true ); + /// \ru Добавить ребро (оригинал, не копию). \en Add an edge (an original, not a copy). + void AddEdge( MbEdge &, bool same = true ); + /// \ru Добавить массив ребер (оригиналы, не копии). \en Add an array of edges (originals, not copies). + void AddEdges( const RPArray &, bool same = true ); + /// \ru Вставить ребро по индексу (оригинал, не копию). \en Insert an edge by index (an original, not a copy). + void InsertEdge( size_t index, MbEdge & item, bool same = true ); + /// \ru Отцепить ребро по индексу. \en Detach an edge by index. + MbEdge * DetachEdge( size_t index ); + /// \ru Удалить все рёбра. \en Delete all edges. + void DeleteEdges(); + /// \ru Удалить ребро по индексу. \en Delete an edge by index. + bool DeleteEdge( size_t index ); + /// \ru Удалить ребро, если таковое имеется. \en Delete an edge if it already exists. + bool DeleteEdge( MbEdge * ); + + /// \ru Выдать массив вершин ребер каркаса. \en Get an array of frame edges vertices. + void GetVerticesArray ( RPArray & ); + /// \ru Выдать массив вершин ребер каркаса. \en Get an array of frame edges vertices. + void GetVerticesArray ( RPArray & ) const; + + /// \ru Выдать вершину-начало каркаса. \en Get the start vertex of a frame. + const MbVertex * GetBegVertex() const; + /// \ru Выдать вершину-конец каркаса. \en Get the end vertex of a frame. + const MbVertex * GetEndVertex() const; + + /// \ru Найти вершину по имени. \en Find vertex by name. + const MbVertex * FindVertexByName( const MbName & ) const; + /// \ru Найти ребро по имени. \en Find edge by name. + const MbEdge * FindEdgeByName ( const MbName & ) const; + + /** \brief \ru Разбить ребро по параметрам его кривой на несколько его частей. + \en Split the edge using the curve parameters into several pieces. \~ + \details \ru . Если beginSafe == true - ребро сохранит начальный участок, + Если beginSafe == false - ребро сохранит конечный участок. + По параметру 'eps' отсеиваются значения в контейнере 'params', совпадающие друг с другом и с начальным и конечным параметрами кривой. + Контейнер 'edges' содержит отрезанные части. + \en . If beginSafe == true then the edge saves its starting piece, + If beginSafe == false then the edge saves its ending piece. + According to the parameter 'eps' drop out value in the container 'params', coinciding with each other and with the initial and final parameters of the curve. + The container 'edges' contains cut parts. \~ + \params[in, out] targetEdge - \ru Ребро для разрезания. Возвращается урезанный кусок с учетом флага beginSafe или NULL, + если параметр разрезания находится на расстоянии меньшим еps от соответствующего конца кривой, + \en Edge for cutting. The return value of 'targetEdge' is the shortened edge according to 'beginSafe' flag + or NULL, if the cut param in 'params' lies at the distance less than 'eps' from the corresponding end of the curve, + \param[in] params - \ru Параметры кривой для разбиения ребра, + \en Parameters of intersection curve of edge to split, \~ + \param[in] beginSafe - \ru Ребро сохранит начальную часть (true) или ребро сохранит конечную часть (false), + \en The edge will keep a beginning piece (true) or the edge will keep an end piece (false) \~ + \param[in] eps - \ru Точность совпадения параметров разбиения, + \en Precision matching options of parameters to split, \~ + \param[out] edges - \ru Отрезанные части ребра. + \en The container of cut parts. \~ + \return \ru Возвращает true, если ребро было разрезано. + \en Returns true, if the edge was cut. \~ + */ + bool CuttingEdge( MbEdge *& targetEdge, SArray & params, bool beginSafe, double eps, RPArray & edges ); + + /// \ru Замкнут ли каркас? \en Is frame closed? + bool IsClosed(); + /// \ru Является ли каркас многосвязным? \en Is frame multiply connected? + bool IsMultiWireFrame(); + /// \ru Количество связных частей каркаса. \en A number of connected parts of a frame. + size_t GetPartsCount(); + + /// \ru Является ли объект плоским? \en Is the object planar? + bool IsPlanar() const; + /// \ru Дать плоскую кривую и ее систему координат, если пространственная кривая плоская (после использования вызывать DeleteItem на двумерные кривые). \en Get planar coordinate system if the space curve is planar (after the using call DeleteItem for two-dimensional curves) + bool MakePlaneCurves( RPArray & curves, MbPlacement3D & place ) const; + /// \ru Дать кривую на поверхности, если пространственная кривая на поверхности (после использования вызывать DeleteItem на двумерные кривые). \en Get a surface curve if a space curve is on a surface (after the using call DeleteItem for two-dimensional curves) + bool MakeSurfaceCurves( RPArray & curves, MbSurface *& surface ) const; + /// \ru Построить контуры из копий кривых. \en Construct contours of curves copies. + bool MakeCurves( RPArray & ) const; + /// \ru Положить в массив оригиналы кривых. \en Put originals of curves into an array. + template + void GetCurves( CurvesVector & ) const; + /// \ru Разложен ли каркас на связные части? \en Is a frame split into connected parts? + bool IsNormalizeWire() const { return normal; } + /// \ru Переставить кривые и переориентировать ребра, создав связные цепочки с общими вершинами. \en Perform curves reposition and edges reorientation by creating connected chains with common vertices. + void NormalizeWire(); + + /** \brief \ru Отделение частей каркаса. + \en Detachment of frame parts \~ + \details \ru Отделение частей каркаса с сохранением исходного объекта. + Если исходный каркас распадается на части, то все части складываются в parts. \n + \en Detachment of frame parts with saving an initial object. + If the initial frame is decomposed, all the parts are put into array 'parts'. \n \~ + \param[out] parts - \ru Каркасы, полученные из frame. + \en Frames obtained from 'frame'. \~ + \result \ru Возвращает количество каркасов в parts. + \en Returns a number of frames in 'parts'. \~ + */ + size_t CreateParts( RPArray & parts ); + /** \} */ + + /// \ru Установить заданный флаг измененности для всех рёбер и вершин. \en Set flag of changes for all edges and vertices. + void SetOwnChangedThrough( MbeChangedType ); + +private: + /// \ru Связано ли ребро с каким-либо ребром каркаса. \en Whether an edge is connected with another edge of a frame. + bool IsConnectedWith( const MbEdge & ); + /// \ru Нормализовать ребро (выставить общую вершину замкнутого ребра) \en Normalize an edge (set the common vertex af a closed edge) + void NormalizeEdge( MbEdge & ); + +DECLARE_PERSISTENT_CLASS_NEW_DEL( MbWireFrame ) +OBVIOUS_PRIVATE_COPY( MbWireFrame ) +}; + +IMPL_PERSISTENT_OPS( MbWireFrame ) + +//------------------------------------------------------------------------------ +// \ru Положить в массив оригиналы кривых. \en Put originals of curves into an array. +// --- +template +void MbWireFrame::GetCurves( CurvesVector & curves ) const +{ + size_t edgesCnt = edges.size(); + curves.reserve( curves.size() + edgesCnt ); + SPtr curve; + for ( size_t k = 0; k < edgesCnt; ++k ) { + const MbEdge * edge = edges[k]; + if ( edge != NULL ) { + curve = const_cast( &edge->GetCurve() ); + curves.push_back( curve ); + ::DetachItem( curve ); + } + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Забрать кривые и удалить каркас, если он не используется. + \en Take curves and delete a frame if it is not used. \~ + \details \ru Забрать кривые и удалить каркас, если он не используется. \n + \en Take curves and delete a frame if it is not used. \n \~ + \param[in] wireFrame - \ru Каркас, подлежащий удалению. + \en A frame to delete. \~ + \param[out] curves - \ru Кривые, полученные из каркаса. + \en Curves obtained from the frame. \~ + \ingroup Curve3D_Modeling +*/ +// --- +inline +void ExtractCurvesDeleteFrame( MbWireFrame *& wireFrame, RPArray & curves ) +{ + if ( wireFrame != NULL ) { + c3d::SpaceCurvesSPtrVector curvesVect; + wireFrame->GetCurves( curvesVect ); + if ( curvesVect.size() > 0 ) { + curves.Reserve( curvesVect.size() ); + for ( size_t k = 0, cnt = curvesVect.size(); k < cnt; k++ ) { + MbCurve3D * curve = ::DetachItem( curvesVect[k] ); + if ( curve != NULL ) { + curves.Add( curve ); + } + } + } + ::AddRefItems( curves ); + ::DeleteItem( wireFrame ); + ::DecRefItems( curves ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Забрать первую кривую и удалить каркас, если он пуст и не используется. + \en Take the first curve and delete a frame if it is empty and not used. \~ + \details \ru Забрать первую кривую и удалить каркас, если он пуст и не используется. \n + \en Take the first curve and delete a frame if it is empty and not used. \n \~ + \param[in] wireFrame - \ru Каркас, подлежащий удалению. + \en A frame to delete. \~ + \param[out] curve - \ru Кривая, полученная из каркаса. + \en A curve obtained from the frame. \~ + \ingroup Curve3D_Modeling +*/ +// --- +inline +void ExtractCurveDeleteFrame( MbWireFrame *& wireFrame, MbCurve3D *& curve ) +{ + if ( wireFrame != NULL ) { + MbEdge * edge = wireFrame->DetachEdge( 0 ); // \ru Отцепить объект \en Detach an object + if ( edge != NULL ) { + curve = &edge->SetCurve(); + ::AddRefItem( curve ); + ::DeleteItem( edge ); + ::DeleteItem( wireFrame ); + ::DecRefItem( curve ); + } + else + ::DeleteItem( wireFrame ); + } +} + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать каркас по множеству кривых. + \en Create a frame by a set of curves. \~ + \details \ru Создать или обновить каркас по множеству кривых. \n + \en Create or update a frame by a set of curves. \n \~ + \param[out] result - \ru Каркас, подлежащий замене или построению. + \en A frame to replace or construct. \~ + \param[in] curves - \ru Кривые для построения каркаса. + \en Curves for the frame construction. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[in] creator - \ru Строитель каркаса. + \en A creator of a frame. \~ + \result \ru Возвращает true, если присланный каркас обновился, или был создан новый при отсутствии каркаса на входе. + \en Returns true if the sent frame has been updated or if the new frame has been created without a frame in the input. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (bool) CreateWireFrame( MbWireFrame *& result, + const RPArray & curves, + const MbSNameMaker & snMaker, + MbCreator * creator = NULL ); + + +//------------------------------------------------------------------------------ +/** \brief \ru Создать каркас по кривой. + \en Create a frame by a curve. \~ + \details \ru Создать или обновить каркас по кривой. \n + \en Create or update a frame by a curve. \n \~ + \param[out] result - \ru Каркас, подлежащий замене или построению. + \en A frame to replace or construct. \~ + \param[in] curve - \ru Кривая для построения каркаса. + \en A curve for the frame construction. \~ + \param[in] snMaker - \ru Именователь кривых каркаса. + \en An object defining the frame curves names. \~ + \param[in] creator - \ru Строитель каркаса. + \en A creator of a frame. \~ + \result \ru Возвращает true, если присланный каркас обновился, или был создан новый при отсутствии каркаса на входе. + \en Returns true if the sent frame has been updated or if the new frame has been created without a frame in the input. \~ + \ingroup Curve3D_Modeling +*/ +// --- +MATH_FUNC (bool) CreateWireFrame( MbWireFrame *& result, + const MbCurve3D & curve, + const MbSNameMaker & snMaker, + MbCreator * creator = NULL ); + + +#endif // __WIRE_FRAME_H